| 363 | } |
| 364 | |
| 365 | Status PyLocalBuffer::CopyToHostAsync() { |
| 366 | std::shared_ptr<SharedDeviceBuffer> device_buffer; |
| 367 | std::shared_ptr<HostValue> host_value; |
| 368 | { |
| 369 | absl::MutexLock lock(&mu_); |
| 370 | if (!device_buffer_) { |
| 371 | return InvalidArgument("CopyToHostAsync() called on invalid buffer."); |
| 372 | } |
| 373 | device_buffer = device_buffer_; |
| 374 | |
| 375 | if (host_value_) { |
| 376 | // The host value has already been requested or is available. |
| 377 | return Status::OK(); |
| 378 | } |
| 379 | host_value = host_value_ = std::make_shared<HostValue>(); |
| 380 | } |
| 381 | se::Stream* stream = device_->local_device_state()->GetDeviceToHostStream(); |
| 382 | WaitForBufferDefinitionEventsOnStream(*device_buffer, stream); |
| 383 | host_value->value = std::make_shared<Literal>(on_host_shape_); |
| 384 | TF_ASSIGN_OR_RETURN(ShapedBuffer shaped_buffer, AsShapedBuffer()); |
| 385 | client_->client()->backend().transfer_manager()->TransferLiteralFromDevice( |
| 386 | stream, shaped_buffer, host_value->value.get(), |
| 387 | [host_value](Status done_status) { |
| 388 | host_value->status = done_status; |
| 389 | host_value->ready.Notify(); |
| 390 | }); |
| 391 | return Status::OK(); |
| 392 | } |
| 393 | |
| 394 | StatusOr<std::shared_ptr<Literal>> PyLocalBuffer::ToLiteral() { |
| 395 | tensorflow::profiler::TraceMe traceme("PyLocalBuffer::ToLiteral"); |
nothing calls this directly
no test coverage detected