| 410 | |
| 411 | private: |
| 412 | void Compute(user_op::KernelComputeContext* ctx) const override { |
| 413 | const user_op::Tensor* dy_tensor = ctx->Tensor4ArgNameAndIndex("dy", 0); |
| 414 | user_op::Tensor* dx_tensor = ctx->Tensor4ArgNameAndIndex("dx", 0); |
| 415 | size_t dx_byte_size = dx_tensor->shape_view().elem_cnt() * sizeof(T); |
| 416 | Memset<device_type>(ctx->stream(), dx_tensor->mut_dptr<T>(), 0, dx_byte_size); |
| 417 | if (dy_tensor->shape_view().elem_cnt() == 0) { return; } |
| 418 | SliceParams params = ConstructSliceParams(ctx, dx_tensor, dy_tensor); |
| 419 | SliceKernelUtil<device_type, T>::Backward(ctx->stream(), params, dy_tensor->dptr<T>(), |
| 420 | dx_tensor->mut_dptr<T>()); |
| 421 | } |
| 422 | bool AlwaysComputeWhenAllOutputsEmpty() const override { return false; } |
| 423 | }; |
| 424 |
nothing calls this directly
no test coverage detected