| 276 | explicit SplitOpGPU(OpKernelConstruction* c) : Base(c) {} |
| 277 | |
| 278 | void Compute(OpKernelContext* context) override { |
| 279 | bool done = false; |
| 280 | Base::ComputeEasyCases(context, &done); |
| 281 | if (!context->status().ok() || done) { |
| 282 | return; |
| 283 | } |
| 284 | const Tensor& input = context->input(1); |
| 285 | const TensorShape& input_shape = input.shape(); |
| 286 | const int32 split_dim_orig = context->input(0).flat<int32>()(0); |
| 287 | const int32 split_dim = |
| 288 | split_dim_orig < 0 ? split_dim_orig + input.dims() : split_dim_orig; |
| 289 | const int32 num_split = Base::num_outputs(); |
| 290 | OP_REQUIRES( |
| 291 | context, |
| 292 | FastBoundsCheck(input.NumElements(), std::numeric_limits<int32>::max()), |
| 293 | errors::InvalidArgument("Split on GPU requires input size " |
| 294 | "< max int32")); |
| 295 | int32 prefix_dim_size; |
| 296 | int32 split_dim_size; |
| 297 | int32 suffix_dim_size; |
| 298 | std::tie(prefix_dim_size, split_dim_size, suffix_dim_size) = |
| 299 | Base::template SetDims<int32>(input_shape, split_dim); |
| 300 | |
| 301 | const int32 split_dim_output_size = split_dim_size / num_split; |
| 302 | TensorShape output_shape(input_shape); |
| 303 | output_shape.set_dim(split_dim, split_dim_output_size); |
| 304 | |
| 305 | GpuDeviceArrayOnHost<T*> ptrs(context, num_split); |
| 306 | OP_REQUIRES_OK(context, ptrs.Init()); |
| 307 | |
| 308 | for (int i = 0; i < num_split; ++i) { |
| 309 | Tensor* result = nullptr; |
| 310 | OP_REQUIRES_OK(context, |
| 311 | context->allocate_output(i, output_shape, &result)); |
| 312 | ptrs.Set(i, result->flat<T>().data()); |
| 313 | } |
| 314 | if (prefix_dim_size * split_dim_output_size * suffix_dim_size == 0) { |
| 315 | return; |
| 316 | } |
| 317 | OP_REQUIRES_OK(context, ptrs.Finalize()); |
| 318 | |
| 319 | SplitOpGPULaunch<T>().Run(context->eigen_device<GPUDevice>(), |
| 320 | input.flat<T>().data(), prefix_dim_size, |
| 321 | split_dim_size, suffix_dim_size, ptrs.data()); |
| 322 | OP_REQUIRES(context, context->op_device_context()->stream()->ok(), |
| 323 | errors::Internal("Launch of gpu kernel for SplitOp failed")); |
| 324 | } |
| 325 | }; |
| 326 | #endif // GOOGLE_CUDA || TENSORFLOW_USE_ROCM |
| 327 |
nothing calls this directly
no test coverage detected