diff options
author | Akshay Modi <nareshmodi@google.com> | 2018-05-17 15:28:09 -0700 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2018-05-17 15:30:39 -0700 |
commit | c1ea01275b93e2d1f96ad1bdacc6aacf6fe231d7 (patch) | |
tree | 85485b194879b7fcd8c1300331529a1fa0a9b3f4 /tensorflow/c/eager | |
parent | 3ede0fdaf69005b79f1783d236a1a4bf904978ba (diff) |
Move runtime.{h,cc,_test.cc} into core/common_runtime/eager as attr_builder
I'm not familiar with how the CMake build is set up but from the description
of the problem the dependency graph is coarser than Bazel's, so I think this
should fix #18925.
PiperOrigin-RevId: 197061764
Diffstat (limited to 'tensorflow/c/eager')
-rw-r--r-- | tensorflow/c/eager/BUILD | 45 | ||||
-rw-r--r-- | tensorflow/c/eager/c_api.cc | 2 | ||||
-rw-r--r-- | tensorflow/c/eager/c_api_internal.h | 2 | ||||
-rw-r--r-- | tensorflow/c/eager/runtime.cc | 246 | ||||
-rw-r--r-- | tensorflow/c/eager/runtime.h | 160 | ||||
-rw-r--r-- | tensorflow/c/eager/runtime_test.cc | 62 |
6 files changed, 4 insertions, 513 deletions
diff --git a/tensorflow/c/eager/BUILD b/tensorflow/c/eager/BUILD index 28f974c5d4..9ce781fab0 100644 --- a/tensorflow/c/eager/BUILD +++ b/tensorflow/c/eager/BUILD @@ -24,10 +24,10 @@ tf_cuda_library( "//tensorflow/core:android_tensorflow_lib_lite", ], "//conditions:default": [ - ":runtime", "//tensorflow/c:c_api", "//tensorflow/c:c_api_internal", "//tensorflow/core:core_cpu", + "//tensorflow/core/common_runtime/eager:attr_builder", "//tensorflow/core/common_runtime/eager:context", "//tensorflow/core/common_runtime/eager:eager_executor", "//tensorflow/core/common_runtime/eager:execute", @@ -70,7 +70,6 @@ tf_cuda_library( visibility = ["//tensorflow:internal"], deps = [ ":c_api", - ":runtime", "//tensorflow/c:c_api", "//tensorflow/c:c_api_internal", "//tensorflow/core:core_cpu", @@ -80,6 +79,7 @@ tf_cuda_library( "//tensorflow/core:framework_lite", "//tensorflow/core:lib", "//tensorflow/core:lib_internal", + "//tensorflow/core/common_runtime/eager:attr_builder", "//tensorflow/core/common_runtime/eager:context", "//tensorflow/core/common_runtime/eager:eager_executor", "//tensorflow/core/common_runtime/eager:eager_operation", @@ -118,47 +118,6 @@ tf_cuda_cc_test( ], ) -tf_cuda_library( - name = "runtime", - srcs = ["runtime.cc"], - hdrs = ["runtime.h"], - copts = tf_copts(), - visibility = ["//tensorflow:internal"], - deps = select({ - "//tensorflow:android": [ - "//tensorflow/core:android_tensorflow_lib_lite", - ], - "//conditions:default": [ - "//tensorflow/c:c_api", - "//tensorflow/core:core_cpu", - "//tensorflow/core/common_runtime/eager:kernel_and_device", - "//tensorflow/core:core_cpu_internal", - "//tensorflow/core:framework", - "//tensorflow/core:framework_internal", - "//tensorflow/core:lib", - "//tensorflow/core:lib_internal", - "//tensorflow/core:protos_all_cc", - ], - }), -) - -tf_cc_test( - name = "runtime_test", - srcs = ["runtime_test.cc"], - deps = [ - ":runtime", - "//tensorflow/cc:cc_ops", - "//tensorflow/cc:client_session", - "//tensorflow/cc:ops", - "//tensorflow/cc:scope", - "//tensorflow/core:core_cpu_internal", - "//tensorflow/core:framework", - "//tensorflow/core:lib", - "//tensorflow/core:test", - "//tensorflow/core:test_main", - ], -) - cc_library( name = "tape", hdrs = ["tape.h"], diff --git a/tensorflow/c/eager/c_api.cc b/tensorflow/c/eager/c_api.cc index 1c1020f812..216210c88c 100644 --- a/tensorflow/c/eager/c_api.cc +++ b/tensorflow/c/eager/c_api.cc @@ -24,7 +24,6 @@ limitations under the License. #include "tensorflow/c/c_api.h" #include "tensorflow/c/c_api_internal.h" #include "tensorflow/c/eager/c_api_internal.h" -#include "tensorflow/c/eager/runtime.h" #ifdef TENSORFLOW_EAGER_USE_XLA #include "tensorflow/compiler/tf2xla/xla_op_registry.h" #endif // TENSORFLOW_EAGER_USE_XLA @@ -32,6 +31,7 @@ limitations under the License. #include "tensorflow/core/common_runtime/device_factory.h" #include "tensorflow/core/common_runtime/device_mgr.h" #include "tensorflow/core/common_runtime/device_set.h" +#include "tensorflow/core/common_runtime/eager/attr_builder.h" #include "tensorflow/core/common_runtime/eager/copy_to_device_node.h" #include "tensorflow/core/common_runtime/eager/execute.h" #include "tensorflow/core/common_runtime/function.h" diff --git a/tensorflow/c/eager/c_api_internal.h b/tensorflow/c/eager/c_api_internal.h index f506ede087..2b8384d720 100644 --- a/tensorflow/c/eager/c_api_internal.h +++ b/tensorflow/c/eager/c_api_internal.h @@ -28,8 +28,8 @@ limitations under the License. #include "tensorflow/c/c_api.h" #include "tensorflow/c/c_api_internal.h" -#include "tensorflow/c/eager/runtime.h" #include "tensorflow/core/common_runtime/device_factory.h" +#include "tensorflow/core/common_runtime/eager/attr_builder.h" #include "tensorflow/core/common_runtime/eager/context.h" #include "tensorflow/core/common_runtime/eager/eager_executor.h" #include "tensorflow/core/common_runtime/eager/eager_operation.h" diff --git a/tensorflow/c/eager/runtime.cc b/tensorflow/c/eager/runtime.cc deleted file mode 100644 index e6c51ab17a..0000000000 --- a/tensorflow/c/eager/runtime.cc +++ /dev/null @@ -1,246 +0,0 @@ -/* Copyright 2017 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/c/eager/runtime.h" - -#include "tensorflow/core/common_runtime/device_factory.h" -#include "tensorflow/core/common_runtime/eager/kernel_and_device.h" -#include "tensorflow/core/common_runtime/rendezvous_mgr.h" -#include "tensorflow/core/framework/allocator.h" -#include "tensorflow/core/framework/node_def.pb.h" -#include "tensorflow/core/lib/core/errors.h" -#include "tensorflow/core/lib/gtl/map_util.h" -#include "tensorflow/core/lib/gtl/stl_util.h" -#include "tensorflow/core/platform/fingerprint.h" -#include "tensorflow/core/platform/mutex.h" -#include "tensorflow/core/public/version.h" -#include "tensorflow/core/util/tensor_slice_reader_cache.h" - -namespace tensorflow { -namespace { - -mutex g_op_name_to_attr_type_map_lock(LINKER_INITIALIZED); - -std::unordered_map<string, const AttrTypeMap*>* OpNameToAttrTypeMap() { - static auto* const m = new std::unordered_map<string, const AttrTypeMap*>; - return m; -} - -const uint32 kIsList = 1U << 31; - -} // namespace - -Status OpDefForOp(const char* op_name, const OpDef** op_def) { - const OpRegistrationData* op_reg_data = nullptr; - Status s = OpRegistry::Global()->LookUp(op_name, &op_reg_data); - if (s.ok()) { - *op_def = &op_reg_data->op_def; - } - return s; -} - -Status AttrTypeMapForOp(const char* op_name, const AttrTypeMap** out) { - mutex_lock l(g_op_name_to_attr_type_map_lock); - *out = gtl::FindPtrOrNull(*OpNameToAttrTypeMap(), op_name); - if (*out != nullptr) return Status::OK(); - const OpDef* op_def = nullptr; - Status s = OpDefForOp(op_name, &op_def); - if (!s.ok()) return s; - std::unique_ptr<AttrTypeMap> m(new AttrTypeMap); - // TODO(agarwal): Avoid having to create this "registry" at runtime, - // perhaps can be done at op registration time? - for (const auto& attr : op_def->attr()) { - string type = attr.type(); - const bool is_list = (type.length() > 6 && type.compare(0, 4, "list") == 0); - if (is_list) { - type = type.substr(5, type.length() - 6); - } - uint32 t = is_list ? kIsList : 0; - if (type == "string") { - t |= TF_ATTR_STRING; - } else if (type == "int") { - t |= TF_ATTR_INT; - } else if (type == "float") { - t |= TF_ATTR_FLOAT; - } else if (type == "bool") { - t |= TF_ATTR_BOOL; - } else if (type == "type") { - t |= TF_ATTR_TYPE; - } else if (type == "shape") { - t |= TF_ATTR_SHAPE; - } else if (type == "tensor") { - t |= TF_ATTR_TENSOR; - } else if (type == "func") { - t |= TF_ATTR_FUNC; - } else { - return errors::Unimplemented( - "TODO(agarwal): Enable support for ops with attributes of type '", - type, "'"); - } - gtl::InsertIfNotPresent(m.get(), attr.name(), t); - } - *out = m.get(); - (*OpNameToAttrTypeMap())[op_name] = m.release(); - return Status::OK(); -} - -#define DEFINE_SET_ATTR(value_type, value_field) \ - template <> \ - AttrBuilder& AttrBuilder::Set(StringPiece attr_name, value_type&& value) { \ - value_field.push_back(std::make_pair(attr_name, value)); \ - return *this; \ - } - -DEFINE_SET_ATTR(StringPiece, string_attrs_); -DEFINE_SET_ATTR(float, float_attrs_); -DEFINE_SET_ATTR(int, int_attrs_); -DEFINE_SET_ATTR(bool, bool_attrs_); -DEFINE_SET_ATTR(tensorflow::DataType, type_attrs_); - -#undef DEFINE_SET_ATTR - -AttrBuilder& AttrBuilder::NumInputs(int n) { - DCHECK(!node_def_finalized_) << "Calling NumInputs after BuildNodeDef."; - num_inputs_ = n; - return *this; -} - -void AttrBuilder::FillAttrValueMap(AttrValueMap* m, - bool include_those_in_node_def) const { - for (const auto& p : string_attrs_) { - SetInAttrValueMap(m, p.first, p.second); - } - for (const auto& p : int_attrs_) { - SetInAttrValueMap(m, p.first, p.second); - } - for (const auto& p : float_attrs_) { - SetInAttrValueMap(m, p.first, p.second); - } - for (const auto& p : bool_attrs_) { - SetInAttrValueMap(m, p.first, p.second); - } - for (const auto& p : type_attrs_) { - SetInAttrValueMap(m, p.first, p.second); - } - if (include_those_in_node_def && node_def_ != nullptr) { - for (AttrValueMap::const_iterator it = node_def_->attr().begin(); - it != node_def_->attr().end(); ++it) { - m->insert(*it); - } - } -} - -const NodeDef& AttrBuilder::BuildNodeDef() { - if (node_def_finalized_) return *node_def_; - MayBeInitializeNodeDef(); - for (int i = 0; i < num_inputs_; ++i) { - node_def_->add_input("dummy_input"); - } - FillAttrValueMap(node_def_->mutable_attr(), false); - node_def_finalized_ = true; - return *node_def_; -} - -Status AttrTypeByName(const AttrTypeMap& m, const string& attr_name, - TF_AttrType* out, unsigned char* is_list) { - auto* t = gtl::FindOrNull(m, attr_name); - if (t == nullptr) { - return errors::InvalidArgument("Attribute '", attr_name, - "' does not exist for this operation"); - } - *out = static_cast<TF_AttrType>(*t & ~kIsList); - if (*t & kIsList) { - *is_list = 1; - } else { - *is_list = 0; - } - return Status::OK(); -} - -namespace { -inline tensorflow::Fprint128 FingerprintCat128(const tensorflow::Fprint128& a, - const tensorflow::Fprint128& b) { - return {tensorflow::FingerprintCat64(a.low64, b.low64), - tensorflow::FingerprintCat64(a.low64, b.low64)}; -} - -void CombineUnordered(const tensorflow::Fprint128& a, - tensorflow::Fprint128* b) { - b->low64 += a.low64; - b->high64 += a.high64; -} - -inline tensorflow::Fprint128 CacheKeyHelper(StringPiece s, - const tensorflow::Fprint128& b) { - tensorflow::Fprint128 a = tensorflow::Fingerprint128(s); - return FingerprintCat128(a, b); -} - -inline tensorflow::Fprint128 CacheKeyHelper(StringPiece s, uint64 b) { - return CacheKeyHelper(s, {b, b}); -} - -} // namespace - -tensorflow::Fprint128 AttrBuilder::CacheKey(const string& device) const { - tensorflow::Fprint128 f = tensorflow::Fingerprint128(op_name_); - f = tensorflow::FingerprintCat128(f, tensorflow::Fingerprint128(device)); - if (node_def_ != nullptr) { - // Some attributes are directly written to node_def_ instead of being - // stored explicitly. - string value; - for (const auto& attr : node_def_->attr()) { - attr.second.SerializeToString(&value); - CombineUnordered( - CacheKeyHelper(attr.first, tensorflow::Fingerprint128(value)), &f); - } - // Note that node_def_ may be created but not finalized. This can happen - // when the creation was triggered by a call to Set, but BuildNodeDef has - // not been called. - if (node_def_finalized_) return f; - } - for (const auto& p : string_attrs_) { - CombineUnordered( - CacheKeyHelper(p.first, tensorflow::Fingerprint128(p.second)), &f); - } - for (const auto& p : int_attrs_) { - CombineUnordered(CacheKeyHelper(p.first, static_cast<uint64>(p.second)), - &f); - } - static std::hash<float> float_hasher; - for (const auto& p : float_attrs_) { - CombineUnordered( - CacheKeyHelper(p.first, static_cast<uint64>(float_hasher(p.second))), - &f); - } - for (const auto& p : bool_attrs_) { - CombineUnordered(CacheKeyHelper(p.first, p.second ? 1u : 0u), &f); - } - for (const auto& p : type_attrs_) { - CombineUnordered(CacheKeyHelper(p.first, static_cast<uint64>(p.second)), - &f); - } - return f; -} - -void AttrBuilder::MayBeInitializeNodeDef() { - if (node_def_ == nullptr) { - node_def_.reset(new NodeDef()); - node_def_->set_name(op_name_); - node_def_->set_op(op_name_); - } -} - -} // namespace tensorflow diff --git a/tensorflow/c/eager/runtime.h b/tensorflow/c/eager/runtime.h deleted file mode 100644 index 929b1b8296..0000000000 --- a/tensorflow/c/eager/runtime.h +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright 2017 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_C_EAGER_RUNTIME_H_ -#define TENSORFLOW_C_EAGER_RUNTIME_H_ - -// Support for eager execution of TensorFlow kernels. - -#include <memory> -#include <unordered_map> - -#include "tensorflow/c/c_api.h" -#include "tensorflow/core/common_runtime/device.h" -#include "tensorflow/core/common_runtime/eager/kernel_and_device.h" -#include "tensorflow/core/framework/node_def.pb.h" -#include "tensorflow/core/framework/op_kernel.h" -#include "tensorflow/core/framework/types.h" -#include "tensorflow/core/lib/core/status.h" -#include "tensorflow/core/lib/gtl/inlined_vector.h" -#include "tensorflow/core/platform/fingerprint.h" -#include "tensorflow/core/util/tensor_slice_reader_cache.h" - -namespace tensorflow { - -// Maps attribute name to an encoding of the type of the attribute value. -// If the type is not a list type, the value is the same as the TF_AttrType type -// of the value. Else, the highest order bit is on, and the rest of the bits -// represent the TF_AttrType type of the values in the list. -typedef std::unordered_map<string, uint32> AttrTypeMap; - -// Look up OpDef for `op_name`. -Status OpDefForOp(const char* op_name, const OpDef** op_def); - -// Returns the AttrTypeMap for the TensorFlow operation named op_name. -Status AttrTypeMapForOp(const char* op_name, const AttrTypeMap** out); - -// Looks for 'attr_name' in 'm' and sets 'out' and 'is_list'. -Status AttrTypeByName(const AttrTypeMap& m, const string& attr_name, - TF_AttrType* out, unsigned char* is_list); - -// Looks for 'attr_name' in 'm' and sets 'out' and 'is_list'. -Status AttrTypeByName(const AttrTypeMap& m, const string& attr_name, - TF_AttrType* out, unsigned char* is_list); - -// KernelAndDevice::Init needs a NodeDef only to pass the attribute map through. -// An AttrBuilder is a convenience class to help with that - providing a smaller -// interface than NodeDefBuilder and avoiding expensive (unnecessary?) sanity -// checks (like number of inputs matching the OpDef - we only care about -// attributes here). -// -// TODO(ashankar): Take a closer look at checks in NodeDefBuilder and see which -// ones make sense to replicate. - -// This is a helper class for creating a NodeDef. Additionally, this class -// allows computing a cache key based on fingerprinting the attributes of this -// NodeDef. -// -// Example usage: -// AttrBuilder a; -// a.NumInputs(2); -// a.Set("T", TF_FLOAT); -// uint64 cache_key = a.CacheKey("cpu:0"); -// const NodeDef& n = a.BuildNodeDef(); -// -// Note that all calls to Set and NumInputs should happen before calling -// BuildNodeDef. Also, calls to NumInputs or Set between multiple invocations -// to CacheKey may cause different values to be returned by CacheKey. -// -// For performance reasons, the class internally delays the actual construction -// of the NodeDef till BuildNodeDef is called, or Set is called with certain -// uncommon types (see template specializations of Set to see which types -// trigger a NodeDef creation). -class AttrBuilder { - public: - explicit AttrBuilder(const char* op) - : op_name_(op), - num_inputs_(0), - node_def_(nullptr), - node_def_finalized_(false) {} - - // Needed to work around call to ValidateNodeDef in CreateOpKernel. - AttrBuilder& NumInputs(int n); - - template <class T> - AttrBuilder& Set(StringPiece attr_name, T&& value) { - MayBeInitializeNodeDef(); - SetInAttrValueMap(node_def_->mutable_attr(), attr_name, value); - return *this; - } - - tensorflow::Fprint128 CacheKey(const string& device) const; - - void FillAttrValueMap(AttrValueMap* m) const { FillAttrValueMap(m, true); } - const NodeDef& BuildNodeDef(); - - private: - template <class T> - using AttrVec = tensorflow::gtl::InlinedVector<std::pair<StringPiece, T>, 2>; - - void MayBeInitializeNodeDef(); - void FillAttrValueMap(AttrValueMap* m, bool include_those_in_node_def) const; - - template <class T> - void SetInAttrValueMap(AttrValueMap* m, StringPiece attr_name, - T&& value) const { - DCHECK(!node_def_finalized_) - << "Calling SetInAttrValueMap after BuildNodeDef."; - // Copied from NodeDefBuilder::Attr - const AttrValue* found = AttrSlice(m).Find(attr_name); - AttrValue attr_value; - if (found == nullptr) { - SetAttrValue(value, &attr_value); - m->insert(AttrValueMap::value_type(attr_name.ToString(), attr_value)); - } else { - // TODO(ashankar): Do what is done in - // NodeDefBuilder::CheckInconsistency(attr_name, *found, attr_value); - SetAttrValue(std::forward<T>(value), &attr_value); - (*m)[attr_name.ToString()] = attr_value; - } - } - - AttrVec<StringPiece> string_attrs_; - AttrVec<int> int_attrs_; - AttrVec<float> float_attrs_; - AttrVec<bool> bool_attrs_; - AttrVec<tensorflow::DataType> type_attrs_; - const string op_name_; - int num_inputs_; - std::unique_ptr<NodeDef> node_def_; - bool node_def_finalized_; -}; // namespace tensorflow - -template <> -AttrBuilder& AttrBuilder::Set(StringPiece attr_name, StringPiece&& value); -template <> -AttrBuilder& AttrBuilder::Set(StringPiece attr_name, int&& value); -template <> -AttrBuilder& AttrBuilder::Set(StringPiece attr_name, float&& value); -template <> -AttrBuilder& AttrBuilder::Set(StringPiece attr_name, bool&& value); -template <> -AttrBuilder& AttrBuilder::Set(StringPiece attr_name, - tensorflow::DataType&& value); - - -} // namespace tensorflow - -#endif // TENSORFLOW_C_EAGER_RUNTIME_H_ diff --git a/tensorflow/c/eager/runtime_test.cc b/tensorflow/c/eager/runtime_test.cc deleted file mode 100644 index 27ebeb0508..0000000000 --- a/tensorflow/c/eager/runtime_test.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright 2017 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/c/eager/runtime.h" - -#include <memory> -#include <vector> - -#include "tensorflow/cc/client/client_session.h" -#include "tensorflow/cc/framework/ops.h" -#include "tensorflow/cc/framework/scope.h" -#include "tensorflow/cc/ops/standard_ops.h" -#include "tensorflow/core/common_runtime/device_factory.h" -#include "tensorflow/core/common_runtime/device_mgr.h" -#include "tensorflow/core/common_runtime/function.h" -#include "tensorflow/core/platform/env.h" -#include "tensorflow/core/platform/test.h" -#include "tensorflow/core/platform/test_benchmark.h" -#include "tensorflow/core/public/version.h" - -namespace tensorflow { -namespace { - -TEST(AttrTypeMap, Lookup) { - const AttrTypeMap* m = nullptr; - Status s = AttrTypeMapForOp("ThisOpCannotPossiblyExist", &m); - EXPECT_FALSE(s.ok()); - s = AttrTypeMapForOp("MatMul", &m); - ASSERT_TRUE(s.ok()) << s; - - TF_AttrType t; - unsigned char is_list = 1; - s = AttrTypeByName(*m, "ThisAttribyteCannotPossiblyExist", &t, &is_list); - EXPECT_FALSE(s.ok()); - EXPECT_NE(is_list, 0); - s = AttrTypeByName(*m, "transpose_a", &t, &is_list); - ASSERT_TRUE(s.ok()) << s; - EXPECT_EQ(TF_ATTR_BOOL, t); - EXPECT_EQ(is_list, 0); - - s = AttrTypeMapForOp("Squeeze", &m); - ASSERT_TRUE(s.ok()) << s; - s = AttrTypeByName(*m, "squeeze_dims", &t, &is_list); - ASSERT_TRUE(s.ok()) << s; - EXPECT_EQ(TF_ATTR_INT, t); - EXPECT_NE(is_list, 0); -} - -} // namespace -} // namespace tensorflow |