MCPcopy Create free account
hub / github.com/Oneflow-Inc/oneflow / Slice

Function Slice

oneflow/core/framework/tensor_methods.cpp:168–218  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

166}
167
168Maybe<Tensor> Slice(const std::shared_ptr<Tensor>& input, const std::vector<int64_t>& starts,
169 const std::vector<int64_t>& ends, const std::vector<int64_t>& steps) {
170 const auto& shape = input->shape();
171 const auto& strides = JUST(input->stride());
172 const int64_t ndim = starts.size();
173
174 CHECK_OR_RETURN(ndim == shape->NumAxes())
175 << Error::RuntimeError() << "view::Slice(): starts size is expected " << shape->NumAxes()
176 << ", but got " << ndim;
177
178 CHECK_OR_RETURN(ends.size() == ndim && steps.size() == ndim)
179 << Error::RuntimeError() << "view::Slice(): " << (ends.size() != ndim ? "ends" : "steps")
180 << " size is not equal to start.";
181
182 DimVector target_dims(ndim);
183 Stride target_strides(ndim);
184 int64_t storage_offset = JUST(JUST(input->AsLocalTensor())->storage_offset());
185 for (int i = 0; i < ndim; ++i) {
186 int64_t step = std::min(steps[i], shape->At(i));
187 CHECK_OR_RETURN(step >= 0) << Error::RuntimeError() << "Step must be greater than zero.";
188 int64_t start = std::min(starts[i], shape->At(i));
189 int64_t end = std::min(ends[i], shape->At(i));
190 if (start < 0) { start += shape->At(i); }
191 if (start < 0) start = 0;
192 if (end < 0) { end += shape->At(i); }
193 if (end < start) end = start;
194 int64_t length = start == end ? 0 : (end - start + step - 1) / step;
195 target_dims[i] = length;
196 target_strides[i] = step * strides->at(i);
197 storage_offset += start * strides->at(i);
198 }
199
200 auto output = JUST(BasicView(input, Shape(target_dims), target_strides, storage_offset));
201 if (autograd::GradMode::is_enabled() && input->requires_grad()) {
202 const Shape in_shape = *input->shape();
203 auto backward_fn = std::make_shared<BackwardFunction>();
204 backward_fn->body = [=](const TensorTuple& out_grads, TensorTuple* in_grads,
205 bool create_graph) -> Maybe<void> {
206 autograd::AutoGradMode mode(create_graph);
207 CHECK_EQ_OR_RETURN(out_grads.size(), 1); // NOLINT(maybe-need-error-msg)
208 in_grads->resize(1);
209 (*in_grads)[0] = JUST(functional::SliceGrad(out_grads[0], in_shape, starts, ends, steps));
210 return Maybe<void>::Ok();
211 };
212 backward_fn->status = []() { return true; };
213 TensorTuple outputs{output};
214 JUST(GetThreadLocalAutogradEngine()->AddNode("view::slice_backward", backward_fn, {input},
215 &outputs));
216 }
217 return output;
218}
219
220Maybe<Tensor> Unsqueeze(const std::shared_ptr<Tensor>& input, const int32_t expand_dim) {
221 const auto& shape = input->shape();

Callers

nothing calls this directly

Calls 15

BasicViewFunction · 0.85
AddNodeMethod · 0.80
ShapeClass · 0.70
is_enabledFunction · 0.70
shapeMethod · 0.45
strideMethod · 0.45
sizeMethod · 0.45
NumAxesMethod · 0.45
storage_offsetMethod · 0.45
AsLocalTensorMethod · 0.45
AtMethod · 0.45

Tested by

no test coverage detected