aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/c/eager
diff options
context:
space:
mode:
authorGravatar Akshay Modi <nareshmodi@google.com>2018-05-17 15:28:09 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-05-17 15:30:39 -0700
commitc1ea01275b93e2d1f96ad1bdacc6aacf6fe231d7 (patch)
tree85485b194879b7fcd8c1300331529a1fa0a9b3f4 /tensorflow/c/eager
parent3ede0fdaf69005b79f1783d236a1a4bf904978ba (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/BUILD45
-rw-r--r--tensorflow/c/eager/c_api.cc2
-rw-r--r--tensorflow/c/eager/c_api_internal.h2
-rw-r--r--tensorflow/c/eager/runtime.cc246
-rw-r--r--tensorflow/c/eager/runtime.h160
-rw-r--r--tensorflow/c/eager/runtime_test.cc62
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