Return debug_string when creating CompilationCacheKey.

PiperOrigin-RevId: 317181056
Change-Id: I02198244c1c3749ff1ecf4e0647b8daa80dd868c
This commit is contained in:
Henry Tan 2020-06-18 14:28:42 -07:00 committed by TensorFlower Gardener
parent bc1c0e86a6
commit cb6e1ed5d8
6 changed files with 223 additions and 138 deletions

View File

@ -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"],

View File

@ -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

View File

@ -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:

View File

@ -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);

View 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

View 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_