| 288 | ~SliceKernel() = default; |
| 289 | |
| 290 | std::shared_ptr<user_op::OpKernelCache> InitOpKernelCache( |
| 291 | user_op::KernelCacheContext* ctx) const override { |
| 292 | SliceContext slice_ctx; |
| 293 | if (ctx->parallel_ctx().parallel_num() == 1) { |
| 294 | // split_axis == SPLIT_AXIS_FOR_NON_SPLIT means the sbp attribute is not 'split' |
| 295 | CHECK_JUST(slice_ctx.PushSplitInfo(SPLIT_AXIS_FOR_NON_SPLIT, 0, 0, 0)); |
| 296 | } else { |
| 297 | const Shape& parallel_hierarchy = *ctx->parallel_desc().hierarchy(); |
| 298 | NdSbp in_nd_sbp = ctx->NdSbp4ArgNameAndIndex("x", 0); |
| 299 | { |
| 300 | const NdSbp& y_nd_sbp = ctx->NdSbp4ArgNameAndIndex("y", 0); |
| 301 | // If x and y both split in the same axis(must be full slice), |
| 302 | // we can consider the physical tensor is broadcast in this axis. |
| 303 | FOR_RANGE(int32_t, i, 0, parallel_hierarchy.NumAxes()) { |
| 304 | const SbpParallel& x_sbp = in_nd_sbp.sbp_parallel(i); |
| 305 | const SbpParallel& y_sbp = y_nd_sbp.sbp_parallel(i); |
| 306 | if (x_sbp.has_split_parallel() && y_sbp.has_split_parallel()) { |
| 307 | CHECK_EQ(x_sbp.split_parallel().axis(), y_sbp.split_parallel().axis()); |
| 308 | in_nd_sbp.mutable_sbp_parallel(i)->clear_split_parallel(); |
| 309 | in_nd_sbp.mutable_sbp_parallel(i)->mutable_broadcast_parallel(); |
| 310 | } |
| 311 | } |
| 312 | } |
| 313 | const Shape& logical_shape = ctx->LogicalTensorDesc4ArgNameAndIndex("x", 0)->shape(); |
| 314 | const int64_t parallel_id = ctx->parallel_ctx().parallel_id(); |
| 315 | const TensorSliceView& slice_view = |
| 316 | GetTensorSliceView4ParallelId(parallel_hierarchy, in_nd_sbp, logical_shape, parallel_id); |
| 317 | for (int i = 0; i < logical_shape.NumAxes(); ++i) { |
| 318 | const Range& range = slice_view.At(i); |
| 319 | if (range.begin() != 0 || range.end() != logical_shape.At(i)) { |
| 320 | CHECK_JUST(slice_ctx.PushSplitInfo(i, range.begin(), range.end(), logical_shape.At(i))); |
| 321 | } |
| 322 | } |
| 323 | } |
| 324 | return std::make_shared<OpKernelCacheWrapper<SliceContext>>(slice_ctx); |
| 325 | } |
| 326 | |
| 327 | private: |
| 328 | void Compute(user_op::KernelComputeContext* ctx, user_op::OpKernelState*, |
nothing calls this directly
no test coverage detected