MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / PopulateOutputs

Method PopulateOutputs

tensorflow/compiler/jit/xla_launch_util.cc:250–433  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

248}
249
250Status XlaComputationLaunchContext::PopulateOutputs(
251 OpKernelContext* ctx, const XlaCompiler::CompilationResult* kernel,
252 ScopedShapedBuffer output, int missing_ctx_input_prefix) {
253 se::Stream* stream =
254 ctx->op_device_context() ? ctx->op_device_context()->stream() : nullptr;
255
256 // Computation output should always be a tuple.
257 if (VLOG_IS_ON(2)) {
258 VLOG(2) << "Result tuple shape: " << output.on_host_shape().DebugString();
259 VLOG(2) << "Result tuple shape (on device): "
260 << output.on_device_shape().DebugString();
261 }
262 CHECK_EQ(ctx->num_outputs(), kernel->outputs.size());
263
264 // If the on-host-shape isn't a tuple, create a new single-element tuple
265 // buffer with a nullptr root index table. This allows the code below to treat
266 // output as a tuple unconditionally.
267 if (!output.on_host_shape().IsTuple()) {
268 ShapedBuffer nontuple_buffer = output.release();
269 ShapedBuffer buffer(
270 xla::ShapeUtil::MakeTupleShape({nontuple_buffer.on_host_shape()}),
271 xla::ShapeUtil::MakeTupleShape({nontuple_buffer.on_device_shape()}),
272 output.platform(), output.device_ordinal());
273 buffer.buffers().CopySubtreeFrom(nontuple_buffer.buffers(),
274 /*source_base_index=*/{},
275 /*target_base_index=*/{0});
276 output = ScopedShapedBuffer(std::move(buffer), output.memory_allocator());
277 }
278
279 std::shared_ptr<se::Event> definition_event;
280 if (use_multiple_streams_) {
281 definition_event = std::make_shared<se::Event>(stream->parent());
282 if (!definition_event->Init()) {
283 return errors::Internal("Failed to initialize tensor definition event.");
284 }
285 stream->ThenRecordEvent(definition_event.get());
286 }
287
288 // Copy XLA results to the OpOutputList.
289 int output_num = 0;
290 for (int i = 0; i < ctx->num_outputs(); ++i) {
291 Allocator* allocator = ctx->device()->GetAllocator({});
292 if (kernel->outputs[i].is_constant) {
293 // Output is a constant.
294 const Tensor& const_tensor = kernel->outputs[i].constant_value;
295 Tensor* output_tensor;
296 const size_t total_bytes = const_tensor.TotalBytes();
297 if (stream && total_bytes > 0) {
298 // Copy host -> device. (Empty tensors don't have backing buffers.)
299 // Manually allocate memory using an XlaTensorBuffer so we can allocate
300 // as much memory as the device requires (as given by
301 // GetByteSizeRequirement). This avoids XlaTransferManager having to
302 // reallocate the device buffer later.
303 VLOG(1) << "Constant output tensor on device";
304
305 TF_RETURN_IF_ERROR(
306 ctx->allocate_output(i, const_tensor.shape(), &output_tensor));
307

Callers 2

RunMethod · 0.80
ComputeMethod · 0.80

Calls 15

ScopedShapedBufferClass · 0.85
InternalFunction · 0.85
HandleFromInputFunction · 0.85
LockVariablesFunction · 0.85
CopySubtreeFromMethod · 0.80
allocate_outputMethod · 0.80
set_host_tensorMethod · 0.80
set_shaped_bufferMethod · 0.80
TakeSubTreeMethod · 0.80
ResetDefinitionEventMethod · 0.80
DeviceSafeDebugStringMethod · 0.80
mutable_outputMethod · 0.60

Tested by

no test coverage detected