| 262 | } |
| 263 | |
| 264 | Maybe<void> InplaceUnsqueeze(const std::shared_ptr<Tensor>& input, const int32_t expand_dim) { |
| 265 | const auto& shape = input->shape(); |
| 266 | const auto& strides = JUST(input->stride()); |
| 267 | const auto& ndim = shape->NumAxes(); |
| 268 | |
| 269 | DimVector target_dim_vec(ndim + 1); |
| 270 | Stride target_stride_vec(ndim + 1); |
| 271 | |
| 272 | { |
| 273 | int cnt = 0; |
| 274 | for (int i = 0; i < ndim; i++) { |
| 275 | if (i == expand_dim) { cnt++; } |
| 276 | target_dim_vec[cnt] = shape->at(i); |
| 277 | target_stride_vec[cnt] = strides->at(i); |
| 278 | cnt++; |
| 279 | } |
| 280 | target_dim_vec[expand_dim] = 1; |
| 281 | target_stride_vec[expand_dim] = |
| 282 | expand_dim < ndim ? strides->at(expand_dim) * target_dim_vec.at(expand_dim + 1) : 1; |
| 283 | } |
| 284 | |
| 285 | int64_t storage_offset = JUST(JUST(input->AsLocalTensor())->storage_offset()); |
| 286 | JUST(view::InplaceView(input, Shape(target_dim_vec), target_stride_vec, storage_offset)); |
| 287 | |
| 288 | if (autograd::GradMode::is_enabled() && input->requires_grad()) { |
| 289 | auto backward_fn = std::make_shared<BackwardFunction>(); |
| 290 | backward_fn->body = [=](const TensorTuple& out_grads, TensorTuple* in_grads, |
| 291 | bool create_graph) -> Maybe<void> { |
| 292 | autograd::AutoGradMode mode(create_graph); |
| 293 | CHECK_EQ_OR_RETURN(out_grads.size(), 1); // NOLINT(maybe-need-error-msg) |
| 294 | in_grads->resize(1); |
| 295 | JUST(oneflow::VectorAt(*in_grads, 0)) = |
| 296 | JUST(functional::Reshape(JUST(oneflow::VectorAt(out_grads, 0)), *shape)); |
| 297 | return Maybe<void>::Ok(); |
| 298 | }; |
| 299 | backward_fn->status = []() { return false; }; |
| 300 | TensorTuple outputs{input}; |
| 301 | JUST(GetThreadLocalAutogradEngine()->AddNode("view::inplace_unsqueeze_backward", backward_fn, |
| 302 | {input}, &outputs)); |
| 303 | } |
| 304 | return Maybe<void>::Ok(); |
| 305 | } |
| 306 | |
| 307 | Maybe<Tensor> Squeeze(const std::shared_ptr<Tensor>& input, |
| 308 | const std::vector<int32_t>& squeeze_dims) { |
no test coverage detected