| 58 | |
| 59 | private: |
| 60 | void Compute(KernelComputeContext* ctx) const override { |
| 61 | auto primitive = NewPermutePrimitive(ctx); |
| 62 | CHECK(primitive); |
| 63 | |
| 64 | const Tensor* tensor_in = ctx->Tensor4ArgNameAndIndex("input", 0); |
| 65 | Tensor* tensor_out = ctx->Tensor4ArgNameAndIndex("output", 0); |
| 66 | const auto& perm = ctx->Attr<std::vector<int32_t>>("perm"); |
| 67 | const ShapeView& in_shape = tensor_in->shape_view(); |
| 68 | DataType dtype = tensor_out->data_type(); |
| 69 | size_t num_dims = tensor_in->shape_view().NumAxes(); |
| 70 | const int64_t* src_dims = in_shape.ptr(); |
| 71 | |
| 72 | int64_t elem_cnt = tensor_out->shape_view().elem_cnt(); |
| 73 | |
| 74 | if (elem_cnt != 0) { |
| 75 | if (IsIdentity(in_shape, perm)) { |
| 76 | // if permute vector is 0,1,...,n, do data copy directly |
| 77 | AutoMemcpy(ctx->stream(), tensor_out->mut_dptr(), tensor_in->dptr(), |
| 78 | elem_cnt * GetSizeOfDataType(dtype), tensor_out->mem_case(), |
| 79 | tensor_in->mem_case()); |
| 80 | } else { |
| 81 | primitive->Launch(ctx->stream(), dtype, num_dims, src_dims, tensor_in->dptr(), perm.data(), |
| 82 | tensor_out->mut_dptr()); |
| 83 | } |
| 84 | |
| 85 | } else { |
| 86 | // For 0-d Tensor |
| 87 | return; |
| 88 | } |
| 89 | } |
| 90 | bool AlwaysComputeWhenAllOutputsEmpty() const override { return false; } |
| 91 | }; |
| 92 |
nothing calls this directly
no test coverage detected