| 84 | |
| 85 | private: |
| 86 | void Compute(user_op::KernelComputeContext* ctx, user_op::OpKernelState*, |
| 87 | const user_op::OpKernelCache* cache) const override { |
| 88 | const user_op::Tensor* in = ctx->Tensor4ArgNameAndIndex("in", 0); |
| 89 | const user_op::Tensor* indices = ctx->Tensor4ArgNameAndIndex("indices", 0); |
| 90 | const int64_t axis = ctx->Attr<int64_t>("axis"); |
| 91 | const int64_t num_indices = indices->shape_view().elem_cnt(); |
| 92 | user_op::Tensor* out = ctx->Tensor4ArgNameAndIndex("out", 0); |
| 93 | if (out->shape_view().elem_cnt() == 0) { return; } |
| 94 | |
| 95 | const Shape in_shape = ExpandDimIf0D(in->shape_view()); |
| 96 | |
| 97 | int64_t offset = 0; |
| 98 | if (cache != nullptr) { |
| 99 | auto* gather_cache = dynamic_cast<const GatherOpKernelCache*>(cache); |
| 100 | CHECK_NOTNULL(gather_cache); |
| 101 | CHECK_EQ(in_shape.At(axis), gather_cache->upper() - gather_cache->lower()); |
| 102 | offset = gather_cache->lower(); |
| 103 | } |
| 104 | |
| 105 | GatherKernelUtilImpl<device_type, T, K>::Forward(ctx->stream(), indices->dptr<K>(), num_indices, |
| 106 | in->dptr<T>(), GetFlatShape(in_shape, axis), |
| 107 | out->mut_dptr<T>(), offset); |
| 108 | } |
| 109 | bool AlwaysComputeWhenAllOutputsEmpty() const override { return false; } |
| 110 | }; |
| 111 |
nothing calls this directly
no test coverage detected