| 59 | } |
| 60 | |
| 61 | void Compute(OpKernelContext* context) override { |
| 62 | const Tensor& src_tensor = context->input(0); |
| 63 | |
| 64 | if (src_tensor.IsInitialized() && |
| 65 | DataTypeCanUseMemcpy(src_tensor.dtype()) && |
| 66 | DebugIO::IsCopyNodeGateOpen(debug_op_and_url_specs_)) { |
| 67 | // Source tensor is initialized and is mem-copyable. Make a copy. |
| 68 | Tensor* copied_tensor; |
| 69 | OP_REQUIRES_OK(context, context->allocate_output(0, src_tensor.shape(), |
| 70 | &copied_tensor)); |
| 71 | |
| 72 | #if GOOGLE_CUDA || TENSORFLOW_USE_ROCM |
| 73 | Device* device = static_cast<Device*>(context->device()); |
| 74 | // Determine if the input tensor is not on CPU (e.g., on GPU). |
| 75 | bool off_host_input = device->device_type() == DEVICE_GPU && |
| 76 | !context->input_alloc_attr(0).on_host(); |
| 77 | |
| 78 | if (off_host_input) { |
| 79 | DeviceContext* device_ctxt = context->op_device_context(); |
| 80 | // Input is not on host: deep-copy it from GPU to the same GPU. |
| 81 | Notification done_copy; |
| 82 | GPUUtil::CopyGPUTensorToSameGPU( |
| 83 | device, device_ctxt, &src_tensor, copied_tensor, |
| 84 | [&done_copy](const Status& s) { done_copy.Notify(); }); |
| 85 | done_copy.WaitForNotification(); |
| 86 | } else { |
| 87 | // The input tensor is on the host (CPU): deep-copy from CPU to CPU. |
| 88 | *copied_tensor = tensor::DeepCopy(src_tensor); |
| 89 | } |
| 90 | #elif defined(TENSORFLOW_USE_SYCL) |
| 91 | Device* device = static_cast<Device*>(context->device()); |
| 92 | // Determine if the input tensor is not on CPU (e.g., on GPU). |
| 93 | const bool off_host_input = device->device_type() == DEVICE_SYCL && |
| 94 | !context->input_alloc_attr(0).on_host(); |
| 95 | |
| 96 | if (off_host_input) { |
| 97 | SYCLmemcpy(context->eigen_sycl_device(), src_tensor, copied_tensor); |
| 98 | } else { |
| 99 | *copied_tensor = tensor::DeepCopy(src_tensor); |
| 100 | } |
| 101 | #else |
| 102 | *copied_tensor = tensor::DeepCopy(src_tensor); |
| 103 | #endif |
| 104 | } else { |
| 105 | // Source tensor is NOT initialized and/or is not mem-copyable: Forward |
| 106 | // the Tensor object. |
| 107 | context->set_output(0, src_tensor); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | bool IsExpensive() override { return false; } |
| 112 |
nothing calls this directly
no test coverage detected