Return debug_string
when creating CompilationCacheKey.
PiperOrigin-RevId: 317181056 Change-Id: I02198244c1c3749ff1ecf4e0647b8daa80dd868c
This commit is contained in:
parent
bc1c0e86a6
commit
cb6e1ed5d8
@ -405,6 +405,22 @@ cc_library(
|
||||
alwayslink = True,
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "tpu_op_util",
|
||||
srcs = ["tpu_op_util.cc"],
|
||||
hdrs = ["tpu_op_util.h"],
|
||||
deps = [
|
||||
":tpu_compilation_cache_key",
|
||||
":tpu_compile_c_api_hdrs",
|
||||
":tpu_mesh_state_interface",
|
||||
"//tensorflow/compiler/xla:xla_data_proto_cc",
|
||||
"//tensorflow/core:framework",
|
||||
"//tensorflow/core:lib",
|
||||
"//tensorflow/core/protobuf/tpu:compile_metadata_proto_cc",
|
||||
"@com_google_absl//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "tpu_util",
|
||||
srcs = ["tpu_util.cc"],
|
||||
|
@ -49,70 +49,6 @@ void PopulateEntry(const std::string& key, CompiledSubgraph* entry,
|
||||
absl::make_unique<TpuProgramGroup>(std::move(tpu_program_group));
|
||||
entry->initialized = true;
|
||||
}
|
||||
|
||||
// Return fingerprint_in_metadata if it's not empty; otherwise read input tensor
|
||||
// data to compute the fingerprint.
|
||||
std::string GuaranteedConstFingerprint(
|
||||
const string& fingerprint_in_metadata,
|
||||
const OpInputList& guaranteed_constants) {
|
||||
if (fingerprint_in_metadata.empty()) {
|
||||
uint64_t fingerprint = 0;
|
||||
for (const auto& constant : guaranteed_constants) {
|
||||
fingerprint = TpuCompile_CreateGuaranteedConstFingerprint(
|
||||
fingerprint, constant.tensor_data().data(),
|
||||
constant.tensor_data().size());
|
||||
}
|
||||
return std::to_string(fingerprint);
|
||||
} else {
|
||||
return fingerprint_in_metadata;
|
||||
}
|
||||
}
|
||||
|
||||
std::string CreateShapePrefix(
|
||||
const std::vector<tensorflow::TensorShape>& dynamic_shapes) {
|
||||
std::string shapes_prefix;
|
||||
for (const TensorShape& shape : dynamic_shapes) {
|
||||
for (int64 size : shape.dim_sizes()) {
|
||||
absl::StrAppend(&shapes_prefix, size, ",");
|
||||
}
|
||||
absl::StrAppend(&shapes_prefix, ";");
|
||||
}
|
||||
return shapes_prefix;
|
||||
}
|
||||
|
||||
// Include compilation configurations of the arguments that are not captured
|
||||
// by the called graph.
|
||||
std::string CreateConfigPrefix(const TPUCompileMetadataProto& metadata) {
|
||||
std::string config_prefix;
|
||||
for (const auto& arg : metadata.args()) {
|
||||
if (arg.is_same_data_across_replicas()) {
|
||||
absl::StrAppend(&config_prefix, ":s");
|
||||
// Same.
|
||||
} else {
|
||||
// Different.
|
||||
absl::StrAppend(&config_prefix, ":");
|
||||
}
|
||||
if (arg.enable_xla_sharding() ==
|
||||
tpu::TPUCompileMetadataProto::Arg::ALLOWED) {
|
||||
// Enabled.
|
||||
absl::StrAppend(&config_prefix, "e");
|
||||
}
|
||||
if (arg.unrestricted_layout()) {
|
||||
// Unrestricted.
|
||||
absl::StrAppend(&config_prefix, ":u");
|
||||
}
|
||||
absl::StrAppend(&config_prefix, ",type(", arg.dtype(), ")");
|
||||
if (arg.has_shape()) {
|
||||
absl::StrAppend(&config_prefix, ",shape(");
|
||||
for (const auto& dim : arg.shape().dim()) {
|
||||
absl::StrAppend(&config_prefix, dim.size(), ",");
|
||||
}
|
||||
absl::StrAppend(&config_prefix, ")");
|
||||
}
|
||||
}
|
||||
return config_prefix;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TpuCompilationCacheExternal::EntryRefImpl::EntryRefImpl(
|
||||
@ -196,68 +132,5 @@ CompiledSubgraph* TpuCompilationCacheExternal::InitializeEntry(
|
||||
marked_for_eviction_size_ += main_entry->total_size;
|
||||
return main_entry;
|
||||
}
|
||||
|
||||
/*static*/ TpuCompilationCacheKey
|
||||
TpuCompilationCacheExternal::CreateCompilationCacheKey(
|
||||
absl::string_view function_name, uint64 function_library_fingerprint,
|
||||
absl::string_view mlir_module,
|
||||
const tensorflow::OpInputList& guaranteed_constants,
|
||||
const std::vector<tensorflow::TensorShape>& dynamic_shapes,
|
||||
const tensorflow::tpu::TPUCompileMetadataProto& metadata,
|
||||
const TpuMeshStateInterface& mesh_state) {
|
||||
VLOG(1) << "FunctionLibraryFingerprint:" << function_library_fingerprint;
|
||||
std::string shapes_prefix = CreateShapePrefix(dynamic_shapes);
|
||||
VLOG(1) << "shapes_prefix = " << shapes_prefix;
|
||||
std::string config_prefix = CreateConfigPrefix(metadata);
|
||||
VLOG(1) << "config_prefix = " << config_prefix;
|
||||
std::vector<int32_t> flattened_device_ids;
|
||||
if (metadata.has_device_assignment()) {
|
||||
for (const auto& device :
|
||||
metadata.device_assignment().computation_devices()) {
|
||||
flattened_device_ids.insert(flattened_device_ids.end(),
|
||||
device.replica_device_ids().begin(),
|
||||
device.replica_device_ids().end());
|
||||
}
|
||||
}
|
||||
// TODO(henrytan): return the debug_string.
|
||||
const char* prefix =
|
||||
TpuCompile_CreateCompilationCacheKey(CompilationCacheKeyProperty{
|
||||
config_prefix.data(),
|
||||
shapes_prefix.data(),
|
||||
function_name.data(),
|
||||
mlir_module.data(),
|
||||
flattened_device_ids.data(),
|
||||
flattened_device_ids.size(),
|
||||
guaranteed_constants.size(),
|
||||
function_library_fingerprint,
|
||||
metadata.num_cores_per_replica(),
|
||||
metadata.num_replicas(),
|
||||
mesh_state.data(),
|
||||
});
|
||||
auto buffer_cleanup = gtl::MakeCleanup([prefix]() { delete[] prefix; });
|
||||
TpuCompilationCacheKey key;
|
||||
key.prefix = prefix;
|
||||
|
||||
// Guaranteed constants can be different across sessions. Use session_handle
|
||||
// and guaranteed_const fingerprint to guarantee no collision.
|
||||
if (guaranteed_constants.size() > 0) {
|
||||
key.has_guaranteed_const = true;
|
||||
key.session_handle = metadata.session_handle();
|
||||
// Both `metadata` and `guaranteed_constants` lifetime are captured by
|
||||
// reference based on the assumption that these variables lifetime is
|
||||
// managed through the `TPUCompileOpKernelImpl` that outlives the
|
||||
// lifetime of the compilation cache lookups.
|
||||
string fingerprint;
|
||||
key.guaranteed_const_fingerprint = [&metadata, &guaranteed_constants,
|
||||
fingerprint]() mutable {
|
||||
if (fingerprint.empty()) {
|
||||
fingerprint = GuaranteedConstFingerprint(
|
||||
metadata.guaranteed_const_fingerprint(), guaranteed_constants);
|
||||
}
|
||||
return fingerprint;
|
||||
};
|
||||
}
|
||||
return key;
|
||||
}
|
||||
} // namespace tpu
|
||||
} // namespace tensorflow
|
||||
|
@ -63,14 +63,6 @@ class TpuCompilationCacheExternal : public TpuCompilationCacheInterface {
|
||||
explicit TpuCompilationCacheExternal(int64 max_cache_size)
|
||||
: TpuCompilationCacheInterface(max_cache_size) {}
|
||||
|
||||
static TpuCompilationCacheKey CreateCompilationCacheKey(
|
||||
absl::string_view function_name, uint64 function_library_fingerprint,
|
||||
absl::string_view mlir_module,
|
||||
const tensorflow::OpInputList& guaranteed_constants,
|
||||
const std::vector<tensorflow::TensorShape>& dynamic_shapes,
|
||||
const tensorflow::tpu::TPUCompileMetadataProto& metadata,
|
||||
const TpuMeshStateInterface& mesh_state);
|
||||
|
||||
string DebugString() const override { return "TpuCompilationCacheExternal"; }
|
||||
|
||||
private:
|
||||
|
@ -42,6 +42,13 @@ struct CompilationCacheKeyProperty {
|
||||
const XLA_TpuMeshState* mesh_state;
|
||||
};
|
||||
|
||||
// Compilation cache key result returning both the key and a more verbose debug
|
||||
// version.
|
||||
struct CompilationCacheKeyResult {
|
||||
const char* key;
|
||||
const char* debug_string;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
// Returns the number of available TPU core count.
|
||||
@ -49,9 +56,14 @@ TFTPU_CAPI_EXPORT int TpuTopology_AvailableCoreCount(
|
||||
const XLA_TpuMeshState* mesh_state, TpuCoreTypeEnum tpu_core_type);
|
||||
|
||||
// Creates a unique compilation cache `key` used for `put` and `get` operations.
|
||||
// Returned buffer is heap-allocated and must be owned.
|
||||
TFTPU_CAPI_EXPORT const char* TpuCompile_CreateCompilationCacheKey(
|
||||
CompilationCacheKeyProperty property);
|
||||
// Returned buffers are heap-allocated and must be owned.
|
||||
TFTPU_CAPI_EXPORT CompilationCacheKeyResult
|
||||
TpuCompile_CreateCompilationCacheKey(CompilationCacheKeyProperty property);
|
||||
|
||||
// Destroys the CompilationCacheKeyResult returned by calling the
|
||||
// `TpuCompile_CreateCompilationCacheKey` API.
|
||||
TFTPU_CAPI_EXPORT void TpuCompile_DestroyCompilationCacheKey(
|
||||
CompilationCacheKeyResult result);
|
||||
|
||||
// Creates a guaranteed const fingerprint. Guarantee const is normally used in
|
||||
// TPU inference to avoid re-copying unchanged variables onto the TPU device.
|
||||
@ -75,6 +87,7 @@ TFTPU_CAPI_EXPORT void TpuCompile_BuildXLADeviceAssignment(
|
||||
struct TfTpu_CompileApiFn {
|
||||
TFTPU_ADD_FN_IN_STRUCT(TpuTopology_AvailableCoreCount);
|
||||
TFTPU_ADD_FN_IN_STRUCT(TpuCompile_CreateCompilationCacheKey);
|
||||
TFTPU_ADD_FN_IN_STRUCT(TpuCompile_DestroyCompilationCacheKey);
|
||||
TFTPU_ADD_FN_IN_STRUCT(TpuCompile_CreateGuaranteedConstFingerprint);
|
||||
TFTPU_ADD_FN_IN_STRUCT(TpuCompile_CompileAheadOfTime);
|
||||
TFTPU_ADD_FN_IN_STRUCT(TpuCompile_BuildXLADeviceAssignment);
|
||||
|
151
tensorflow/core/tpu/kernels/tpu_op_util.cc
Normal file
151
tensorflow/core/tpu/kernels/tpu_op_util.cc
Normal file
@ -0,0 +1,151 @@
|
||||
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==============================================================================*/
|
||||
#include "tensorflow/core/tpu/kernels/tpu_op_util.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "tensorflow/core/lib/gtl/cleanup.h"
|
||||
#include "tensorflow/core/tpu/kernels/tpu_compile_c_api.h"
|
||||
|
||||
namespace tensorflow {
|
||||
namespace tpu {
|
||||
namespace {
|
||||
// Return fingerprint_in_metadata if it's not empty; otherwise read input tensor
|
||||
// data to compute the fingerprint.
|
||||
std::string GuaranteedConstFingerprint(
|
||||
const string& fingerprint_in_metadata,
|
||||
const OpInputList& guaranteed_constants) {
|
||||
if (fingerprint_in_metadata.empty()) {
|
||||
uint64_t fingerprint = 0;
|
||||
for (const auto& constant : guaranteed_constants) {
|
||||
fingerprint = TpuCompile_CreateGuaranteedConstFingerprint(
|
||||
fingerprint, constant.tensor_data().data(),
|
||||
constant.tensor_data().size());
|
||||
}
|
||||
return std::to_string(fingerprint);
|
||||
} else {
|
||||
return fingerprint_in_metadata;
|
||||
}
|
||||
}
|
||||
|
||||
std::string CreateShapePrefix(
|
||||
const std::vector<tensorflow::TensorShape>& dynamic_shapes) {
|
||||
std::string shapes_prefix;
|
||||
for (const TensorShape& shape : dynamic_shapes) {
|
||||
for (int64 size : shape.dim_sizes()) {
|
||||
absl::StrAppend(&shapes_prefix, size, ",");
|
||||
}
|
||||
absl::StrAppend(&shapes_prefix, ";");
|
||||
}
|
||||
return shapes_prefix;
|
||||
}
|
||||
|
||||
// Include compilation configurations of the arguments that are not captured
|
||||
// by the called graph.
|
||||
std::string CreateConfigPrefix(const TPUCompileMetadataProto& metadata) {
|
||||
std::string config_prefix;
|
||||
for (const auto& arg : metadata.args()) {
|
||||
if (arg.is_same_data_across_replicas()) {
|
||||
absl::StrAppend(&config_prefix, ":s");
|
||||
// Same.
|
||||
} else {
|
||||
// Different.
|
||||
absl::StrAppend(&config_prefix, ":");
|
||||
}
|
||||
if (arg.enable_xla_sharding() ==
|
||||
tpu::TPUCompileMetadataProto::Arg::ALLOWED) {
|
||||
// Enabled.
|
||||
absl::StrAppend(&config_prefix, "e");
|
||||
}
|
||||
if (arg.unrestricted_layout()) {
|
||||
// Unrestricted.
|
||||
absl::StrAppend(&config_prefix, ":u");
|
||||
}
|
||||
absl::StrAppend(&config_prefix, ",type(", arg.dtype(), ")");
|
||||
if (arg.has_shape()) {
|
||||
absl::StrAppend(&config_prefix, ",shape(");
|
||||
for (const auto& dim : arg.shape().dim()) {
|
||||
absl::StrAppend(&config_prefix, dim.size(), ",");
|
||||
}
|
||||
absl::StrAppend(&config_prefix, ")");
|
||||
}
|
||||
}
|
||||
return config_prefix;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TpuCompilationCacheKey CreateCompilationCacheKey(
|
||||
absl::string_view function_name, uint64 function_library_fingerprint,
|
||||
absl::string_view mlir_module, const OpInputList& guaranteed_constants,
|
||||
const std::vector<TensorShape>& dynamic_shapes,
|
||||
const TPUCompileMetadataProto& metadata,
|
||||
const TpuMeshStateInterface& mesh_state) {
|
||||
VLOG(1) << "FunctionLibraryFingerprint:" << function_library_fingerprint;
|
||||
std::string shapes_prefix = CreateShapePrefix(dynamic_shapes);
|
||||
VLOG(1) << "shapes_prefix = " << shapes_prefix;
|
||||
std::string config_prefix = CreateConfigPrefix(metadata);
|
||||
VLOG(1) << "config_prefix = " << config_prefix;
|
||||
std::vector<int32_t> flattened_device_ids;
|
||||
if (metadata.has_device_assignment()) {
|
||||
for (const auto& device :
|
||||
metadata.device_assignment().computation_devices()) {
|
||||
flattened_device_ids.insert(flattened_device_ids.end(),
|
||||
device.replica_device_ids().begin(),
|
||||
device.replica_device_ids().end());
|
||||
}
|
||||
}
|
||||
CompilationCacheKeyResult result =
|
||||
TpuCompile_CreateCompilationCacheKey(CompilationCacheKeyProperty{
|
||||
config_prefix.data(),
|
||||
shapes_prefix.data(),
|
||||
function_name.data(),
|
||||
mlir_module.data(),
|
||||
flattened_device_ids.data(),
|
||||
flattened_device_ids.size(),
|
||||
guaranteed_constants.size(),
|
||||
function_library_fingerprint,
|
||||
metadata.num_cores_per_replica(),
|
||||
metadata.num_replicas(),
|
||||
mesh_state.data(),
|
||||
});
|
||||
auto buffer_cleanup = gtl::MakeCleanup(
|
||||
[result]() { TpuCompile_DestroyCompilationCacheKey(result); });
|
||||
TpuCompilationCacheKey key;
|
||||
key.prefix = result.key;
|
||||
key.debug_string = result.debug_string;
|
||||
|
||||
// Guaranteed constants can be different across sessions. Use session_handle
|
||||
// and guaranteed_const fingerprint to guarantee no collision.
|
||||
if (guaranteed_constants.size() > 0) {
|
||||
key.has_guaranteed_const = true;
|
||||
key.session_handle = metadata.session_handle();
|
||||
// Both `metadata` and `guaranteed_constants` lifetime are captured by
|
||||
// reference based on the assumption that these variables lifetime is
|
||||
// managed through the `TPUCompileOpKernelImpl` that outlives the
|
||||
// lifetime of the compilation cache lookups.
|
||||
string fingerprint;
|
||||
key.guaranteed_const_fingerprint = [&metadata, &guaranteed_constants,
|
||||
fingerprint]() mutable {
|
||||
if (fingerprint.empty()) {
|
||||
fingerprint = GuaranteedConstFingerprint(
|
||||
metadata.guaranteed_const_fingerprint(), guaranteed_constants);
|
||||
}
|
||||
return fingerprint;
|
||||
};
|
||||
}
|
||||
return key;
|
||||
}
|
||||
} // namespace tpu
|
||||
} // namespace tensorflow
|
40
tensorflow/core/tpu/kernels/tpu_op_util.h
Normal file
40
tensorflow/core/tpu/kernels/tpu_op_util.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==============================================================================*/
|
||||
#ifndef TENSORFLOW_CORE_TPU_KERNELS_TPU_OP_UTIL_H_
|
||||
#define TENSORFLOW_CORE_TPU_KERNELS_TPU_OP_UTIL_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "tensorflow/compiler/xla/xla_data.pb.h"
|
||||
#include "tensorflow/core/framework/op_kernel.h"
|
||||
#include "tensorflow/core/framework/tensor_shape.h"
|
||||
#include "tensorflow/core/protobuf/tpu/compile_metadata.pb.h"
|
||||
#include "tensorflow/core/tpu/kernels/tpu_compilation_cache_key.h"
|
||||
#include "tensorflow/core/tpu/kernels/tpu_mesh_state_interface.h"
|
||||
|
||||
namespace tensorflow {
|
||||
namespace tpu {
|
||||
// Creates a unique compilation cache `key`.
|
||||
TpuCompilationCacheKey CreateCompilationCacheKey(
|
||||
absl::string_view function_name, uint64 function_library_fingerprint,
|
||||
absl::string_view mlir_module, const OpInputList& guaranteed_constants,
|
||||
const std::vector<TensorShape>& dynamic_shapes,
|
||||
const TPUCompileMetadataProto& metadata,
|
||||
const TpuMeshStateInterface& mesh_state);
|
||||
} // namespace tpu
|
||||
} // namespace tensorflow
|
||||
|
||||
#endif // TENSORFLOW_CORE_TPU_KERNELS_TPU_OP_UTIL_H_
|
Loading…
Reference in New Issue
Block a user