aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Benoit Steiner <benoit.steiner.goog@gmail.com>2017-02-09 11:05:12 -0800
committerGravatar Benoit Steiner <benoit.steiner.goog@gmail.com>2017-02-09 11:05:12 -0800
commitee35de4d92bbae179a2bf93e9c00a991c095b591 (patch)
tree3c697ea527336cca6c43b6c7a9493caaa8e4e918
parentc7fca9eed7b584cbfd95b253908c51f4e9b7fa8b (diff)
parent9683b095fce7b77df01d95ac3b07dcd17a083782 (diff)
Merge commit for internal changes
-rw-r--r--tensorflow/BUILD4
-rw-r--r--tensorflow/c/checkpoint_reader.cc1
-rw-r--r--tensorflow/compiler/tests/BUILD1
-rw-r--r--tensorflow/compiler/tf2xla/xla_compiler.cc16
-rw-r--r--tensorflow/compiler/tf2xla/xla_context.cc9
-rw-r--r--tensorflow/compiler/tf2xla/xla_context.h25
-rw-r--r--tensorflow/compiler/xla/reference_util.cc38
-rw-r--r--tensorflow/compiler/xla/reference_util.h6
-rw-r--r--tensorflow/compiler/xla/service/BUILD1
-rw-r--r--tensorflow/compiler/xla/service/elemental_ir_emitter.cc9
-rw-r--r--tensorflow/compiler/xla/service/gpu/instruction_fusion.cc5
-rw-r--r--tensorflow/compiler/xla/service/hlo_cost_analysis.cc193
-rw-r--r--tensorflow/compiler/xla/service/hlo_cost_analysis.h60
-rw-r--r--tensorflow/compiler/xla/service/hlo_cost_analysis_test.cc81
-rw-r--r--tensorflow/compiler/xla/service/hlo_execution_profile.cc5
-rw-r--r--tensorflow/compiler/xla/service/hlo_instruction.cc15
-rw-r--r--tensorflow/compiler/xla/service/local_service.cc5
-rw-r--r--tensorflow/compiler/xla/tests/vector_ops_simple_test.cc29
-rw-r--r--tensorflow/contrib/cmake/tf_core_kernels.cmake4
-rw-r--r--tensorflow/contrib/cmake/tf_tests.cmake4
-rw-r--r--tensorflow/contrib/distributions/python/kernel_tests/bijector_test.py116
-rw-r--r--tensorflow/contrib/distributions/python/kernel_tests/poisson_test.py50
-rw-r--r--tensorflow/contrib/distributions/python/ops/bijector.py75
-rw-r--r--tensorflow/contrib/distributions/python/ops/poisson.py6
-rw-r--r--tensorflow/contrib/framework/python/ops/variables.py14
-rw-r--r--tensorflow/contrib/framework/python/ops/variables_test.py11
-rw-r--r--tensorflow/contrib/layers/python/layers/feature_column_ops.py5
-rw-r--r--tensorflow/contrib/layers/python/layers/feature_column_ops_test.py22
-rw-r--r--tensorflow/contrib/learn/__init__.py4
-rw-r--r--tensorflow/contrib/learn/python/learn/estimators/constants.py11
-rw-r--r--tensorflow/contrib/learn/python/learn/estimators/dynamic_rnn_estimator.py717
-rw-r--r--tensorflow/contrib/learn/python/learn/estimators/dynamic_rnn_estimator_test.py136
-rw-r--r--tensorflow/contrib/learn/python/learn/estimators/estimator.py1
-rw-r--r--tensorflow/contrib/learn/python/learn/estimators/estimators_test.py7
-rw-r--r--tensorflow/contrib/learn/python/learn/estimators/head.py73
-rw-r--r--tensorflow/contrib/learn/python/learn/estimators/head_test.py45
-rw-r--r--tensorflow/contrib/learn/python/learn/estimators/linear.py120
-rw-r--r--tensorflow/contrib/learn/python/learn/estimators/linear_test.py87
-rw-r--r--tensorflow/contrib/learn/python/learn/utils/input_fn_utils.py33
-rw-r--r--tensorflow/contrib/legacy_seq2seq/python/kernel_tests/seq2seq_test.py305
-rw-r--r--tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in11
-rw-r--r--tensorflow/contrib/makefile/sub_makefiles/quantization/Makefile.in15
-rw-r--r--tensorflow/contrib/slim/python/slim/data/dataset_data_provider.py13
-rw-r--r--tensorflow/contrib/slim/python/slim/data/dataset_data_provider_test.py20
-rw-r--r--tensorflow/contrib/sparsemax/BUILD1
-rw-r--r--tensorflow/contrib/sparsemax/__init__.py5
-rw-r--r--tensorflow/contrib/sparsemax/python/ops/sparsemax.py18
-rw-r--r--tensorflow/contrib/sparsemax/python/ops/sparsemax_loss.py3
-rw-r--r--tensorflow/core/BUILD12
-rw-r--r--tensorflow/core/common_runtime/debugger_state_interface.h18
-rw-r--r--tensorflow/core/common_runtime/direct_session.cc16
-rw-r--r--tensorflow/core/common_runtime/direct_session.h4
-rw-r--r--tensorflow/core/common_runtime/pending_counts.h4
-rw-r--r--tensorflow/core/common_runtime/step_stats_collector.cc1
-rw-r--r--tensorflow/core/debug/debug_graph_utils.cc10
-rw-r--r--tensorflow/core/debug/debug_graph_utils.h11
-rw-r--r--tensorflow/core/debug/debug_grpc_io_utils_test.cc8
-rw-r--r--tensorflow/core/debug/debug_io_utils.cc126
-rw-r--r--tensorflow/core/debug/debug_io_utils.h16
-rw-r--r--tensorflow/core/framework/cost_graph.proto5
-rw-r--r--tensorflow/core/framework/tensor_util.cc18
-rw-r--r--tensorflow/core/framework/tensor_util_test.cc8
-rw-r--r--tensorflow/core/graph/costmodel.cc55
-rw-r--r--tensorflow/core/graph/costmodel.h38
-rw-r--r--tensorflow/core/graph/testlib.cc10
-rw-r--r--tensorflow/core/graph/testlib.h4
-rw-r--r--tensorflow/core/kernels/BUILD27
-rw-r--r--tensorflow/core/kernels/example_parsing_ops.cc24
-rw-r--r--tensorflow/core/kernels/example_parsing_ops_test.cc54
-rw-r--r--tensorflow/core/kernels/fused_batch_norm_op.cc2
-rw-r--r--tensorflow/core/kernels/hexagon/graph_transfer_utils.cc11
-rw-r--r--tensorflow/core/kernels/hexagon/graph_transfer_utils.h1
-rw-r--r--tensorflow/core/kernels/hexagon/graph_transferer.cc108
-rw-r--r--tensorflow/core/kernels/hexagon/graph_transferer_test.cc93
-rw-r--r--tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc14
-rw-r--r--tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc175
-rw-r--r--tensorflow/core/kernels/hexagon/hexagon_ops_definitions.cc5
-rw-r--r--tensorflow/core/kernels/hexagon/hexagon_ops_definitions.h1
-rw-r--r--tensorflow/core/kernels/hexagon/i_graph_transfer_ops_definitions.h3
-rw-r--r--tensorflow/core/kernels/random_op.cc2
-rw-r--r--tensorflow/core/kernels/random_poisson_op.cc357
-rw-r--r--tensorflow/core/kernels/random_poisson_op.h31
-rw-r--r--tensorflow/core/kernels/random_poisson_op_test.cc82
-rw-r--r--tensorflow/core/kernels/remote_fused_graph_execute_op.cc10
-rw-r--r--tensorflow/core/ops/array_ops.cc5
-rw-r--r--tensorflow/core/ops/compat/ops_history.v0.pbtxt51
-rw-r--r--tensorflow/core/ops/compat/ops_history.v1.pbtxt22366
-rw-r--r--tensorflow/core/ops/ops.pbtxt116
-rw-r--r--tensorflow/core/ops/parsing_ops.cc13
-rw-r--r--tensorflow/core/ops/parsing_ops_test.cc42
-rw-r--r--tensorflow/core/ops/random_ops.cc44
-rw-r--r--tensorflow/core/ops/random_ops_test.cc15
-rw-r--r--tensorflow/core/protobuf/debug.proto12
-rw-r--r--tensorflow/core/util/example_proto_fast_parsing.cc347
-rw-r--r--tensorflow/core/util/example_proto_fast_parsing.h1
-rw-r--r--tensorflow/core/util/example_proto_fast_parsing_test.cc52
-rw-r--r--tensorflow/core/util/example_proto_fast_parsing_test.proto21
-rw-r--r--tensorflow/core/util/example_proto_helper.h26
-rw-r--r--tensorflow/g3doc/api_docs/python/array_ops.md12
-rw-r--r--tensorflow/g3doc/api_docs/python/constant_op.md41
-rw-r--r--tensorflow/g3doc/api_docs/python/contrib.distributions.bijector.md10
-rw-r--r--tensorflow/g3doc/api_docs/python/contrib.layers.md3
-rw-r--r--tensorflow/g3doc/api_docs/python/contrib.learn.md111
-rw-r--r--tensorflow/g3doc/api_docs/python/framework.md9
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.distributions.bijector.CholeskyOuterProduct.md6
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.learn.make_export_strategy.md28
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf_debug.watch_graph_with_blacklists.md4
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.unsorted_segment_max.md38
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.contrib.learn.ProblemType.md9
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.test.TestCase.md6
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.fake_quant_with_min_max_vars.md5
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf_debug.add_debug_tensor_watch.md4
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.contrib.distributions.bijector.Invert.md4
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.contrib.layers.check_feature_columns.md3
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf_debug.DebugDumpDir.md32
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.import_graph_def.md9
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf_debug.watch_graph.md4
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.contrib.learn.InputFnOps.md64
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.concat_v2.md4
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.contrib.learn.InputFnOps.__new__.md4
-rw-r--r--tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.random_poisson.md38
-rw-r--r--tensorflow/g3doc/api_docs/python/index.md5
-rw-r--r--tensorflow/g3doc/api_docs/python/math_ops.md41
-rw-r--r--tensorflow/g3doc/api_docs/python/test.md6
-rw-r--r--tensorflow/g3doc/api_docs/python/tf_debug.md44
-rw-r--r--tensorflow/g3doc/how_tos/new_data_formats/index.md23
-rw-r--r--tensorflow/g3doc/tutorials/image_recognition/index.md2
-rw-r--r--tensorflow/g3doc/tutorials/input_fn/index.md2
-rw-r--r--tensorflow/go/genop/internal/genop.go11
-rw-r--r--tensorflow/go/genop/internal/genop_test.go6
-rw-r--r--tensorflow/go/op/wrappers.go934
-rw-r--r--tensorflow/go/operation.go5
-rw-r--r--tensorflow/go/operation_test.go11
-rw-r--r--tensorflow/go/session.go38
-rw-r--r--tensorflow/go/session_test.go12
-rw-r--r--tensorflow/python/debug/BUILD1
-rw-r--r--tensorflow/python/debug/debug_data.py61
-rw-r--r--tensorflow/python/debug/debug_utils.py22
-rw-r--r--tensorflow/python/debug/session_debug_file_test.py23
-rw-r--r--tensorflow/python/debug/session_debug_testlib.py167
-rw-r--r--tensorflow/python/framework/constant_op.py1
-rw-r--r--tensorflow/python/kernel_tests/BUILD15
-rw-r--r--tensorflow/python/kernel_tests/parsing_ops_test.py98
-rw-r--r--tensorflow/python/kernel_tests/random_poisson_test.py178
-rw-r--r--tensorflow/python/ops/hidden_ops.txt1
-rw-r--r--tensorflow/python/ops/parsing_ops.py48
-rw-r--r--tensorflow/python/ops/random_ops.py104
-rw-r--r--tensorflow/stream_executor/lib/status_macros.h2
-rw-r--r--tensorflow/tensorboard/components/tf_audio_dashboard/test/audioDashboardTests.ts5
-rw-r--r--tensorflow/tensorboard/components/tf_backend/BUILD79
-rw-r--r--tensorflow/tensorboard/components/tf_backend/backend.ts2
-rw-r--r--tensorflow/tensorboard/components/tf_color_scale/BUILD63
-rw-r--r--tensorflow/tensorboard/components/tf_color_scale/demo/BUILD26
-rw-r--r--tensorflow/tensorboard/components/tf_color_scale/demo/index.html94
-rw-r--r--tensorflow/tensorboard/components/tf_color_scale/tf-color-scale.html1
-rw-r--r--tensorflow/tensorboard/components/tf_globals/BUILD49
-rw-r--r--tensorflow/tensorboard/components/tf_graph/tf-graph-scene.html23
-rw-r--r--tensorflow/tensorboard/components/tf_graph_common/lib/render.ts13
-rw-r--r--tensorflow/tensorboard/components/tf_graph_common/lib/scene/scene.ts280
-rw-r--r--tensorflow/tensorboard/components/tf_graph_dashboard/tf-graph-dashboard.html17
-rw-r--r--tensorflow/tensorboard/components/tf_tensorboard/test/autoReloadTests.ts4
-rw-r--r--tensorflow/tensorboard/components/tf_tensorboard/tf-tensorboard.html20
-rw-r--r--tensorflow/tensorboard/defs.bzl9
-rw-r--r--tensorflow/tensorflow.bzl2
-rw-r--r--tensorflow/third_party/mkl/BUILD9
-rw-r--r--tensorflow/third_party/mkl/build_defs.bzl2
-rw-r--r--tensorflow/tools/docs/parser.py46
-rw-r--r--tensorflow/tools/docs/parser_test.py29
-rw-r--r--third_party/eigen3/BUILD3
-rw-r--r--third_party/mkl/BUILD5
-rw-r--r--third_party/mkl/build_defs.bzl26
171 files changed, 28489 insertions, 1537 deletions
diff --git a/tensorflow/BUILD b/tensorflow/BUILD
index 999e11c0e9..a568aa50d4 100644
--- a/tensorflow/BUILD
+++ b/tensorflow/BUILD
@@ -256,7 +256,7 @@ filegroup(
)
load(
- "//third_party/mkl:build_defs.bzl",
+ "//tensorflow/third_party/mkl:build_defs.bzl",
"if_mkl",
)
@@ -264,7 +264,7 @@ filegroup(
name = "intel_binary_blob",
data = if_mkl(
[
- "//third_party/mkl:intel_binary_blob",
+ "//tensorflow/third_party/mkl:intel_binary_blob",
],
),
)
diff --git a/tensorflow/c/checkpoint_reader.cc b/tensorflow/c/checkpoint_reader.cc
index 17b3f93193..e7b9bca5b5 100644
--- a/tensorflow/c/checkpoint_reader.cc
+++ b/tensorflow/c/checkpoint_reader.cc
@@ -58,6 +58,7 @@ CheckpointReader::CheckpointReader(const string& filename,
CheckpointReader::~CheckpointReader() {
delete var_to_shape_map_ptr_;
delete reader_;
+ delete v2_reader_;
}
bool CheckpointReader::HasTensor(const string& name) const {
diff --git a/tensorflow/compiler/tests/BUILD b/tensorflow/compiler/tests/BUILD
index a3c634c1ab..2ea04c9596 100644
--- a/tensorflow/compiler/tests/BUILD
+++ b/tensorflow/compiler/tests/BUILD
@@ -294,7 +294,6 @@ tf_cuda_cc_test(
# This test is randomized, so only run it if explicitly requested.
tags = [
"manual",
- "noguitar",
"notap",
],
deps = [":randomized_tests_library"],
diff --git a/tensorflow/compiler/tf2xla/xla_compiler.cc b/tensorflow/compiler/tf2xla/xla_compiler.cc
index 17adb9b1fd..d56d6518b7 100644
--- a/tensorflow/compiler/tf2xla/xla_compiler.cc
+++ b/tensorflow/compiler/tf2xla/xla_compiler.cc
@@ -256,24 +256,12 @@ Status ExecuteGraph(XlaContext* xla_context, std::unique_ptr<Graph> graph,
std::unique_ptr<Executor> exec(exec_ptr);
// At this point ownership of the graph has been transferred to exec.
- auto runner = [](Executor::Args::Closure c) {
- // TODO(misard) Temporarily just schedule c eagerly while we
- // decide what to do about the fact that the ComputationBuilder is
- // thread-compatible, but we don't really want Op writers to have
- // to remember to acquire a lock around every call to
- // ComputationBuilder. One possibility is to add the (generally
- // useful) ability to run a single-threaded Executor based on an
- // option in LocalExecutorParams. Another is to automagically
- // acquire a lock around ComputationBuilder calls using some
- // wrapper or RAII funny business.
- c();
- };
-
// Run the graph symbolically, turning the graph into an XLA computation.
Executor::Args exec_args;
exec_args.step_id = step_id;
exec_args.step_container = step_container.get();
- exec_args.runner = runner;
+ // Run all compilation kernels on the main thread.
+ exec_args.runner = [](Executor::Args::Closure c) { c(); };
TF_RETURN_WITH_CONTEXT_IF_ERROR(
exec->Run(exec_args),
"Conversion from TensorFlow graph to XLA computation failed.");
diff --git a/tensorflow/compiler/tf2xla/xla_context.cc b/tensorflow/compiler/tf2xla/xla_context.cc
index a770271628..05876f86dc 100644
--- a/tensorflow/compiler/tf2xla/xla_context.cc
+++ b/tensorflow/compiler/tf2xla/xla_context.cc
@@ -131,8 +131,6 @@ Status XlaContext::CollectResults(
xla::Computation* computation, bool* requires_runtime_context,
std::vector<ConstRetVal>* compile_time_constants,
int* num_nonconst_outputs) {
- mutex_lock l(mu_);
-
xla::ComputationDataHandle handle;
if (retval_.empty() && has_side_effects_) {
// Build a empty tuple return value for computations that have side effects
@@ -200,7 +198,6 @@ XlaContext::XlaContext(XlaCompiler* compiler, xla::Client* client,
const xla::ComputationDataHandle&
XlaContext::GetOrCreateRuntimeContextParameter() {
- mutex_lock lock(mu_);
CHECK(allow_cpu_custom_calls_);
CHECK(!use_tuple_arg_);
if (has_context_parameter_) return context_parameter_;
@@ -220,7 +217,6 @@ void XlaContext::AddRetval(int retval_index,
// Add the return value to the list being built up. The executor
// is multi-threaded so this has to happen under the
// lock.
- mutex_lock l(mu_);
retval_.emplace_back(retval_index, handle);
}
@@ -232,17 +228,14 @@ Status XlaContext::AddConstRetval(int retval_index, DataType dtype,
ConstRetVal value;
value.index = retval_index;
TF_RETURN_IF_ERROR(LiteralToHostTensor(literal, dtype, &value.value));
- mutex_lock l(mu_);
compile_time_constant_.push_back(std::move(value));
} else {
- mutex_lock l(mu_);
retval_.emplace_back(retval_index, xla_builder_.ConstantLiteral(literal));
}
return Status::OK();
}
void XlaContext::AddSideEffects() {
- mutex_lock lock(mu_);
has_side_effects_ = true;
}
@@ -323,7 +316,6 @@ const xla::Computation* XlaContext::LookupOrCreate(
DataType type, ComputationMap* out,
const std::function<xla::Computation()>& create) {
{
- mutex_lock l(mu_);
const auto& entry = (*out)[type];
if (!entry.IsNull()) {
return &entry;
@@ -331,7 +323,6 @@ const xla::Computation* XlaContext::LookupOrCreate(
}
auto new_entry = create();
{
- mutex_lock l(mu_);
// Somebody else might have made one concurrently.
auto& entry = (*out)[type];
if (entry.IsNull()) {
diff --git a/tensorflow/compiler/tf2xla/xla_context.h b/tensorflow/compiler/tf2xla/xla_context.h
index 8ece3d3798..53009bf880 100644
--- a/tensorflow/compiler/tf2xla/xla_context.h
+++ b/tensorflow/compiler/tf2xla/xla_context.h
@@ -29,8 +29,6 @@ limitations under the License.
#include "tensorflow/core/framework/resource_mgr.h"
#include "tensorflow/core/graph/graph.h"
#include "tensorflow/core/platform/macros.h"
-#include "tensorflow/core/platform/mutex.h"
-#include "tensorflow/core/platform/thread_annotations.h"
namespace tensorflow {
@@ -223,11 +221,9 @@ class XlaContext : public ResourceBase {
XlaCompiler* const compiler_;
- mutable mutex mu_;
-
// The ComputationBuilder used to construct the subgraph's compiled
// representation.
- xla::ComputationBuilder xla_builder_ GUARDED_BY(mu_);
+ xla::ComputationBuilder xla_builder_;
// Number of XLA Parameters, not counting the context parameter, if any.
int num_parameters_;
@@ -252,18 +248,17 @@ class XlaContext : public ResourceBase {
// for an additional final parameter to the computation, through which will be
// passed a XlaLocalRuntimeContext* at runtime. Created on demand by
// GetOrCreateRuntimeContextParameter().
- bool has_context_parameter_ GUARDED_BY(mu_) = false;
- xla::ComputationDataHandle context_parameter_ GUARDED_BY(mu_);
+ bool has_context_parameter_ = false;
+ xla::ComputationDataHandle context_parameter_;
// The data-dependent return values of the computation.
- std::vector<std::pair<int, xla::ComputationDataHandle>> retval_
- GUARDED_BY(mu_);
+ std::vector<std::pair<int, xla::ComputationDataHandle>> retval_;
// The non-data-dependent return values of the computation.
- std::vector<ConstRetVal> compile_time_constant_ GUARDED_BY(mu_);
+ std::vector<ConstRetVal> compile_time_constant_;
// Does the computation have side effects, i.e., Send() calls?
- bool has_side_effects_ GUARDED_BY(mu_) = false;
+ bool has_side_effects_ = false;
// Cache of prebuilt computations indexed by their type.
using ComputationMap = std::map<DataType, xla::Computation>;
@@ -273,16 +268,16 @@ class XlaContext : public ResourceBase {
// map. The returned value != nullptr and is owned by the map.
const xla::Computation* LookupOrCreate(
DataType type, ComputationMap* out,
- const std::function<xla::Computation()>& create) LOCKS_EXCLUDED(mu_);
+ const std::function<xla::Computation()>& create);
// Cached computation to compute Max of two elements, specialized by type.
- ComputationMap max_func_ GUARDED_BY(mu_);
+ ComputationMap max_func_;
// Cached computation to compute Sum of two elements, specialized by type.
- ComputationMap add_func_ GUARDED_BY(mu_);
+ ComputationMap add_func_;
// Cached computation to compute Sigmoid of an element, specialized by type.
- ComputationMap sigmoid_func_ GUARDED_BY(mu_);
+ ComputationMap sigmoid_func_;
TF_DISALLOW_COPY_AND_ASSIGN(XlaContext);
};
diff --git a/tensorflow/compiler/xla/reference_util.cc b/tensorflow/compiler/xla/reference_util.cc
index d8ed1ee0f7..7b1a361b93 100644
--- a/tensorflow/compiler/xla/reference_util.cc
+++ b/tensorflow/compiler/xla/reference_util.cc
@@ -134,6 +134,44 @@ ReferenceUtil::SeparableConvArray4D(const Array4D<float>& input,
return tensorflow::MathUtil::CeilOfRatio(unpadded_width, stride);
}
+/* static */ std::unique_ptr<Array2D<float>> ReferenceUtil::ReduceWindow2DAdd(
+ const Array2D<float>& operand, float init,
+ const tensorflow::gtl::ArraySlice<int64>& window,
+ const tensorflow::gtl::ArraySlice<int64>& stride, Padding padding) {
+ std::vector<int64> dim_lengths{operand.height(), operand.width()};
+ auto padding_both = xla::MakePadding(dim_lengths, window, stride, padding);
+
+ std::vector<int64> window_counts(window.size(), 0);
+ std::vector<int64> pad_low(window.size(), 0);
+ for (int64 i = 0; i < window.size(); ++i) {
+ window_counts[i] =
+ WindowCount(dim_lengths[i], window[i], stride[i], padding);
+ pad_low[i] = padding_both[i].first;
+ }
+ auto result = MakeUnique<Array2D<float>>(window_counts[0], window_counts[1]);
+
+ // Do a full 2D reduce window.
+ for (int64 i0 = 0; i0 < window_counts[0]; ++i0) {
+ for (int64 i1 = 0; i1 < window_counts[1]; ++i1) {
+ int64 i0_base = i0 * stride[0] - pad_low[0];
+ int64 i1_base = i1 * stride[1] - pad_low[1];
+
+ float val = init;
+ for (int64 i0_win = 0; i0_win < window[0]; ++i0_win) {
+ for (int64 i1_win = 0; i1_win < window[1]; ++i1_win) {
+ if (i0_base + i0_win >= 0 && i1_base + i1_win >= 0 &&
+ i0_base + i0_win < operand.n1() &&
+ i1_base + i1_win < operand.n2()) {
+ val += operand(i0_base + i0_win, i1_base + i1_win);
+ }
+ }
+ }
+ (*result)(i0, i1) = val;
+ }
+ }
+ return result;
+}
+
/* static */ std::unique_ptr<Array4D<float>> ReferenceUtil::ReduceWindow4DAdd(
const Array4D<float>& operand, float init,
const tensorflow::gtl::ArraySlice<int64>& window,
diff --git a/tensorflow/compiler/xla/reference_util.h b/tensorflow/compiler/xla/reference_util.h
index d19d5f9dbb..52578a1b23 100644
--- a/tensorflow/compiler/xla/reference_util.h
+++ b/tensorflow/compiler/xla/reference_util.h
@@ -144,6 +144,12 @@ class ReferenceUtil {
static int64 WindowCount(int64 unpadded_width, int64 window_len, int64 stride,
Padding padding);
+ // Performs a 2D window reduction with Add as the function to apply.
+ static std::unique_ptr<Array2D<float>> ReduceWindow2DAdd(
+ const Array2D<float>& operand, float init,
+ const tensorflow::gtl::ArraySlice<int64>& window,
+ const tensorflow::gtl::ArraySlice<int64>& stride, Padding padding);
+
// Performs a 4D window reduction with Add as the function to apply.
static std::unique_ptr<Array4D<float>> ReduceWindow4DAdd(
const Array4D<float>& operand, float init,
diff --git a/tensorflow/compiler/xla/service/BUILD b/tensorflow/compiler/xla/service/BUILD
index 0b51032e19..7031e5fee1 100644
--- a/tensorflow/compiler/xla/service/BUILD
+++ b/tensorflow/compiler/xla/service/BUILD
@@ -254,6 +254,7 @@ cc_library(
"//tensorflow/compiler/xla:types",
"//tensorflow/compiler/xla:util",
"//tensorflow/compiler/xla:xla_data_proto",
+ "//tensorflow/compiler/xla/legacy_flags:service_flags",
"//tensorflow/core:lib",
"//tensorflow/core:stream_executor_no_cuda",
],
diff --git a/tensorflow/compiler/xla/service/elemental_ir_emitter.cc b/tensorflow/compiler/xla/service/elemental_ir_emitter.cc
index 9dd276952c..a4b50836d7 100644
--- a/tensorflow/compiler/xla/service/elemental_ir_emitter.cc
+++ b/tensorflow/compiler/xla/service/elemental_ir_emitter.cc
@@ -428,8 +428,8 @@ StatusOr<llvm::Value*> ElementalIrEmitter::EmitIntegerBinaryOp(
llvm_ir::IrArray::Index ElementalIrEmitter::ElementwiseSourceIndex(
const llvm_ir::IrArray::Index& target_index, const HloInstruction& hlo,
int64 operand_no) const {
- CHECK(hlo.IsElementwise()) << "HLO " << hlo.ToString()
- << " is not elementwise.";
+ CHECK(hlo.IsElementwise())
+ << "HLO " << hlo.ToString() << " is not elementwise.";
const Shape& operand_shape = hlo.operand(operand_no)->shape();
// If the operand is scalar, the source index is always {}.
@@ -474,8 +474,9 @@ llvm_ir::ElementGenerator ElementalIrEmitter::MakeRngElementGenerator(
llvm::APInt(128, {0x14057B7EF767814F, 0x5851F42D4C957F2D}));
auto random_value = [hlo]() {
- CHECK(hlo->parent() != nullptr && hlo->parent()->parent() != nullptr);
- const HloModule* module = hlo->parent()->parent();
+ const HloModule* module =
+ hlo->IsFused() ? hlo->fusion_instruction()->parent()->parent()
+ : hlo->parent()->parent();
return module->RandomNew64();
};
diff --git a/tensorflow/compiler/xla/service/gpu/instruction_fusion.cc b/tensorflow/compiler/xla/service/gpu/instruction_fusion.cc
index 91fd7ae77a..34a44ad405 100644
--- a/tensorflow/compiler/xla/service/gpu/instruction_fusion.cc
+++ b/tensorflow/compiler/xla/service/gpu/instruction_fusion.cc
@@ -46,6 +46,11 @@ bool GpuInstructionFusion::ShouldFuse(HloInstruction* consumer,
int64 operand_index) {
HloInstruction* producer = consumer->mutable_operand(operand_index);
+ // RNG operations are not currently parallel-friendly on GPU.
+ if (producer->opcode() == HloOpcode::kRng) {
+ return false;
+ }
+
// Do not fuse to-vector reduction into other consumers. They should be
// unfused or the root of a kInput fusion.
if (IsReductionToVector(*producer)) {
diff --git a/tensorflow/compiler/xla/service/hlo_cost_analysis.cc b/tensorflow/compiler/xla/service/hlo_cost_analysis.cc
index 2866f8158d..84cf025e1c 100644
--- a/tensorflow/compiler/xla/service/hlo_cost_analysis.cc
+++ b/tensorflow/compiler/xla/service/hlo_cost_analysis.cc
@@ -24,6 +24,45 @@ limitations under the License.
namespace xla {
+int64 HloCostAnalysis::ShapeSizeBytes(const Shape& shape) const {
+ return shape_size_ == nullptr ? 0 : shape_size_(shape);
+}
+
+Status HloCostAnalysis::Preprocess(HloInstruction* hlo) {
+ // Set current instruction cost values to reasonable default values. Each
+ // handler can overwrite these values. In Postprocess, these value are
+ // accumulated and written to the per-instruction maps.
+ current_flop_count_ = 0;
+ current_transcendental_count_ = 0;
+
+ // The default element count for an instruction is the sum of elements in the
+ // operands and output. The default ShapeUtil::ByteSizeOf does not handle
+ // opaque types.
+ current_bytes_accessed_ =
+ ShapeUtil::IsOpaque(hlo->shape()) ? 0 : ShapeSizeBytes(hlo->shape());
+ for (const HloInstruction* operand : hlo->operands()) {
+ current_bytes_accessed_ += ShapeUtil::IsOpaque(operand->shape())
+ ? 0
+ : ShapeSizeBytes(operand->shape());
+ }
+
+ return Status::OK();
+}
+
+Status HloCostAnalysis::Postprocess(HloInstruction* hlo) {
+ // Accumulate cost values and write into per-instruction maps.
+ flop_count_ += current_flop_count_;
+ hlo_to_flop_count_[hlo] = current_flop_count_;
+
+ transcendental_count_ += current_transcendental_count_;
+ hlo_to_transcendental_count_[hlo] = current_transcendental_count_;
+
+ bytes_accessed_ += current_bytes_accessed_;
+ hlo_to_bytes_accessed_[hlo] = current_bytes_accessed_;
+
+ return Status::OK();
+}
+
Status HloCostAnalysis::HandleElementwiseOp(HloInstruction* hlo_instruction) {
const auto& shape = hlo_instruction->shape();
// For element-wise operations, the number of computations is the same as the
@@ -32,12 +71,11 @@ Status HloCostAnalysis::HandleElementwiseOp(HloInstruction* hlo_instruction) {
auto opcode = hlo_instruction->opcode();
// We treat the two opcodes (kExp, kPower) as transcendental operations.
if (opcode == HloOpcode::kExp || opcode == HloOpcode::kPower) {
- transcendental_count_ += computation_count;
+ current_transcendental_count_ = computation_count;
} else {
// Note: transcendental operations are considered a separate category from
// FLOPs.
- hlo_to_flop_count_[hlo_instruction] = computation_count;
- flop_count_ += computation_count;
+ current_flop_count_ = computation_count;
}
return Status::OK();
}
@@ -69,16 +107,21 @@ Status HloCostAnalysis::HandleClamp(HloInstruction* clamp,
}
Status HloCostAnalysis::HandleParameter(HloInstruction* parameter) {
+ current_bytes_accessed_ = 0;
return Status::OK();
}
Status HloCostAnalysis::HandleConstant(HloInstruction* constant,
const Literal& literal) {
+ current_bytes_accessed_ = 0;
return Status::OK();
}
Status HloCostAnalysis::HandleGetTupleElement(HloInstruction* get_tuple_element,
HloInstruction* operand) {
+ // GetTupleElement forwards a pointer and does not touch each element in the
+ // output.
+ current_bytes_accessed_ = 0;
return Status::OK();
}
@@ -114,6 +157,10 @@ Status HloCostAnalysis::HandleDynamicUpdateSlice(
Status HloCostAnalysis::HandleTuple(
HloInstruction* tuple,
tensorflow::gtl::ArraySlice<HloInstruction*> operands) {
+ // The tuple instruction only gathers pointers from inputs (it doesn't iterate
+ // through them). The memory touched is then only the size of the output
+ // buffer.
+ current_bytes_accessed_ = ShapeSizeBytes(tuple->shape());
return Status::OK();
}
@@ -125,8 +172,7 @@ Status HloCostAnalysis::HandleConcatenate(
Status HloCostAnalysis::HandleConvert(HloInstruction* convert,
HloInstruction* operand) {
- flop_count_ += ShapeUtil::ElementsIn(operand->shape());
- return Status::OK();
+ return HandleElementwiseOp(convert);
}
Status HloCostAnalysis::HandleCopy(HloInstruction* copy,
@@ -137,15 +183,24 @@ Status HloCostAnalysis::HandleCopy(HloInstruction* copy,
Status HloCostAnalysis::HandleDot(HloInstruction* dot,
HloInstruction* lhs_instruction,
HloInstruction* rhs_instruction) {
+ const Shape& lhs_shape = lhs_instruction->shape();
+ const Shape& rhs_shape = rhs_instruction->shape();
+ // Count of elements along the reduction dimension (last dimension for the
+ // rhs).
+ int64 reduction_width = lhs_shape.dimensions(ShapeUtil::Rank(lhs_shape) - 1);
+
+ // First divide by reduction width before multiplying by rhs elements to avoid
+ // overflow.
+ int64 fma_count;
+ if (reduction_width == 0) {
+ fma_count = 0;
+ } else {
+ fma_count = (ShapeUtil::ElementsIn(lhs_shape) / reduction_width) *
+ ShapeUtil::ElementsIn(rhs_shape);
+ }
+
// We count an FMA operation as 2 floating point operations.
- // Multiplying the sizes of lhs, rhs, and result produces the square of the
- // number of FMAs during the computation.
- auto fma_count = std::sqrt(
- static_cast<double>(ShapeUtil::ElementsIn(lhs_instruction->shape())) *
- ShapeUtil::ElementsIn(rhs_instruction->shape()) *
- ShapeUtil::ElementsIn(dot->shape()));
- flop_count_ += 2 * fma_count;
- hlo_to_flop_count_[dot] = 2 * fma_count;
+ current_flop_count_ = kFmaFlops * fma_count;
return Status::OK();
}
@@ -163,15 +218,14 @@ Status HloCostAnalysis::HandleMap(
tensorflow::gtl::ArraySlice<HloInstruction*> /*static_operands*/) {
// Compute the cost of the user function.
HloInstruction* function_instruction = function->root_instruction();
- HloCostAnalysis visitor;
+ HloCostAnalysis visitor(shape_size_);
TF_RETURN_IF_ERROR(function_instruction->Accept(&visitor));
// Compute the cost of all elements for this Map operation.
- auto element_count = ShapeUtil::ElementsIn(map->shape());
- transcendental_count_ += element_count * visitor.transcendental_count();
- auto hlo_flop_count = element_count * visitor.flop_count();
- hlo_to_flop_count_[map] = hlo_flop_count;
- flop_count_ += hlo_flop_count;
+ int64 element_count = ShapeUtil::ElementsIn(map->shape());
+ current_transcendental_count_ =
+ element_count * visitor.transcendental_count();
+ current_flop_count_ = element_count * visitor.flop_count();
return Status::OK();
}
@@ -180,16 +234,15 @@ Status HloCostAnalysis::HandleReduce(
tensorflow::gtl::ArraySlice<int64> dimensions, HloComputation* function) {
// Compute the cost of the user function.
HloInstruction* function_instruction = function->root_instruction();
- HloCostAnalysis visitor;
+ HloCostAnalysis visitor(shape_size_);
TF_RETURN_IF_ERROR(function_instruction->Accept(&visitor));
// Compute the cost of all elements for this Reduce operation.
- auto reduction_count = ShapeUtil::ElementsIn(arg->shape()) -
- ShapeUtil::ElementsIn(reduce->shape());
- auto hlo_flop_count = reduction_count * visitor.flop_count();
- hlo_to_flop_count_[reduce] = hlo_flop_count;
- flop_count_ += hlo_flop_count;
- transcendental_count_ += reduction_count * visitor.transcendental_count();
+ int64 reduction_count = ShapeUtil::ElementsIn(arg->shape()) -
+ ShapeUtil::ElementsIn(reduce->shape());
+ current_flop_count_ = reduction_count * visitor.flop_count();
+ current_transcendental_count_ =
+ reduction_count * visitor.transcendental_count();
return Status::OK();
}
@@ -199,7 +252,7 @@ Status HloCostAnalysis::HandleReduceWindow(HloInstruction* reduce_window,
HloComputation* function) {
// Compute the cost of the user function.
HloInstruction* function_instruction = function->root_instruction();
- HloCostAnalysis visitor;
+ HloCostAnalysis visitor(shape_size_);
TF_RETURN_IF_ERROR(function_instruction->Accept(&visitor));
// Compute the cost of all elements for this ReduceWindow operation. For each
@@ -209,10 +262,8 @@ Status HloCostAnalysis::HandleReduceWindow(HloInstruction* reduce_window,
for (const auto& dimension : window.dimensions()) {
window_size *= dimension.size();
}
- auto hlo_flop_count = output_size * (window_size - 1) * visitor.flop_count();
- hlo_to_flop_count_[reduce_window] = hlo_flop_count;
- flop_count_ += hlo_flop_count;
- transcendental_count_ +=
+ current_flop_count_ = output_size * (window_size - 1) * visitor.flop_count();
+ current_transcendental_count_ =
output_size * (window_size - 1) * visitor.transcendental_count();
return Status::OK();
}
@@ -220,10 +271,10 @@ Status HloCostAnalysis::HandleReduceWindow(HloInstruction* reduce_window,
Status HloCostAnalysis::HandleSelectAndScatter(HloInstruction* instruction) {
// Compute the cost of the select and scatter function.
HloInstruction* select = instruction->select()->root_instruction();
- HloCostAnalysis select_visitor;
+ HloCostAnalysis select_visitor(shape_size_);
TF_RETURN_IF_ERROR(select->Accept(&select_visitor));
HloInstruction* scatter = instruction->scatter()->root_instruction();
- HloCostAnalysis scatter_visitor;
+ HloCostAnalysis scatter_visitor(shape_size_);
TF_RETURN_IF_ERROR(scatter->Accept(&scatter_visitor));
// Compute the cost of all elements for this operation. For each scatter
@@ -235,12 +286,10 @@ Status HloCostAnalysis::HandleSelectAndScatter(HloInstruction* instruction) {
for (const auto& dimension : instruction->window().dimensions()) {
window_size *= dimension.size();
}
- auto hlo_flop_count =
+ current_flop_count_ =
source_element_count * ((window_size - 1) * select_visitor.flop_count() +
scatter_visitor.flop_count());
- hlo_to_flop_count_[instruction] = hlo_flop_count;
- flop_count_ += hlo_flop_count;
- transcendental_count_ +=
+ current_transcendental_count_ =
source_element_count *
((window_size - 1) * select_visitor.transcendental_count() +
scatter_visitor.transcendental_count());
@@ -248,6 +297,8 @@ Status HloCostAnalysis::HandleSelectAndScatter(HloInstruction* instruction) {
}
Status HloCostAnalysis::HandleBitcast(HloInstruction* bitcast) {
+ // A bitcast does no computation and touches no memory.
+ current_bytes_accessed_ = 0;
return Status::OK();
}
@@ -286,10 +337,7 @@ Status HloCostAnalysis::HandleConvolution(HloInstruction* convolution,
const int64 fmas_per_output_element =
ShapeUtil::ElementsIn(rhs_instruction->shape()) / output_features;
const int64 output_elements = ShapeUtil::ElementsIn(convolution->shape());
- const double hlo_flop_count = static_cast<double>(output_elements) *
- fmas_per_output_element * kFmaFlops;
- flop_count_ += hlo_flop_count;
- hlo_to_flop_count_[convolution] = hlo_flop_count;
+ current_flop_count_ = output_elements * fmas_per_output_element * kFmaFlops;
return Status::OK();
}
@@ -299,9 +347,7 @@ Status HloCostAnalysis::HandleCrossReplicaSum(HloInstruction* crs) {
//
// TODO(b/33004697): Compute correct cost here, taking the actual number of
// replicas into account.
- const double hlo_flop_count = ShapeUtil::ElementsIn(crs->shape());
- flop_count_ += hlo_flop_count;
- hlo_to_flop_count_[crs] = hlo_flop_count;
+ current_flop_count_ = ShapeUtil::ElementsIn(crs->shape());
return Status::OK();
}
@@ -310,20 +356,19 @@ Status HloCostAnalysis::HandleRng(HloInstruction* random,
// TODO(b/26346211): Implement better estimates for the RNG cost, since the
// cost changes with the implementation and the distribution. For now, assume
// the cost of each RNG is same as a transcendental operation.
- transcendental_count_ += ShapeUtil::ElementsIn(random->shape());
+ current_transcendental_count_ = ShapeUtil::ElementsIn(random->shape());
return Status::OK();
}
Status HloCostAnalysis::HandleFusion(HloInstruction* fusion) {
// Compute the cost of the fused expression.
HloInstruction* fused_expression_root = fusion->fused_expression_root();
- HloCostAnalysis visitor;
+ HloCostAnalysis visitor(shape_size_);
TF_RETURN_IF_ERROR(fused_expression_root->Accept(&visitor));
// Attribute the cost of the fused expression to the fusion node.
- transcendental_count_ += visitor.transcendental_count();
- hlo_to_flop_count_[fusion] += visitor.flop_count();
- flop_count_ += visitor.flop_count();
+ current_transcendental_count_ = visitor.transcendental_count();
+ current_flop_count_ = visitor.flop_count();
return Status::OK();
}
@@ -353,18 +398,58 @@ Status HloCostAnalysis::HandleWhile(HloInstruction* xla_while,
HloComputation* condition,
HloComputation* body) {
// Since the number of iterations of the while node is not statically
- // determined, we cannot analyze the computation cost of a while node.
- // TODO(b/26346211): Add cost analysis for while node.
- return Unimplemented("HandleWhile");
+ // determined, we cannot precisely compute the cost of a while node. For now
+ // compute the cost of a single iteration.
+ // TODO(b/26346211): Improve the cost analysis for while node.
+ HloCostAnalysis body_visitor(shape_size_);
+ TF_RETURN_IF_ERROR(body->Accept(&body_visitor));
+ HloCostAnalysis condition_visitor(shape_size_);
+ TF_RETURN_IF_ERROR(condition->Accept(&condition_visitor));
+
+ current_flop_count_ =
+ body_visitor.flop_count() + condition_visitor.flop_count();
+ current_transcendental_count_ = body_visitor.transcendental_count() +
+ condition_visitor.transcendental_count();
+ if (shape_size_ != nullptr) {
+ TF_ASSIGN_OR_RETURN(int64 body_bytes, body_visitor.bytes_accessed());
+ TF_ASSIGN_OR_RETURN(int64 condition_bytes,
+ condition_visitor.bytes_accessed());
+ current_bytes_accessed_ = body_bytes + condition_bytes;
+ }
+
+ return Status::OK();
}
Status HloCostAnalysis::FinishVisit(HloInstruction* root) {
return Status::OK();
}
-double HloCostAnalysis::hlo_to_flop_count(const HloInstruction& hlo) const {
+int64 HloCostAnalysis::flop_count(const HloInstruction& hlo) const {
auto it = hlo_to_flop_count_.find(&hlo);
- return it == hlo_to_flop_count_.end() ? 0.0 : it->second;
+ return it == hlo_to_flop_count_.end() ? 0 : it->second;
+}
+
+int64 HloCostAnalysis::transcendental_count(const HloInstruction& hlo) const {
+ auto it = hlo_to_transcendental_count_.find(&hlo);
+ return it == hlo_to_transcendental_count_.end() ? 0 : it->second;
+}
+
+StatusOr<int64> HloCostAnalysis::bytes_accessed(
+ const HloInstruction& hlo) const {
+ if (shape_size_ == nullptr) {
+ return FailedPrecondition(
+ "Cannot determine number of bytes accessed; no size function given");
+ }
+ auto it = hlo_to_bytes_accessed_.find(&hlo);
+ return it == hlo_to_bytes_accessed_.end() ? 0 : it->second;
+}
+
+StatusOr<int64> HloCostAnalysis::bytes_accessed() const {
+ if (shape_size_ == nullptr) {
+ return FailedPrecondition(
+ "Cannot determine number of bytes accessed; no size function given");
+ }
+ return bytes_accessed_;
}
} // namespace xla
diff --git a/tensorflow/compiler/xla/service/hlo_cost_analysis.h b/tensorflow/compiler/xla/service/hlo_cost_analysis.h
index 2377b5b9be..87752ef335 100644
--- a/tensorflow/compiler/xla/service/hlo_cost_analysis.h
+++ b/tensorflow/compiler/xla/service/hlo_cost_analysis.h
@@ -20,6 +20,7 @@ limitations under the License.
#include "tensorflow/compiler/xla/service/hlo_computation.h"
#include "tensorflow/compiler/xla/service/hlo_instruction.h"
#include "tensorflow/compiler/xla/service/hlo_opcode.h"
+#include "tensorflow/compiler/xla/shape_util.h"
#include "tensorflow/compiler/xla/statusor.h"
#include "tensorflow/compiler/xla/xla_data.pb.h"
#include "tensorflow/core/lib/gtl/array_slice.h"
@@ -35,7 +36,15 @@ namespace xla {
// operations separately from transcendental operations.
class HloCostAnalysis : public DfsHloVisitor {
public:
- HloCostAnalysis() = default;
+ HloCostAnalysis() {}
+
+ // Constructor which accepts a function for computing the size in bytes of the
+ // top-level buffer of a shape. This constructor must be used if
+ // bytes_accessed methods are to be called.
+ using ShapeSizeFunction = std::function<int64(const Shape&)>;
+ explicit HloCostAnalysis(const ShapeSizeFunction& shape_size)
+ : shape_size_(shape_size) {}
+
~HloCostAnalysis() override = default;
Status HandleElementwiseUnary(HloInstruction* hlo, HloOpcode opcode,
@@ -115,30 +124,55 @@ class HloCostAnalysis : public DfsHloVisitor {
HloComputation* condition, HloComputation* body) override;
Status FinishVisit(HloInstruction* root) override;
+ Status Preprocess(HloInstruction* hlo) override;
+ Status Postprocess(HloInstruction* hlo) override;
+
// Returns the amount of computations in the graph.
- double flop_count() { return flop_count_; }
- double transcendental_count() { return transcendental_count_; }
+ int64 flop_count() const { return flop_count_; }
+ int64 transcendental_count() const { return transcendental_count_; }
+
+ // Returns the respective cost computed for a particular HLO instruction, or 0
+ // if the HLO was not found to have a cost in the analysis.
+ int64 flop_count(const HloInstruction& hlo) const;
+ int64 transcendental_count(const HloInstruction& hlo) const;
- // Resolves the provided HLO instruction to a flop count, or 0 if the HLO was
- // not found to have a flop count in the analysis.
- double hlo_to_flop_count(const HloInstruction& hlo) const;
+ // Returns the number of bytes read/written. Returns an Status error if no
+ // ShapeSizeFunction was given at construction time.
+ StatusOr<int64> bytes_accessed(const HloInstruction& hlo) const;
+ StatusOr<int64> bytes_accessed() const;
private:
+ // Returns the size in bytes of the top-level buffer of a shape.
+ int64 ShapeSizeBytes(const Shape& shape) const;
+
// An FMA counts as two floating point operations in these analyses.
static constexpr int64 kFmaFlops = 2;
// Utility function to handle all element-wise operations.
Status HandleElementwiseOp(HloInstruction* hlo_instruction);
- // Mapping from HLO instructions to the flop count we computed for them in the
- // course of the graph analysis.
- std::map<const HloInstruction*, double> hlo_to_flop_count_;
+ // Function which computes the size of the top-level of a given shape (not
+ // including nested elements, if any). If null then bytes_accessed methods
+ // return an error.
+ ShapeSizeFunction shape_size_ = nullptr;
- // The number of floating point operations in the graph.
- double flop_count_ = 0.0;
+ // The total number of floating point operations, transcendental operations,
+ // and bytes accesses (read or written) in the computation.
+ int64 flop_count_ = 0;
+ int64 transcendental_count_ = 0;
+ int64 bytes_accessed_ = 0;
- // The number of transcendental operations in the graph.
- double transcendental_count_ = 0.0;
+ // Cost counts of the current instruction. These should be set by each
+ // handlers if different from the default values computed in Preprocess.
+ int64 current_flop_count_;
+ int64 current_transcendental_count_;
+ int64 current_bytes_accessed_;
+
+ // Mapping from HLO instructions to the cost we computed for them in the
+ // course of the graph analysis.
+ std::map<const HloInstruction*, int64> hlo_to_flop_count_;
+ std::map<const HloInstruction*, int64> hlo_to_transcendental_count_;
+ std::map<const HloInstruction*, int64> hlo_to_bytes_accessed_;
TF_DISALLOW_COPY_AND_ASSIGN(HloCostAnalysis);
};
diff --git a/tensorflow/compiler/xla/service/hlo_cost_analysis_test.cc b/tensorflow/compiler/xla/service/hlo_cost_analysis_test.cc
index f55d939b42..abdde619fb 100644
--- a/tensorflow/compiler/xla/service/hlo_cost_analysis_test.cc
+++ b/tensorflow/compiler/xla/service/hlo_cost_analysis_test.cc
@@ -39,6 +39,12 @@ limitations under the License.
namespace xla {
namespace {
+constexpr int64 kPointerSize = 8;
+
+int64 ShapeSize(const Shape& shape) {
+ return ShapeUtil::ByteSizeOf(shape, kPointerSize);
+}
+
// This test suite tests the HLO cost analysis by first building a computation
// using the client computation builder and running the HloCostAnalysis that
// returns the number of floating point and transcendental operations in the
@@ -144,12 +150,18 @@ TEST_F(HloCostAnalysisTest, MatrixMultiply) {
// Run HLO cost analysis.
auto hlo_module = BuildHloGraph(&builder);
- HloCostAnalysis analysis;
+ HloCostAnalysis analysis(ShapeSize);
ASSERT_IS_OK(
hlo_module->entry_computation()->root_instruction()->Accept(&analysis));
// Check the number of computations returned from the analysis (1500 FMAs).
EXPECT_EQ(analysis.flop_count(), 2 * 10 * 30 * 5);
+
+ EXPECT_EQ(analysis.transcendental_count(), 0);
+
+ // Bytes accessed is sum of inputs and output.
+ TF_ASSIGN_OR_ASSERT_OK(int64 bytes_accessed, analysis.bytes_accessed());
+ EXPECT_EQ(bytes_accessed, sizeof(float) * (10 * 5 + 5 * 30 + 10 * 30));
}
TEST_F(HloCostAnalysisTest, Map) {
@@ -159,13 +171,15 @@ TEST_F(HloCostAnalysisTest, Map) {
// Run HLO cost analysis.
auto hlo_module = BuildHloGraph(&builder);
- HloCostAnalysis analysis;
+ HloCostAnalysis analysis(ShapeSize);
ASSERT_IS_OK(
hlo_module->entry_computation()->root_instruction()->Accept(&analysis));
// add contributes to 10 flops and exp contributes to 10 transcendental ops.
EXPECT_EQ(analysis.flop_count(), 10);
EXPECT_EQ(analysis.transcendental_count(), 10);
+ TF_ASSIGN_OR_ASSERT_OK(int64 bytes_accessed, analysis.bytes_accessed());
+ EXPECT_EQ(bytes_accessed, 80);
}
TEST_F(HloCostAnalysisTest, Convolution) {
@@ -182,13 +196,17 @@ TEST_F(HloCostAnalysisTest, Convolution) {
// Run HLO cost analysis.
auto hlo_module = BuildHloGraph(&builder);
- HloCostAnalysis analysis;
+ HloCostAnalysis analysis(ShapeSize);
ASSERT_IS_OK(
hlo_module->entry_computation()->root_instruction()->Accept(&analysis));
// Output shape is [1x1x8x18] and each output element requires (3x3)
// FMAs and one FMA is 2 flops.
EXPECT_EQ(analysis.flop_count(), 8 * 18 * 2 * 3 * 3);
+
+ // Bytes accessed is sum of inputs and output.
+ TF_ASSIGN_OR_ASSERT_OK(int64 bytes_accessed, analysis.bytes_accessed());
+ EXPECT_EQ(bytes_accessed, sizeof(float) * (10 * 20 + 3 * 3 + 8 * 18));
}
TEST_F(HloCostAnalysisTest, Reduce) {
@@ -200,7 +218,7 @@ TEST_F(HloCostAnalysisTest, Reduce) {
// Run HLO cost analysis.
auto hlo_module = BuildHloGraph(&builder);
- HloCostAnalysis analysis;
+ HloCostAnalysis analysis(ShapeSize);
ASSERT_IS_OK(
hlo_module->entry_computation()->root_instruction()->Accept(&analysis));
@@ -218,7 +236,7 @@ TEST_F(HloCostAnalysisTest, ReduceWindow) {
// Run HLO cost analysis.
auto hlo_module = BuildHloGraph(&builder);
- HloCostAnalysis analysis;
+ HloCostAnalysis analysis(ShapeSize);
ASSERT_IS_OK(
hlo_module->entry_computation()->root_instruction()->Accept(&analysis));
@@ -238,7 +256,7 @@ TEST_F(HloCostAnalysisTest, SelectAndScatter) {
// Run HLO cost analysis.
auto hlo_module = BuildHloGraph(&builder);
- HloCostAnalysis analysis;
+ HloCostAnalysis analysis(ShapeSize);
ASSERT_IS_OK(
hlo_module->entry_computation()->root_instruction()->Accept(&analysis));
@@ -251,7 +269,7 @@ TEST_F(HloCostAnalysisTest, Broadcast) {
ComputationBuilder b(client_, "broadcast");
b.Broadcast(b.ConstantR0<float>(42), {10, 7});
auto hlo_module = BuildHloGraph(&b);
- HloCostAnalysis analysis;
+ HloCostAnalysis analysis(ShapeSize);
ASSERT_IS_OK(
hlo_module->entry_computation()->root_instruction()->Accept(&analysis));
EXPECT_EQ(analysis.flop_count(), 0);
@@ -271,7 +289,7 @@ TEST_F(HloCostAnalysisTest, FullyConnectedForward) {
// Run HLO cost analysis.
auto hlo_module = BuildHloGraph(&builder);
- HloCostAnalysis analysis;
+ HloCostAnalysis analysis(ShapeSize);
ASSERT_IS_OK(
hlo_module->entry_computation()->root_instruction()->Accept(&analysis));
@@ -282,7 +300,7 @@ TEST_F(HloCostAnalysisTest, FullyConnectedForward) {
}
TEST_F(HloCostAnalysisTest, MatmulAndConvolutionCanBeTheSameComputation) {
- HloCostAnalysis conv_analysis;
+ HloCostAnalysis conv_analysis(ShapeSize);
{
ComputationBuilder builder(client_, "conv_looking_matmul");
auto lhs = builder.Parameter(0, ShapeUtil::MakeShape(F32, {64, 64, 1, 1}),
@@ -295,7 +313,7 @@ TEST_F(HloCostAnalysisTest, MatmulAndConvolutionCanBeTheSameComputation) {
&conv_analysis));
}
- HloCostAnalysis matmul_analysis;
+ HloCostAnalysis matmul_analysis(ShapeSize);
{
ComputationBuilder builder(client_, "matmul");
auto lhs =
@@ -311,28 +329,6 @@ TEST_F(HloCostAnalysisTest, MatmulAndConvolutionCanBeTheSameComputation) {
EXPECT_EQ(conv_analysis.flop_count(), matmul_analysis.flop_count());
}
-// Note that we still expect that any given operation won't overflow 2^64 FLOPs,
-// just that the sum total may.
-TEST_F(HloCostAnalysisTest, TotalOverflowsInt64) {
- HloCostAnalysis matmul_analysis;
- {
- ComputationBuilder builder(client_, "matmul");
- auto lhs = builder.Parameter(0, ShapeUtil::MakeShape(F32, {1, 1LL << 62}),
- "input");
- auto rhs = builder.Parameter(1, ShapeUtil::MakeShape(F32, {1LL << 62, 1}),
- "weights");
- auto a = builder.Dot(lhs, rhs);
- auto b = builder.Dot(a, lhs);
- builder.Dot(b, rhs);
- auto hlo_module = BuildHloGraph(&builder);
- ASSERT_IS_OK(hlo_module->entry_computation()->root_instruction()->Accept(
- &matmul_analysis));
- }
-
- LOG(INFO) << matmul_analysis.flop_count();
- EXPECT_GT(matmul_analysis.flop_count(), std::numeric_limits<int64>::max());
-}
-
using FusionCostAnalysis = ::testing::Test;
TEST_F(FusionCostAnalysis, LoopFusion) {
@@ -373,12 +369,31 @@ TEST_F(FusionCostAnalysis, LoopFusion) {
fusion->FuseInstruction(clamp.get());
fusion->FuseInstruction(add.get());
- HloCostAnalysis fusion_analysis;
+ HloCostAnalysis fusion_analysis(ShapeSize);
ASSERT_IS_OK(fusion->Accept(&fusion_analysis));
EXPECT_EQ(fusion_analysis.flop_count(), 16);
EXPECT_EQ(fusion_analysis.transcendental_count(), 4);
}
+TEST_F(HloCostAnalysisTest, TupleCost) {
+ HloCostAnalysis analysis(ShapeSize);
+ {
+ ComputationBuilder builder(client_, "matmul");
+ auto x = builder.Parameter(0, ShapeUtil::MakeShape(F32, {123}), "x");
+ auto y = builder.Parameter(1, ShapeUtil::MakeShape(F32, {42}), "y");
+ auto tuple = builder.Tuple({x, y});
+ auto hlo_module = BuildHloGraph(&builder);
+
+ ASSERT_IS_OK(
+ hlo_module->entry_computation()->root_instruction()->Accept(&analysis));
+ }
+
+ EXPECT_EQ(analysis.flop_count(), 0);
+ EXPECT_EQ(analysis.transcendental_count(), 0);
+ TF_ASSIGN_OR_ASSERT_OK(int64 bytes_accessed, analysis.bytes_accessed());
+ EXPECT_EQ(bytes_accessed, kPointerSize * 2);
+}
+
} // namespace
} // namespace xla
diff --git a/tensorflow/compiler/xla/service/hlo_execution_profile.cc b/tensorflow/compiler/xla/service/hlo_execution_profile.cc
index 0b87b04fc4..82c85635f0 100644
--- a/tensorflow/compiler/xla/service/hlo_execution_profile.cc
+++ b/tensorflow/compiler/xla/service/hlo_execution_profile.cc
@@ -80,9 +80,8 @@ string HloExecutionProfile::ToString(
append_item(total_cycles, -1, "[total]");
for (const auto& item : items) {
tensorflow::strings::StrAppend(&result, "\n\t");
- auto flops = item.first == nullptr
- ? -1
- : cost_analysis.hlo_to_flop_count(*item.first);
+ auto flops =
+ item.first == nullptr ? -1 : cost_analysis.flop_count(*item.first);
string display = item.first == nullptr ? "<none>" : item.first->ToString();
append_item(item.second, flops, display);
}
diff --git a/tensorflow/compiler/xla/service/hlo_instruction.cc b/tensorflow/compiler/xla/service/hlo_instruction.cc
index cd67757bb2..d4b6d726e4 100644
--- a/tensorflow/compiler/xla/service/hlo_instruction.cc
+++ b/tensorflow/compiler/xla/service/hlo_instruction.cc
@@ -1447,10 +1447,12 @@ string HloInstruction::ToString(bool compact_operands) const {
string HloInstruction::ToShortString() const {
return tensorflow::strings::Printf(
"%s = %s(%s)", name().c_str(), HloOpcodeString(opcode()).c_str(),
- tensorflow::str_util::Join(operands_, ", ", [](string* out,
- HloInstruction* operand) {
- tensorflow::strings::StrAppend(out, operand->name());
- }).c_str());
+ tensorflow::str_util::Join(operands_, ", ",
+ [](string* out, HloInstruction* operand) {
+ tensorflow::strings::StrAppend(
+ out, operand->name());
+ })
+ .c_str());
}
string HloInstruction::ToCategory() const {
@@ -1528,6 +1530,10 @@ bool HloInstruction::IsFusable() const {
case HloOpcode::kSend:
case HloOpcode::kRecv:
return false;
+ // Only fuse Rng if it is used once, otherwise the random numbers generated
+ // will be different in each fusion.
+ case HloOpcode::kRng:
+ return users_.size() == 1;
default:
return true;
}
@@ -1879,6 +1885,7 @@ bool HloInstruction::IsElementwise() const {
return true;
// Other operations.
+ case HloOpcode::kRng:
case HloOpcode::kMap:
return true;
case HloOpcode::kFusion:
diff --git a/tensorflow/compiler/xla/service/local_service.cc b/tensorflow/compiler/xla/service/local_service.cc
index 30bf450c5b..73d6305362 100644
--- a/tensorflow/compiler/xla/service/local_service.cc
+++ b/tensorflow/compiler/xla/service/local_service.cc
@@ -19,6 +19,7 @@ limitations under the License.
#include <utility>
#include <vector>
+#include "tensorflow/compiler/xla/legacy_flags/service_flags.h"
#include "tensorflow/compiler/xla/ptr_util.h"
#include "tensorflow/compiler/xla/service/backend.h"
#include "tensorflow/compiler/xla/service/computation_layout.h"
@@ -519,6 +520,10 @@ StatusOr<std::unique_ptr<Executable>> LocalService::CompileExecutable(
auto module_config = MakeUnique<HloModuleConfig>(*program_shape);
module_config->set_has_hybrid_result(has_hybrid_result);
module_config->set_replica_count(execute_backend_->Replicas().size());
+ legacy_flags::ServiceFlags* flags = legacy_flags::GetServiceFlags();
+ if (flags->xla_hlo_profile) {
+ module_config->enable_hlo_profiling(true);
+ }
auto* computation_layout = module_config->mutable_entry_computation_layout();
for (int i = 0; i < argument_layouts.size(); ++i) {
const Shape& shape = *argument_layouts[i];
diff --git a/tensorflow/compiler/xla/tests/vector_ops_simple_test.cc b/tensorflow/compiler/xla/tests/vector_ops_simple_test.cc
index d9fc1e1e8f..4ab4c84aa5 100644
--- a/tensorflow/compiler/xla/tests/vector_ops_simple_test.cc
+++ b/tensorflow/compiler/xla/tests/vector_ops_simple_test.cc
@@ -155,6 +155,35 @@ TEST_F(VecOpsSimpleTest, ReciprocalTenValues) {
ComputeAndCompareR1<float>(&builder, expected, {}, error_spec_);
}
+XLA_TEST_F(VecOpsSimpleTest, SqrtZeroes) {
+ ComputationBuilder builder(client_, TestName());
+ auto x = builder.ConstantR1<float>({0.0, -0.0});
+ auto exp = builder.SqrtF32(x);
+
+ ComputeAndCompareR1<float>(&builder, {0, 0}, {}, error_spec_);
+}
+
+XLA_TEST_F(VecOpsSimpleTest, SqrtSixValues) {
+ ComputationBuilder builder(client_, TestName());
+ auto x = builder.ConstantR1<float>({16.0, 1.0, 1024.0, 0.16, 0.2, 12345});
+ auto exp = builder.SqrtF32(x);
+
+ std::vector<float> expected = {4, 1, 32, 0.4, 0.4472, 111.1080};
+ ComputeAndCompareR1<float>(&builder, expected, {}, error_spec_);
+}
+
+XLA_TEST_F(VecOpsSimpleTest, InvSqrtSevenValues) {
+ ComputationBuilder builder(client_, TestName());
+ auto x =
+ builder.ConstantR1<float>({16.0, 1.0, 1024.0, 0.16, 0.2, 12345, 1.2345});
+ auto exp = builder.Pow(x, builder.ConstantR0<float>(-.5f));
+
+ std::vector<float> expected = {.25, 1, .03125, 2.5,
+ 2.23607, .009000, .900025};
+
+ ComputeAndCompareR1<float>(&builder, expected, {}, error_spec_);
+}
+
TEST_F(VecOpsSimpleTest, AddTenValuesViaMap) {
ComputationBuilder builder(client_, TestName());
auto add = CreateScalarAddComputation(F32, &builder);
diff --git a/tensorflow/contrib/cmake/tf_core_kernels.cmake b/tensorflow/contrib/cmake/tf_core_kernels.cmake
index 1f31482048..5a92518fc4 100644
--- a/tensorflow/contrib/cmake/tf_core_kernels.cmake
+++ b/tensorflow/contrib/cmake/tf_core_kernels.cmake
@@ -84,15 +84,15 @@ file(GLOB_RECURSE tf_core_kernels_exclude_srcs
"${tensorflow_source_dir}/tensorflow/core/kernels/*.cu.cc"
"${tensorflow_source_dir}/tensorflow/core/kernels/debug_ops.h" # stream_executor dependency
"${tensorflow_source_dir}/tensorflow/core/kernels/debug_ops.cc" # stream_executor dependency
+ "${tensorflow_source_dir}/tensorflow/core/kernels/hexagon/*"
+ "${tensorflow_source_dir}/tensorflow/core/kernels/remote_fused_graph_execute*.cc"
)
list(REMOVE_ITEM tf_core_kernels_srcs ${tf_core_kernels_exclude_srcs})
if(WIN32)
file(GLOB_RECURSE tf_core_kernels_windows_exclude_srcs
# not working on windows yet
- "${tensorflow_source_dir}/tensorflow/core/kernels/hexagon/*"
"${tensorflow_source_dir}/tensorflow/core/kernels/meta_support.*"
- "${tensorflow_source_dir}/tensorflow/core/kernels/remote_fused_graph_execute_op*.cc"
"${tensorflow_source_dir}/tensorflow/core/kernels/*quantiz*.h"
"${tensorflow_source_dir}/tensorflow/core/kernels/*quantiz*.cc"
)
diff --git a/tensorflow/contrib/cmake/tf_tests.cmake b/tensorflow/contrib/cmake/tf_tests.cmake
index d92dab23ed..a8c1ba0f2b 100644
--- a/tensorflow/contrib/cmake/tf_tests.cmake
+++ b/tensorflow/contrib/cmake/tf_tests.cmake
@@ -237,6 +237,8 @@ if (tensorflow_BUILD_CC_TESTS)
"${tensorflow_source_dir}/tensorflow/cc/framework/gradients_test.cc"
"${tensorflow_source_dir}/tensorflow/core/distributed_runtime/call_options_test.cc"
"${tensorflow_source_dir}/tensorflow/core/distributed_runtime/tensor_coding_test.cc"
+ "${tensorflow_source_dir}/tensorflow/core/kernels/hexagon/graph_transferer_test.cc"
+ "${tensorflow_source_dir}/tensorflow/core/kernels/hexagon/quantized_matmul_op_for_hexagon_test.cc"
)
if (NOT tensorflow_ENABLE_GPU)
@@ -279,8 +281,6 @@ if (tensorflow_BUILD_CC_TESTS)
"${tensorflow_source_dir}/tensorflow/core/kernels/quantization_utils_test.cc"
"${tensorflow_source_dir}/tensorflow/core/kernels/quantize_and_dequantize_op_test.cc"
"${tensorflow_source_dir}/tensorflow/core/kernels/quantize_down_and_shrink_range_op_test.cc"
- "${tensorflow_source_dir}/tensorflow/core/kernels/hexagon/graph_transferer_test.cc"
- "${tensorflow_source_dir}/tensorflow/core/kernels/hexagon/quantized_matmul_op_for_hexagon_test.cc"
"${tensorflow_source_dir}/tensorflow/core/kernels/debug_ops_test.cc"
"${tensorflow_source_dir}/tensorflow/core/kernels/quantized_activation_ops_test.cc"
"${tensorflow_source_dir}/tensorflow/core/kernels/quantized_bias_add_op_test.cc"
diff --git a/tensorflow/contrib/distributions/python/kernel_tests/bijector_test.py b/tensorflow/contrib/distributions/python/kernel_tests/bijector_test.py
index 092758e6ef..d85327b905 100644
--- a/tensorflow/contrib/distributions/python/kernel_tests/bijector_test.py
+++ b/tensorflow/contrib/distributions/python/kernel_tests/bijector_test.py
@@ -235,13 +235,51 @@ def assert_bijective_and_finite(bijector, x, y, atol=0, rtol=1e-5, sess=None):
class BaseBijectorTest(test.TestCase):
"""Tests properties of the Bijector base-class."""
- def testBijector(self):
+ def testIsAbstract(self):
with self.test_session():
with self.assertRaisesRegexp(TypeError,
("Can't instantiate abstract class Bijector "
"with abstract methods __init__")):
bijectors.Bijector()
+ def testDefaults(self):
+ class _BareBonesBijector(bijectors.Bijector):
+ """Minimal specification of a `Bijector`."""
+
+ def __init__(self):
+ super(_BareBonesBijector, self).__init__()
+
+ with self.test_session() as sess:
+ bij = _BareBonesBijector()
+ self.assertEqual(None, bij.event_ndims)
+ self.assertEqual([], bij.graph_parents)
+ self.assertEqual(False, bij.is_constant_jacobian)
+ self.assertEqual(False, bij.validate_args)
+ self.assertEqual(None, bij.dtype)
+ self.assertEqual("bare_bones_bijector", bij.name)
+
+ for shape in [[], [1, 2], [1, 2, 3]]:
+ [
+ forward_event_shape_,
+ inverse_event_shape_,
+ ] = sess.run([
+ bij.inverse_event_shape_tensor(shape),
+ bij.forward_event_shape_tensor(shape),
+ ])
+ self.assertAllEqual(shape, forward_event_shape_)
+ self.assertAllEqual(shape, bij.forward_event_shape(shape))
+ self.assertAllEqual(shape, inverse_event_shape_)
+ self.assertAllEqual(shape, bij.inverse_event_shape(shape))
+
+ for fn in ["forward",
+ "inverse",
+ "inverse_log_det_jacobian",
+ "inverse_and_inverse_log_det_jacobian",
+ "forward_log_det_jacobian"]:
+ with self.assertRaisesRegexp(
+ NotImplementedError, fn + " not implemented"):
+ getattr(bij, fn)(0)
+
class IntentionallyMissingError(Exception):
pass
@@ -1601,7 +1639,7 @@ class SigmoidCenteredBijectorTest(test.TestCase):
class CholeskyOuterProductBijectorTest(test.TestCase):
- """Tests the correctness of the Y = X * X^T transformation."""
+ """Tests the correctness of the Y = X @ X.T transformation."""
def testBijectorMatrix(self):
with self.test_session():
@@ -1660,6 +1698,72 @@ class CholeskyOuterProductBijectorTest(test.TestCase):
event_ndims=0, validate_args=True)
assert_scalar_congruency(bijector, lower_x=1e-3, upper_x=1.5, rtol=0.05)
+ def testNoBatchStatic(self):
+ x = np.array([[1., 0], [2, 1]]) # np.linalg.cholesky(y)
+ y = np.array([[1., 2], [2, 5]]) # np.matmul(x, x.T)
+ with self.test_session() as sess:
+ y_actual = bijectors.CholeskyOuterProduct(event_ndims=2).forward(x=x)
+ x_actual = bijectors.CholeskyOuterProduct(event_ndims=2).inverse(y=y)
+ [y_actual_, x_actual_] = sess.run([y_actual, x_actual])
+ self.assertAllEqual([2, 2], y_actual.get_shape())
+ self.assertAllEqual([2, 2], x_actual.get_shape())
+ self.assertAllClose(y, y_actual_)
+ self.assertAllClose(x, x_actual_)
+
+ def testNoBatchDeferred(self):
+ x = np.array([[1., 0], [2, 1]]) # np.linalg.cholesky(y)
+ y = np.array([[1., 2], [2, 5]]) # np.matmul(x, x.T)
+ with self.test_session() as sess:
+ x_pl = array_ops.placeholder(dtypes.float32)
+ y_pl = array_ops.placeholder(dtypes.float32)
+ y_actual = bijectors.CholeskyOuterProduct(event_ndims=2).forward(x=x_pl)
+ x_actual = bijectors.CholeskyOuterProduct(event_ndims=2).inverse(y=y_pl)
+ [y_actual_, x_actual_] = sess.run([y_actual, x_actual],
+ feed_dict={x_pl: x, y_pl: y})
+ self.assertEqual(None, y_actual.get_shape())
+ self.assertEqual(None, x_actual.get_shape())
+ self.assertAllClose(y, y_actual_)
+ self.assertAllClose(x, x_actual_)
+
+ def testBatchStatic(self):
+ x = np.array([[[1., 0],
+ [2, 1]],
+ [[3., 0],
+ [1, 2]]]) # np.linalg.cholesky(y)
+ y = np.array([[[1., 2],
+ [2, 5]],
+ [[9., 3],
+ [3, 5]]]) # np.matmul(x, x.T)
+ with self.test_session() as sess:
+ y_actual = bijectors.CholeskyOuterProduct(event_ndims=2).forward(x=x)
+ x_actual = bijectors.CholeskyOuterProduct(event_ndims=2).inverse(y=y)
+ [y_actual_, x_actual_] = sess.run([y_actual, x_actual])
+ self.assertEqual([2, 2, 2], y_actual.get_shape())
+ self.assertEqual([2, 2, 2], x_actual.get_shape())
+ self.assertAllClose(y, y_actual_)
+ self.assertAllClose(x, x_actual_)
+
+ def testBatchDeferred(self):
+ x = np.array([[[1., 0],
+ [2, 1]],
+ [[3., 0],
+ [1, 2]]]) # np.linalg.cholesky(y)
+ y = np.array([[[1., 2],
+ [2, 5]],
+ [[9., 3],
+ [3, 5]]]) # np.matmul(x, x.T)
+ with self.test_session() as sess:
+ x_pl = array_ops.placeholder(dtypes.float32)
+ y_pl = array_ops.placeholder(dtypes.float32)
+ y_actual = bijectors.CholeskyOuterProduct(event_ndims=2).forward(x=x_pl)
+ x_actual = bijectors.CholeskyOuterProduct(event_ndims=2).inverse(y=y_pl)
+ [y_actual_, x_actual_] = sess.run([y_actual, x_actual],
+ feed_dict={x_pl: x, y_pl: y})
+ self.assertEqual(None, y_actual.get_shape())
+ self.assertEqual(None, x_actual.get_shape())
+ self.assertAllClose(y, y_actual_)
+ self.assertAllClose(x, x_actual_)
+
class ChainBijectorTest(test.TestCase):
"""Tests the correctness of the Y = Chain(bij1, bij2, bij3) transformation."""
@@ -1761,6 +1865,14 @@ class InvertBijectorTest(test.TestCase):
x.as_list(),
bijector.inverse_event_shape_tensor(y.as_list()).eval())
+ def testDocstringExample(self):
+ with self.test_session():
+ exp_gamma_distribution = ds.TransformedDistribution(
+ distribution=ds.Gamma(concentration=1., rate=2.),
+ bijector=bijectors.Invert(bijectors.Exp()))
+ self.assertAllEqual(
+ [], array_ops.shape(exp_gamma_distribution.sample()).eval())
+
if __name__ == "__main__":
test.main()
diff --git a/tensorflow/contrib/distributions/python/kernel_tests/poisson_test.py b/tensorflow/contrib/distributions/python/kernel_tests/poisson_test.py
index 0adaf7d816..e1644d548d 100644
--- a/tensorflow/contrib/distributions/python/kernel_tests/poisson_test.py
+++ b/tensorflow/contrib/distributions/python/kernel_tests/poisson_test.py
@@ -170,6 +170,56 @@ class PoissonTest(test.TestCase):
self.assertEqual((6,), poisson.mode().get_shape())
self.assertAllClose(lam_v, poisson.mode().eval())
+ def testPoissonSample(self):
+ with self.test_session():
+ lam_v = 4.0
+ lam = constant_op.constant(lam_v)
+ # Choosing `n >= (k/rtol)**2, roughly ensures our sample mean should be
+ # within `k` std. deviations of actual up to rtol precision.
+ n = int(100e3)
+ poisson = poisson_lib.Poisson(rate=lam)
+ samples = poisson.sample(n, seed=123456)
+ sample_values = samples.eval()
+ self.assertEqual(samples.get_shape(), (n,))
+ self.assertEqual(sample_values.shape, (n,))
+ self.assertAllClose(
+ sample_values.mean(), stats.poisson.mean(lam_v), rtol=.01)
+ self.assertAllClose(
+ sample_values.var(), stats.poisson.var(lam_v), rtol=.01)
+
+ def testPoissonSampleMultidimensionalMean(self):
+ with self.test_session():
+ lam_v = np.array([np.arange(1, 51, dtype=np.float32)]) # 1 x 50
+ poisson = poisson_lib.Poisson(rate=lam_v)
+ # Choosing `n >= (k/rtol)**2, roughly ensures our sample mean should be
+ # within `k` std. deviations of actual up to rtol precision.
+ n = int(100e3)
+ samples = poisson.sample(n, seed=123456)
+ sample_values = samples.eval()
+ self.assertEqual(samples.get_shape(), (n, 1, 50))
+ self.assertEqual(sample_values.shape, (n, 1, 50))
+ self.assertAllClose(
+ sample_values.mean(axis=0),
+ stats.poisson.mean(lam_v),
+ rtol=.01,
+ atol=0)
+
+ def testPoissonSampleMultidimensionalVariance(self):
+ with self.test_session():
+ lam_v = np.array([np.arange(5, 15, dtype=np.float32)]) # 1 x 10
+ poisson = poisson_lib.Poisson(rate=lam_v)
+ # Choosing `n >= 2 * lam * (k/rtol)**2, roughly ensures our sample
+ # variance should be within `k` std. deviations of actual up to rtol
+ # precision.
+ n = int(300e3)
+ samples = poisson.sample(n, seed=123456)
+ sample_values = samples.eval()
+ self.assertEqual(samples.get_shape(), (n, 1, 10))
+ self.assertEqual(sample_values.shape, (n, 1, 10))
+
+ self.assertAllClose(
+ sample_values.var(axis=0), stats.poisson.var(lam_v), rtol=.03, atol=0)
+
if __name__ == "__main__":
test.main()
diff --git a/tensorflow/contrib/distributions/python/ops/bijector.py b/tensorflow/contrib/distributions/python/ops/bijector.py
index 5e003b3f5f..7c55d58d03 100644
--- a/tensorflow/contrib/distributions/python/ops/bijector.py
+++ b/tensorflow/contrib/distributions/python/ops/bijector.py
@@ -443,7 +443,7 @@ class Bijector(object):
def camel_to_snake(name):
s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower()
- self._name = camel_to_snake(type(self).__name__)
+ self._name = camel_to_snake(type(self).__name__.lstrip("_"))
@property
def event_ndims(self):
@@ -483,6 +483,7 @@ class Bijector(object):
def _forward_event_shape_tensor(self, input_shape):
"""Subclass implementation for `forward_event_shape_tensor` function."""
+ # By default, we assume event_shape is unchanged.
return input_shape
def forward_event_shape_tensor(self,
@@ -506,6 +507,7 @@ class Bijector(object):
def _forward_event_shape(self, input_shape):
"""Subclass implementation for `forward_event_shape` public function."""
+ # By default, we assume event_shape is unchanged.
return input_shape
def forward_event_shape(self, input_shape):
@@ -525,6 +527,7 @@ class Bijector(object):
def _inverse_event_shape_tensor(self, output_shape):
"""Subclass implementation for `inverse_event_shape_tensor` function."""
+ # By default, we assume event_shape is unchanged.
return output_shape
def inverse_event_shape_tensor(self,
@@ -548,7 +551,8 @@ class Bijector(object):
def _inverse_event_shape(self, output_shape):
"""Subclass implementation for `inverse_event_shape` public function."""
- return self._inverse_event_shape(tensor_shape.TensorShape(output_shape))
+ # By default, we assume event_shape is unchanged.
+ return tensor_shape.TensorShape(output_shape)
def inverse_event_shape(self, output_shape):
"""Shape of a single sample from a single batch as a `TensorShape`.
@@ -996,8 +1000,8 @@ class Invert(Bijector):
```python
exp_gamma_distribution = TransformedDistribution(
- Gamma(alpha=1., beta=2.),
- bijector.Invert(bijector.Exp())
+ distribution=Gamma(concentration=1., rate=2.),
+ bijector=bijector.Invert(bijector.Exp())
```
"""
@@ -2354,10 +2358,10 @@ class CholeskyOuterProduct(Bijector):
```python
bijector.CholeskyOuterProduct(event_ndims=2).forward(x=[[1., 0], [2, 1]])
- # Result: [[1, 1], [1, 5]], i.e., x x.T
+ # Result: [[1., 2], [2, 5]], i.e., x @ x.T
- bijector.SoftmaxCentered(event_ndims=2).inverse(y=[[1., 1], [1, 5]])
- # Result: [[1, 0], [2, 1]], i.e., chol(y).
+ bijector.CholeskyOuterProduct(event_ndims=2).inverse(y=[[1., 2], [2, 5]])
+ # Result: [[1., 0], [2, 1]], i.e., cholesky(y).
```
"""
@@ -2456,6 +2460,12 @@ class CholeskyOuterProduct(Bijector):
return math.log(2.) + math_ops.log(x)
diag = array_ops.matrix_diag_part(x)
+
+ # We now ensure diag is columnar. Eg, if `diag = [1, 2, 3]` then the output
+ # is `[[1], [2], [3]]` and if `diag = [[1, 2, 3], [4, 5, 6]]` then the
+ # output is unchanged.
+ diag = self._make_columnar(diag)
+
if self.validate_args:
is_matrix = check_ops.assert_rank_at_least(
x, 2, message="Input must be a (batch of) matrix.")
@@ -2469,20 +2479,49 @@ class CholeskyOuterProduct(Bijector):
x = control_flow_ops.with_dependencies(
[is_matrix, is_square, is_positive_definite], x)
- # Create a column vector equal to: [p, p-1, ..., 2, 1].T.
+ # Create a vector equal to: [p, p-1, ..., 2, 1].
if x.get_shape().ndims is None or x.get_shape()[-1].value is None:
- p = array_ops.shape(x)[-1]
+ p_int = array_ops.shape(x)[-1]
+ p_float = math_ops.cast(p_int, dtype=x.dtype)
else:
- p = x.get_shape()[-1].value
- exponents = array_ops.expand_dims(
- math_ops.linspace(math_ops.cast(p, dtype=x.dtype), 1., p),
- dim=1)
+ p_int = x.get_shape()[-1].value
+ p_float = np.array(p_int, dtype=x.dtype.as_numpy_dtype)
+ exponents = math_ops.linspace(p_float, 1., p_int)
sum_weighted_log_diag = array_ops.squeeze(
- math_ops.matmul(math_ops.log(diag), exponents), squeeze_dims=-1)
- fldj = p * math.log(2.) + sum_weighted_log_diag
-
- if x.get_shape().ndims is not None:
- fldj.set_shape(x.get_shape()[:-2])
+ math_ops.matmul(math_ops.log(diag),
+ exponents[..., array_ops.newaxis]),
+ squeeze_dims=-1)
+ fldj = p_float * math.log(2.) + sum_weighted_log_diag
return fldj
+
+ def _make_columnar(self, x):
+ """Ensures non-scalar input has at least one column.
+
+ Example:
+ If `x = [1, 2, 3]` then the output is `[[1], [2], [3]]`.
+
+ If `x = [[1, 2, 3], [4, 5, 6]]` then the output is unchanged.
+
+ If `x = 1` then the output is unchanged.
+
+ Args:
+ x: `Tensor`.
+
+ Returns:
+ columnar_x: `Tensor` with at least two dimensions.
+ """
+ if x.get_shape().ndims is not None:
+ if x.get_shape().ndims == 1:
+ x = x[array_ops.newaxis, :]
+ return x
+ shape = array_ops.shape(x)
+ maybe_expanded_shape = array_ops.concat([
+ shape[:-1],
+ distribution_util.pick_vector(
+ math_ops.equal(array_ops.rank(x), 1),
+ [1], np.array([], dtype=np.int32)),
+ shape[-1:],
+ ], 0)
+ return array_ops.reshape(x, maybe_expanded_shape)
diff --git a/tensorflow/contrib/distributions/python/ops/poisson.py b/tensorflow/contrib/distributions/python/ops/poisson.py
index 799796ace0..e1ddc9a0e1 100644
--- a/tensorflow/contrib/distributions/python/ops/poisson.py
+++ b/tensorflow/contrib/distributions/python/ops/poisson.py
@@ -28,7 +28,7 @@ from tensorflow.python.ops import array_ops
from tensorflow.python.ops import check_ops
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.ops import math_ops
-
+from tensorflow.python.ops import random_ops
__all__ = [
"Poisson",
@@ -148,6 +148,10 @@ class Poisson(distribution.Distribution):
def _mode(self):
return math_ops.floor(self.rate)
+ def _sample_n(self, n, seed=None):
+ return random_ops.random_poisson(
+ self.rate, [n], dtype=self.dtype, seed=seed)
+
def _assert_valid_sample(self, x, check_integer=True):
if not self.validate_args:
return x
diff --git a/tensorflow/contrib/framework/python/ops/variables.py b/tensorflow/contrib/framework/python/ops/variables.py
index f8a41bb526..6a59b6c8e7 100644
--- a/tensorflow/contrib/framework/python/ops/variables.py
+++ b/tensorflow/contrib/framework/python/ops/variables.py
@@ -53,6 +53,7 @@ __all__ = ['add_model_variable',
'get_or_create_global_step',
'get_local_variables',
'get_model_variables',
+ 'get_trainable_variables',
'get_unique_variable',
'get_variables_by_name',
'get_variables_by_suffix',
@@ -328,6 +329,19 @@ def get_local_variables(scope=None, suffix=None):
return get_variables(scope, suffix, ops.GraphKeys.LOCAL_VARIABLES)
+def get_trainable_variables(scope=None, suffix=None):
+ """Gets the list of trainable variables, filtered by scope and/or suffix.
+
+ Args:
+ scope: an optional scope for filtering the variables to return.
+ suffix: an optional suffix for filtering the variables to return.
+
+ Returns:
+ a list of variables in the trainable collection with scope and suffix.
+ """
+ return get_variables(scope, suffix, ops.GraphKeys.TRAINABLE_VARIABLES)
+
+
def get_variables_to_restore(include=None, exclude=None):
"""Gets the list of the variables to restore.
diff --git a/tensorflow/contrib/framework/python/ops/variables_test.py b/tensorflow/contrib/framework/python/ops/variables_test.py
index 7da103f32b..10120355ef 100644
--- a/tensorflow/contrib/framework/python/ops/variables_test.py
+++ b/tensorflow/contrib/framework/python/ops/variables_test.py
@@ -495,6 +495,17 @@ class ModelVariablesTest(test.TestCase):
self.assertEquals([a], variables_lib2.get_model_variables('A'))
self.assertEquals([b], variables_lib2.get_model_variables('B'))
+ def testGetTrainableVariables(self):
+ with self.test_session():
+ with variable_scope.variable_scope('A'):
+ variables_lib2.local_variable([5])
+ a = variables_lib.Variable([5])
+ with variable_scope.variable_scope('B'):
+ variables_lib2.local_variable([5])
+ b = variables_lib.Variable([5])
+ self.assertEquals([a], variables_lib2.get_trainable_variables('A'))
+ self.assertEquals([b], variables_lib2.get_trainable_variables('B'))
+
def testGetLocalVariables(self):
with self.test_session():
with variable_scope.variable_scope('A'):
diff --git a/tensorflow/contrib/layers/python/layers/feature_column_ops.py b/tensorflow/contrib/layers/python/layers/feature_column_ops.py
index b3fc61f2f9..78da45b986 100644
--- a/tensorflow/contrib/layers/python/layers/feature_column_ops.py
+++ b/tensorflow/contrib/layers/python/layers/feature_column_ops.py
@@ -798,11 +798,14 @@ def check_feature_columns(feature_columns):
"""Checks the validity of the set of FeatureColumns.
Args:
- feature_columns: A set of instances or subclasses of FeatureColumn.
+ feature_columns: An iterable of instances or subclasses of FeatureColumn.
Raises:
+ ValueError: If `feature_columns` is a dict.
ValueError: If there are duplicate feature column keys.
"""
+ if isinstance(feature_columns, dict):
+ raise ValueError('Expected feature_columns to be iterable, found dict.')
seen_keys = set()
for f in feature_columns:
key = f.key
diff --git a/tensorflow/contrib/layers/python/layers/feature_column_ops_test.py b/tensorflow/contrib/layers/python/layers/feature_column_ops_test.py
index 6dd688b30d..d5f38ae282 100644
--- a/tensorflow/contrib/layers/python/layers/feature_column_ops_test.py
+++ b/tensorflow/contrib/layers/python/layers/feature_column_ops_test.py
@@ -557,6 +557,15 @@ class TransformerTest(test.TestCase):
class CreateInputLayersForDNNsTest(test.TestCase):
+ def testFeatureColumnDictFails(self):
+ real_valued = feature_column.real_valued_column("price")
+ features = {"price": constant_op.constant([[20.], [110], [-3]])}
+ with self.assertRaisesRegexp(
+ ValueError,
+ "Expected feature_columns to be iterable, found dict"):
+ feature_column_ops.input_from_feature_columns(
+ features, {"feature": real_valued})
+
def testAllDNNColumns(self):
sparse_column = feature_column.sparse_column_with_keys(
"ids", ["a", "b", "c", "unseen"])
@@ -1405,6 +1414,19 @@ class SequenceInputFromFeatureColumnTest(test.TestCase):
class WeightedSumTest(test.TestCase):
+ def testFeatureColumnDictFails(self):
+ hashed_sparse = feature_column.sparse_column_with_hash_bucket("wire", 10)
+ wire_tensor = sparse_tensor.SparseTensor(
+ values=["omar", "stringer", "marlo"],
+ indices=[[0, 0], [1, 0], [1, 1]],
+ dense_shape=[2, 2])
+ features = {"wire": wire_tensor}
+ with self.assertRaisesRegexp(
+ ValueError,
+ "Expected feature_columns to be iterable, found dict"):
+ feature_column_ops.weighted_sum_from_feature_columns(
+ features, {"feature": hashed_sparse}, num_outputs=5)
+
def testSparseColumn(self):
hashed_sparse = feature_column.sparse_column_with_hash_bucket("wire", 10)
wire_tensor = sparse_tensor.SparseTensor(
diff --git a/tensorflow/contrib/learn/__init__.py b/tensorflow/contrib/learn/__init__.py
index 2cc38fbbec..839c370b2c 100644
--- a/tensorflow/contrib/learn/__init__.py
+++ b/tensorflow/contrib/learn/__init__.py
@@ -71,8 +71,10 @@ Queue and read batched input data.
Export utilities
-@@build_parsing_serving_input_fn
+@@InputFnOps
@@ProblemType
+@@build_parsing_serving_input_fn
+@@make_export_strategy
"""
from __future__ import absolute_import
diff --git a/tensorflow/contrib/learn/python/learn/estimators/constants.py b/tensorflow/contrib/learn/python/learn/estimators/constants.py
index aee4541627..e07a085388 100644
--- a/tensorflow/contrib/learn/python/learn/estimators/constants.py
+++ b/tensorflow/contrib/learn/python/learn/estimators/constants.py
@@ -20,6 +20,17 @@ from __future__ import print_function
class ProblemType(object):
+ """Enum-like values for the type of problem that the model solves.
+
+ These values are used when exporting the model to produce the appropriate
+ signature function for serving.
+
+ The following values are supported:
+ UNSPECIFIED: Produces a predict signature_fn.
+ CLASSIFICATION: Produces a classify signature_fn.
+ LINEAR_REGRESSION: Produces a regression signature_fn.
+ LOGISTIC_REGRESSION: Produces a classify signature_fn.
+ """
UNSPECIFIED = 0
CLASSIFICATION = 1
LINEAR_REGRESSION = 2
diff --git a/tensorflow/contrib/learn/python/learn/estimators/dynamic_rnn_estimator.py b/tensorflow/contrib/learn/python/learn/estimators/dynamic_rnn_estimator.py
index 508a815cf7..c4d15a3766 100644
--- a/tensorflow/contrib/learn/python/learn/estimators/dynamic_rnn_estimator.py
+++ b/tensorflow/contrib/learn/python/learn/estimators/dynamic_rnn_estimator.py
@@ -21,10 +21,12 @@ from __future__ import print_function
from tensorflow.contrib import layers
from tensorflow.contrib import metrics
from tensorflow.contrib import rnn as contrib_rnn
-from tensorflow.contrib.framework.python.framework import experimental
+from tensorflow.contrib.framework.python.framework import deprecated
from tensorflow.contrib.layers.python.layers import optimizers
+from tensorflow.contrib.learn.python.learn.estimators import constants
from tensorflow.contrib.learn.python.learn.estimators import estimator
from tensorflow.contrib.learn.python.learn.estimators import model_fn
+from tensorflow.contrib.learn.python.learn.estimators import prediction_key
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops
@@ -35,21 +37,21 @@ from tensorflow.python.training import momentum as momentum_opt
from tensorflow.python.util import nest
-class ProblemType(object):
- REGRESSION = 1
- CLASSIFICATION = 2
-
-
class PredictionType(object):
SINGLE_VALUE = 1
MULTIPLE_VALUE = 2
+# NOTE(jamieas): As of February 7, 2017, some of the `RNNKeys` have been removed
+# and replaced with values from `prediction_key.PredictionKey`. The key
+# `RNNKeys.PREDICTIONS_KEY` has been replaced by
+# `prediction_key.PredictionKey.SCORES` for regression and
+# `prediction_key.PredictionKey.CLASSES` for classification. The key
+# `RNNKeys.PROBABILITIES_KEY` has been replaced by
+# `prediction_key.PredictionKey.PROBABILITIES`.
class RNNKeys(object):
SEQUENCE_LENGTH_KEY = 'sequence_length'
STATE_PREFIX = 'rnn_cell_state'
- PREDICTIONS_KEY = 'predictions'
- PROBABILITIES_KEY = 'probabilities'
_CELL_TYPES = {'basic_rnn': contrib_rnn.BasicRNNCell,
'lstm': contrib_rnn.LSTMCell,
@@ -332,7 +334,8 @@ def _get_eval_metric_ops(problem_type, prediction_type, sequence_length,
"""Returns eval metric ops for given `problem_type` and `prediction_type`.
Args:
- problem_type: `ProblemType.CLASSIFICATION` or`ProblemType.REGRESSION`.
+ problem_type: `ProblemType.CLASSIFICATION` or
+ `ProblemType.LINEAR_REGRESSION`.
prediction_type: `PredictionType.SINGLE_VALUE` or
`PredictionType.MULTIPLE_VALUE`.
sequence_length: A `Tensor` with shape `[batch_size]` and dtype `int32`
@@ -345,20 +348,22 @@ def _get_eval_metric_ops(problem_type, prediction_type, sequence_length,
A `dict` mapping strings to the result of calling the metric_fn.
"""
eval_metric_ops = {}
- if problem_type == ProblemType.CLASSIFICATION:
+ if problem_type == constants.ProblemType.CLASSIFICATION:
# Multi value classification
if prediction_type == PredictionType.MULTIPLE_VALUE:
masked_predictions, masked_labels = mask_activations_and_labels(
- prediction_dict[RNNKeys.PREDICTIONS_KEY], labels, sequence_length)
+ prediction_dict[prediction_key.PredictionKey.CLASSES],
+ labels,
+ sequence_length)
eval_metric_ops['accuracy'] = metrics.streaming_accuracy(
predictions=masked_predictions,
labels=masked_labels)
# Single value classification
elif prediction_type == PredictionType.SINGLE_VALUE:
eval_metric_ops['accuracy'] = metrics.streaming_accuracy(
- predictions=prediction_dict[RNNKeys.PREDICTIONS_KEY],
+ predictions=prediction_dict[prediction_key.PredictionKey.CLASSES],
labels=labels)
- elif problem_type == ProblemType.REGRESSION:
+ elif problem_type == constants.ProblemType.LINEAR_REGRESSION:
# Multi value regression
if prediction_type == PredictionType.MULTIPLE_VALUE:
pass
@@ -369,7 +374,7 @@ def _get_eval_metric_ops(problem_type, prediction_type, sequence_length,
def _multi_value_predictions(
- activations, target_column, predict_probabilities):
+ activations, target_column, problem_type, predict_probabilities):
"""Maps `activations` from the RNN to predictions for multi value models.
If `predict_probabilities` is `False`, this function returns a `dict`
@@ -386,6 +391,8 @@ def _multi_value_predictions(
activations: Output from an RNN. Should have dtype `float32` and shape
`[batch_size, padded_length, ?]`.
target_column: An initialized `TargetColumn`, calculate predictions.
+ problem_type: Either `ProblemType.CLASSIFICATION` or
+ `ProblemType.LINEAR_REGRESSION`.
predict_probabilities: A Python boolean, indicating whether probabilities
should be returned. Should only be set to `True` for
classification/logistic regression problems.
@@ -406,20 +413,29 @@ def _multi_value_predictions(
else:
probability_shape = activations_shape
probabilities = array_ops.reshape(
- flat_probabilities, probability_shape, name=RNNKeys.PROBABILITIES_KEY)
- prediction_dict[RNNKeys.PROBABILITIES_KEY] = probabilities
+ flat_probabilities,
+ probability_shape,
+ name=prediction_key.PredictionKey.PROBABILITIES)
+ prediction_dict[
+ prediction_key.PredictionKey.PROBABILITIES] = probabilities
else:
flat_predictions = target_column.logits_to_predictions(
flattened_activations, proba=False)
+ predictions_name = (prediction_key.PredictionKey.CLASSES
+ if problem_type == constants.ProblemType.CLASSIFICATION
+ else prediction_key.PredictionKey.SCORES)
predictions = array_ops.reshape(
flat_predictions, [activations_shape[0], activations_shape[1]],
- name=RNNKeys.PREDICTIONS_KEY)
- prediction_dict[RNNKeys.PREDICTIONS_KEY] = predictions
+ name=predictions_name)
+ prediction_dict[predictions_name] = predictions
return prediction_dict
-def _single_value_predictions(
- activations, sequence_length, target_column, predict_probabilities):
+def _single_value_predictions(activations,
+ sequence_length,
+ target_column,
+ problem_type,
+ predict_probabilities):
"""Maps `activations` from the RNN to predictions for single value models.
If `predict_probabilities` is `False`, this function returns a `dict`
@@ -435,6 +451,8 @@ def _single_value_predictions(
containing the length of each sequence in the batch. If `None`, sequences
are assumed to be unpadded.
target_column: An initialized `TargetColumn`, calculate predictions.
+ problem_type: Either `ProblemType.CLASSIFICATION` or
+ `ProblemType.LINEAR_REGRESSION`.
predict_probabilities: A Python boolean, indicating whether probabilities
should be returned. Should only be set to `True` for
classification/logistic regression problems.
@@ -443,16 +461,19 @@ def _single_value_predictions(
"""
with ops.name_scope('SingleValuePrediction'):
last_activations = select_last_activations(activations, sequence_length)
+ predictions_name = (prediction_key.PredictionKey.CLASSES
+ if problem_type == constants.ProblemType.CLASSIFICATION
+ else prediction_key.PredictionKey.SCORES)
if predict_probabilities:
probabilities = target_column.logits_to_predictions(
last_activations, proba=True)
prediction_dict = {
- RNNKeys.PROBABILITIES_KEY: probabilities,
- RNNKeys.PREDICTIONS_KEY: math_ops.argmax(probabilities, 1)}
+ prediction_key.PredictionKey.PROBABILITIES: probabilities,
+ predictions_name: math_ops.argmax(probabilities, 1)}
else:
predictions = target_column.logits_to_predictions(
last_activations, proba=False)
- prediction_dict = {RNNKeys.PREDICTIONS_KEY: predictions}
+ prediction_dict = {predictions_name: predictions}
return prediction_dict
@@ -502,34 +523,8 @@ def _single_value_loss(
return target_column.loss(last_activations, labels, features)
-def apply_dropout(
- cell, input_keep_probability, output_keep_probability, random_seed=None):
- """Apply dropout to the outputs and inputs of `cell`.
-
- Args:
- cell: An `RNNCell`.
- input_keep_probability: Probability to keep inputs to `cell`. If `None`,
- no dropout is applied.
- output_keep_probability: Probability to keep outputs of `cell`. If `None`,
- no dropout is applied.
- random_seed: Seed for random dropout.
-
- Returns:
- An `RNNCell`, the result of applying the supplied dropouts to `cell`.
- """
- input_prob_none = input_keep_probability is None
- output_prob_none = output_keep_probability is None
- if input_prob_none and output_prob_none:
- return cell
- if input_prob_none:
- input_keep_probability = 1.0
- if output_prob_none:
- output_keep_probability = 1.0
- return contrib_rnn.DropoutWrapper(
- cell, input_keep_probability, output_keep_probability, random_seed)
-
-
-def _get_dynamic_rnn_model_fn(cell,
+def _get_dynamic_rnn_model_fn(cell_type,
+ num_units,
target_column,
problem_type,
prediction_type,
@@ -539,8 +534,7 @@ def _get_dynamic_rnn_model_fn(cell,
predict_probabilities=False,
learning_rate=None,
gradient_clipping_norm=None,
- input_keep_probability=None,
- output_keep_probability=None,
+ dropout_keep_probabilities=None,
sequence_length_key=RNNKeys.SEQUENCE_LENGTH_KEY,
dtype=dtypes.float32,
parallel_iterations=None,
@@ -549,10 +543,12 @@ def _get_dynamic_rnn_model_fn(cell,
"""Creates an RNN model function for an `Estimator`.
Args:
- cell: An initialized `RNNCell` to be used in the RNN.
+ cell_type: A string, a subclass of `RNNCell` or an instance of an `RNNCell`.
+ num_units: A single `int` or a list of `int`s. The size of the `RNNCell`s.
target_column: An initialized `TargetColumn`, used to calculate prediction
and loss.
- problem_type: `ProblemType.CLASSIFICATION` or`ProblemType.REGRESSION`.
+ problem_type: `ProblemType.CLASSIFICATION` or
+ `ProblemType.LINEAR_REGRESSION`.
prediction_type: `PredictionType.SINGLE_VALUE` or
`PredictionType.MULTIPLE_VALUE`.
optimizer: A subclass of `Optimizer`, an instance of an `Optimizer` or a
@@ -565,14 +561,13 @@ def _get_dynamic_rnn_model_fn(cell,
steps. All items in the set should be instances of classes derived from
`FeatureColumn`.
predict_probabilities: A boolean indicating whether to predict probabilities
- for all classes. Must only be used with `ProblemType.CLASSIFICATION`.
+ for all classes. Must only be used with
+ `ProblemType.CLASSIFICATION`.
learning_rate: Learning rate used for optimization. This argument has no
effect if `optimizer` is an instance of an `Optimizer`.
gradient_clipping_norm: A float. Gradients will be clipped to this value.
- input_keep_probability: Probability to keep inputs to `cell`. If `None`,
- no dropout is applied.
- output_keep_probability: Probability to keep outputs of `cell`. If `None`,
- no dropout is applied.
+ dropout_keep_probabilities: a list of dropout keep probabilities or `None`.
+ If a list is given, it must have length `len(num_units) + 1`.
sequence_length_key: The key that will be used to look up sequence length in
the `features` dict.
dtype: The dtype of the state and output of the given `cell`.
@@ -589,16 +584,18 @@ def _get_dynamic_rnn_model_fn(cell,
A model function to be passed to an `Estimator`.
Raises:
- ValueError: `problem_type` is not one of `ProblemType.REGRESSION` or
- `ProblemType.CLASSIFICATION`.
+ ValueError: `problem_type` is not one of
+ `ProblemType.LINEAR_REGRESSION` or `ProblemType.CLASSIFICATION`.
ValueError: `prediction_type` is not one of `PredictionType.SINGLE_VALUE`
or `PredictionType.MULTIPLE_VALUE`.
ValueError: `predict_probabilities` is `True` for `problem_type` other
than `ProblemType.CLASSIFICATION`.
+ ValueError: `len(dropout_keep_probabilities)` is not `len(num_units) + 1`.
"""
- if problem_type not in (ProblemType.CLASSIFICATION, ProblemType.REGRESSION):
+ if problem_type not in (constants.ProblemType.CLASSIFICATION,
+ constants.ProblemType.LINEAR_REGRESSION):
raise ValueError(
- 'problem_type must be ProblemType.REGRESSION or '
+ 'problem_type must be ProblemType.LINEAR_REGRESSION or '
'ProblemType.CLASSIFICATION; got {}'.
format(problem_type))
if prediction_type not in (
@@ -607,28 +604,27 @@ def _get_dynamic_rnn_model_fn(cell,
'prediction_type must be PredictionType.MULTIPLE_VALUEs or '
'PredictionType.SINGLE_VALUE; got {}'.
format(prediction_type))
- if problem_type != ProblemType.CLASSIFICATION and predict_probabilities:
+ if (problem_type != constants.ProblemType.CLASSIFICATION
+ and predict_probabilities):
raise ValueError(
'predict_probabilities can only be set to True for problem_type'
' ProblemType.CLASSIFICATION; got {}.'.format(problem_type))
-
def _dynamic_rnn_model_fn(features, labels, mode):
"""The model to be passed to an `Estimator`."""
with ops.name_scope(name):
- initial_state = dict_to_state_tuple(features, cell)
sequence_length = features.get(sequence_length_key)
sequence_input = build_sequence_input(features,
sequence_feature_columns,
context_feature_columns)
- if mode == model_fn.ModeKeys.TRAIN:
- cell_for_mode = apply_dropout(
- cell, input_keep_probability, output_keep_probability)
- else:
- cell_for_mode = cell
+ dropout = (dropout_keep_probabilities
+ if mode == model_fn.ModeKeys.TRAIN
+ else None)
+ cell = _construct_rnn_cell(cell_type, num_units, dropout)
+ initial_state = dict_to_state_tuple(features, cell)
rnn_activations, final_state = construct_rnn(
initial_state,
sequence_input,
- cell_for_mode,
+ cell,
target_column.num_label_columns,
dtype=dtype,
parallel_iterations=parallel_iterations,
@@ -637,14 +633,14 @@ def _get_dynamic_rnn_model_fn(cell,
loss = None # Created below for modes TRAIN and EVAL.
if prediction_type == PredictionType.MULTIPLE_VALUE:
prediction_dict = _multi_value_predictions(
- rnn_activations, target_column, predict_probabilities)
+ rnn_activations, target_column, problem_type, predict_probabilities)
if mode != model_fn.ModeKeys.INFER:
loss = _multi_value_loss(
rnn_activations, labels, sequence_length, target_column, features)
elif prediction_type == PredictionType.SINGLE_VALUE:
prediction_dict = _single_value_predictions(
rnn_activations, sequence_length, target_column,
- predict_probabilities)
+ problem_type, predict_probabilities)
if mode != model_fn.ModeKeys.INFER:
loss = _single_value_loss(
rnn_activations, labels, sequence_length, target_column, features)
@@ -675,41 +671,271 @@ def _get_dynamic_rnn_model_fn(cell,
return _dynamic_rnn_model_fn
-def _to_rnn_cell(cell_or_type, num_units, num_layers):
- """Constructs and return an `RNNCell`.
+def _apply_dropout(
+ cells, dropout_keep_probabilities, random_seed=None):
+ """Applies dropout to the outputs and inputs of `cell`.
Args:
- cell_or_type: Either a string identifying the `RNNCell` type, a subclass of
+ cells: A list of `RNNCell`s.
+ dropout_keep_probabilities: a list whose elements are either floats in
+ `[0.0, 1.0]` or `None`. It must have length one greater than `cells`.
+ random_seed: Seed for random dropout.
+
+ Returns:
+ A list of `RNNCell`s, the result of applying the supplied dropouts.
+
+ Raises:
+ ValueError: If `len(dropout_keep_probabilities) != len(cells) + 1`.
+ """
+ if len(dropout_keep_probabilities) != len(cells) + 1:
+ raise ValueError(
+ 'The number of dropout probabilites must be one greater than the '
+ 'number of cells. Got {} cells and {} dropout probabilities.'.format(
+ len(cells), len(dropout_keep_probabilities)))
+ wrapped_cells = [
+ contrib_rnn.DropoutWrapper(cell, prob, 1.0, random_seed)
+ for cell, prob in zip(cells[:-1], dropout_keep_probabilities[:-2])
+ ]
+ wrapped_cells.append(contrib_rnn.DropoutWrapper(
+ cells[-1],
+ dropout_keep_probabilities[-2],
+ dropout_keep_probabilities[-1]))
+ return wrapped_cells
+
+
+def _get_single_cell(cell_type, num_units):
+ """Constructs and return an single `RNNCell`.
+
+ Args:
+ cell_type: Either a string identifying the `RNNCell` type, a subclass of
`RNNCell` or an instance of an `RNNCell`.
num_units: The number of units in the `RNNCell`.
- num_layers: The number of layers in the RNN.
Returns:
An initialized `RNNCell`.
Raises:
- ValueError: `cell_or_type` is an invalid `RNNCell` name.
- TypeError: `cell_or_type` is not a string or a subclass of `RNNCell`.
+ ValueError: `cell_type` is an invalid `RNNCell` name.
+ TypeError: `cell_type` is not a string or a subclass of `RNNCell`.
"""
- if isinstance(cell_or_type, contrib_rnn.RNNCell):
- return cell_or_type
- if isinstance(cell_or_type, str):
- cell_or_type = _CELL_TYPES.get(cell_or_type)
- if cell_or_type is None:
+ if isinstance(cell_type, contrib_rnn.RNNCell):
+ return cell_type
+ if isinstance(cell_type, str):
+ cell_type = _CELL_TYPES.get(cell_type)
+ if cell_type is None:
raise ValueError('The supported cell types are {}; got {}'.format(
- list(_CELL_TYPES.keys()), cell_or_type))
- if not issubclass(cell_or_type, contrib_rnn.RNNCell):
+ list(_CELL_TYPES.keys()), cell_type))
+ if not issubclass(cell_type, contrib_rnn.RNNCell):
raise TypeError(
- 'cell_or_type must be a subclass of RNNCell or one of {}.'.format(
+ 'cell_type must be a subclass of RNNCell or one of {}.'.format(
list(_CELL_TYPES.keys())))
- single_cell = lambda: cell_or_type(num_units=num_units)
- if num_layers > 1:
- cell = contrib_rnn.MultiRNNCell(
- [single_cell() for _ in range(num_layers)], state_is_tuple=True)
+ return cell_type(num_units=num_units)
+
+
+def _construct_rnn_cell(cell_type, num_units, dropout_keep_probabilities):
+ """Constructs cells, applies dropout and assembles a `MultiRNNCell`.
+
+ Args:
+ cell_type: A string identifying the `RNNCell` type, a subclass of
+ `RNNCell` or an instance of an `RNNCell`.
+ num_units: A single `int` or a list/tuple of `int`s. The size of the
+ `RNNCell`s.
+ dropout_keep_probabilities: a list of dropout probabilities or `None`. If a
+ list is given, it must have length `len(cell_type) + 1`.
+
+ Returns:
+ An initialized `RNNCell`.
+ """
+ if not isinstance(num_units, (list, tuple)):
+ num_units = (num_units,)
+
+ cells = [_get_single_cell(cell_type, n) for n in num_units]
+ if dropout_keep_probabilities:
+ cells = _apply_dropout(cells, dropout_keep_probabilities)
+ if len(cells) == 1:
+ return cells[0]
+ return contrib_rnn.MultiRNNCell(cells)
+
+
+def _get_dropout_and_num_units(cell_type,
+ num_units,
+ num_rnn_layers,
+ input_keep_probability,
+ output_keep_probability):
+ """Helper function for deprecated factory functions."""
+ dropout_keep_probabilities = None
+ if isinstance(cell_type, contrib_rnn.RNNCell):
+ num_units = None
else:
- cell = single_cell()
- return cell
+ num_units = [num_units for _ in range(num_rnn_layers)]
+ if input_keep_probability or output_keep_probability:
+ dropout_keep_probabilities = ([input_keep_probability]
+ + [1.0] * (num_rnn_layers - 1)
+ + [output_keep_probability])
+ return dropout_keep_probabilities, num_units
+
+
+class DynamicRnnEstimator(estimator.Estimator):
+
+ def __init__(self,
+ problem_type,
+ prediction_type,
+ sequence_feature_columns,
+ context_feature_columns=None,
+ num_classes=None,
+ num_units=None,
+ cell_type='basic_rnn',
+ optimizer='SGD',
+ learning_rate=0.1,
+ predict_probabilities=False,
+ momentum=None,
+ gradient_clipping_norm=5.0,
+ dropout_keep_probabilities=None,
+ model_dir=None,
+ feature_engineering_fn=None,
+ config=None):
+ """Initializes a `DynamicRnnEstimator`.
+ The input function passed to this `Estimator` optionally contains keys
+ `RNNKeys.SEQUENCE_LENGTH_KEY`. The value corresponding to
+ `RNNKeys.SEQUENCE_LENGTH_KEY` must be vector of size `batch_size` where
+ entry `n` corresponds to the length of the `n`th sequence in the batch. The
+ sequence length feature is required for batches of varying sizes. It will be
+ used to calculate loss and evaluation metrics. If
+ `RNNKeys.SEQUENCE_LENGTH_KEY` is not included, all sequences are assumed to
+ have length equal to the size of dimension 1 of the input to the RNN.
+
+ In order to specify an initial state, the input function must include keys
+ `STATE_PREFIX_i` for all `0 <= i < n` where `n` is the number of nested
+ elements in `cell.state_size`. The input function must contain values for
+ all state components or none of them. If none are included, then the default
+ (zero) state is used as an initial state. See the documentation for
+ `dict_to_state_tuple` and `state_tuple_to_dict` for further details.
+
+ The `predict()` method of the `Estimator` returns a dictionary with keys
+ `STATE_PREFIX_i` for `0 <= i < n` where `n` is the number of nested elements
+ in `cell.state_size`, along with `PredictionKey.CLASSES` for problem type
+ `CLASSIFICATION` or `PredictionKey.SCORES` for problem type
+ `LINEAR_REGRESSION`. The value keyed by
+ `PredictionKey.CLASSES` or `PredictionKey.SCORES` has shape
+ `[batch_size, padded_length]` in the multi-value case and shape
+ `[batch_size]` in the single-value case. Here, `padded_length` is the
+ largest value in the `RNNKeys.SEQUENCE_LENGTH` `Tensor` passed as input.
+ Entry `[i, j]` is the prediction associated with sequence `i` and time step
+ `j`. If the problem type is `CLASSIFICATION` and `predict_probabilities` is
+ `True`, it will also include key`PredictionKey.PROBABILITIES`.
+
+ Args:
+ problem_type: whether the `Estimator` is intended for a regression or
+ classification problem. Value must be one of
+ `ProblemType.CLASSIFICATION` or `ProblemType.LINEAR_REGRESSION`.
+ prediction_type: whether the `Estimator` should return a value for each
+ step in the sequence, or just a single value for the final time step.
+ Must be one of `ProblemType.SINGLE_VALUE` or
+ `ProblemType.MULTIPLE_VALUE`.
+ sequence_feature_columns: An iterable containing all the feature columns
+ describing sequence features. All items in the iterable should be
+ instances of classes derived from `FeatureColumn`.
+ context_feature_columns: An iterable containing all the feature columns
+ describing context features, i.e., features that apply accross all time
+ steps. All items in the set should be instances of classes derived from
+ `FeatureColumn`.
+ num_classes: the number of classes for a classification problem. Only
+ used when `problem_type=ProblemType.CLASSIFICATION`.
+ num_units: A list of integers indicating the number of units in the
+ `RNNCell`s in each layer. Either `num_units` is specified or `cell_type`
+ is an instance of `RNNCell`.
+ cell_type: A subclass of `RNNCell`, an instance of an `RNNCell` or one of
+ 'basic_rnn,' 'lstm' or 'gru'.
+ optimizer: The type of optimizer to use. Either a subclass of
+ `Optimizer`, an instance of an `Optimizer`, a callback that returns an
+ optimizer, or a string. Strings must be one of 'Adagrad', 'Adam',
+ 'Ftrl', 'Momentum', 'RMSProp' or 'SGD. See `layers.optimize_loss` for
+ more details.
+ learning_rate: Learning rate. This argument has no effect if `optimizer`
+ is an instance of an `Optimizer`.
+ predict_probabilities: A boolean indicating whether to predict
+ probabilities for all classes. Used only if `problem_type` is
+ `ProblemType.CLASSIFICATION`
+ momentum: Momentum value. Only used if `optimizer_type` is 'Momentum'.
+ gradient_clipping_norm: Parameter used for gradient clipping. If `None`,
+ then no clipping is performed.
+ dropout_keep_probabilities: a list of dropout probabilities or `None`.
+ If a list is given, it must have length `len(num_units) + 1`. If
+ `None`, then no dropout is applied.
+ model_dir: The directory in which to save and restore the model graph,
+ parameters, etc.
+ feature_engineering_fn: Takes features and labels which are the output of
+ `input_fn` and returns features and labels which will be fed into
+ `model_fn`. Please check `model_fn` for a definition of features and
+ labels.
+ config: A `RunConfig` instance.
+
+ Raises:
+ ValueError: Both or neither of the following are true: (a) `num_units` is
+ specified and (b) `cell_type` is an instance of `RNNCell`.
+ ValueError: `problem_type` is not one of
+ `ProblemType.LINEAR_REGRESSION` or `ProblemType.CLASSIFICATION`.
+ ValueError: `problem_type` is `ProblemType.CLASSIFICATION` but
+ `num_classes` is not specifieProblemType
+ ValueError: `prediction_type` is not one of
+ `PredictionType.MULTIPLE_VALUE` or `PredictionType.SINGLE_VALUE`.
+ """
+ if (num_units is not None) == isinstance(cell_type, contrib_rnn.RNNCell):
+ raise ValueError(
+ 'Either num_units is specified OR cell_type is an instance of '
+ 'RNNCell. Got num_units = {} and cell_type = {}.'.format(
+ num_units, cell_type))
-@experimental
+ if prediction_type == PredictionType.MULTIPLE_VALUE:
+ name = 'MultiValueDynamicRNN'
+ elif prediction_type == PredictionType.SINGLE_VALUE:
+ name = 'SingleValueDynamicRNN'
+ else:
+ raise ValueError(
+ 'prediction_type must be one of PredictionType.MULTIPLE_VALUE or '
+ 'PredictionType.SINGLE_VALUE; got {}'.format(prediction_type))
+
+ if problem_type == constants.ProblemType.LINEAR_REGRESSION:
+ name += 'Regressor'
+ target_column = layers.regression_target()
+ elif problem_type == constants.ProblemType.CLASSIFICATION:
+ if not num_classes:
+ raise ValueError('For CLASSIFICATION problem_type, num_classes must be '
+ 'specified.')
+ target_column = layers.multi_class_target(n_classes=num_classes)
+ name += 'Classifier'
+ else:
+ raise ValueError(
+ 'problem_type must be either ProblemType.LINEAR_REGRESSION '
+ 'or ProblemType.CLASSIFICATION; got {}'.format(
+ problem_type))
+
+ if optimizer == 'Momentum':
+ optimizer = momentum_opt.MomentumOptimizer(learning_rate, momentum)
+ dynamic_rnn_model_fn = _get_dynamic_rnn_model_fn(
+ cell_type=cell_type,
+ num_units=num_units,
+ target_column=target_column,
+ problem_type=problem_type,
+ prediction_type=prediction_type,
+ optimizer=optimizer,
+ sequence_feature_columns=sequence_feature_columns,
+ context_feature_columns=context_feature_columns,
+ predict_probabilities=predict_probabilities,
+ learning_rate=learning_rate,
+ gradient_clipping_norm=gradient_clipping_norm,
+ dropout_keep_probabilities=dropout_keep_probabilities,
+ name=name)
+
+ super(DynamicRnnEstimator, self).__init__(
+ model_fn=dynamic_rnn_model_fn,
+ model_dir=model_dir,
+ config=config,
+ feature_engineering_fn=feature_engineering_fn)
+
+
+@deprecated('2017-04-01',
+ 'multi_value_rnn_regressor is deprecated. '
+ 'Please construct a DynamicRnnEstimator directly.')
def multi_value_rnn_regressor(num_units,
sequence_feature_columns,
context_feature_columns=None,
@@ -724,31 +950,10 @@ def multi_value_rnn_regressor(num_units,
model_dir=None,
config=None,
feature_engineering_fn=None):
- """Creates a RNN `Estimator` that predicts sequences of values.
-
- The input function passed to this `Estimator` optionally contains keys
- `RNNKeys.SEQUENCE_LENGTH_KEY`. The value corresponding to
- `RNNKeys.SEQUENCE_LENGTH_KEY` must be vector of size `batch_size` where entry
- `n` corresponds to the length of the `n`th sequence in the batch. The sequence
- length feature is required for batches of varying sizes. It will be used to
- calculate loss and evaluation metrics. If `RNNKeys.SEQUENCE_LENGTH_KEY` is not
- included, all sequences are assumed to have length equal to the size of
- dimension 1 of the input to the RNN.
-
- In order to specify an initial state, the input function must include keys
- `STATE_PREFIX_i` for all `0 <= i < n` where `n` is the number of nested
- elements in `cell.state_size`. The input function must contain values for all
- state components or none of them. If none are included, then the default
- (zero) state is used as an initial state. See the documentation for
- `dict_to_state_tuple` and `state_tuple_to_dict` for further details.
-
- The `predict()` method of the `Estimator` returns a dictionary with keys
- `RNNKeys.PREDICTIONS_KEY` and `STATE_PREFIX_i` for `0 <= i < n` where `n` is
- the number of nested elements in `cell.state_size`. The value keyed by
- `RNNKeys.PREDICTIONS_KEY` has shape `[batch_size, padded_length]`. Here,
- `padded_length` is the largest value in the `RNNKeys.SEQUENCE_LENGTH` `Tensor`
- passed as input. Entry `[i, j]` is the prediction associated with sequence `i`
- and time step `j`.
+ """Creates a `DynamicRnnEstimator` for multi-value regression.
+
+ Returns an `Estimator` that given input sequences, processes them in a dynamic
+ recurrent network and outputs a sequence of continuous values.
Args:
num_units: The size of the RNN cells. This argument has no effect
@@ -765,8 +970,10 @@ def multi_value_rnn_regressor(num_units,
num_rnn_layers: Number of RNN layers. Leave this at its default value 1
if passing a `cell_type` that is already a MultiRNNCell.
optimizer_type: The type of optimizer to use. Either a subclass of
- `Optimizer`, an instance of an `Optimizer` or a string. Strings must be
- one of 'Adagrad', 'Momentum' or 'SGD'.
+ `Optimizer`, an instance of an `Optimizer`, a callback that returns an
+ optimizer, or a string. Strings must be one of 'Adagrad', 'Adam',
+ 'Ftrl', 'Momentum', 'RMSProp' or 'SGD. See `layers.optimize_loss` for
+ more details.
learning_rate: Learning rate. This argument has no effect if `optimizer`
is an instance of an `Optimizer`.
momentum: Momentum value. Only used if `optimizer_type` is 'Momentum'.
@@ -786,31 +993,32 @@ def multi_value_rnn_regressor(num_units,
Returns:
An initialized `Estimator`.
"""
- cell = _to_rnn_cell(cell_type, num_units, num_rnn_layers)
- target_column = layers.regression_target()
- if optimizer_type == 'Momentum':
- optimizer_type = momentum_opt.MomentumOptimizer(learning_rate, momentum)
- dynamic_rnn_model_fn = _get_dynamic_rnn_model_fn(
- cell=cell,
- target_column=target_column,
- problem_type=ProblemType.REGRESSION,
+ dropout_keep_probabilities, num_units = _get_dropout_and_num_units(
+ cell_type,
+ num_units,
+ num_rnn_layers,
+ input_keep_probability,
+ output_keep_probability)
+ return DynamicRnnEstimator(
+ problem_type=constants.ProblemType.LINEAR_REGRESSION,
prediction_type=PredictionType.MULTIPLE_VALUE,
- optimizer=optimizer_type,
sequence_feature_columns=sequence_feature_columns,
context_feature_columns=context_feature_columns,
+ num_units=num_units,
+ cell_type=cell_type,
+ optimizer=optimizer_type,
learning_rate=learning_rate,
+ momentum=momentum,
gradient_clipping_norm=gradient_clipping_norm,
- input_keep_probability=input_keep_probability,
- output_keep_probability=output_keep_probability,
- name='MultiValueRnnRegressor')
+ dropout_keep_probabilities=dropout_keep_probabilities,
+ model_dir=model_dir,
+ feature_engineering_fn=feature_engineering_fn,
+ config=config)
- return estimator.Estimator(model_fn=dynamic_rnn_model_fn,
- model_dir=model_dir,
- config=config,
- feature_engineering_fn=feature_engineering_fn)
-
-@experimental
+@deprecated('2017-04-01',
+ 'multi_value_rnn_classifier is deprecated. '
+ 'Please construct a DynamicRNNEstimator directly.')
def multi_value_rnn_classifier(num_classes,
num_units,
sequence_feature_columns,
@@ -827,37 +1035,11 @@ def multi_value_rnn_classifier(num_classes,
model_dir=None,
config=None,
feature_engineering_fn=None):
- """Creates a RNN `Estimator` that predicts sequences of labels.
+ """Creates a `DynamicRNNEstimator` for multi-value classification.
- The input function passed to this `Estimator` optionally contains keys
- `RNNKeys.SEQUENCE_LENGTH_KEY`. The value corresponding to
- `RNNKeys.SEQUENCE_LENGTH_KEY` must be vector of size `batch_size` where entry
- `n` corresponds to the length of the `n`th sequence in the batch. The sequence
- length feature is required for batches of varying sizes. It will be used to
- calculate loss and evaluation metrics. If `RNNKeys.SEQUENCE_LENGTH_KEY` is not
- included, all sequences are assumed to have length equal to the size of
- dimension 1 of the input to the RNN.
-
- In order to specify an initial state, the input function must include keys
- `STATE_PREFIX_i` for all `0 <= i < n` where `n` is the number of nested
- elements in `cell.state_size`. The input function must contain values for all
- state components or none of them. If none are included, then the default
- (zero) state is used as an initial state. See the documentation for
- `dict_to_state_tuple` and `state_tuple_to_dict` for further details.
-
- The `predict()` method of the `Estimator` returns a dictionary with keys
- `RNNKeys.PREDICTIONS_KEY` and `STATE_PREFIX_i` for `0 <= i < n` where `n` is
- the number of nested elements in `cell.state_size`. The value keyed by
- `RNNKeys.PREDICTIONS_KEY` has shape `[batch_size, padded_length]`. Here,
- `padded_length` is the largest value in the `RNNKeys.SEQUENCE_LENGTH` `Tensor`
- passed as input. Entry `[i, j]` is the prediction associated with sequence `i`
- and time step `j`.
-
- If `predict_probabilities` is set to true, the `dict` returned by `predict()`
- contains an additional key `RNNKeys.PROBABILITIES_KEY`. The associated array
- has shape `[batch_size, padded_length, num_classes]` where entry `[i, j, k]`
- is the probability assigned to class `k` at time step `j` in sequence `i` of
- the batch.
+ Returns an `Estimator` that given input sequences, processes them in a dynamic
+ recurrent network and outputs a sequence of classifications, along with
+ (optionally) a probability distribution over classes.
Args:
num_classes: The number of classes for categorization.
@@ -875,8 +1057,10 @@ def multi_value_rnn_classifier(num_classes,
num_rnn_layers: Number of RNN layers. Leave this at its default value 1
if passing a `cell_type` that is already a MultiRNNCell.
optimizer_type: The type of optimizer to use. Either a subclass of
- `Optimizer`, an instance of an `Optimizer` or a string. Strings must be
- one of 'Adagrad', 'Momentum' or 'SGD'.
+ `Optimizer`, an instance of an `Optimizer`, a callback that returns an
+ optimizer, or a string. Strings must be one of 'Adagrad', 'Adam',
+ 'Ftrl', 'Momentum', 'RMSProp' or 'SGD. See `layers.optimize_loss` for
+ more details.
learning_rate: Learning rate. This argument has no effect if `optimizer`
is an instance of an `Optimizer`.
predict_probabilities: A boolean indicating whether to predict probabilities
@@ -898,32 +1082,34 @@ def multi_value_rnn_classifier(num_classes,
Returns:
An initialized `Estimator`.
"""
- cell = _to_rnn_cell(cell_type, num_units, num_rnn_layers)
- target_column = layers.multi_class_target(n_classes=num_classes)
- if optimizer_type == 'Momentum':
- optimizer_type = momentum_opt.MomentumOptimizer(learning_rate, momentum)
- dynamic_rnn_model_fn = _get_dynamic_rnn_model_fn(
- cell=cell,
- target_column=target_column,
- problem_type=ProblemType.CLASSIFICATION,
+ dropout_keep_probabilities, num_units = _get_dropout_and_num_units(
+ cell_type,
+ num_units,
+ num_rnn_layers,
+ input_keep_probability,
+ output_keep_probability)
+ return DynamicRnnEstimator(
+ problem_type=constants.ProblemType.CLASSIFICATION,
prediction_type=PredictionType.MULTIPLE_VALUE,
- optimizer=optimizer_type,
+ num_classes=num_classes,
sequence_feature_columns=sequence_feature_columns,
context_feature_columns=context_feature_columns,
- predict_probabilities=predict_probabilities,
+ num_units=num_units,
+ cell_type=cell_type,
+ optimizer=optimizer_type,
learning_rate=learning_rate,
+ predict_probabilities=predict_probabilities,
+ momentum=momentum,
gradient_clipping_norm=gradient_clipping_norm,
- input_keep_probability=input_keep_probability,
- output_keep_probability=output_keep_probability,
- name='MultiValueRnnClassifier')
-
- return estimator.Estimator(model_fn=dynamic_rnn_model_fn,
- model_dir=model_dir,
- config=config,
- feature_engineering_fn=feature_engineering_fn)
+ dropout_keep_probabilities=dropout_keep_probabilities,
+ model_dir=model_dir,
+ feature_engineering_fn=feature_engineering_fn,
+ config=config)
-@experimental
+@deprecated('2017-04-01',
+ 'single_value_rnn_regressor is deprecated. '
+ 'Please construct a DynamicRnnEstimator directly.')
def single_value_rnn_regressor(num_units,
sequence_feature_columns,
context_feature_columns=None,
@@ -938,31 +1124,10 @@ def single_value_rnn_regressor(num_units,
model_dir=None,
config=None,
feature_engineering_fn=None):
- """Create a RNN `Estimator` that predicts single values.
-
- The input function passed to this `Estimator` optionally contains keys
- `RNNKeys.SEQUENCE_LENGTH_KEY`. The value corresponding to
- `RNNKeys.SEQUENCE_LENGTH_KEY` must be vector of size `batch_size` where entry
- `n` corresponds to the length of the `n`th sequence in the batch. The sequence
- length feature is required for batches of varying sizes. It will be used to
- calculate loss and evaluation metrics. If `RNNKeys.SEQUENCE_LENGTH_KEY` is not
- included, all sequences are assumed to have length equal to the size of
- dimension 1 of the input to the RNN.
-
- In order to specify an initial state, the input function must include keys
- `STATE_PREFIX_i` for all `0 <= i < n` where `n` is the number of nested
- elements in `cell.state_size`. The input function must contain values for all
- state components or none of them. If none are included, then the default
- (zero) state is used as an initial state. See the documentation for
- `dict_to_state_tuple` and `state_tuple_to_dict` for further details.
-
- The `predict()` method of the `Estimator` returns a dictionary with keys
- `RNNKeys.PREDICTIONS_KEY` and `STATE_PREFIX_i` for `0 <= i < n` where `n` is
- the number of nested elements in `cell.state_size`. The value keyed by
- `RNNKeys.PREDICTIONS_KEY` has shape `[batch_size, padded_length]`. Here,
- `padded_length` is the largest value in the `RNNKeys.SEQUENCE_LENGTH` `Tensor`
- passed as input. Entry `[i, j]` is the prediction associated with sequence `i`
- and time step `j`.
+ """Creates a `DynamicRnnEstimator` for single-value regression.
+
+ Returns an `Estimator` that given input sequences, processes them in a dynamic
+ recurrent network and outputs a single continuous values.
Args:
num_units: The size of the RNN cells. This argument has no effect
@@ -979,8 +1144,10 @@ def single_value_rnn_regressor(num_units,
num_rnn_layers: Number of RNN layers. Leave this at its default value 1
if passing a `cell_type` that is already a MultiRNNCell.
optimizer_type: The type of optimizer to use. Either a subclass of
- `Optimizer`, an instance of an `Optimizer` or a string. Strings must be
- one of 'Adagrad', 'Momentum' or 'SGD'.
+ `Optimizer`, an instance of an `Optimizer`, a callback that returns an
+ optimizer, or a string. Strings must be one of 'Adagrad', 'Adam',
+ 'Ftrl', 'Momentum', 'RMSProp' or 'SGD. See `layers.optimize_loss` for
+ more details.
learning_rate: Learning rate. This argument has no effect if `optimizer`
is an instance of an `Optimizer`.
momentum: Momentum value. Only used if `optimizer_type` is 'Momentum'.
@@ -1000,31 +1167,32 @@ def single_value_rnn_regressor(num_units,
Returns:
An initialized `Estimator`.
"""
- cell = _to_rnn_cell(cell_type, num_units, num_rnn_layers)
- target_column = layers.regression_target()
- if optimizer_type == 'Momentum':
- optimizer_type = momentum_opt.MomentumOptimizer(learning_rate, momentum)
- dynamic_rnn_model_fn = _get_dynamic_rnn_model_fn(
- cell=cell,
- target_column=target_column,
- problem_type=ProblemType.REGRESSION,
+ dropout_keep_probabilities, num_units = _get_dropout_and_num_units(
+ cell_type,
+ num_units,
+ num_rnn_layers,
+ input_keep_probability,
+ output_keep_probability)
+ return DynamicRnnEstimator(
+ problem_type=constants.ProblemType.LINEAR_REGRESSION,
prediction_type=PredictionType.SINGLE_VALUE,
- optimizer=optimizer_type,
sequence_feature_columns=sequence_feature_columns,
context_feature_columns=context_feature_columns,
+ num_units=num_units,
+ cell_type=cell_type,
+ optimizer=optimizer_type,
learning_rate=learning_rate,
+ momentum=momentum,
gradient_clipping_norm=gradient_clipping_norm,
- input_keep_probability=input_keep_probability,
- output_keep_probability=output_keep_probability,
- name='SingleValueRnnRegressor')
+ dropout_keep_probabilities=dropout_keep_probabilities,
+ model_dir=model_dir,
+ feature_engineering_fn=feature_engineering_fn,
+ config=config)
- return estimator.Estimator(model_fn=dynamic_rnn_model_fn,
- model_dir=model_dir,
- config=config,
- feature_engineering_fn=feature_engineering_fn)
-
-@experimental
+@deprecated('2017-04-01',
+ 'single_value_rnn_classifier is deprecated. '
+ 'Please construct a DynamicRnnEstimator directly.')
def single_value_rnn_classifier(num_classes,
num_units,
sequence_feature_columns,
@@ -1041,34 +1209,11 @@ def single_value_rnn_classifier(num_classes,
model_dir=None,
config=None,
feature_engineering_fn=None):
- """Creates a RNN `Estimator` that predicts single labels.
-
- The input function passed to this `Estimator` optionally contains keys
- `RNNKeys.SEQUENCE_LENGTH_KEY`. The value corresponding to
- `RNNKeys.SEQUENCE_LENGTH_KEY` must be vector of size `batch_size` where entry
- `n` corresponds to the length of the `n`th sequence in the batch. The sequence
- length feature is required for batches of varying sizes. It will be used to
- calculate loss and evaluation metrics.
-
- In order to specify an initial state, the input function must include keys
- `STATE_PREFIX_i` for all `0 <= i < n` where `n` is the number of nested
- elements in `cell.state_size`. The input function must contain values for all
- state components or none of them. If none are included, then the default
- (zero) state is used as an initial state. See the documentation for
- `dict_to_state_tuple` and `state_tuple_to_dict` for further details.
-
- The `predict()` method of the `Estimator` returns a dictionary with keys
- `RNNKeys.PREDICTIONS_KEY` and `STATE_PREFIX_i` for `0 <= i < n` where `n` is
- the number of nested elements in `cell.state_size`. The value keyed by
- `RNNKeys.PREDICTIONS_KEY` has shape `[batch_size, padded_length]`. Here,
- `padded_length` is the largest value in the `RNNKeys.SEQUENCE_LENGTH` `Tensor`
- passed as input. Entry `[i, j]` is the prediction associated with sequence `i`
- and time step `j`.
-
- If `predict_probabilities` is set to true, the `dict` returned by `predict()`
- contains an additional key `RNNKeys.PROBABILITIES_KEY`. The associated array
- has shape `[batch_size, num_classes]` where entry `[i, j]`
- is the probability assigned to class `k` in sequence `i` of the batch.
+ """Creates a `DynamicRnnEstimator` for single-value classification.
+
+ Returns an `Estimator` that given input sequences, processes them in a dynamic
+ recurrent network and outputs a single classifications, along with
+ (optionally) a probability distribution over classes.
Args:
num_classes: The number of classes for categorization.
@@ -1086,8 +1231,10 @@ def single_value_rnn_classifier(num_classes,
num_rnn_layers: Number of RNN layers. Leave this at its default value 1
if passing a `cell_type` that is already a MultiRNNCell.
optimizer_type: The type of optimizer to use. Either a subclass of
- `Optimizer`, an instance of an `Optimizer` or a string. Strings must be
- one of 'Adagrad', 'Momentum' or 'SGD'.
+ `Optimizer`, an instance of an `Optimizer`, a callback that returns an
+ optimizer, or a string. Strings must be one of 'Adagrad', 'Adam',
+ 'Ftrl', 'Momentum', 'RMSProp' or 'SGD. See `layers.optimize_loss` for
+ more details.
learning_rate: Learning rate. This argument has no effect if `optimizer`
is an instance of an `Optimizer`.
predict_probabilities: A boolean indicating whether to predict probabilities
@@ -1109,26 +1256,26 @@ def single_value_rnn_classifier(num_classes,
Returns:
An initialized `Estimator`.
"""
- cell = _to_rnn_cell(cell_type, num_units, num_rnn_layers)
- target_column = layers.multi_class_target(n_classes=num_classes)
- if optimizer_type == 'Momentum':
- optimizer_type = momentum_opt.MomentumOptimizer(learning_rate, momentum)
- dynamic_rnn_model_fn = _get_dynamic_rnn_model_fn(
- cell=cell,
- target_column=target_column,
- problem_type=ProblemType.CLASSIFICATION,
+ dropout_keep_probabilities, num_units = _get_dropout_and_num_units(
+ cell_type,
+ num_units,
+ num_rnn_layers,
+ input_keep_probability,
+ output_keep_probability)
+ return DynamicRnnEstimator(
+ problem_type=constants.ProblemType.CLASSIFICATION,
prediction_type=PredictionType.SINGLE_VALUE,
- optimizer=optimizer_type,
+ num_classes=num_classes,
sequence_feature_columns=sequence_feature_columns,
context_feature_columns=context_feature_columns,
- predict_probabilities=predict_probabilities,
+ num_units=num_units,
+ cell_type=cell_type,
+ optimizer=optimizer_type,
learning_rate=learning_rate,
+ predict_probabilities=predict_probabilities,
+ momentum=momentum,
gradient_clipping_norm=gradient_clipping_norm,
- input_keep_probability=input_keep_probability,
- output_keep_probability=output_keep_probability,
- name='SingleValueRnnClassifier')
-
- return estimator.Estimator(model_fn=dynamic_rnn_model_fn,
- model_dir=model_dir,
- config=config,
- feature_engineering_fn=feature_engineering_fn)
+ dropout_keep_probabilities=dropout_keep_probabilities,
+ model_dir=model_dir,
+ feature_engineering_fn=feature_engineering_fn,
+ config=config)
diff --git a/tensorflow/contrib/learn/python/learn/estimators/dynamic_rnn_estimator_test.py b/tensorflow/contrib/learn/python/learn/estimators/dynamic_rnn_estimator_test.py
index 955b57e893..181fe8e1bc 100644
--- a/tensorflow/contrib/learn/python/learn/estimators/dynamic_rnn_estimator_test.py
+++ b/tensorflow/contrib/learn/python/learn/estimators/dynamic_rnn_estimator_test.py
@@ -31,8 +31,10 @@ import numpy as np
from tensorflow.contrib import rnn
from tensorflow.contrib.layers.python.layers import feature_column
from tensorflow.contrib.layers.python.layers import target_column as target_column_lib
+from tensorflow.contrib.learn.python.learn.estimators import constants
from tensorflow.contrib.learn.python.learn.estimators import dynamic_rnn_estimator
from tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib
+from tensorflow.contrib.learn.python.learn.estimators import prediction_key
from tensorflow.contrib.learn.python.learn.estimators import run_config
from tensorflow.contrib.rnn.python.ops import core_rnn_cell_impl
from tensorflow.python.client import session
@@ -305,10 +307,11 @@ class DynamicRnnEstimatorTest(test.TestCase):
def _GetModelFnOpsForMode(self, mode):
"""Helper for testGetDynamicRnnModelFn{Train,Eval,Infer}()."""
model_fn = dynamic_rnn_estimator._get_dynamic_rnn_model_fn(
- self.rnn_cell,
+ cell_type='basic_rnn',
+ num_units=[10],
target_column=target_column_lib.multi_class_target(n_classes=2),
# Only CLASSIFICATION yields eval metrics to test for.
- problem_type=dynamic_rnn_estimator.ProblemType.CLASSIFICATION,
+ problem_type=constants.ProblemType.CLASSIFICATION,
prediction_type=dynamic_rnn_estimator.PredictionType.MULTIPLE_VALUE,
optimizer='SGD',
sequence_feature_columns=self.sequence_feature_columns,
@@ -338,7 +341,9 @@ class DynamicRnnEstimatorTest(test.TestCase):
model_dir = tempfile.mkdtemp()
def estimator_fn():
- return dynamic_rnn_estimator.multi_value_rnn_classifier(
+ return dynamic_rnn_estimator.DynamicRnnEstimator(
+ problem_type=constants.ProblemType.CLASSIFICATION,
+ prediction_type=dynamic_rnn_estimator.PredictionType.MULTIPLE_VALUE,
num_classes=2,
num_units=self.NUM_RNN_CELL_UNITS,
sequence_feature_columns=self.sequence_feature_columns,
@@ -443,9 +448,10 @@ class DynamicRnnEstimatorTest(test.TestCase):
config = run_config.RunConfig(tf_random_seed=21212)
cell = core_rnn_cell_impl.MultiRNNCell(
[core_rnn_cell_impl.BasicLSTMCell(size) for size in cell_sizes])
- sequence_estimator = dynamic_rnn_estimator.multi_value_rnn_classifier(
+ sequence_estimator = dynamic_rnn_estimator.DynamicRnnEstimator(
+ problem_type=constants.ProblemType.CLASSIFICATION,
+ prediction_type=dynamic_rnn_estimator.PredictionType.MULTIPLE_VALUE,
num_classes=2,
- num_units=None,
sequence_feature_columns=seq_columns,
cell_type=cell,
learning_rate=learning_rate,
@@ -463,6 +469,56 @@ class DynamicRnnEstimatorTest(test.TestCase):
state_piece = prediction_dict[dynamic_rnn_estimator._get_state_name(i)]
self.assertListEqual(list(state_piece.shape), [batch_size, state_size])
+ def testLegacyConstructor(self):
+ """Exercise legacy constructor function."""
+ num_units = 16
+ num_layers = 6
+ output_keep_prob = 0.9
+ input_keep_prob = 0.7
+ batch_size = 11
+ learning_rate = 0.1
+ train_sequence_length = 21
+ train_steps = 121
+
+ def get_input_fn(batch_size, sequence_length, state_dict, starting_step=0):
+
+ def input_fn():
+ sequence = constant_op.constant(
+ [[(starting_step + i + j) % 2 for j in range(sequence_length + 1)]
+ for i in range(batch_size)],
+ dtype=dtypes.int32)
+ labels = array_ops.slice(sequence, [0, 0],
+ [batch_size, sequence_length])
+ inputs = array_ops.expand_dims(
+ math_ops.to_float(
+ array_ops.slice(sequence, [0, 1], [batch_size, sequence_length
+ ])), 2)
+ input_dict = state_dict
+ input_dict['inputs'] = inputs
+ return input_dict, labels
+
+ return input_fn
+
+ seq_columns = [feature_column.real_valued_column('inputs', dimension=1)]
+ config = run_config.RunConfig(tf_random_seed=21212)
+
+ model_dir = tempfile.mkdtemp()
+ sequence_estimator = dynamic_rnn_estimator.multi_value_rnn_classifier(
+ num_classes=2,
+ num_units=num_units,
+ num_rnn_layers=num_layers,
+ input_keep_probability=input_keep_prob,
+ output_keep_probability=output_keep_prob,
+ sequence_feature_columns=seq_columns,
+ learning_rate=learning_rate,
+ config=config,
+ model_dir=model_dir)
+
+ train_input_fn = get_input_fn(
+ batch_size, train_sequence_length, state_dict={})
+
+ sequence_estimator.fit(input_fn=train_input_fn, steps=train_steps)
+
def testMultipleRuns(self):
"""Tests resuming training by feeding state."""
cell_sizes = [4, 7]
@@ -470,6 +526,7 @@ class DynamicRnnEstimatorTest(test.TestCase):
learning_rate = 0.1
train_sequence_length = 21
train_steps = 121
+ dropout_keep_probabilities = [0.5, 0.5, 0.5]
prediction_steps = [3, 2, 5, 11, 6]
def get_input_fn(batch_size, sequence_length, state_dict, starting_step=0):
@@ -493,15 +550,16 @@ class DynamicRnnEstimatorTest(test.TestCase):
seq_columns = [feature_column.real_valued_column('inputs', dimension=1)]
config = run_config.RunConfig(tf_random_seed=21212)
- cell = core_rnn_cell_impl.MultiRNNCell(
- [core_rnn_cell_impl.BasicLSTMCell(size) for size in cell_sizes])
model_dir = tempfile.mkdtemp()
- sequence_estimator = dynamic_rnn_estimator.multi_value_rnn_classifier(
+ sequence_estimator = dynamic_rnn_estimator.DynamicRnnEstimator(
+ problem_type=constants.ProblemType.CLASSIFICATION,
+ prediction_type=dynamic_rnn_estimator.PredictionType.MULTIPLE_VALUE,
num_classes=2,
- num_units=None,
sequence_feature_columns=seq_columns,
- cell_type=cell,
+ num_units=cell_sizes,
+ cell_type='lstm',
+ dropout_keep_probabilities=dropout_keep_probabilities,
learning_rate=learning_rate,
config=config,
model_dir=model_dir)
@@ -539,8 +597,9 @@ class DynamicRnnEstimatorTest(test.TestCase):
# Check that the last `prediction_steps[-1]` steps give the same
# predictions.
np.testing.assert_array_equal(
- pred_all_at_once['predictions'][:, -1 * prediction_steps[-1]:],
- pred_step_by_step['predictions'],
+ pred_all_at_once[prediction_key.PredictionKey.CLASSES]
+ [:, -1 * prediction_steps[-1]:],
+ pred_step_by_step[prediction_key.PredictionKey.CLASSES],
err_msg='Mismatch on last {} predictions.'.format(prediction_steps[-1]))
# Check that final states are identical.
for k, v in pred_all_at_once.items():
@@ -559,7 +618,7 @@ class DynamicRNNEstimatorLearningTest(test.TestCase):
sequence_length = 64
train_steps = 200
eval_steps = 20
- cell_size = 4
+ cell_size = [4]
learning_rate = 0.1
loss_threshold = 0.02
@@ -587,15 +646,16 @@ class DynamicRNNEstimatorLearningTest(test.TestCase):
seq_columns = [
feature_column.real_valued_column(
- 'inputs', dimension=cell_size)
+ 'inputs', dimension=cell_size[0])
]
config = run_config.RunConfig(tf_random_seed=1234)
- sequence_estimator = dynamic_rnn_estimator.multi_value_rnn_regressor(
+ sequence_estimator = dynamic_rnn_estimator.DynamicRnnEstimator(
+ problem_type=constants.ProblemType.LINEAR_REGRESSION,
+ prediction_type=dynamic_rnn_estimator.PredictionType.MULTIPLE_VALUE,
num_units=cell_size,
sequence_feature_columns=seq_columns,
learning_rate=learning_rate,
- input_keep_probability=0.9,
- output_keep_probability=0.9,
+ dropout_keep_probabilities=[0.9, 0.9],
config=config)
train_input_fn = get_sin_input_fn(
@@ -648,7 +708,9 @@ class DynamicRNNEstimatorLearningTest(test.TestCase):
'inputs', dimension=cell_size)
]
config = run_config.RunConfig(tf_random_seed=21212)
- sequence_estimator = dynamic_rnn_estimator.multi_value_rnn_classifier(
+ sequence_estimator = dynamic_rnn_estimator.DynamicRnnEstimator(
+ problem_type=constants.ProblemType.CLASSIFICATION,
+ prediction_type=dynamic_rnn_estimator.PredictionType.MULTIPLE_VALUE,
num_classes=2,
num_units=cell_size,
sequence_feature_columns=seq_columns,
@@ -674,13 +736,13 @@ class DynamicRNNEstimatorLearningTest(test.TestCase):
self.assertListEqual(
sorted(list(prediction_dict.keys())),
sorted([
- dynamic_rnn_estimator.RNNKeys.PREDICTIONS_KEY,
- dynamic_rnn_estimator.RNNKeys.PROBABILITIES_KEY,
+ prediction_key.PredictionKey.CLASSES,
+ prediction_key.PredictionKey.PROBABILITIES,
dynamic_rnn_estimator._get_state_name(0)
]))
- predictions = prediction_dict[dynamic_rnn_estimator.RNNKeys.PREDICTIONS_KEY]
+ predictions = prediction_dict[prediction_key.PredictionKey.CLASSES]
probabilities = prediction_dict[
- dynamic_rnn_estimator.RNNKeys.PROBABILITIES_KEY]
+ prediction_key.PredictionKey.PROBABILITIES]
self.assertListEqual(list(predictions.shape), [batch_size, sequence_length])
self.assertListEqual(
list(probabilities.shape), [batch_size, sequence_length, 2])
@@ -725,11 +787,13 @@ class DynamicRNNEstimatorLearningTest(test.TestCase):
'inputs', dimension=cell_size)
]
config = run_config.RunConfig(tf_random_seed=6)
- sequence_regressor = dynamic_rnn_estimator.single_value_rnn_regressor(
+ sequence_estimator = dynamic_rnn_estimator.DynamicRnnEstimator(
+ problem_type=constants.ProblemType.LINEAR_REGRESSION,
+ prediction_type=dynamic_rnn_estimator.PredictionType.SINGLE_VALUE,
num_units=cell_size,
sequence_feature_columns=seq_columns,
cell_type=cell_type,
- optimizer_type=optimizer_type,
+ optimizer=optimizer_type,
learning_rate=learning_rate,
momentum=momentum,
config=config)
@@ -737,8 +801,8 @@ class DynamicRNNEstimatorLearningTest(test.TestCase):
train_input_fn = get_mean_input_fn(batch_size, sequence_length, 121)
eval_input_fn = get_mean_input_fn(batch_size, sequence_length, 212)
- sequence_regressor.fit(input_fn=train_input_fn, steps=train_steps)
- evaluation = sequence_regressor.evaluate(
+ sequence_estimator.fit(input_fn=train_input_fn, steps=train_steps)
+ evaluation = sequence_estimator.evaluate(
input_fn=eval_input_fn, steps=eval_steps)
loss = evaluation['loss']
self.assertLess(loss, loss_threshold,
@@ -778,12 +842,14 @@ class DynamicRNNEstimatorLearningTest(test.TestCase):
'inputs', dimension=cell_size)
]
config = run_config.RunConfig(tf_random_seed=77)
- sequence_classifier = dynamic_rnn_estimator.single_value_rnn_classifier(
+ sequence_estimator = dynamic_rnn_estimator.DynamicRnnEstimator(
+ problem_type=constants.ProblemType.CLASSIFICATION,
+ prediction_type=dynamic_rnn_estimator.PredictionType.SINGLE_VALUE,
num_classes=2,
num_units=cell_size,
sequence_feature_columns=seq_columns,
cell_type=cell_type,
- optimizer_type=optimizer_type,
+ optimizer=optimizer_type,
learning_rate=learning_rate,
momentum=momentum,
config=config,
@@ -792,8 +858,8 @@ class DynamicRNNEstimatorLearningTest(test.TestCase):
train_input_fn = get_majority_input_fn(batch_size, sequence_length, 1111)
eval_input_fn = get_majority_input_fn(batch_size, sequence_length, 2222)
- sequence_classifier.fit(input_fn=train_input_fn, steps=train_steps)
- evaluation = sequence_classifier.evaluate(
+ sequence_estimator.fit(input_fn=train_input_fn, steps=train_steps)
+ evaluation = sequence_estimator.evaluate(
input_fn=eval_input_fn, steps=eval_steps)
accuracy = evaluation['accuracy']
self.assertGreater(accuracy, accuracy_threshold,
@@ -801,19 +867,19 @@ class DynamicRNNEstimatorLearningTest(test.TestCase):
accuracy_threshold, accuracy))
# Testing `predict` when `predict_probabilities=True`.
- prediction_dict = sequence_classifier.predict(
+ prediction_dict = sequence_estimator.predict(
input_fn=eval_input_fn, as_iterable=False)
self.assertListEqual(
sorted(list(prediction_dict.keys())),
sorted([
- dynamic_rnn_estimator.RNNKeys.PREDICTIONS_KEY,
- dynamic_rnn_estimator.RNNKeys.PROBABILITIES_KEY,
+ prediction_key.PredictionKey.CLASSES,
+ prediction_key.PredictionKey.PROBABILITIES,
dynamic_rnn_estimator._get_state_name(0),
dynamic_rnn_estimator._get_state_name(1)
]))
- predictions = prediction_dict[dynamic_rnn_estimator.RNNKeys.PREDICTIONS_KEY]
+ predictions = prediction_dict[prediction_key.PredictionKey.CLASSES]
probabilities = prediction_dict[
- dynamic_rnn_estimator.RNNKeys.PROBABILITIES_KEY]
+ prediction_key.PredictionKey.PROBABILITIES]
self.assertListEqual(list(predictions.shape), [batch_size])
self.assertListEqual(list(probabilities.shape), [batch_size, 2])
diff --git a/tensorflow/contrib/learn/python/learn/estimators/estimator.py b/tensorflow/contrib/learn/python/learn/estimators/estimator.py
index ebb3a5d378..3ebb92bd9e 100644
--- a/tensorflow/contrib/learn/python/learn/estimators/estimator.py
+++ b/tensorflow/contrib/learn/python/learn/estimators/estimator.py
@@ -1156,6 +1156,7 @@ class Estimator(BaseEstimator):
model_fn_ops = self._call_model_fn(
features, labels, model_fn_lib.ModeKeys.EVAL)
+ features, labels = self._feature_engineering_fn(features, labels)
# Custom metrics should overwrite defaults.
if metrics:
model_fn_ops.eval_metric_ops.update(_make_metrics_ops(
diff --git a/tensorflow/contrib/learn/python/learn/estimators/estimators_test.py b/tensorflow/contrib/learn/python/learn/estimators/estimators_test.py
index 00032d9f91..7372bb7a1a 100644
--- a/tensorflow/contrib/learn/python/learn/estimators/estimators_test.py
+++ b/tensorflow/contrib/learn/python/learn/estimators/estimators_test.py
@@ -30,6 +30,7 @@ import numpy as np
from tensorflow.contrib.learn.python import learn
from tensorflow.contrib.learn.python.learn import datasets
+from tensorflow.contrib.learn.python.learn import metric_spec
from tensorflow.contrib.learn.python.learn.estimators import estimator as estimator_lib
from tensorflow.contrib.learn.python.learn.estimators._sklearn import accuracy_score
from tensorflow.contrib.learn.python.learn.estimators._sklearn import train_test_split
@@ -74,6 +75,12 @@ class FeatureEngineeringFunctionTest(test.TestCase):
prediction = next(estimator.predict(input_fn=input_fn, as_iterable=True))
# predictions = transformed_x (9)
self.assertEqual(9., prediction)
+ metrics = estimator.evaluate(
+ input_fn=input_fn, steps=1,
+ metrics={"label":
+ metric_spec.MetricSpec(lambda predictions, labels: labels)})
+ # labels = transformed_y (99)
+ self.assertEqual(99., metrics["label"])
def testNoneFeatureEngineeringFn(self):
diff --git a/tensorflow/contrib/learn/python/learn/estimators/head.py b/tensorflow/contrib/learn/python/learn/estimators/head.py
index 4b8bf635fc..2f005a70cb 100644
--- a/tensorflow/contrib/learn/python/learn/estimators/head.py
+++ b/tensorflow/contrib/learn/python/learn/estimators/head.py
@@ -78,8 +78,45 @@ def _regression_head(label_name=None,
weight_column_name=weight_column_name,
label_dimension=label_dimension,
enable_centered_bias=enable_centered_bias,
- head_name=head_name)
+ head_name=head_name,
+ loss_fn=_mean_squared_loss,
+ link_fn=array_ops.identity)
+
+
+def _poisson_regression_head(label_name=None,
+ weight_column_name=None,
+ label_dimension=1,
+ enable_centered_bias=False,
+ head_name=None):
+ """Creates a _Head for linear regression.
+
+ Args:
+ label_name: String, name of the key in label dict. Can be null if label
+ is a tensor (single headed models).
+ weight_column_name: A string defining feature column name representing
+ weights. It is used to down weight or boost examples during training. It
+ will be multiplied by the loss of the example.
+ label_dimension: Number of regression labels per example. This is the size
+ of the last dimension of the labels `Tensor` (typically, this has shape
+ `[batch_size, label_dimension]`).
+ enable_centered_bias: A bool. If True, estimator will learn a centered
+ bias variable for each class. Rest of the model structure learns the
+ residual after centered bias.
+ head_name: name of the head. If provided, predictions, summary and metrics
+ keys will be suffixed by `"/" + head_name` and the default variable scope
+ will be `head_name`.
+ Returns:
+ An instance of _Head
+ """
+ return _RegressionHead(
+ label_name=label_name,
+ weight_column_name=weight_column_name,
+ label_dimension=label_dimension,
+ enable_centered_bias=enable_centered_bias,
+ head_name=head_name,
+ loss_fn=_poisson_loss,
+ link_fn=math_ops.exp)
# TODO(zakaria): Add logistic_regression_head
@@ -259,7 +296,7 @@ def _multi_head(heads, loss_weights=None):
# TODO(zakaria): Make the classes public once we are ready for users to subclass
-# them.
+# them. See b/34751732
class _Head(object):
"""Interface for the head/top of a model.
@@ -383,6 +420,22 @@ def _mean_squared_loss(logits, labels):
return math_ops.square(logits - math_ops.to_float(labels), name=name)
+def _poisson_loss(logits, labels):
+ """Computes poisson loss from logits."""
+ with ops.name_scope(None, "_poisson_loss", (logits, labels)) as name:
+ logits = ops.convert_to_tensor(logits)
+ labels = ops.convert_to_tensor(labels)
+ # To prevent broadcasting inside "-".
+ if len(labels.get_shape()) == 1:
+ labels = array_ops.expand_dims(labels, dim=(1,))
+ # TODO(zakaria): make sure it does not recreate the broadcast bug.
+ if len(logits.get_shape()) == 1:
+ logits = array_ops.expand_dims(logits, dim=(1,))
+ logits.get_shape().assert_is_compatible_with(labels.get_shape())
+ return nn.log_poisson_loss(labels, logits,
+ compute_full_loss=True, name=name)
+
+
def _logits(logits_input, logits, logits_dimension):
"""Validate logits args, and create `logits` if necessary.
@@ -422,21 +475,24 @@ def _logits(logits_input, logits, logits_dimension):
class _RegressionHead(_SingleHead):
- """_Head for regression."""
+ """_Head for regression with a generalized linear model."""
def __init__(self,
label_dimension,
+ loss_fn,
+ link_fn,
label_name=None,
weight_column_name=None,
enable_centered_bias=False,
- head_name=None,
- loss_fn=_mean_squared_loss):
- """Base type for all single heads.
+ head_name=None):
+ """Head for regression.
Args:
label_dimension: Number of regression labels per example. This is the
size of the last dimension of the labels `Tensor` (typically, this has
shape `[batch_size, label_dimension]`).
+ loss_fn: Loss function, takes logits and labels and returns loss.
+ link_fn: Link function, takes a logits tensor and returns the output.
label_name: String, name of the key in label dict. Can be null if label
is a tensor (single headed models).
weight_column_name: A string defining feature column name representing
@@ -448,7 +504,6 @@ class _RegressionHead(_SingleHead):
head_name: name of the head. Predictions, summary and metrics keys are
suffixed by `"/" + head_name` and the default variable scope is
`head_name`.
- loss_fn: Loss function.
"""
super(_RegressionHead, self).__init__(
problem_type=constants.ProblemType.LINEAR_REGRESSION,
@@ -458,6 +513,7 @@ class _RegressionHead(_SingleHead):
head_name=head_name)
self._loss_fn = loss_fn
+ self._link_fn = link_fn
self._enable_centered_bias = enable_centered_bias
def create_model_fn_ops(self,
@@ -500,7 +556,6 @@ class _RegressionHead(_SingleHead):
with ops.name_scope("default_metrics", values=[weighted_average_loss]):
eval_metric_ops = {_summary_key(self.head_name, mkey.LOSS):
metrics_lib.streaming_mean(weighted_average_loss)}
-
return model_fn.ModelFnOps(
mode=mode,
predictions=predictions,
@@ -522,7 +577,7 @@ class _RegressionHead(_SingleHead):
with ops.name_scope(None, "predictions", (logits,)):
if self.logits_dimension == 1:
logits = array_ops.squeeze(logits, squeeze_dims=(1,), name=key)
- return {key: logits}
+ return {key: self._link_fn(logits)}
def _log_loss_with_two_classes(logits, labels):
diff --git a/tensorflow/contrib/learn/python/learn/estimators/head_test.py b/tensorflow/contrib/learn/python/learn/estimators/head_test.py
index 88255e20ce..715275e3eb 100644
--- a/tensorflow/contrib/learn/python/learn/estimators/head_test.py
+++ b/tensorflow/contrib/learn/python/learn/estimators/head_test.py
@@ -100,7 +100,42 @@ def _sigmoid(x):
return 1. / (1. + math.exp(-1 * x))
-class RegressionModelHeadTest(test.TestCase):
+class PoissonHeadTest(test.TestCase):
+
+ def _assert_output_alternatives(self, model_fn_ops):
+ self.assertEquals({
+ None: constants.ProblemType.LINEAR_REGRESSION
+ }, {
+ k: v[0] for k, v in six.iteritems(model_fn_ops.output_alternatives)
+ })
+
+ def _log_poisson_loss(self, logits, labels):
+ x = np.array([f[0] for f in logits])
+ z = np.array([f[0] for f in labels])
+ lpl = np.exp(x) - z * x
+ stirling_approx = z * np.log(z) - z + 0.5 * np.log(2. * np.pi * z)
+ lpl += np.ma.masked_array(stirling_approx, mask=(z <= 1)).filled(0.)
+ return sum(lpl)/len(lpl)
+
+ def testPoissonWithLogits(self):
+ head = head_lib._poisson_regression_head()
+ labels = ((0.,), (1.,), (1.,))
+ logits = ((0.,), (-1.,), (3.,))
+ with ops.Graph().as_default(), session.Session():
+ model_fn_ops = head.create_model_fn_ops(
+ {},
+ labels=labels,
+ mode=model_fn.ModeKeys.TRAIN,
+ train_op_fn=_noop_train_op,
+ logits=logits)
+ self._assert_output_alternatives(model_fn_ops)
+ _assert_summary_tags(self, ["loss"])
+ _assert_no_variables(self)
+ loss = self._log_poisson_loss(logits, labels)
+ _assert_metrics(self, loss, {"loss": loss}, model_fn_ops)
+
+
+class RegressionHeadTest(test.TestCase):
def _assert_output_alternatives(self, model_fn_ops):
self.assertEquals({
@@ -251,7 +286,7 @@ class RegressionModelHeadTest(test.TestCase):
logits=((1.,), (1.,), (3.,)))
-class MultiLabelModelHeadTest(test.TestCase):
+class MultiLabelHeadTest(test.TestCase):
def _assert_output_alternatives(self, model_fn_ops):
self.assertEquals({
@@ -482,7 +517,7 @@ class MultiLabelModelHeadTest(test.TestCase):
logits=[0.])
-class BinaryClassificationModelHeadTest(test.TestCase):
+class BinaryClassificationHeadTest(test.TestCase):
def _assert_output_alternatives(self, model_fn_ops):
self.assertEquals({
@@ -713,7 +748,7 @@ class BinaryClassificationModelHeadTest(test.TestCase):
self._expected_eval_metrics(expected_loss), model_fn_ops)
-class MultiClassModelHeadTest(test.TestCase):
+class MultiClassHeadTest(test.TestCase):
def _assert_output_alternatives(self, model_fn_ops):
self.assertEquals({
@@ -870,7 +905,7 @@ class MultiClassModelHeadTest(test.TestCase):
head_lib._multi_class_head(n_classes=n_classes)
-class BinarySvmModelHeadTest(test.TestCase):
+class BinarySvmHeadTest(test.TestCase):
def _assert_output_alternatives(self, model_fn_ops):
self.assertEquals({
diff --git a/tensorflow/contrib/learn/python/learn/estimators/linear.py b/tensorflow/contrib/learn/python/learn/estimators/linear.py
index f35828d342..b3ed9b1a0a 100644
--- a/tensorflow/contrib/learn/python/learn/estimators/linear.py
+++ b/tensorflow/contrib/learn/python/learn/estimators/linear.py
@@ -196,7 +196,7 @@ def sdca_model_fn(features, labels, mode, params):
params: A dict of hyperparameters.
The following hyperparameters are expected:
* head: A `Head` instance. Type must be one of `_BinarySvmHead`,
- `_RegressionHead` or `_MultiClassHead`.
+ `_RegressionHead` or `_BinaryLogisticHead`.
* feature_columns: An iterable containing all the feature columns used by
the model.
* optimizer: An `SDCAOptimizer` instance.
@@ -223,17 +223,16 @@ def sdca_model_fn(features, labels, mode, params):
if not isinstance(optimizer, sdca_optimizer.SDCAOptimizer):
raise ValueError("Optimizer must be of type SDCAOptimizer")
- # pylint: disable=protected-access
- if isinstance(head, head_lib._BinarySvmHead):
+ if isinstance(head, head_lib._BinarySvmHead): # pylint: disable=protected-access
loss_type = "hinge_loss"
- elif isinstance(
- head, (head_lib._MultiClassHead, head_lib._BinaryLogisticHead)):
+ elif isinstance(head, head_lib._BinaryLogisticHead): # pylint: disable=protected-access
loss_type = "logistic_loss"
- elif isinstance(head, head_lib._RegressionHead):
+ elif isinstance(head, head_lib._RegressionHead): # pylint: disable=protected-access
+ assert head.logits_dimension == 1, ("SDCA only applies for "
+ "logits_dimension=1.")
loss_type = "squared_loss"
else:
raise ValueError("Unsupported head type: {}".format(head))
- # pylint: enable=protected-access
parent_scope = "linear"
@@ -887,3 +886,110 @@ class LinearRegressor(estimator.Estimator):
"get_variable_value().")
def bias_(self):
return self.get_variable_value("linear/bias_weight")
+
+
+# TODO(zakaria): Make it public when b/34751732 is fixed.
+class _LinearEstimator(estimator.Estimator):
+ """Linear model with user specified head.
+
+ Train a generalized linear model to predict label value given observation of
+ feature values.
+
+ Example:
+ To do poisson regression,
+
+ ```python
+ sparse_column_a = sparse_column_with_hash_bucket(...)
+ sparse_column_b = sparse_column_with_hash_bucket(...)
+
+ sparse_feature_a_x_sparse_feature_b = crossed_column(...)
+
+ estimator = _LinearEstimator(
+ feature_columns=[sparse_column_a, sparse_feature_a_x_sparse_feature_b],
+ head=head_lib._poisson_regression_head())
+
+ # Input builders
+ def input_fn_train: # returns x, y
+ ...
+ def input_fn_eval: # returns x, y
+ ...
+ estimator.fit(input_fn=input_fn_train)
+ estimator.evaluate(input_fn=input_fn_eval)
+ estimator.predict(x=x)
+ ```
+
+ Input of `fit` and `evaluate` should have following features,
+ otherwise there will be a KeyError:
+
+ * if `weight_column_name` is not `None`:
+ key=weight_column_name, value=a `Tensor`
+ * for column in `feature_columns`:
+ - if isinstance(column, `SparseColumn`):
+ key=column.name, value=a `SparseTensor`
+ - if isinstance(column, `WeightedSparseColumn`):
+ {key=id column name, value=a `SparseTensor`,
+ key=weight column name, value=a `SparseTensor`}
+ - if isinstance(column, `RealValuedColumn`):
+ key=column.name, value=a `Tensor`
+ """
+
+ def __init__(self, # _joint_weights: pylint: disable=invalid-name
+ feature_columns,
+ head,
+ model_dir=None,
+ weight_column_name=None,
+ optimizer=None,
+ gradient_clip_norm=None,
+ _joint_weights=False,
+ config=None,
+ feature_engineering_fn=None):
+ """Construct a `_LinearEstimator` object.
+
+ Args:
+ feature_columns: An iterable containing all the feature columns used by
+ the model. All items in the set should be instances of classes derived
+ from `FeatureColumn`.
+ head: An instance of _Head class.
+ model_dir: Directory to save model parameters, graph, etc. This can
+ also be used to load checkpoints from the directory into a estimator
+ to continue training a previously saved model.
+ weight_column_name: A string defining feature column name representing
+ weights. It is used to down weight or boost examples during training. It
+ will be multiplied by the loss of the example.
+ optimizer: An instance of `tf.Optimizer` used to train the model. If
+ `None`, will use an Ftrl optimizer.
+ gradient_clip_norm: A `float` > 0. If provided, gradients are clipped
+ to their global norm with this clipping ratio. See
+ `tf.clip_by_global_norm` for more details.
+ _joint_weights: If True use a single (possibly partitioned) variable to
+ store the weights. It's faster, but requires all feature columns are
+ sparse and have the 'sum' combiner. Incompatible with SDCAOptimizer.
+ config: `RunConfig` object to configure the runtime settings.
+ feature_engineering_fn: Feature engineering function. Takes features and
+ labels which are the output of `input_fn` and
+ returns features and labels which will be fed
+ into the model.
+
+ Returns:
+ A `_LinearEstimator` estimator.
+
+ Raises:
+ ValueError: if optimizer is not supported, e.g., SDCAOptimizer
+ """
+ assert feature_columns
+ if isinstance(optimizer, sdca_optimizer.SDCAOptimizer):
+ raise ValueError("_LinearEstimator does not support SDCA optimizer.")
+
+ params = {
+ "head": head,
+ "feature_columns": feature_columns,
+ "optimizer": optimizer,
+ "gradient_clip_norm": gradient_clip_norm,
+ "joint_weights": _joint_weights,
+ }
+ super(_LinearEstimator, self).__init__(
+ model_fn=_linear_model_fn,
+ model_dir=model_dir,
+ config=config,
+ params=params,
+ feature_engineering_fn=feature_engineering_fn)
diff --git a/tensorflow/contrib/learn/python/learn/estimators/linear_test.py b/tensorflow/contrib/learn/python/learn/estimators/linear_test.py
index 5cac1ea07b..ef5bd0175c 100644
--- a/tensorflow/contrib/learn/python/learn/estimators/linear_test.py
+++ b/tensorflow/contrib/learn/python/learn/estimators/linear_test.py
@@ -36,6 +36,7 @@ from tensorflow.contrib.learn.python.learn.datasets import base
from tensorflow.contrib.learn.python.learn.estimators import _sklearn
from tensorflow.contrib.learn.python.learn.estimators import estimator
from tensorflow.contrib.learn.python.learn.estimators import estimator_test_utils
+from tensorflow.contrib.learn.python.learn.estimators import head as head_lib
from tensorflow.contrib.learn.python.learn.estimators import linear
from tensorflow.contrib.learn.python.learn.estimators import run_config
from tensorflow.contrib.learn.python.learn.estimators import test_data
@@ -1627,6 +1628,92 @@ class LinearRegressorTest(test.TestCase):
self.assertNear(regressor.weights_['linear/b/weight'][0], -0.1, err=0.05)
+class LinearEstimatorTest(test.TestCase):
+
+ def testExperimentIntegration(self):
+ cont_features = [
+ feature_column_lib.real_valued_column(
+ 'feature', dimension=4)
+ ]
+ exp = experiment.Experiment(
+ estimator=linear._LinearEstimator(feature_columns=cont_features,
+ head=head_lib._regression_head()),
+ train_input_fn=test_data.iris_input_logistic_fn,
+ eval_input_fn=test_data.iris_input_logistic_fn)
+ exp.test()
+
+ def testEstimatorContract(self):
+ estimator_test_utils.assert_estimator_contract(self,
+ linear._LinearEstimator)
+
+ def testLinearRegression(self):
+ """Tests that loss goes down with training."""
+
+ def input_fn():
+ return {
+ 'age':
+ constant_op.constant([1]),
+ 'language':
+ sparse_tensor.SparseTensor(
+ values=['english'], indices=[[0, 0]], dense_shape=[1, 1])
+ }, constant_op.constant([[10.]])
+
+ language = feature_column_lib.sparse_column_with_hash_bucket('language',
+ 100)
+ age = feature_column_lib.real_valued_column('age')
+
+ linear_estimator = linear._LinearEstimator(feature_columns=[age, language],
+ head=head_lib._regression_head())
+ linear_estimator.fit(input_fn=input_fn, steps=100)
+ loss1 = linear_estimator.evaluate(input_fn=input_fn, steps=1)['loss']
+ linear_estimator.fit(input_fn=input_fn, steps=400)
+ loss2 = linear_estimator.evaluate(input_fn=input_fn, steps=1)['loss']
+
+ self.assertLess(loss2, loss1)
+ self.assertLess(loss2, 0.5)
+
+ def testPoissonRegression(self):
+ """Tests that loss goes down with training."""
+
+ def input_fn():
+ return {
+ 'age':
+ constant_op.constant([1]),
+ 'language':
+ sparse_tensor.SparseTensor(
+ values=['english'], indices=[[0, 0]], dense_shape=[1, 1])
+ }, constant_op.constant([[10.]])
+
+ language = feature_column_lib.sparse_column_with_hash_bucket('language',
+ 100)
+ age = feature_column_lib.real_valued_column('age')
+
+ linear_estimator = linear._LinearEstimator(
+ feature_columns=[age, language],
+ head=head_lib._poisson_regression_head())
+ linear_estimator.fit(input_fn=input_fn, steps=10)
+ loss1 = linear_estimator.evaluate(input_fn=input_fn, steps=1)['loss']
+ linear_estimator.fit(input_fn=input_fn, steps=100)
+ loss2 = linear_estimator.evaluate(input_fn=input_fn, steps=1)['loss']
+
+ self.assertLess(loss2, loss1)
+ # Here loss of 2.1 implies a prediction of ~9.9998
+ self.assertLess(loss2, 2.1)
+
+ def testSDCANotSupported(self):
+ """Tests that we detect error for SDCA."""
+ maintenance_cost = feature_column_lib.real_valued_column('maintenance_cost')
+ sq_footage = feature_column_lib.real_valued_column('sq_footage')
+ sdca_optimizer = sdca_optimizer_lib.SDCAOptimizer(
+ example_id_column='example_id')
+ with self.assertRaises(ValueError):
+ linear._LinearEstimator(
+ head=head_lib._regression_head(label_dimension=1),
+ feature_columns=[maintenance_cost, sq_footage],
+ optimizer=sdca_optimizer,
+ _joint_weights=True)
+
+
def boston_input_fn():
boston = base.load_boston()
features = math_ops.cast(
diff --git a/tensorflow/contrib/learn/python/learn/utils/input_fn_utils.py b/tensorflow/contrib/learn/python/learn/utils/input_fn_utils.py
index 1a51971619..f7dac819fe 100644
--- a/tensorflow/contrib/learn/python/learn/utils/input_fn_utils.py
+++ b/tensorflow/contrib/learn/python/learn/utils/input_fn_utils.py
@@ -26,19 +26,26 @@ from tensorflow.python.ops import array_ops
from tensorflow.python.ops import parsing_ops
-# A return type allowing input_fns to return multiple values in a well-
-# defined way (analogous to ModelFnOps).
-# The expected return values are:
-# features: a dict of string to `Tensor` or `SparseTensor`, giving the features
-# to be passed to the model.
-# labels: a dict of string to `Tensor` or `SparseTensor`, giving labels (aka
-# targets) for training.
-# default_inputs: a dict of string to `Tensor` or `SparseTensor`, giving the
-# input placeholders (if any) that this input_fn expects to be fed.
-InputFnOps = collections.namedtuple('InputFnOps',
- ['features',
- 'labels',
- 'default_inputs'])
+class InputFnOps(collections.namedtuple('InputFnOps',
+ ['features',
+ 'labels',
+ 'default_inputs'])):
+ """A return type for an input_fn.
+
+ This return type is currently only supported for serving input_fn.
+ Training and eval input_fn should return a `(features, labels)` tuple.
+
+ The expected return values are:
+ features: A dict of string to `Tensor` or `SparseTensor`, specifying the
+ features to be passed to the model.
+ labels: A `Tensor`, `SparseTensor`, or a dict of string to `Tensor` or
+ `SparseTensor`, specifying labels for training or eval. For serving, set
+ `labels` to `None`.
+ default_inputs: a dict of string to `Tensor` or `SparseTensor`, specifying
+ the input placeholders (if any) that this input_fn expects to be fed.
+ Typically, this is used by a serving input_fn, which expects to be fed
+ serialized `tf.Example` protos.
+ """
def build_parsing_serving_input_fn(feature_spec, default_batch_size=None):
diff --git a/tensorflow/contrib/legacy_seq2seq/python/kernel_tests/seq2seq_test.py b/tensorflow/contrib/legacy_seq2seq/python/kernel_tests/seq2seq_test.py
index 900f609681..0f9f0a955c 100644
--- a/tensorflow/contrib/legacy_seq2seq/python/kernel_tests/seq2seq_test.py
+++ b/tensorflow/contrib/legacy_seq2seq/python/kernel_tests/seq2seq_test.py
@@ -18,6 +18,7 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+import functools
import math
import random
import sys
@@ -110,14 +111,17 @@ class Seq2SeqTest(test.TestCase):
with variable_scope.variable_scope(
"root", initializer=init_ops.constant_initializer(0.5)):
inp = [constant_op.constant(0.5, shape=[2, 2])] * 2
- cell = core_rnn_cell_impl.BasicLSTMCell(2, state_is_tuple=True)
+ cell_fn = lambda: core_rnn_cell_impl.BasicLSTMCell(2)
+ cell = cell_fn()
_, enc_state = core_rnn.static_rnn(cell, inp, dtype=dtypes.float32)
dec_inp = [
constant_op.constant(
i, dtypes.int32, shape=[2]) for i in range(3)
]
+ # Use a new cell instance since the attention decoder uses a
+ # different variable scope.
dec, mem = seq2seq_lib.embedding_rnn_decoder(
- dec_inp, enc_state, cell, num_symbols=4, embedding_size=2)
+ dec_inp, enc_state, cell_fn(), num_symbols=4, embedding_size=2)
sess.run([variables.global_variables_initializer()])
res = sess.run(dec)
self.assertEqual(3, len(res))
@@ -140,7 +144,8 @@ class Seq2SeqTest(test.TestCase):
constant_op.constant(
i, dtypes.int32, shape=[2]) for i in range(3)
]
- cell = core_rnn_cell_impl.BasicLSTMCell(2, state_is_tuple=True)
+ cell_fn = lambda: core_rnn_cell_impl.BasicLSTMCell(2)
+ cell = cell_fn()
dec, mem = seq2seq_lib.embedding_rnn_seq2seq(
enc_inp,
dec_inp,
@@ -159,11 +164,11 @@ class Seq2SeqTest(test.TestCase):
# Test with state_is_tuple=False.
with variable_scope.variable_scope("no_tuple"):
- cell1 = core_rnn_cell_impl.BasicLSTMCell(2, state_is_tuple=False)
+ cell_nt = core_rnn_cell_impl.BasicLSTMCell(2, state_is_tuple=False)
dec, mem = seq2seq_lib.embedding_rnn_seq2seq(
enc_inp,
dec_inp,
- cell1,
+ cell_nt,
num_encoder_symbols=2,
num_decoder_symbols=5,
embedding_size=2)
@@ -182,7 +187,7 @@ class Seq2SeqTest(test.TestCase):
dec, _ = seq2seq_lib.embedding_rnn_seq2seq(
enc_inp,
dec_inp,
- cell,
+ cell_fn(),
num_encoder_symbols=2,
num_decoder_symbols=5,
embedding_size=2,
@@ -201,7 +206,7 @@ class Seq2SeqTest(test.TestCase):
d3, _ = seq2seq_lib.embedding_rnn_seq2seq(
enc_inp,
dec_inp2,
- cell,
+ cell_fn(),
num_encoder_symbols=2,
num_decoder_symbols=5,
embedding_size=2,
@@ -211,7 +216,7 @@ class Seq2SeqTest(test.TestCase):
d1, _ = seq2seq_lib.embedding_rnn_seq2seq(
enc_inp,
dec_inp,
- cell,
+ cell_fn(),
num_encoder_symbols=2,
num_decoder_symbols=5,
embedding_size=2,
@@ -219,7 +224,7 @@ class Seq2SeqTest(test.TestCase):
d2, _ = seq2seq_lib.embedding_rnn_seq2seq(
enc_inp,
dec_inp2,
- cell,
+ cell_fn(),
num_encoder_symbols=2,
num_decoder_symbols=5,
embedding_size=2,
@@ -242,9 +247,11 @@ class Seq2SeqTest(test.TestCase):
constant_op.constant(
i, dtypes.int32, shape=[2]) for i in range(3)
]
- cell = core_rnn_cell_impl.BasicLSTMCell(2, state_is_tuple=True)
+ cell = functools.partial(
+ core_rnn_cell_impl.BasicLSTMCell,
+ 2, state_is_tuple=True)
dec, mem = seq2seq_lib.embedding_tied_rnn_seq2seq(
- enc_inp, dec_inp, cell, num_symbols=5, embedding_size=2)
+ enc_inp, dec_inp, cell(), num_symbols=5, embedding_size=2)
sess.run([variables.global_variables_initializer()])
res = sess.run(dec)
self.assertEqual(3, len(res))
@@ -260,7 +267,7 @@ class Seq2SeqTest(test.TestCase):
dec, mem = seq2seq_lib.embedding_tied_rnn_seq2seq(
enc_inp,
dec_inp,
- cell,
+ cell(),
num_symbols=5,
num_decoder_symbols=3,
embedding_size=2)
@@ -276,7 +283,7 @@ class Seq2SeqTest(test.TestCase):
dec, _ = seq2seq_lib.embedding_tied_rnn_seq2seq(
enc_inp,
dec_inp,
- cell,
+ cell(),
num_symbols=5,
embedding_size=2,
output_projection=(w, b))
@@ -291,7 +298,7 @@ class Seq2SeqTest(test.TestCase):
d3, _ = seq2seq_lib.embedding_tied_rnn_seq2seq(
enc_inp,
dec_inp2,
- cell,
+ cell(),
num_symbols=5,
embedding_size=2,
feed_previous=constant_op.constant(True))
@@ -300,14 +307,14 @@ class Seq2SeqTest(test.TestCase):
d1, _ = seq2seq_lib.embedding_tied_rnn_seq2seq(
enc_inp,
dec_inp,
- cell,
+ cell(),
num_symbols=5,
embedding_size=2,
feed_previous=True)
d2, _ = seq2seq_lib.embedding_tied_rnn_seq2seq(
enc_inp,
dec_inp2,
- cell,
+ cell(),
num_symbols=5,
embedding_size=2,
feed_previous=True)
@@ -321,7 +328,8 @@ class Seq2SeqTest(test.TestCase):
with self.test_session() as sess:
with variable_scope.variable_scope(
"root", initializer=init_ops.constant_initializer(0.5)):
- cell = core_rnn_cell_impl.GRUCell(2)
+ cell_fn = lambda: core_rnn_cell_impl.GRUCell(2)
+ cell = cell_fn()
inp = [constant_op.constant(0.5, shape=[2, 2])] * 2
enc_outputs, enc_state = core_rnn.static_rnn(
cell, inp, dtype=dtypes.float32)
@@ -329,8 +337,11 @@ class Seq2SeqTest(test.TestCase):
array_ops.reshape(e, [-1, 1, cell.output_size]) for e in enc_outputs
], 1)
dec_inp = [constant_op.constant(0.4, shape=[2, 2])] * 3
+
+ # Create a new cell instance for the decoder, since it uses a
+ # different variable scope
dec, mem = seq2seq_lib.attention_decoder(
- dec_inp, enc_state, attn_states, cell, output_size=4)
+ dec_inp, enc_state, attn_states, cell_fn(), output_size=4)
sess.run([variables.global_variables_initializer()])
res = sess.run(dec)
self.assertEqual(3, len(res))
@@ -343,7 +354,8 @@ class Seq2SeqTest(test.TestCase):
with self.test_session() as sess:
with variable_scope.variable_scope(
"root", initializer=init_ops.constant_initializer(0.5)):
- cell = core_rnn_cell_impl.GRUCell(2)
+ cell_fn = lambda: core_rnn_cell_impl.GRUCell(2)
+ cell = cell_fn()
inp = [constant_op.constant(0.5, shape=[2, 2])] * 2
enc_outputs, enc_state = core_rnn.static_rnn(
cell, inp, dtype=dtypes.float32)
@@ -351,8 +363,12 @@ class Seq2SeqTest(test.TestCase):
array_ops.reshape(e, [-1, 1, cell.output_size]) for e in enc_outputs
], 1)
dec_inp = [constant_op.constant(0.4, shape=[2, 2])] * 3
+
+ # Use a new cell instance since the attention decoder uses a
+ # different variable scope.
dec, mem = seq2seq_lib.attention_decoder(
- dec_inp, enc_state, attn_states, cell, output_size=4, num_heads=2)
+ dec_inp, enc_state, attn_states, cell_fn(),
+ output_size=4, num_heads=2)
sess.run([variables.global_variables_initializer()])
res = sess.run(dec)
self.assertEqual(3, len(res))
@@ -365,14 +381,18 @@ class Seq2SeqTest(test.TestCase):
with self.test_session() as sess:
with variable_scope.variable_scope(
"root", initializer=init_ops.constant_initializer(0.5)):
- cell = core_rnn_cell_impl.GRUCell(2)
+ cell_fn = lambda: core_rnn_cell_impl.GRUCell(2)
+ cell = cell_fn()
inp = constant_op.constant(0.5, shape=[2, 2, 2])
enc_outputs, enc_state = rnn.dynamic_rnn(
cell, inp, dtype=dtypes.float32)
attn_states = enc_outputs
dec_inp = [constant_op.constant(0.4, shape=[2, 2])] * 3
+
+ # Use a new cell instance since the attention decoder uses a
+ # different variable scope.
dec, mem = seq2seq_lib.attention_decoder(
- dec_inp, enc_state, attn_states, cell, output_size=4)
+ dec_inp, enc_state, attn_states, cell_fn(), output_size=4)
sess.run([variables.global_variables_initializer()])
res = sess.run(dec)
self.assertEqual(3, len(res))
@@ -385,14 +405,19 @@ class Seq2SeqTest(test.TestCase):
with self.test_session() as sess:
with variable_scope.variable_scope(
"root", initializer=init_ops.constant_initializer(0.5)):
- cell = core_rnn_cell_impl.GRUCell(2)
+ cell_fn = lambda: core_rnn_cell_impl.GRUCell(2)
+ cell = cell_fn()
inp = constant_op.constant(0.5, shape=[2, 2, 2])
enc_outputs, enc_state = rnn.dynamic_rnn(
cell, inp, dtype=dtypes.float32)
attn_states = enc_outputs
dec_inp = [constant_op.constant(0.4, shape=[2, 2])] * 3
+
+ # Use a new cell instance since the attention decoder uses a
+ # different variable scope.
dec, mem = seq2seq_lib.attention_decoder(
- dec_inp, enc_state, attn_states, cell, output_size=4, num_heads=2)
+ dec_inp, enc_state, attn_states, cell_fn(),
+ output_size=4, num_heads=2)
sess.run([variables.global_variables_initializer()])
res = sess.run(dec)
self.assertEqual(3, len(res))
@@ -407,8 +432,9 @@ class Seq2SeqTest(test.TestCase):
"root", initializer=init_ops.constant_initializer(0.5)):
single_cell = lambda: core_rnn_cell_impl.BasicLSTMCell( # pylint: disable=g-long-lambda
2, state_is_tuple=True)
- cell = core_rnn_cell_impl.MultiRNNCell(
+ cell_fn = lambda: core_rnn_cell_impl.MultiRNNCell( # pylint: disable=g-long-lambda
cells=[single_cell() for _ in range(2)], state_is_tuple=True)
+ cell = cell_fn()
inp = [constant_op.constant(0.5, shape=[2, 2])] * 2
enc_outputs, enc_state = core_rnn.static_rnn(
cell, inp, dtype=dtypes.float32)
@@ -416,8 +442,11 @@ class Seq2SeqTest(test.TestCase):
array_ops.reshape(e, [-1, 1, cell.output_size]) for e in enc_outputs
], 1)
dec_inp = [constant_op.constant(0.4, shape=[2, 2])] * 3
+
+ # Use a new cell instance since the attention decoder uses a
+ # different variable scope.
dec, mem = seq2seq_lib.attention_decoder(
- dec_inp, enc_state, attn_states, cell, output_size=4)
+ dec_inp, enc_state, attn_states, cell_fn(), output_size=4)
sess.run([variables.global_variables_initializer()])
res = sess.run(dec)
self.assertEqual(3, len(res))
@@ -434,11 +463,9 @@ class Seq2SeqTest(test.TestCase):
with self.test_session() as sess:
with variable_scope.variable_scope(
"root", initializer=init_ops.constant_initializer(0.5)):
- single_cell = lambda: core_rnn_cell_impl.BasicLSTMCell( # pylint: disable=g-long-lambda
- 2, state_is_tuple=True)
-
- cell = core_rnn_cell_impl.MultiRNNCell(
- cells=[single_cell() for _ in range(2)], state_is_tuple=True)
+ cell_fn = lambda: core_rnn_cell_impl.MultiRNNCell( # pylint: disable=g-long-lambda
+ cells=[core_rnn_cell_impl.BasicLSTMCell(2) for _ in range(2)])
+ cell = cell_fn()
inp = constant_op.constant(0.5, shape=[2, 2, 2])
enc_outputs, enc_state = core_rnn.static_rnn(
cell, inp, dtype=dtypes.float32)
@@ -447,8 +474,11 @@ class Seq2SeqTest(test.TestCase):
for e in enc_outputs
], 1)
dec_inp = [constant_op.constant(0.4, shape=[2, 2])] * 3
+
+ # Use a new cell instance since the attention decoder uses a
+ # different variable scope.
dec, mem = seq2seq_lib.attention_decoder(
- dec_inp, enc_state, attn_states, cell, output_size=4)
+ dec_inp, enc_state, attn_states, cell_fn(), output_size=4)
sess.run([variables.global_variables_initializer()])
res = sess.run(dec)
self.assertEqual(3, len(res))
@@ -466,7 +496,8 @@ class Seq2SeqTest(test.TestCase):
with variable_scope.variable_scope(
"root", initializer=init_ops.constant_initializer(0.5)):
inp = [constant_op.constant(0.5, shape=[2, 2])] * 2
- cell = core_rnn_cell_impl.GRUCell(2)
+ cell_fn = lambda: core_rnn_cell_impl.GRUCell(2)
+ cell = cell_fn()
enc_outputs, enc_state = core_rnn.static_rnn(
cell, inp, dtype=dtypes.float32)
attn_states = array_ops.concat([
@@ -476,11 +507,14 @@ class Seq2SeqTest(test.TestCase):
constant_op.constant(
i, dtypes.int32, shape=[2]) for i in range(3)
]
+
+ # Use a new cell instance since the attention decoder uses a
+ # different variable scope.
dec, mem = seq2seq_lib.embedding_attention_decoder(
dec_inp,
enc_state,
attn_states,
- cell,
+ cell_fn(),
num_symbols=4,
embedding_size=2,
output_size=3)
@@ -504,7 +538,8 @@ class Seq2SeqTest(test.TestCase):
constant_op.constant(
i, dtypes.int32, shape=[2]) for i in range(3)
]
- cell = core_rnn_cell_impl.BasicLSTMCell(2, state_is_tuple=True)
+ cell_fn = lambda: core_rnn_cell_impl.BasicLSTMCell(2)
+ cell = cell_fn()
dec, mem = seq2seq_lib.embedding_attention_seq2seq(
enc_inp,
dec_inp,
@@ -523,11 +558,14 @@ class Seq2SeqTest(test.TestCase):
# Test with state_is_tuple=False.
with variable_scope.variable_scope("no_tuple"):
- cell = core_rnn_cell_impl.BasicLSTMCell(2, state_is_tuple=False)
+ cell_fn = functools.partial(
+ core_rnn_cell_impl.BasicLSTMCell,
+ 2, state_is_tuple=False)
+ cell_nt = cell_fn()
dec, mem = seq2seq_lib.embedding_attention_seq2seq(
enc_inp,
dec_inp,
- cell,
+ cell_nt,
num_encoder_symbols=2,
num_decoder_symbols=5,
embedding_size=2)
@@ -546,7 +584,7 @@ class Seq2SeqTest(test.TestCase):
dec, _ = seq2seq_lib.embedding_attention_seq2seq(
enc_inp,
dec_inp,
- cell,
+ cell_fn(),
num_encoder_symbols=2,
num_decoder_symbols=5,
embedding_size=2,
@@ -556,43 +594,47 @@ class Seq2SeqTest(test.TestCase):
self.assertEqual(3, len(res))
self.assertEqual((2, 2), res[0].shape)
- # Test that previous-feeding model ignores inputs after the first.
- dec_inp2 = [
- constant_op.constant(
- 0, dtypes.int32, shape=[2]) for _ in range(3)
- ]
- with variable_scope.variable_scope("other"):
- d3, _ = seq2seq_lib.embedding_attention_seq2seq(
- enc_inp,
- dec_inp2,
- cell,
- num_encoder_symbols=2,
- num_decoder_symbols=5,
- embedding_size=2,
- feed_previous=constant_op.constant(True))
- sess.run([variables.global_variables_initializer()])
- variable_scope.get_variable_scope().reuse_variables()
- d1, _ = seq2seq_lib.embedding_attention_seq2seq(
- enc_inp,
- dec_inp,
- cell,
- num_encoder_symbols=2,
- num_decoder_symbols=5,
- embedding_size=2,
- feed_previous=True)
- d2, _ = seq2seq_lib.embedding_attention_seq2seq(
- enc_inp,
- dec_inp2,
- cell,
- num_encoder_symbols=2,
- num_decoder_symbols=5,
- embedding_size=2,
- feed_previous=True)
- res1 = sess.run(d1)
- res2 = sess.run(d2)
- res3 = sess.run(d3)
- self.assertAllClose(res1, res2)
- self.assertAllClose(res1, res3)
+ # TODO(ebrevdo, lukaszkaiser): Re-enable once RNNCells allow reuse
+ # within a variable scope that already has a weights tensor.
+ #
+ # # Test that previous-feeding model ignores inputs after the first.
+ # dec_inp2 = [
+ # constant_op.constant(
+ # 0, dtypes.int32, shape=[2]) for _ in range(3)
+ # ]
+ # with variable_scope.variable_scope("other"):
+ # d3, _ = seq2seq_lib.embedding_attention_seq2seq(
+ # enc_inp,
+ # dec_inp2,
+ # cell_fn(),
+ # num_encoder_symbols=2,
+ # num_decoder_symbols=5,
+ # embedding_size=2,
+ # feed_previous=constant_op.constant(True))
+ # sess.run([variables.global_variables_initializer()])
+ # variable_scope.get_variable_scope().reuse_variables()
+ # cell = cell_fn()
+ # d1, _ = seq2seq_lib.embedding_attention_seq2seq(
+ # enc_inp,
+ # dec_inp,
+ # cell,
+ # num_encoder_symbols=2,
+ # num_decoder_symbols=5,
+ # embedding_size=2,
+ # feed_previous=True)
+ # d2, _ = seq2seq_lib.embedding_attention_seq2seq(
+ # enc_inp,
+ # dec_inp2,
+ # cell,
+ # num_encoder_symbols=2,
+ # num_decoder_symbols=5,
+ # embedding_size=2,
+ # feed_previous=True)
+ # res1 = sess.run(d1)
+ # res2 = sess.run(d2)
+ # res3 = sess.run(d3)
+ # self.assertAllClose(res1, res2)
+ # self.assertAllClose(res1, res3)
def testOne2ManyRNNSeq2Seq(self):
with self.test_session() as sess:
@@ -734,61 +776,64 @@ class Seq2SeqTest(test.TestCase):
res = sess.run(loss_per_sequence)
self.assertAllClose(np.asarray([4.828314, 4.828314]), res)
- def testModelWithBucketsScopeAndLoss(self):
- """Test that variable scope reuse is not reset after model_with_buckets."""
- classes = 10
- buckets = [(4, 4), (8, 8)]
-
- with self.test_session():
- # Here comes a sample Seq2Seq model using GRU cells.
- def SampleGRUSeq2Seq(enc_inp, dec_inp, weights, per_example_loss):
- """Example sequence-to-sequence model that uses GRU cells."""
-
- def GRUSeq2Seq(enc_inp, dec_inp):
- cell = core_rnn_cell_impl.MultiRNNCell(
- [core_rnn_cell_impl.GRUCell(24) for _ in range(2)],
- state_is_tuple=True)
- return seq2seq_lib.embedding_attention_seq2seq(
- enc_inp,
- dec_inp,
- cell,
- num_encoder_symbols=classes,
- num_decoder_symbols=classes,
- embedding_size=24)
-
- targets = [dec_inp[i + 1] for i in range(len(dec_inp) - 1)] + [0]
- return seq2seq_lib.model_with_buckets(
- enc_inp,
- dec_inp,
- targets,
- weights,
- buckets,
- GRUSeq2Seq,
- per_example_loss=per_example_loss)
-
- # Now we construct the copy model.
- inp = [
- array_ops.placeholder(
- dtypes.int32, shape=[None]) for _ in range(8)
- ]
- out = [
- array_ops.placeholder(
- dtypes.int32, shape=[None]) for _ in range(8)
- ]
- weights = [
- array_ops.ones_like(
- inp[0], dtype=dtypes.float32) for _ in range(8)
- ]
- with variable_scope.variable_scope("root"):
- _, losses1 = SampleGRUSeq2Seq(inp, out, weights, per_example_loss=False)
- # Now check that we did not accidentally set reuse.
- self.assertEqual(False, variable_scope.get_variable_scope().reuse)
- # Construct one more model with per-example loss.
- variable_scope.get_variable_scope().reuse_variables()
- _, losses2 = SampleGRUSeq2Seq(inp, out, weights, per_example_loss=True)
- # First loss is scalar, the second one is a 1-dimensinal tensor.
- self.assertEqual([], losses1[0].get_shape().as_list())
- self.assertEqual([None], losses2[0].get_shape().as_list())
+ # TODO(ebrevdo, lukaszkaiser): Re-enable once RNNCells allow reuse
+ # within a variable scope that already has a weights tensor.
+ #
+ # def testModelWithBucketsScopeAndLoss(self):
+ # """Test variable scope reuse is not reset after model_with_buckets."""
+ # classes = 10
+ # buckets = [(4, 4), (8, 8)]
+
+ # with self.test_session():
+ # # Here comes a sample Seq2Seq model using GRU cells.
+ # def SampleGRUSeq2Seq(enc_inp, dec_inp, weights, per_example_loss):
+ # """Example sequence-to-sequence model that uses GRU cells."""
+
+ # def GRUSeq2Seq(enc_inp, dec_inp):
+ # cell = core_rnn_cell_impl.MultiRNNCell(
+ # [core_rnn_cell_impl.GRUCell(24) for _ in range(2)])
+ # return seq2seq_lib.embedding_attention_seq2seq(
+ # enc_inp,
+ # dec_inp,
+ # cell,
+ # num_encoder_symbols=classes,
+ # num_decoder_symbols=classes,
+ # embedding_size=24)
+
+ # targets = [dec_inp[i + 1] for i in range(len(dec_inp) - 1)] + [0]
+ # return seq2seq_lib.model_with_buckets(
+ # enc_inp,
+ # dec_inp,
+ # targets,
+ # weights,
+ # buckets,
+ # GRUSeq2Seq,
+ # per_example_loss=per_example_loss)
+
+ # # Now we construct the copy model.
+ # inp = [
+ # array_ops.placeholder(
+ # dtypes.int32, shape=[None]) for _ in range(8)
+ # ]
+ # out = [
+ # array_ops.placeholder(
+ # dtypes.int32, shape=[None]) for _ in range(8)
+ # ]
+ # weights = [
+ # array_ops.ones_like(
+ # inp[0], dtype=dtypes.float32) for _ in range(8)
+ # ]
+ # with variable_scope.variable_scope("root"):
+ # _, losses1 = SampleGRUSeq2Seq(
+ # inp, out, weights, per_example_loss=False)
+ # # Now check that we did not accidentally set reuse.
+ # self.assertEqual(False, variable_scope.get_variable_scope().reuse)
+ # with variable_scope.variable_scope("new"):
+ # _, losses2 = SampleGRUSeq2Seq
+ # inp, out, weights, per_example_loss=True)
+ # # First loss is scalar, the second one is a 1-dimensinal tensor.
+ # self.assertEqual([], losses1[0].get_shape().as_list())
+ # self.assertEqual([None], losses2[0].get_shape().as_list())
def testModelWithBuckets(self):
"""Larger tests that does full sequence-to-sequence model training."""
diff --git a/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in b/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in
index 986150cb3f..201edbf5b4 100644
--- a/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in
+++ b/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in
@@ -43,11 +43,20 @@ CXXFLAGS += -DTENSORFLOW_DISABLE_META
# Declare __ANDROID_TYPES_FULL__ to enable required types for hvx
CXXFLAGS += -D__ANDROID_TYPES_FULL__
-GRAPH_EXECUTION_SRCS := \
+GRAPH_TRANSFER_SRCS := \
+tensorflow/cc/framework/scope.cc \
+tensorflow/cc/framework/ops.cc \
+tensorflow/cc/ops/const_op.cc \
tensorflow/core/kernels/hexagon/graph_transfer_utils.cc \
tensorflow/core/kernels/hexagon/graph_transferer.cc \
tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc \
tensorflow/core/kernels/hexagon/hexagon_ops_definitions.cc \
+tensorflow/core/kernels/remote_fused_graph_execute_op.cc \
+tensorflow/core/ops/remote_fused_graph_ops.cc \
+tensorflow/core/platform/posix/test.cc
+
+GRAPH_EXECUTION_SRCS := \
+$(GRAPH_TRANSFER_SRCS) \
tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc \
tensorflow/contrib/makefile/test/test_main.cc
diff --git a/tensorflow/contrib/makefile/sub_makefiles/quantization/Makefile.in b/tensorflow/contrib/makefile/sub_makefiles/quantization/Makefile.in
index ef41913663..bc7a238fdb 100644
--- a/tensorflow/contrib/makefile/sub_makefiles/quantization/Makefile.in
+++ b/tensorflow/contrib/makefile/sub_makefiles/quantization/Makefile.in
@@ -40,8 +40,23 @@ $(GTEST_HEADERS)
# TODO(satok): Remove once it's fixed
CXXFLAGS += -DTENSORFLOW_DISABLE_META
+GRAPH_TRANSFER_SRCS := \
+tensorflow/cc/framework/scope.cc \
+tensorflow/cc/framework/ops.cc \
+tensorflow/cc/ops/const_op.cc \
+tensorflow/core/kernels/hexagon/graph_transfer_utils.cc \
+tensorflow/core/kernels/hexagon/graph_transferer.cc \
+tensorflow/core/kernels/hexagon/graph_transferer_test.cc \
+tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc \
+tensorflow/core/kernels/hexagon/hexagon_ops_definitions.cc \
+tensorflow/core/kernels/remote_fused_graph_execute_op.cc \
+tensorflow/core/ops/remote_fused_graph_ops.cc \
+tensorflow/core/platform/posix/test.cc
+
QUANTIZATION_TEST_SRCS := \
+$(GRAPH_TRANSFER_SRCS) \
tensorflow/core/kernels/hexagon/quantized_matmul_op_for_hexagon_test.cc \
+tensorflow/core/kernels/hexagon/graph_transferer_test.cc \
tensorflow/contrib/makefile/test/test_main.cc
QUANTIZATION_TEST_OBJS := $(addprefix $(OBJDIR), $(QUANTIZATION_TEST_SRCS:.cc=.o))
diff --git a/tensorflow/contrib/slim/python/slim/data/dataset_data_provider.py b/tensorflow/contrib/slim/python/slim/data/dataset_data_provider.py
index 542b3bfcd5..f1b425aab7 100644
--- a/tensorflow/contrib/slim/python/slim/data/dataset_data_provider.py
+++ b/tensorflow/contrib/slim/python/slim/data/dataset_data_provider.py
@@ -58,6 +58,7 @@ class DatasetDataProvider(data_provider.DataProvider):
num_epochs=None,
common_queue_capacity=256,
common_queue_min=128,
+ record_key='record_key',
seed=None):
"""Creates a DatasetDataProvider.
@@ -72,9 +73,13 @@ class DatasetDataProvider(data_provider.DataProvider):
common_queue_capacity: The capacity of the common queue.
common_queue_min: The minimum number of elements in the common queue after
a dequeue.
+ record_key: The item name to use for the dataset record keys in the
+ provided tensors.
seed: The seed to use if shuffling.
+ Raises:
+ ValueError: If `record_key` matches one of the items in the dataset.
"""
- _, data = parallel_reader.parallel_read(
+ key, data = parallel_reader.parallel_read(
dataset.data_sources,
reader_class=dataset.reader,
num_epochs=num_epochs,
@@ -88,6 +93,12 @@ class DatasetDataProvider(data_provider.DataProvider):
items = dataset.decoder.list_items()
tensors = dataset.decoder.decode(data, items)
+ if record_key in items:
+ raise ValueError('The item name used for `record_key` cannot also be '
+ 'used for a dataset item: %s', record_key)
+ items.append(record_key)
+ tensors.append(key)
+
super(DatasetDataProvider, self).__init__(
items_to_tensors=dict(zip(items, tensors)),
num_samples=dataset.num_samples)
diff --git a/tensorflow/contrib/slim/python/slim/data/dataset_data_provider_test.py b/tensorflow/contrib/slim/python/slim/data/dataset_data_provider_test.py
index 01fbf2c6b4..b1a89fe5aa 100644
--- a/tensorflow/contrib/slim/python/slim/data/dataset_data_provider_test.py
+++ b/tensorflow/contrib/slim/python/slim/data/dataset_data_provider_test.py
@@ -89,14 +89,18 @@ class DatasetDataProviderTest(test.TestCase):
width = 280
with self.test_session():
- provider = dataset_data_provider.DatasetDataProvider(
- _create_tfrecord_dataset(dataset_dir))
- image, label = provider.get(['image', 'label'])
+ test_dataset = _create_tfrecord_dataset(dataset_dir)
+ provider = dataset_data_provider.DatasetDataProvider(test_dataset)
+ key, image, label = provider.get(['record_key', 'image', 'label'])
image = _resize_image(image, height, width)
with session.Session('') as sess:
with queues.QueueRunners(sess):
- image, label = sess.run([image, label])
+ key, image, label = sess.run([key, image, label])
+ split_key = key.split(':')
+ self.assertEqual(2, len(split_key))
+ self.assertEqual(test_dataset.data_sources[0], split_key[0])
+ self.assertTrue(split_key[1].isdigit())
self.assertListEqual([height, width, 3], list(image.shape))
self.assertListEqual([1], list(label.shape))
@@ -120,6 +124,14 @@ class DatasetDataProviderTest(test.TestCase):
self.assertListEqual([height, width, 3], list(image.shape))
self.assertListEqual([1], list(label.shape))
+ def testConflictingRecordKeyItem(self):
+ dataset_dir = tempfile.mkdtemp(prefix=os.path.join(self.get_temp_dir(),
+ 'tfrecord_dataset'))
+
+ with self.test_session():
+ with self.assertRaises(ValueError):
+ dataset_data_provider.DatasetDataProvider(
+ _create_tfrecord_dataset(dataset_dir), record_key='image')
if __name__ == '__main__':
test.main()
diff --git a/tensorflow/contrib/sparsemax/BUILD b/tensorflow/contrib/sparsemax/BUILD
index bd59c626f2..7441f1429f 100644
--- a/tensorflow/contrib/sparsemax/BUILD
+++ b/tensorflow/contrib/sparsemax/BUILD
@@ -27,6 +27,7 @@ py_library(
deps = [
"//tensorflow/contrib/util:util_py",
"//tensorflow/python:array_ops",
+ "//tensorflow/python:framework",
"//tensorflow/python:framework_for_generated_wrappers",
"//tensorflow/python:math_ops",
"//tensorflow/python:nn",
diff --git a/tensorflow/contrib/sparsemax/__init__.py b/tensorflow/contrib/sparsemax/__init__.py
index 0be4988dbf..19d213fb3e 100644
--- a/tensorflow/contrib/sparsemax/__init__.py
+++ b/tensorflow/contrib/sparsemax/__init__.py
@@ -28,3 +28,8 @@ from __future__ import print_function
from tensorflow.contrib.sparsemax.python.ops.sparsemax import sparsemax
from tensorflow.contrib.sparsemax.python.ops.sparsemax_loss \
import sparsemax_loss
+from tensorflow.python.util.all_util import remove_undocumented
+
+_allowed_symbols = ['sparsemax', 'sparsemax_loss']
+
+remove_undocumented(__name__, _allowed_symbols)
diff --git a/tensorflow/contrib/sparsemax/python/ops/sparsemax.py b/tensorflow/contrib/sparsemax/python/ops/sparsemax.py
index 6e1cd75f22..73a5cf1e92 100644
--- a/tensorflow/contrib/sparsemax/python/ops/sparsemax.py
+++ b/tensorflow/contrib/sparsemax/python/ops/sparsemax.py
@@ -13,16 +13,19 @@
# limitations under the License.
# ==============================================================================
"""Sparsemax op."""
+
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.util import loader
-from tensorflow.python.platform import resource_loader
-from tensorflow.python.framework import ops, dtypes
-from tensorflow.python.ops import math_ops
+from tensorflow.python.framework import dtypes
+from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops
+from tensorflow.python.ops import math_ops
from tensorflow.python.ops import nn
+from tensorflow.python.platform import resource_loader
+
+__all__ = ["sparsemax"]
def sparsemax(logits, name=None):
@@ -55,8 +58,7 @@ def sparsemax(logits, name=None):
# calculate k(z)
z_cumsum = math_ops.cumsum(z_sorted, axis=1)
k = math_ops.range(
- 1, math_ops.cast(dims, logits.dtype) + 1, dtype=logits.dtype
- )
+ 1, math_ops.cast(dims, logits.dtype) + 1, dtype=logits.dtype)
z_check = 1 + k * z_sorted > z_cumsum
# because the z_check vector is always [1,1,...1,0,0,...0] finding the
# (index + 1) of the last `1` is the same as just summing the number of 1.
@@ -69,6 +71,4 @@ def sparsemax(logits, name=None):
# calculate p
return math_ops.maximum(
- math_ops.cast(0, logits.dtype),
- z - tau_z[:, array_ops.newaxis]
- )
+ math_ops.cast(0, logits.dtype), z - tau_z[:, array_ops.newaxis])
diff --git a/tensorflow/contrib/sparsemax/python/ops/sparsemax_loss.py b/tensorflow/contrib/sparsemax/python/ops/sparsemax_loss.py
index 1f5e8c37e3..ba18f89e16 100644
--- a/tensorflow/contrib/sparsemax/python/ops/sparsemax_loss.py
+++ b/tensorflow/contrib/sparsemax/python/ops/sparsemax_loss.py
@@ -13,6 +13,7 @@
# limitations under the License.
# ==============================================================================
"""Sparsemax Loss op."""
+
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -23,6 +24,8 @@ from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import math_ops
+__all__ = ["sparsemax_loss"]
+
def sparsemax_loss(logits, sparsemax, labels, name=None):
"""Computes sparsemax loss function [1].
diff --git a/tensorflow/core/BUILD b/tensorflow/core/BUILD
index 0d3279874b..89b64a2d8d 100644
--- a/tensorflow/core/BUILD
+++ b/tensorflow/core/BUILD
@@ -113,7 +113,7 @@ load(
"tf_cuda_tests_tags",
)
load(
- "//third_party/mkl:build_defs.bzl",
+ "//tensorflow/third_party/mkl:build_defs.bzl",
"if_mkl",
)
# -----------------------------------------------------------------------------
@@ -184,6 +184,14 @@ tf_proto_library(
visibility = ["//visibility:public"],
)
+tf_proto_library(
+ name = "protos_test",
+ srcs = ["util/example_proto_fast_parsing_test.proto"],
+ cc_api_version = 2,
+ protodeps = [":protos_all"],
+ visibility = ["//visibility:public"],
+)
+
# Minimal lib so that tools used for mobile compilation
# don't have to depend on lib/platformlib.
cc_library(
@@ -639,6 +647,7 @@ cc_library(
"//tensorflow/core/kernels:parameterized_truncated_normal_op",
"//tensorflow/core/kernels:parsing",
"//tensorflow/core/kernels:random_ops",
+ "//tensorflow/core/kernels:random_poisson_op",
"//tensorflow/core/kernels:remote_fused_graph_ops",
"//tensorflow/core/kernels:required",
"//tensorflow/core/kernels:resource_variable_ops",
@@ -1854,6 +1863,7 @@ tf_cc_tests(
":lib_internal",
":ops",
":protos_all_cc",
+ ":protos_test_cc",
":test",
":test_main",
":testlib",
diff --git a/tensorflow/core/common_runtime/debugger_state_interface.h b/tensorflow/core/common_runtime/debugger_state_interface.h
index a4ff6b74fc..fb72f9fa3e 100644
--- a/tensorflow/core/common_runtime/debugger_state_interface.h
+++ b/tensorflow/core/common_runtime/debugger_state_interface.h
@@ -39,6 +39,24 @@ class DebuggerStateInterface {
// record. See the documentation of DebugNodeInserter::InsertNodes() for
// details.
virtual Status DecorateGraphForDebug(Graph* graph, Device* device) = 0;
+
+ // Publish metadata about the debugged Session::Run() call.
+ //
+ // Args:
+ // global_step: A global step count supplied by the caller of
+ // Session::Run().
+ // session_run_count: A counter for calls to the Run() method of the
+ // Session object.
+ // executor_step_count: A counter for invocations of the executor charged
+ // to serve this Session::Run() call.
+ // input_names: Name of the input Tensors (feed keys).
+ // output_names: Names of the fetched Tensors.
+ // target_names: Names of the target nodes.
+ virtual Status PublishDebugMetadata(
+ const int64 global_step, const int64 session_run_count,
+ const int64 executor_step_count, const std::vector<string>& input_names,
+ const std::vector<string>& output_names,
+ const std::vector<string>& target_nodes) = 0;
};
typedef std::function<std::unique_ptr<DebuggerStateInterface>(
diff --git a/tensorflow/core/common_runtime/direct_session.cc b/tensorflow/core/common_runtime/direct_session.cc
index 953c4180fd..f00f5ffd8f 100644
--- a/tensorflow/core/common_runtime/direct_session.cc
+++ b/tensorflow/core/common_runtime/direct_session.cc
@@ -397,6 +397,9 @@ Status DirectSession::Run(const RunOptions& run_options,
ExecutorsAndKeys* executors_and_keys;
RunStateArgs run_state_args;
+ Executor::Args args;
+ args.step_id = step_id_counter_.fetch_add(1);
+
// EXPERIMENTAL: Options that allow the client to insert nodes into partition
// graphs for debugging.
if (!run_options.debug_options().debug_tensor_watch_opts().empty()) {
@@ -407,10 +410,15 @@ Status DirectSession::Run(const RunOptions& run_options,
TF_RETURN_IF_ERROR(
GetOrCreateExecutors(pool, input_tensor_names, output_names, target_nodes,
&executors_and_keys, &run_state_args));
+ const int64 executor_step_count = executors_and_keys->step_count.fetch_add(1);
+
+ if (run_state_args.debugger_state) {
+ TF_RETURN_IF_ERROR(run_state_args.debugger_state->PublishDebugMetadata(
+ run_options.debug_options().global_step(), args.step_id,
+ executor_step_count, input_tensor_names, output_names, target_nodes));
+ }
// Create a run state and start execution.
- Executor::Args args;
- args.step_id = step_id_counter_.fetch_add(1);
RunState run_state(args.step_id, &devices_);
run_state.rendez = new IntraProcessRendezvous(device_mgr_.get());
CancellationManager step_cancellation_manager;
@@ -450,8 +458,7 @@ Status DirectSession::Run(const RunOptions& run_options,
options_.config.graph_options().build_cost_model();
const int64 build_cost_model_after =
options_.config.graph_options().build_cost_model_after();
- int measure_step_count =
- executors_and_keys->step_count - build_cost_model_after;
+ int measure_step_count = executor_step_count - build_cost_model_after;
if (measure_step_count >= 0) {
update_cost_model =
((measure_step_count + 1) % build_cost_model_every == 0);
@@ -527,7 +534,6 @@ Status DirectSession::Run(const RunOptions& run_options,
// Build and return the cost model as instructed.
mutex_lock l(executor_lock_);
- ++executors_and_keys->step_count;
if (update_cost_model) {
// Build the cost model
std::unordered_map<string, const Graph*> device_to_graph;
diff --git a/tensorflow/core/common_runtime/direct_session.h b/tensorflow/core/common_runtime/direct_session.h
index ff4786f998..3e3a5eaa8f 100644
--- a/tensorflow/core/common_runtime/direct_session.h
+++ b/tensorflow/core/common_runtime/direct_session.h
@@ -125,7 +125,9 @@ class DirectSession : public Session {
// library. Consider giving each partition its own function library to enable
// per-partition rewrites.
struct ExecutorsAndKeys {
- int64 step_count = 0;
+ ExecutorsAndKeys() : step_count(0) {}
+
+ std::atomic_int_fast64_t step_count;
std::unique_ptr<Graph> graph;
NameNodeMap name_to_node;
std::unique_ptr<FunctionLibraryDefinition> flib_def;
diff --git a/tensorflow/core/common_runtime/pending_counts.h b/tensorflow/core/common_runtime/pending_counts.h
index 0ab5311c5f..f0c79ad601 100644
--- a/tensorflow/core/common_runtime/pending_counts.h
+++ b/tensorflow/core/common_runtime/pending_counts.h
@@ -305,8 +305,8 @@ class PendingCounts {
void operator=(const PendingCounts&) = delete;
};
-PendingCounts::Handle PendingCounts::Layout::CreateHandle(int max_pending_count,
- int max_dead_count) {
+inline PendingCounts::Handle PendingCounts::Layout::CreateHandle(
+ int max_pending_count, int max_dead_count) {
Handle result;
if ((max_pending_count > kMaxCountForPackedCounts) ||
(max_dead_count > kMaxCountForPackedCounts)) {
diff --git a/tensorflow/core/common_runtime/step_stats_collector.cc b/tensorflow/core/common_runtime/step_stats_collector.cc
index 57466fa918..e60f77de0f 100644
--- a/tensorflow/core/common_runtime/step_stats_collector.cc
+++ b/tensorflow/core/common_runtime/step_stats_collector.cc
@@ -186,6 +186,7 @@ void StepStatsCollector::BuildCostModel(
.allocation_description()
.allocation_id());
}
+ cm->RecordAllocatorMemory(node, stats.memory());
// Use hardware stats to record the execution time if they're available,
// otherwise use the regular (less accurate) stats
string node_name = dev_stats.regular_stats->node_stats(i).node_name();
diff --git a/tensorflow/core/debug/debug_graph_utils.cc b/tensorflow/core/debug/debug_graph_utils.cc
index 06c129ecc8..217022759b 100644
--- a/tensorflow/core/debug/debug_graph_utils.cc
+++ b/tensorflow/core/debug/debug_graph_utils.cc
@@ -75,6 +75,16 @@ Status DebuggerState::DecorateGraphForDebug(Graph* graph, Device* device) {
return status;
}
+Status DebuggerState::PublishDebugMetadata(
+ const int64 global_step, const int64 session_run_count,
+ const int64 executor_step_count, const std::vector<string>& input_names,
+ const std::vector<string>& output_names,
+ const std::vector<string>& target_nodes) {
+ return DebugIO::PublishDebugMetadata(global_step, session_run_count,
+ executor_step_count, input_names,
+ output_names, target_nodes, debug_urls_);
+}
+
// static
Status DebugNodeInserter::InsertNodes(
const protobuf::RepeatedPtrField<DebugTensorWatch>& watches, Graph* graph,
diff --git a/tensorflow/core/debug/debug_graph_utils.h b/tensorflow/core/debug/debug_graph_utils.h
index cda2c31f0c..6edd26c260 100644
--- a/tensorflow/core/debug/debug_graph_utils.h
+++ b/tensorflow/core/debug/debug_graph_utils.h
@@ -43,6 +43,17 @@ class DebuggerState : public DebuggerStateInterface {
const protobuf::RepeatedPtrField<DebugTensorWatch>& watches;
+ // Publish metadata about the debugged Session::Run() call.
+ //
+ // See the doc string of DebuggerStateInterface::PublishDebugMetadata() for
+ // details.
+ Status PublishDebugMetadata(const int64 global_step,
+ const int64 session_run_count,
+ const int64 executor_step_count,
+ const std::vector<string>& input_names,
+ const std::vector<string>& output_names,
+ const std::vector<string>& target_names);
+
private:
std::unordered_set<string> debug_urls_;
};
diff --git a/tensorflow/core/debug/debug_grpc_io_utils_test.cc b/tensorflow/core/debug/debug_grpc_io_utils_test.cc
index acf1224be1..bb79528cc1 100644
--- a/tensorflow/core/debug/debug_grpc_io_utils_test.cc
+++ b/tensorflow/core/debug/debug_grpc_io_utils_test.cc
@@ -80,10 +80,10 @@ TEST_F(GrpcDebugTest, AttemptToSendToNonexistentGrpcAddress) {
"foo_tensor", "DebugIdentity", tensor, Env::Default()->NowMicros(),
{kInvalidGrpcUrl});
ASSERT_FALSE(publish_status.ok());
- ASSERT_NE(
- string::npos,
- publish_status.error_message().find(
- "Channel at the following gRPC address is not ready: 0.0.0.0:0"));
+ ASSERT_NE(string::npos,
+ publish_status.error_message().find(
+ "Channel at the following gRPC stream URL is not ready: "
+ "grpc://0.0.0.0:0"));
DebugIO::CloseDebugURL(kInvalidGrpcUrl);
}
diff --git a/tensorflow/core/debug/debug_io_utils.cc b/tensorflow/core/debug/debug_io_utils.cc
index 7819600765..f4136dcaba 100644
--- a/tensorflow/core/debug/debug_io_utils.cc
+++ b/tensorflow/core/debug/debug_io_utils.cc
@@ -99,6 +99,83 @@ const char* const DebugIO::kFileURLScheme = "file://";
const char* const DebugIO::kGrpcURLScheme = "grpc://";
// static
+Status DebugIO::PublishDebugMetadata(
+ const int64 global_step, const int64 session_run_count,
+ const int64 executor_step_count, const std::vector<string>& input_names,
+ const std::vector<string>& output_names,
+ const std::vector<string>& target_nodes,
+ const std::unordered_set<string>& debug_urls) {
+ std::ostringstream oss;
+
+ // Construct a JSON string to carry the metadata.
+ oss << "{";
+ oss << "\"global_step\":" << global_step << ",";
+ oss << "\"session_run_count\":" << session_run_count << ",";
+ oss << "\"executor_step_count\":" << executor_step_count << ",";
+ oss << "\"input_names\":[";
+ for (size_t i = 0; i < input_names.size(); ++i) {
+ oss << "\"" << input_names[i] << "\"";
+ if (i < input_names.size() - 1) {
+ oss << ",";
+ }
+ }
+ oss << "],";
+ oss << "\"output_names\":[";
+ for (size_t i = 0; i < output_names.size(); ++i) {
+ oss << "\"" << output_names[i] << "\"";
+ if (i < output_names.size() - 1) {
+ oss << ",";
+ }
+ }
+ oss << "],";
+ oss << "\"target_nodes\":[";
+ for (size_t i = 0; i < target_nodes.size(); ++i) {
+ oss << "\"" << target_nodes[i] << "\"";
+ if (i < target_nodes.size() - 1) {
+ oss << ",";
+ }
+ }
+ oss << "]";
+ oss << "}";
+
+ const string json_metadata = oss.str();
+ Event event;
+ event.set_wall_time(static_cast<double>(Env::Default()->NowMicros()));
+ LogMessage* log_message = event.mutable_log_message();
+ log_message->set_message(json_metadata);
+
+ Status status;
+ for (const string& url : debug_urls) {
+ if (str_util::Lowercase(url).find(kGrpcURLScheme) == 0) {
+ Event grpc_event;
+
+ // Determine the path (if any) in the grpc:// URL, and add it as a field
+ // of the JSON string.
+ const string address = url.substr(strlen(DebugIO::kFileURLScheme));
+ const string path = address.find("/") == string::npos
+ ? ""
+ : address.substr(address.find("/"));
+ grpc_event.set_wall_time(event.wall_time());
+ LogMessage* log_message_grpc = grpc_event.mutable_log_message();
+ log_message_grpc->set_message(
+ strings::StrCat(json_metadata.substr(0, json_metadata.size() - 1),
+ ",\"grpc_path\":\"", path, "\"}"));
+
+ status.Update(
+ DebugGrpcIO::SendEventProtoThroughGrpcStream(grpc_event, url));
+ } else if (str_util::Lowercase(url).find(kFileURLScheme) == 0) {
+ const string dump_root_dir = url.substr(strlen(kFileURLScheme));
+ const string file_name =
+ strings::StrCat("_tfdbg_core_metadata_", Env::Default()->NowMicros());
+ status.Update(
+ DebugFileIO::DumpEventProtoToFile(event, dump_root_dir, file_name));
+ }
+ }
+
+ return status;
+}
+
+// static
Status DebugIO::PublishDebugTensor(const string& tensor_name,
const string& debug_op, const Tensor& tensor,
const uint64 wall_time_us,
@@ -136,10 +213,8 @@ Status DebugIO::PublishDebugTensor(const string& tensor_name,
fail_statuses.push_back(s);
}
} else if (str_util::Lowercase(url).find(kGrpcURLScheme) == 0) {
- const string grpc_server_stream_addr = url.substr(strlen(kGrpcURLScheme));
Status s = DebugGrpcIO::SendTensorThroughGrpcStream(
- node_name, output_slot, debug_op, tensor, wall_time_us,
- grpc_server_stream_addr);
+ node_name, output_slot, debug_op, tensor, wall_time_us, url);
if (!s.ok()) {
num_failed_urls++;
@@ -189,8 +264,7 @@ Status DebugIO::PublishGraph(const Graph& graph,
status.Update(
DebugFileIO::DumpEventProtoToFile(event, dump_root_dir, file_name));
} else if (debug_url.find(kGrpcURLScheme) == 0) {
- DebugGrpcIO::SendEventProtoThroughGrpcStream(
- event, debug_url.substr(strlen(kGrpcURLScheme)));
+ DebugGrpcIO::SendEventProtoThroughGrpcStream(event, debug_url);
}
}
@@ -200,8 +274,7 @@ Status DebugIO::PublishGraph(const Graph& graph,
// static
Status DebugIO::CloseDebugURL(const string& debug_url) {
if (debug_url.find(DebugIO::kGrpcURLScheme) == 0) {
- return DebugGrpcIO::CloseGrpcStream(
- debug_url.substr(strlen(DebugIO::kGrpcURLScheme)));
+ return DebugGrpcIO::CloseGrpcStream(debug_url);
} else {
// No-op for non-gRPC URLs.
return Status::OK();
@@ -348,57 +421,64 @@ std::unordered_map<string, std::shared_ptr<DebugGrpcChannel>>
DebugGrpcIO::stream_channels;
// static
-Status DebugGrpcIO::SendTensorThroughGrpcStream(
- const string& node_name, const int32 output_slot, const string& debug_op,
- const Tensor& tensor, const uint64 wall_time_us,
- const string& server_stream_addr) {
+Status DebugGrpcIO::SendTensorThroughGrpcStream(const string& node_name,
+ const int32 output_slot,
+ const string& debug_op,
+ const Tensor& tensor,
+ const uint64 wall_time_us,
+ const string& grpc_stream_url) {
const string tensor_name = strings::StrCat(node_name, ":", output_slot);
// Prepare tensor Event data to be sent.
Event event = WrapTensorAsEvent(tensor_name, debug_op, tensor, wall_time_us);
- return SendEventProtoThroughGrpcStream(event, server_stream_addr);
+ return SendEventProtoThroughGrpcStream(event, grpc_stream_url);
}
// static
Status DebugGrpcIO::SendEventProtoThroughGrpcStream(
- const Event& event_proto, const string& server_stream_addr) {
+ const Event& event_proto, const string& grpc_stream_url) {
+ const string addr_with_path =
+ grpc_stream_url.substr(strlen(DebugIO::kFileURLScheme));
+ const string server_stream_addr =
+ addr_with_path.substr(0, addr_with_path.find('/'));
+
std::shared_ptr<DebugGrpcChannel> debug_grpc_channel;
{
mutex_lock l(streams_mu);
- if (stream_channels.find(server_stream_addr) == stream_channels.end()) {
+ if (stream_channels.find(grpc_stream_url) == stream_channels.end()) {
debug_grpc_channel.reset(new DebugGrpcChannel(server_stream_addr));
if (!debug_grpc_channel->is_channel_ready()) {
return errors::FailedPrecondition(
- strings::StrCat("Channel at the following gRPC address is ",
- "not ready: ", server_stream_addr));
+ strings::StrCat("Channel at the following gRPC stream URL is ",
+ "not ready: ", grpc_stream_url));
}
- stream_channels[server_stream_addr] = debug_grpc_channel;
+ stream_channels[grpc_stream_url] = debug_grpc_channel;
} else {
- debug_grpc_channel = stream_channels[server_stream_addr];
+ debug_grpc_channel = stream_channels[grpc_stream_url];
}
}
bool write_ok = debug_grpc_channel->WriteEvent(event_proto);
if (!write_ok) {
return errors::Cancelled(strings::StrCat("Write event to stream URL ",
- server_stream_addr, "failed."));
+ grpc_stream_url, "failed."));
}
return Status::OK();
}
-Status DebugGrpcIO::CloseGrpcStream(const string& server_stream_addr) {
+Status DebugGrpcIO::CloseGrpcStream(const string& grpc_stream_url) {
mutex_lock l(streams_mu);
- if (stream_channels.find(server_stream_addr) != stream_channels.end()) {
+ if (stream_channels.find(grpc_stream_url) != stream_channels.end()) {
// Stream of the specified address exists. Close it and remove it from
// record.
Status s;
- s = stream_channels[server_stream_addr]->Close();
- stream_channels.erase(server_stream_addr);
+ s = stream_channels[grpc_stream_url]->Close();
+ stream_channels.erase(grpc_stream_url);
return s;
} else {
// Stream of the specified address does not exist. No action.
diff --git a/tensorflow/core/debug/debug_io_utils.h b/tensorflow/core/debug/debug_io_utils.h
index a10e24386a..a12bea6dbc 100644
--- a/tensorflow/core/debug/debug_io_utils.h
+++ b/tensorflow/core/debug/debug_io_utils.h
@@ -32,6 +32,13 @@ Status ReadEventFromFile(const string& dump_file_path, Event* event);
class DebugIO {
public:
+ static Status PublishDebugMetadata(
+ const int64 global_step, const int64 session_run_count,
+ const int64 executor_step_count, const std::vector<string>& input_names,
+ const std::vector<string>& output_names,
+ const std::vector<string>& target_nodes,
+ const std::unordered_set<string>& debug_urls);
+
// Publish a tensor to a debug target URL.
//
// Args:
@@ -59,7 +66,6 @@ class DebugIO {
static Status CloseDebugURL(const string& debug_url);
- private:
static const char* const kFileURLScheme;
static const char* const kGrpcURLScheme;
};
@@ -172,18 +178,18 @@ class DebugGrpcIO {
const string& debug_op,
const Tensor& tensor,
const uint64 wall_time_us,
- const string& server_stream_addr);
+ const string& grpc_stream_url);
// Send an Event proto through a debug gRPC stream.
// Thread-safety: Safe with respect to other calls to the same method and
// calls to CloseGrpcStream().
- static Status SendEventProtoThroughGrpcStream(
- const Event& event_proto, const string& server_stream_addr);
+ static Status SendEventProtoThroughGrpcStream(const Event& event_proto,
+ const string& grpc_stream_url);
// Close a gRPC stream to the given address, if it exists.
// Thread-safety: Safe with respect to other calls to the same method and
// calls to SendTensorThroughGrpcStream().
- static Status CloseGrpcStream(const string& server_stream_addr);
+ static Status CloseGrpcStream(const string& grpc_stream_url);
private:
static mutex streams_mu;
diff --git a/tensorflow/core/framework/cost_graph.proto b/tensorflow/core/framework/cost_graph.proto
index 2f83765e2e..dfd4e5b327 100644
--- a/tensorflow/core/framework/cost_graph.proto
+++ b/tensorflow/core/framework/cost_graph.proto
@@ -45,6 +45,11 @@ message CostGraphDef {
// Temporary memory used by this node.
int64 temporary_memory_size = 6;
+ int64 host_peak_memory_size = 10;
+ int64 device_peak_memory_size = 11;
+ int64 persisted_memory_size = 12;
+ int64 auxiliary_memory_size = 13;
+
// Estimate of the computational cost of this node, in microseconds.
int64 compute_cost = 9;
diff --git a/tensorflow/core/framework/tensor_util.cc b/tensorflow/core/framework/tensor_util.cc
index ecf51e22b1..6d9ae6a350 100644
--- a/tensorflow/core/framework/tensor_util.cc
+++ b/tensorflow/core/framework/tensor_util.cc
@@ -25,14 +25,16 @@ namespace tensor {
Tensor DeepCopy(const Tensor& other) {
Tensor tmp = Tensor(other.dtype(), other.shape());
if (DataTypeCanUseMemcpy(other.dtype())) {
- StringPiece other_data = other.tensor_data();
-
- // We use StringPiece as a convenient map over the tensor buffer,
- // but we cast the type to get to the underlying buffer to do the
- // copy.
- StringPiece tmp_data = tmp.tensor_data();
- memcpy(const_cast<char*>(tmp_data.data()), other_data.data(),
- other_data.size());
+ if (other.NumElements() > 0) {
+ StringPiece other_data = other.tensor_data();
+
+ // We use StringPiece as a convenient map over the tensor buffer,
+ // but we cast the type to get to the underlying buffer to do the
+ // copy.
+ StringPiece tmp_data = tmp.tensor_data();
+ memcpy(const_cast<char*>(tmp_data.data()), other_data.data(),
+ other_data.size());
+ }
} else {
CHECK_EQ(DT_STRING, other.dtype());
tmp.flat<string>() = other.flat<string>();
diff --git a/tensorflow/core/framework/tensor_util_test.cc b/tensorflow/core/framework/tensor_util_test.cc
index 6761194025..34f79ed73e 100644
--- a/tensorflow/core/framework/tensor_util_test.cc
+++ b/tensorflow/core/framework/tensor_util_test.cc
@@ -60,6 +60,14 @@ TEST(TensorUtil, DeepCopy0d) {
EXPECT_EQ(DT_FLOAT, z.dtype());
}
+TEST(TensorUtil, DeepCopyZeroElements) {
+ Tensor x;
+ Tensor y = tensor::DeepCopy(x);
+ EXPECT_EQ(TensorShape({0}), y.shape());
+ EXPECT_EQ(DT_FLOAT, y.dtype());
+ EXPECT_EQ(0, y.NumElements());
+}
+
TEST(TensorUtil, DeepCopy) {
Tensor x(DT_FLOAT, TensorShape({1}));
x.flat<float>()(0) = 10.0;
diff --git a/tensorflow/core/graph/costmodel.cc b/tensorflow/core/graph/costmodel.cc
index e05297e295..11d199a88b 100644
--- a/tensorflow/core/graph/costmodel.cc
+++ b/tensorflow/core/graph/costmodel.cc
@@ -147,6 +147,10 @@ void CostModel::SetNumOutputs(const Node* node, int num_outputs) {
max_mem_usage->output_port_shape.resize(num_outputs, TensorShapeProto());
max_mem_usage->output_port_type.resize(num_outputs, DT_INVALID);
max_mem_usage->temp_memory_size = Bytes(-1);
+ max_mem_usage->host_peak_memory_size = Bytes(0);
+ max_mem_usage->device_peak_memory_size = Bytes(0);
+ max_mem_usage->persisted_memory_size = Bytes(0);
+ max_mem_usage->auxiliary_memory_size = Bytes(0);
output_port_alloc_ids->resize(num_outputs, -1);
}
}
@@ -290,6 +294,53 @@ Bytes CostModel::TempMemorySize(const Node* node) const {
return max_mem_usage_[id].temp_memory_size;
}
+Bytes CostModel::HostPeakMemorySize(const Node* node) const {
+ const int id = Id(node);
+ if (id < 0) {
+ return Bytes(0);
+ }
+ return max_mem_usage_[id].host_peak_memory_size;
+}
+
+Bytes CostModel::DevicePeakMemorySize(const Node* node) const {
+ const int id = Id(node);
+ if (id < 0) {
+ return Bytes(0);
+ }
+ return max_mem_usage_[id].device_peak_memory_size;
+}
+
+Bytes CostModel::PersistedMemorySize(const Node* node) const {
+ const int id = Id(node);
+ if (id < 0) {
+ return Bytes(0);
+ }
+ return max_mem_usage_[id].persisted_memory_size;
+}
+
+Bytes CostModel::AuxiliaryMemorySize(const Node* node) const {
+ const int id = Id(node);
+ if (id < 0) {
+ return Bytes(0);
+ }
+ return max_mem_usage_[id].auxiliary_memory_size;
+}
+
+void CostModel::RecordAllocatorMemory(
+ const Node* node,
+ const protobuf::RepeatedPtrField<AllocatorMemoryUsed>& memory) {
+ const int id = Id(node);
+ for (const auto& allocator_memory : memory) {
+ if (allocator_memory.allocator_name().find("cpu") != string::npos) {
+ max_mem_usage_[id].host_peak_memory_size +=
+ Bytes(allocator_memory.peak_bytes());
+ } else {
+ max_mem_usage_[id].device_peak_memory_size +=
+ Bytes(allocator_memory.peak_bytes());
+ }
+ }
+}
+
void CostModel::RecordMaxExecutionTime(const Node* node, Microseconds time) {
const int id = Id(node);
if (id < 0) return;
@@ -467,6 +518,10 @@ void CostModel::AddToCostGraphDef(const Graph* graph,
}
cnode->set_temporary_memory_size(TempMemorySize(n).value());
+ cnode->set_host_peak_memory_size(HostPeakMemorySize(n).value());
+ cnode->set_device_peak_memory_size(DevicePeakMemorySize(n).value());
+ cnode->set_persisted_memory_size(PersistedMemorySize(n).value());
+ cnode->set_auxiliary_memory_size(AuxiliaryMemorySize(n).value());
cnode->set_compute_cost(MaxExecutionTime(n).value());
diff --git a/tensorflow/core/graph/costmodel.h b/tensorflow/core/graph/costmodel.h
index f1fcd7820f..6cb7b37392 100644
--- a/tensorflow/core/graph/costmodel.h
+++ b/tensorflow/core/graph/costmodel.h
@@ -20,12 +20,14 @@ limitations under the License.
#include <vector>
#include "tensorflow/core/framework/cost_graph.pb.h"
+#include "tensorflow/core/framework/step_stats.pb.h"
#include "tensorflow/core/framework/tensor_shape.pb.h"
#include "tensorflow/core/graph/graph.h"
#include "tensorflow/core/graph/types.h"
#include "tensorflow/core/lib/core/stringpiece.h"
#include "tensorflow/core/lib/gtl/array_slice.h"
#include "tensorflow/core/platform/macros.h"
+#include "tensorflow/core/platform/protobuf.h"
namespace tensorflow {
typedef std::unordered_map<StringPiece, int32, StringPiece::Hasher>
@@ -128,6 +130,23 @@ class CostModel {
// Returns the size in bytes of temporary memory consumed by "node".
Bytes TempMemorySize(const Node* node) const;
+ // Returns the size in bytes of host memory consumed by "node".
+ Bytes HostPeakMemorySize(const Node* node) const;
+
+ // Returns the size in bytes of device memory consumed by "node".
+ Bytes DevicePeakMemorySize(const Node* node) const;
+
+ // Returns the size in bytes of persisted memory consumed by "node".
+ Bytes PersistedMemorySize(const Node* node) const;
+
+ // Returns the size in bytes of auxiliary memory consumed by "node".
+ Bytes AuxiliaryMemorySize(const Node* node) const;
+
+ // Records the memory allocated by allocators for a node.
+ void RecordAllocatorMemory(
+ const Node* node,
+ const protobuf::RepeatedPtrField<AllocatorMemoryUsed>& memory);
+
// Records the maximum execution time (in microseconds) of "node".
void RecordMaxExecutionTime(const Node* node, Microseconds time);
@@ -192,7 +211,26 @@ class CostModel {
// Maximum memory usage
struct MemUsage {
+ // TODO(yuefengz): temp_memory_size is not being used, remove it.
Bytes temp_memory_size;
+
+ // Peak memory includes temporary tensors, output tensors and persistent
+ // tensors. Some kernels may allocate temporary tensors on host even they
+ // are running on devices.
+ Bytes host_peak_memory_size;
+ Bytes device_peak_memory_size;
+
+ // Persisted memory includes the output memory, persistent tensors.
+ // The current set of kernels only allocate persistent tensors on their own
+ // devices.
+ Bytes persisted_memory_size;
+
+ // Auxiliary memory is the momery used by resources (i.e. those in
+ // ResourceMgr, e.g. lookup tables) excluding their underlying persistent
+ // tensors (e.g. in variable containers). The auxiliary memory is usually
+ // allocated on host.
+ Bytes auxiliary_memory_size;
+
gtl::InlinedVector<Bytes, 2> output_port_mem;
gtl::InlinedVector<TensorShapeProto, 2> output_port_shape;
gtl::InlinedVector<DataType, 2> output_port_type;
diff --git a/tensorflow/core/graph/testlib.cc b/tensorflow/core/graph/testlib.cc
index ef4dd04787..f0ab5520f1 100644
--- a/tensorflow/core/graph/testlib.cc
+++ b/tensorflow/core/graph/testlib.cc
@@ -219,6 +219,16 @@ Node* RandomGamma(Graph* g, Node* shape, Node* alpha) {
return ret;
}
+Node* RandomPoisson(Graph* g, Node* shape, Node* lam) {
+ Node* ret;
+ TF_CHECK_OK(NodeBuilder(g->NewName("n"), "RandomPoisson")
+ .Input(shape)
+ .Input(lam)
+ .Attr("seed", 0)
+ .Finalize(g, &ret));
+ return ret;
+}
+
Node* Unary(Graph* g, const string& func, Node* input, int index) {
Node* ret;
TF_CHECK_OK(NodeBuilder(g->NewName("n"), func, g->op_registry())
diff --git a/tensorflow/core/graph/testlib.h b/tensorflow/core/graph/testlib.h
index 7a23b20c2c..d508f65ada 100644
--- a/tensorflow/core/graph/testlib.h
+++ b/tensorflow/core/graph/testlib.h
@@ -113,6 +113,10 @@ Node* RandomGaussian(Graph* g, Node* input, DataType dtype);
// Output dtype determined by alpha.
Node* RandomGamma(Graph* g, Node* shape, Node* alpha);
+// Generates random poisson distribution with the given shape and lam[s].
+// Output dtype determined by lam.
+Node* RandomPoisson(Graph* g, Node* shape, Node* lam);
+
// Generates random parameters from the truncated standard normal distribution
// of the nput shape
Node* TruncatedNormal(Graph* g, Node* input, DataType dtype);
diff --git a/tensorflow/core/kernels/BUILD b/tensorflow/core/kernels/BUILD
index 7fa59fc437..45a0006baa 100644
--- a/tensorflow/core/kernels/BUILD
+++ b/tensorflow/core/kernels/BUILD
@@ -3362,6 +3362,33 @@ tf_cuda_cc_test(
)
tf_kernel_library(
+ name = "random_poisson_op",
+ prefix = "random_poisson_op",
+ deps = [
+ ":random_ops",
+ "//tensorflow/core:framework",
+ "//tensorflow/core:lib",
+ "//tensorflow/core:lib_internal",
+ "//tensorflow/core:random_ops_op_lib",
+ ],
+)
+
+tf_cuda_cc_test(
+ name = "random_poisson_op_test",
+ size = "small",
+ srcs = ["random_poisson_op_test.cc"],
+ deps = [
+ ":ops_util",
+ ":random_poisson_op",
+ "//tensorflow/core:core_cpu",
+ "//tensorflow/core:framework",
+ "//tensorflow/core:test",
+ "//tensorflow/core:test_main",
+ "//tensorflow/core:testlib",
+ ],
+)
+
+tf_kernel_library(
name = "word2vec_kernels",
prefix = "word2vec_kernels",
deps = [
diff --git a/tensorflow/core/kernels/example_parsing_ops.cc b/tensorflow/core/kernels/example_parsing_ops.cc
index d03f8fa33a..f4c4460fa4 100644
--- a/tensorflow/core/kernels/example_parsing_ops.cc
+++ b/tensorflow/core/kernels/example_parsing_ops.cc
@@ -92,7 +92,18 @@ class ExampleParserOp : public OpKernel {
for (int d = 0; d < static_cast<int>(attrs_.num_dense); ++d) {
const Tensor& def_value = dense_defaults[d];
- if (def_value.NumElements() > 0) {
+ if (attrs_.variable_length[d]) {
+ OP_REQUIRES(ctx, def_value.NumElements() == 1,
+ errors::InvalidArgument(
+ "dense_shape[", d, "] is a variable length shape: ",
+ attrs_.dense_shapes[d].DebugString(),
+ ", therefore "
+ "def_value[",
+ d,
+ "] must contain a single element ("
+ "the padding element). But its shape is: ",
+ def_value.shape().DebugString()));
+ } else if (def_value.NumElements() > 0) {
OP_REQUIRES(ctx,
attrs_.dense_shapes[d].IsCompatibleWith(def_value.shape()),
errors::InvalidArgument(
@@ -100,12 +111,12 @@ class ExampleParserOp : public OpKernel {
"].shape() == ", def_value.shape().DebugString(),
" is not compatible with dense_shapes_[", d,
"] == ", attrs_.dense_shapes[d].DebugString()));
- OP_REQUIRES(ctx, def_value.dtype() == attrs_.dense_types[d],
- errors::InvalidArgument(
- "dense_defaults[", d, "].dtype() == ",
- DataTypeString(def_value.dtype()), " != dense_types_[",
- d, "] == ", DataTypeString(attrs_.dense_types[d])));
}
+ OP_REQUIRES(ctx, def_value.dtype() == attrs_.dense_types[d],
+ errors::InvalidArgument(
+ "dense_defaults[", d, "].dtype() == ",
+ DataTypeString(def_value.dtype()), " != dense_types_[", d,
+ "] == ", DataTypeString(attrs_.dense_types[d])));
}
example::Result result;
@@ -114,6 +125,7 @@ class ExampleParserOp : public OpKernel {
for (int d = 0; d < attrs_.num_dense; ++d) {
config.dense.push_back({dense_keys_t[d], attrs_.dense_types[d],
attrs_.dense_shapes[d], dense_defaults[d],
+ attrs_.variable_length[d],
attrs_.elements_per_stride[d]});
}
for (int d = 0; d < attrs_.num_sparse; ++d) {
diff --git a/tensorflow/core/kernels/example_parsing_ops_test.cc b/tensorflow/core/kernels/example_parsing_ops_test.cc
index 67ac477713..29dbfd3b1b 100644
--- a/tensorflow/core/kernels/example_parsing_ops_test.cc
+++ b/tensorflow/core/kernels/example_parsing_ops_test.cc
@@ -127,9 +127,11 @@ template <>
ExampleTensorMap ExampleStore<FloatFiller>::serialized_example =
ExampleStore<FloatFiller>::GetSerializedExamples();
-template <typename S, bool BenchmarkDense>
+enum BenchmarkType { kDense, kSparse, kVarLenDense };
+
+template <typename S, BenchmarkType b_type>
struct BenchmarkOptions {
- bool benchmark_dense = BenchmarkDense;
+ int benchmark_type = b_type;
typedef S Store;
typename S::Filler filler;
};
@@ -145,19 +147,28 @@ static Graph* ParseExample(int batch_size, int num_keys, int feature_size) {
std::vector<NodeBuilder::NodeOut> dense_keys;
std::vector<NodeBuilder::NodeOut> dense_defaults;
std::vector<DataType> sparse_types;
- std::vector<TensorShape> dense_shapes;
+ std::vector<PartialTensorShape> dense_shapes;
Options opt;
for (int i = 0; i < num_keys; ++i) {
Tensor key(DT_STRING, TensorShape());
key.scalar<string>()() = strings::Printf("feature_%d", i);
- if (opt.benchmark_dense) {
- dense_keys.emplace_back(test::graph::Constant(g, key));
- dense_defaults.emplace_back(test::graph::Constant(
- g, opt.filler.make_dense_default(feature_size)));
- dense_shapes.push_back(TensorShape({feature_size}));
- } else {
- sparse_keys.emplace_back(test::graph::Constant(g, key));
- sparse_types.push_back(opt.filler.dtype);
+ switch (opt.benchmark_type) {
+ case kDense:
+ dense_keys.emplace_back(test::graph::Constant(g, key));
+ dense_defaults.emplace_back(test::graph::Constant(
+ g, opt.filler.make_dense_default(feature_size)));
+ dense_shapes.push_back(PartialTensorShape({feature_size}));
+ break;
+ case kVarLenDense:
+ dense_keys.emplace_back(test::graph::Constant(g, key));
+ dense_defaults.emplace_back(
+ test::graph::Constant(g, opt.filler.make_dense_default(1)));
+ dense_shapes.push_back(PartialTensorShape({-1}));
+ break;
+ case kSparse:
+ sparse_keys.emplace_back(test::graph::Constant(g, key));
+ sparse_types.push_back(opt.filler.dtype);
+ break;
}
}
@@ -176,12 +187,18 @@ static Graph* ParseExample(int batch_size, int num_keys, int feature_size) {
}
// Benchmark settings (Sparse, Dense) X (Bytes, Int64, Float)
-typedef BenchmarkOptions<ExampleStore<BytesFiller>, false> SparseString;
-typedef BenchmarkOptions<ExampleStore<BytesFiller>, true> DenseString;
-typedef BenchmarkOptions<ExampleStore<Int64Filler>, false> SparseInt64;
-typedef BenchmarkOptions<ExampleStore<Int64Filler>, true> DenseInt64;
-typedef BenchmarkOptions<ExampleStore<FloatFiller>, false> SparseFloat;
-typedef BenchmarkOptions<ExampleStore<FloatFiller>, true> DenseFloat;
+typedef BenchmarkOptions<ExampleStore<BytesFiller>, kSparse> SparseString;
+typedef BenchmarkOptions<ExampleStore<BytesFiller>, kDense> DenseString;
+typedef BenchmarkOptions<ExampleStore<BytesFiller>, kVarLenDense>
+ VarLenDenseString;
+typedef BenchmarkOptions<ExampleStore<Int64Filler>, kSparse> SparseInt64;
+typedef BenchmarkOptions<ExampleStore<Int64Filler>, kDense> DenseInt64;
+typedef BenchmarkOptions<ExampleStore<Int64Filler>, kVarLenDense>
+ VarLenDenseInt64;
+typedef BenchmarkOptions<ExampleStore<FloatFiller>, kSparse> SparseFloat;
+typedef BenchmarkOptions<ExampleStore<FloatFiller>, kDense> DenseFloat;
+typedef BenchmarkOptions<ExampleStore<FloatFiller>, kVarLenDense>
+ VarLenDenseFloat;
// B == batch_size, K == num_keys. F == feature_size.
// K must be one of 10, 100, 1000
@@ -205,9 +222,12 @@ typedef BenchmarkOptions<ExampleStore<FloatFiller>, true> DenseFloat;
BM_AllParseExample(SparseString);
BM_AllParseExample(DenseString);
+BM_AllParseExample(VarLenDenseString);
BM_AllParseExample(SparseInt64);
BM_AllParseExample(DenseInt64);
+BM_AllParseExample(VarLenDenseInt64);
BM_AllParseExample(SparseFloat);
BM_AllParseExample(DenseFloat);
+BM_AllParseExample(VarLenDenseFloat);
} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fused_batch_norm_op.cc b/tensorflow/core/kernels/fused_batch_norm_op.cc
index c79f6d8249..31570e2fc8 100644
--- a/tensorflow/core/kernels/fused_batch_norm_op.cc
+++ b/tensorflow/core/kernels/fused_batch_norm_op.cc
@@ -108,7 +108,7 @@ struct FusedBatchNorm<CPUDevice, T> {
x_rest_by_depth - mean.reshape(one_by_depth).broadcast(bcast_spec);
if (is_training) {
- variance = x_centered.square().sum(reduce_dims) * rest_size_inv;
+ variance.device(d) = x_centered.square().sum(reduce_dims) * rest_size_inv;
batch_var.device(d) = variance * rest_size_adjust;
saved_var.device(d) = variance;
} else {
diff --git a/tensorflow/core/kernels/hexagon/graph_transfer_utils.cc b/tensorflow/core/kernels/hexagon/graph_transfer_utils.cc
index 42fa91484d..340c25e85b 100644
--- a/tensorflow/core/kernels/hexagon/graph_transfer_utils.cc
+++ b/tensorflow/core/kernels/hexagon/graph_transfer_utils.cc
@@ -50,15 +50,18 @@ GraphTransferUtils::GetTopNFloatResults(const float* const data,
}
/* static */ GraphDef GraphTransferUtils::BuildFusedGraphDef(
+ const IGraphTransferOpsDefinitions& ops_definitions,
const string& remote_graph_execute_name,
const std::vector<GraphTransferer::InputNodeInfo>& inputs,
const std::vector<string>& outputs, const GraphDef& def,
GraphTransferer* const gt) {
CHECK(gt != nullptr);
- std::vector<tensorflow::Tensor> output_tensors;
- Status status = gt->DryRunInference(
- def, inputs, outputs, false /* initialize_by_zero */, &output_tensors);
+ GraphTransferer::OutputTensorInfo output_tensor_info;
+ Status status = gt->DryRunInferenceForAllNode(
+ def, inputs, false /* initialize_by_zero */, &output_tensor_info);
CHECK(status.ok());
+ status = gt->LoadGraphFromProto(ops_definitions, def, inputs, outputs,
+ output_tensor_info.output_tensor_map);
Scope root = Scope::NewRootScope();
std::vector<Output> output_list;
@@ -77,6 +80,7 @@ GraphTransferUtils::GetTopNFloatResults(const float* const data,
string serialized_graph = gt->GetGraphTransferInfo().SerializeAsString();
const Scope& scope = root.WithOpName(remote_graph_execute_name);
+ CHECK(scope.ok());
auto node_out_list = ops::AsNodeOutList(scope, InputList(output_list));
Node* node;
const auto unique_name = scope.GetUniqueNameForOp("RemoteFusedGraphExecute");
@@ -85,6 +89,7 @@ GraphTransferUtils::GetTopNFloatResults(const float* const data,
.Attr("N", static_cast<int64>(outputs.size()))
.Attr("serialized_graph_transfer_info",
StringPiece(serialized_graph));
+ CHECK(scope.ok());
scope.UpdateBuilder(&builder);
scope.UpdateStatus(builder.Finalize(scope.graph(), &node));
CHECK(scope.ok());
diff --git a/tensorflow/core/kernels/hexagon/graph_transfer_utils.h b/tensorflow/core/kernels/hexagon/graph_transfer_utils.h
index b6a9a3d289..a9de914538 100644
--- a/tensorflow/core/kernels/hexagon/graph_transfer_utils.h
+++ b/tensorflow/core/kernels/hexagon/graph_transfer_utils.h
@@ -35,6 +35,7 @@ class GraphTransferUtils {
const int element_count, const int top_n);
static GraphDef BuildFusedGraphDef(
+ const IGraphTransferOpsDefinitions& ops_definitions,
const string& remote_graph_execute_name,
const std::vector<GraphTransferer::InputNodeInfo>& inputs,
const std::vector<string>& outputs, const GraphDef& def,
diff --git a/tensorflow/core/kernels/hexagon/graph_transferer.cc b/tensorflow/core/kernels/hexagon/graph_transferer.cc
index e5fd127abe..e6ff105e29 100644
--- a/tensorflow/core/kernels/hexagon/graph_transferer.cc
+++ b/tensorflow/core/kernels/hexagon/graph_transferer.cc
@@ -31,17 +31,17 @@ namespace tensorflow {
constexpr bool DBG_DUMP_VERIFICATION_STRING = false;
constexpr bool DBG_DUMP_PARAMS = false;
-const string RESHAPE_NODE_TYPE_STRING = "Reshape";
-const string SOURCE_NODE_NAME = "_SOURCE";
-const string SINK_NODE_NAME = "_SINK";
-const string INPUTS_NODE_PREFIX = "inputs_for_";
-const string OUTPUTS_NODE_PREFIX = "outputs_for_";
-const string DATA_NODE_PREFIX = "data_for_op_";
-const string CONST_SHAPE_PREFIX = "const_shape_";
-const string PADDING_ATTR_NAME = "padding";
-const string STRIDES_ATTR_NAME = "strides";
-const string KSIZE_ATTR_NAME = "ksize";
-const string NULL_OUTPUT_NAME = "NULL";
+const char RESHAPE_NODE_TYPE_STRING[] = "Reshape";
+const char SOURCE_NODE_NAME[] = "_SOURCE";
+const char SINK_NODE_NAME[] = "_SINK";
+const char INPUTS_NODE_PREFIX[] = "inputs_for_";
+const char OUTPUTS_NODE_PREFIX[] = "outputs_for_";
+const char DATA_NODE_PREFIX[] = "data_for_op_";
+const char CONST_SHAPE_PREFIX[] = "const_shape_";
+const char PADDING_ATTR_NAME[] = "padding";
+const char STRIDES_ATTR_NAME[] = "strides";
+const char KSIZE_ATTR_NAME[] = "ksize";
+const char NULL_OUTPUT_NAME[] = "NULL";
const int PADDING_NA_ID = 0; // VALID = 1, SAME = 2
// This is a temporary workaround to support android build
@@ -101,6 +101,35 @@ Status GraphTransferer::LoadGraphFromProto(
}
}
SortParams(output_node_names);
+
+ for (const InputNodeInfo& input_node_info : input_node_info_list) {
+ GraphTransferInfo::GraphInputNodeInfo& graph_input_node_info =
+ *graph_transfer_info_.add_graph_input_node_info();
+ graph_input_node_info.set_name(input_node_info.name);
+ for (const int64 dim : ToTensorShapeArray(input_node_info.tensor.shape())) {
+ graph_input_node_info.add_shape(dim);
+ }
+ }
+
+ for (const string& output_node_name : output_node_names) {
+ GraphTransferInfo::GraphOutputNodeInfo& graph_output_node_info =
+ *graph_transfer_info_.add_graph_output_node_info();
+ graph_output_node_info.set_name(output_node_name);
+ // TODO(satok): Use shape inference to obtain output shapes
+ if (!output_tensor_map.empty()) {
+ CHECK_EQ(output_tensor_map.count(output_node_name), 1)
+ << output_tensor_map.count(output_node_name);
+ Tensor* output_tensor = output_tensor_map.at(output_node_name);
+ CHECK(output_tensor != nullptr);
+ for (const int64 dim : ToTensorShapeArray(output_tensor->shape())) {
+ graph_output_node_info.add_shape(dim);
+ }
+ }
+ }
+
+ graph_transfer_info_.set_destination(
+ ops_definitions.GetTransferDestination());
+
ClearCache();
if (DBG_DUMP_PARAMS) {
DumpNodeTransferParams();
@@ -245,7 +274,7 @@ Status GraphTransferer::LoadGraphFromProtoFile(
VLOG(1) << "Failed to dryrun " << status;
return status;
}
- CHECK(output_node_names.size() == output_tensors.size())
+ CHECK_EQ(output_node_names.size(), output_tensors.size())
<< output_node_names.size() << ", " << output_tensors.size();
// Append output tensor of input node in advance to create a map
@@ -256,12 +285,12 @@ Status GraphTransferer::LoadGraphFromProtoFile(
for (int i = 0; i < output_node_names.size(); ++i) {
const string& name = output_node_names.at(i);
- CHECK(output_tensor_map.count(name) == 0);
+ CHECK_EQ(output_tensor_map.count(name), 0);
output_tensor_map[name] = &output_tensors.at(i);
}
for (int i = 0; i < input_node_info_list.size(); ++i) {
const string& name = input_node_info_list.at(i).name;
- CHECK(output_tensor_map.count(name) == 0);
+ CHECK_EQ(output_tensor_map.count(name), 0);
output_tensor_map.emplace(name,
&output_tensors.at(output_node_names.size() + i));
}
@@ -294,7 +323,7 @@ void GraphTransferer::SortParams(const std::vector<string>& output_node_names) {
if (params.input_count() == 0) {
continue;
}
- CHECK(input_map.count(node_id) == 1);
+ CHECK_EQ(input_map.count(node_id), 1);
for (const GraphTransferInfo::NodeInput& node_input :
input_map.at(node_id)->node_input()) {
dependency_map.at(node_id).emplace(node_input.node_id());
@@ -399,17 +428,18 @@ void GraphTransferer::RegisterConstantNode(
const ShapeRefiner& shape_refiner, const Node& node,
const OutputTensorMap& output_tensor_map) {
VLOG(1) << "Register constant node: " << node.name();
- CHECK(node_name_to_id_cache_map_.count(node.name()) == 1);
+ CHECK_EQ(node_name_to_id_cache_map_.count(node.name()), 1);
const int id = node_name_to_id_cache_map_[node.name()];
const int output_node_size = node.num_outputs();
- CHECK(output_node_size == 1);
+ CHECK_EQ(output_node_size, 1);
// TODO(satok): support multiple outputs?
const int output_index = 0;
const DataType dt = node.output_type(output_index);
const size_t max_bytes_per_data = DataTypeSize(dt);
- CHECK(max_bytes_per_data > 0) << "dt = " << dt << ", " + DataTypeString(dt)
- << ", " << max_bytes_per_data << ", "
- << (int)(DataTypeSize(dt)) << ",,,,,,,";
+ CHECK_GT(max_bytes_per_data, 0)
+ << "dt = " << dt << ", " + DataTypeString(dt) << ", "
+ << max_bytes_per_data << ", " << static_cast<int>(DataTypeSize(dt))
+ << ",,,,,,,";
shape_inference::InferenceContext* context = shape_refiner.GetContext(&node);
shape_inference::ShapeHandle shape_handle = context->output(output_index);
const shape_inference::DimensionHandle num_elements_dim =
@@ -450,7 +480,7 @@ void GraphTransferer::RegisterConstantNode(
const Tensor* tensor = output_tensor_map.at(node.name());
CHECK(tensor != nullptr);
StringPiece sp = tensor->tensor_data();
- CHECK(data_size == sp.size());
+ CHECK_EQ(data_size, sp.size());
const_node_info.set_data(sp.data(), data_size);
}
}
@@ -459,7 +489,7 @@ void GraphTransferer::RegisterConstantNode(
int GraphTransferer::RegisterConstantShape(const std::vector<int>& shape) {
VLOG(1) << "Cache constant shape.";
// TODO(satok): Handle non-4dim strides
- CHECK(shape.size() == 4);
+ CHECK_EQ(shape.size(), 4);
const string shape_name = CONST_SHAPE_PREFIX + ToString(shape.at(0)) + 'x' +
ToString(shape.at(1)) + 'x' +
ToString(shape.at(2)) + 'x' + ToString(shape.at(3));
@@ -528,14 +558,14 @@ void GraphTransferer::RegisterNodeWithPaddingAndStrides(
const IGraphTransferOpsDefinitions& ops_definitions,
const ShapeRefiner& shape_refiner, const OutputTensorMap& output_tensor_map,
const Node& node) {
- CHECK(node_name_to_id_cache_map_.count(node.name()) == 1);
+ CHECK_EQ(node_name_to_id_cache_map_.count(node.name()), 1);
const int id = node_name_to_id_cache_map_[node.name()];
shape_inference::InferenceContext* context = shape_refiner.GetContext(&node);
- CHECK(node.def().attr().count(PADDING_ATTR_NAME) > 0);
+ CHECK_GT(node.def().attr().count(PADDING_ATTR_NAME), 0);
// TODO(satok): Use context->GetAttr(...) instead?
Padding padding;
context->GetAttr(PADDING_ATTR_NAME, &padding);
- CHECK(node.def().attr().count(STRIDES_ATTR_NAME) > 0);
+ CHECK_GT(node.def().attr().count(STRIDES_ATTR_NAME), 0);
std::vector<int32> strides;
context->GetAttr(STRIDES_ATTR_NAME, &strides);
const int stride_id = RegisterConstantShape(strides);
@@ -564,7 +594,7 @@ void GraphTransferer::RegisterInputNode(
const ShapeRefiner& shape_refiner, const OutputTensorMap& output_tensor_map,
const Node& node) {
VLOG(1) << "Register input node: " << node.name();
- CHECK(node_name_to_id_cache_map_.count(node.name()) == 1);
+ CHECK_EQ(node_name_to_id_cache_map_.count(node.name()), 1);
const int id = node_name_to_id_cache_map_[node.name()];
const string op_type = IGraphTransferOpsDefinitions::INPUT_OP_NAME;
const int op_type_id = ops_definitions.GetOpIdFor(op_type);
@@ -580,7 +610,7 @@ void GraphTransferer::RegisterOutputNode(
const ShapeRefiner& shape_refiner, const OutputTensorMap& output_tensor_map,
const Node& node) {
VLOG(1) << "Register output node: " << node.name();
- CHECK(node_name_to_id_cache_map_.count(node.name()) == 1);
+ CHECK_EQ(node_name_to_id_cache_map_.count(node.name()), 1);
const int id = node_name_to_id_cache_map_[node.name()];
const string op_type = IGraphTransferOpsDefinitions::OUTPUT_OP_NAME;
const int op_type_id = ops_definitions.GetOpIdFor(op_type);
@@ -597,7 +627,7 @@ void GraphTransferer::RegisterFlattenNode(
const ShapeRefiner& shape_refiner, const OutputTensorMap& output_tensor_map,
const Node& node) {
VLOG(1) << "Register flatten node: " << node.name();
- CHECK(node_name_to_id_cache_map_.count(node.name()) == 1);
+ CHECK_EQ(node_name_to_id_cache_map_.count(node.name()), 1);
const int id = node_name_to_id_cache_map_[node.name()];
const string op_type = IGraphTransferOpsDefinitions::FLATTEN_OP_NAME;
const int op_type_id = ops_definitions.GetOpIdFor(op_type);
@@ -614,7 +644,7 @@ void GraphTransferer::RegisterGenericNode(
const ShapeRefiner& shape_refiner, const OutputTensorMap& output_tensor_map,
const Node& node) {
VLOG(1) << "Register generic node: " << node.name();
- CHECK(node_name_to_id_cache_map_.count(node.name()) == 1);
+ CHECK_EQ(node_name_to_id_cache_map_.count(node.name()), 1);
const int id = node_name_to_id_cache_map_[node.name()];
const int op_type_id = ops_definitions.GetOpIdFor(node.type_string());
CHECK(op_type_id >= 0 && op_type_id < ops_definitions.GetTotalOpsCount());
@@ -675,7 +705,7 @@ void GraphTransferer::AppendNodeInputParams(
const int port = edge->src_output();
const std::string& op_name = input_node->name();
- CHECK(node_name_to_id_cache_map_.count(op_name) > 0) << op_name;
+ CHECK_GT(node_name_to_id_cache_map_.count(op_name), 0) << op_name;
const int src_id = node_name_to_id_cache_map_[op_name];
GraphTransferInfo::NodeInput& node_input =
*node_input_info.add_node_input();
@@ -719,10 +749,10 @@ void GraphTransferer::AppendNodeOutputParams(
const int64 num_output_elements = context->Value(num_elements_dim);
data_size = max_bytes_per_data * num_output_elements;
if (!output_tensor_map.empty() && strict_check_mode_) {
- CHECK(output_tensor_map.count(node.name()) == 1) << node.name();
+ CHECK_EQ(output_tensor_map.count(node.name()), 1) << node.name();
const TensorShape& tensor_shape =
output_tensor_map.at(node.name())->shape();
- CHECK(num_output_elements == tensor_shape.num_elements())
+ CHECK_EQ(num_output_elements, tensor_shape.num_elements())
<< "num elements of node " << node.name() << " doesn't match "
<< num_output_elements << " vs " << tensor_shape.num_elements()
<< ", " << node.type_string();
@@ -731,12 +761,12 @@ void GraphTransferer::AppendNodeOutputParams(
// Use dryrun result to get the output data size
// TODO(satok): Remove and stop using dryrun result
CHECK(!output_tensor_map.empty());
- CHECK(output_tensor_map.count(node.name()) == 1);
+ CHECK_EQ(output_tensor_map.count(node.name()), 1);
const TensorShape& tensor_shape =
output_tensor_map.at(node.name())->shape();
data_size = max_bytes_per_data * tensor_shape.num_elements();
}
- CHECK(data_size >= 0);
+ CHECK_GE(data_size, 0);
node_output_info.add_max_byte_size(data_size);
}
}
@@ -836,11 +866,11 @@ GraphTransferer::ToTensorShapeArray(const TensorShape& shape) {
return;
}
VLOG(1) << "Check shape for " << node_name;
- CHECK(output_tensor_map.count(node_name) == 1);
+ CHECK_EQ(output_tensor_map.count(node_name), 1);
const std::array<int64, SHAPE_ARRAY_SIZE> actual =
ToTensorShapeArray(output_tensor_map.at(node_name)->shape());
for (int i = 0; i < SHAPE_ARRAY_SIZE; ++i) {
- CHECK(expected[i] == actual[i]);
+ CHECK_EQ(expected[i], actual[i]);
}
}
@@ -878,7 +908,7 @@ bool GraphTransferer::TransferParamsComparator::operator()(
completed.count(node_id) == 1) {
return;
}
- CHECK(dep_map.count(node_id) == 1);
+ CHECK_EQ(dep_map.count(node_id), 1);
// Complete children's dependency map
for (int child_node_id : dep_map.at(node_id)) {
@@ -921,7 +951,7 @@ void GraphTransferer::DumpNodeTransferParams() const {
for (const GraphTransferInfo::ConstNodeInfo& params :
graph_transfer_info_.const_node_info()) {
// TODO(satok): Stop assuming shape size is 4.
- CHECK(params.shape_size() == 4);
+ CHECK_EQ(params.shape_size(), 4);
LOG(INFO) << "[ " << params.node_id() << " \"" << params.name()
<< "\" (Const)";
LOG(INFO) << " shape: " << params.shape(0) << params.shape(1)
@@ -975,7 +1005,7 @@ void GraphTransferer::DumpVerificationStringOfNodeTransferParams() const {
graph_transfer_info_.const_node_info()) {
std::stringstream sstream;
// TODO(satok): Stop assuming shape size is 4.
- CHECK(params.shape_size() == 4);
+ CHECK_EQ(params.shape_size(), 4);
sstream << "---(CONST) [" << std::hex << params.node_id() << std::dec << ","
<< params.shape(0) << "," << params.shape(1) << ","
<< params.shape(2) << "," << params.shape(3) << ","
diff --git a/tensorflow/core/kernels/hexagon/graph_transferer_test.cc b/tensorflow/core/kernels/hexagon/graph_transferer_test.cc
index bd14fe58ab..0e65091999 100644
--- a/tensorflow/core/kernels/hexagon/graph_transferer_test.cc
+++ b/tensorflow/core/kernels/hexagon/graph_transferer_test.cc
@@ -16,8 +16,6 @@ limitations under the License.
#include <memory>
#include "tensorflow/cc/ops/const_op.h"
-#include "tensorflow/cc/ops/nn_ops.h"
-#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/graph_transfer_info.pb.h"
#include "tensorflow/core/framework/tensor_testutil.h"
#include "tensorflow/core/graph/graph_def_builder.h"
@@ -65,15 +63,91 @@ class TestGraphTransferOpsDefinitions : public IGraphTransferOpsDefinitions {
}
return -1;
}
+ GraphTransferInfo::Destination GetTransferDestination() const final {
+ return GraphTransferInfo::NOP;
+ }
private:
} TEST_GRAPH_TRANSFER_OPS_DEFINITIONS;
+static Output BuildAddOps(const Scope& scope, const Input& x, const Input& y) {
+ EXPECT_TRUE(scope.ok());
+ auto _x = ops::AsNodeOut(scope, x);
+ EXPECT_TRUE(scope.ok());
+ auto _y = ops::AsNodeOut(scope, y);
+ EXPECT_TRUE(scope.ok());
+ Node* ret;
+ const auto unique_name = scope.GetUniqueNameForOp("Add");
+ auto builder = NodeBuilder(unique_name, "Add").Input(_x).Input(_y);
+ scope.UpdateBuilder(&builder);
+ scope.UpdateStatus(builder.Finalize(scope.graph(), &ret));
+ EXPECT_TRUE(scope.ok());
+ return Output(ret, 0);
+}
+
+static Output BuildSoftmaxOps(const Scope& scope, const Input& logits) {
+ EXPECT_TRUE(scope.ok());
+ auto _logits = ops::AsNodeOut(scope, logits);
+ EXPECT_TRUE(scope.ok());
+ Node* ret;
+ const auto unique_name = scope.GetUniqueNameForOp("Softmax");
+ auto builder = NodeBuilder(unique_name, "Softmax").Input(_logits);
+ scope.UpdateBuilder(&builder);
+ scope.UpdateStatus(builder.Finalize(scope.graph(), &ret));
+ EXPECT_TRUE(scope.ok());
+ return Output(ret, 0);
+}
+
+static Output BuildConv2DOps(const Scope& scope, const Input& input,
+ const Input& filter,
+ const gtl::ArraySlice<int>& strides,
+ const StringPiece& padding) {
+ EXPECT_TRUE(scope.ok());
+ auto _input = ops::AsNodeOut(scope, input);
+ EXPECT_TRUE(scope.ok());
+ auto _filter = ops::AsNodeOut(scope, filter);
+ EXPECT_TRUE(scope.ok());
+ Node* ret;
+ const auto unique_name = scope.GetUniqueNameForOp("Conv2D");
+ auto builder = NodeBuilder(unique_name, "Conv2D")
+ .Input(_input)
+ .Input(_filter)
+ .Attr("strides", strides)
+ .Attr("use_cudnn_on_gpu", true)
+ .Attr("padding", padding)
+ .Attr("data_format", "NHWC");
+ scope.UpdateBuilder(&builder);
+ scope.UpdateStatus(builder.Finalize(scope.graph(), &ret));
+ EXPECT_TRUE(scope.ok());
+ return Output(ret, 0);
+}
+
+static Output BuildMaxPoolOps(const Scope& scope, const Input& input,
+ const gtl::ArraySlice<int>& ksize,
+ const gtl::ArraySlice<int>& strides,
+ const StringPiece& padding) {
+ EXPECT_TRUE(scope.ok());
+ auto _input = ops::AsNodeOut(scope, input);
+ EXPECT_TRUE(scope.ok());
+ Node* ret;
+ const auto unique_name = scope.GetUniqueNameForOp("MaxPool");
+ auto builder = NodeBuilder(unique_name, "MaxPool")
+ .Input(_input)
+ .Attr("ksize", ksize)
+ .Attr("strides", strides)
+ .Attr("padding", padding)
+ .Attr("data_format", "NHWC");
+ scope.UpdateBuilder(&builder);
+ scope.UpdateStatus(builder.Finalize(scope.graph(), &ret));
+ EXPECT_TRUE(scope.ok());
+ return Output(ret, 0);
+}
+
static GraphDef CreateAddGraphDef() {
Scope root = Scope::NewRootScope();
Output node_a = ops::Const(root.WithOpName(NAME_A), NODE_A_VAL);
Output node_b = ops::Const(root.WithOpName(NAME_B), NODE_B_VAL);
- Output node_add = ops::Add(root.WithOpName(NAME_A_PLUS_B), node_a, node_b);
+ Output node_add = BuildAddOps(root.WithOpName(NAME_A_PLUS_B), node_a, node_b);
GraphDef def;
TF_CHECK_OK(root.ToGraphDef(&def));
return def;
@@ -91,8 +165,8 @@ static GraphDef CreateConvGraphDef() {
ops::Const(root.WithOpName("filter"), Input::Initializer(filter_data));
const std::vector<int> strides{1, 1, 1, 1};
Output conv =
- ops::Conv2D(root.WithOpName("conv"), input, filter, strides, "SAME");
- Output softmax = ops::Softmax(root.WithOpName("softmax"), conv);
+ BuildConv2DOps(root.WithOpName("conv"), input, filter, strides, "SAME");
+ Output softmax = BuildSoftmaxOps(root.WithOpName("softmax"), conv);
GraphDef def;
TF_CHECK_OK(root.ToGraphDef(&def));
return def;
@@ -111,9 +185,9 @@ static GraphDef CreatePoolGraphDef() {
const std::vector<int> ksize{1, 1, 1, 1};
const std::vector<int> padding{0, 0, 0, 0};
const std::vector<int> strides{1, 1, 1, 1};
- Output max_pool =
- ops::MaxPool(root.WithOpName("maxpool"), input, ksize, strides, "SAME");
- Output softmax = ops::Softmax(root.WithOpName("softmax"), max_pool);
+ Output max_pool = BuildMaxPoolOps(root.WithOpName("maxpool"), input, ksize,
+ strides, "SAME");
+ Output softmax = BuildSoftmaxOps(root.WithOpName("softmax"), max_pool);
GraphDef def;
TF_CHECK_OK(root.ToGraphDef(&def));
return def;
@@ -444,7 +518,8 @@ TEST_F(GraphTransfererTest, BuildRemoteFusedGraphDefAddGraph) {
std::vector<string> outputs = {NAME_A_PLUS_B};
GraphDef fused_graph_def = GraphTransferUtils::BuildFusedGraphDef(
- "remote_fused_graph_execute_node", inputs, outputs, def, &gt_);
+ TEST_GRAPH_TRANSFER_OPS_DEFINITIONS, "remote_fused_graph_execute_node",
+ inputs, outputs, def, &gt_);
EXPECT_EQ(3, fused_graph_def.node_size());
}
diff --git a/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc b/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc
index a96c0e281e..ed2b9a0280 100644
--- a/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc
+++ b/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc
@@ -26,6 +26,7 @@ const bool SHOW_DBG_IN_SOC = false;
const bool DBG_USE_DUMMY_INPUT = false;
const bool DBG_USE_SAMPLE_INPUT = false;
const int64 FLAG_ENABLE_PANDA_BINARY_INPUT = 0x01;
+const bool DBG_DUMP_INPUT_TENSOR_AS_FLOAT_DATA = false;
#ifdef USE_HEXAGON_LIBS
int HexagonControlWrapper::GetVersion() {
@@ -219,6 +220,19 @@ bool HexagonControlWrapper::FillInputNode(const string& node_name,
const ConstByteArray ba =
ConstByteArray(reinterpret_cast<const uint8*>(tensor_data.data()),
tensor_data.size(), tensor.dtype());
+ if (DBG_DUMP_INPUT_TENSOR_AS_FLOAT_DATA) {
+ LOG(INFO) << "Input tensor data: element size = " << tensor.NumElements()
+ << ", byte syze = " << tensor.TotalBytes();
+ std::stringstream line;
+ for (int i = 0; i < tensor.NumElements(); ++i) {
+ line << tensor.flat<float>().data()[i] << ", ";
+ if ((i - 2) % 3 == 0 || i == tensor.NumElements() - 1) {
+ LOG(INFO) << "(" << ((i - 2) / 3) << ") " << line.str();
+ line.str("");
+ line.clear();
+ }
+ }
+ }
FillInputNode(node_name, ba);
return true;
}
diff --git a/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc b/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc
index 81e49bd147..9e924eef83 100644
--- a/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc
+++ b/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc
@@ -38,11 +38,19 @@ limitations under the License.
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/profile_utils/clock_cycle_profiler.h"
#include "tensorflow/core/platform/test.h"
+#include "tensorflow/core/public/session.h"
+#include "tensorflow/core/public/session_options.h"
namespace tensorflow {
using ByteArray = ISocControlWrapper::ByteArray;
+using ConstByteArray = ISocControlWrapper::ConstByteArray;
+constexpr const char* const IMAGE_FILENAME = "/data/local/tmp/img_299x299.bmp";
+constexpr const char* const MODEL_FILENAME =
+ "/data/local/tmp/tensorflow_inception_v3_stripped_optimized_quantized.pb";
+
+const bool USE_TF_RUNTIME = true;
const bool DBG_DUMP_FLOAT_DATA = false;
const int WIDTH = 299;
const int HEIGHT = 299;
@@ -50,13 +58,9 @@ const int DEPTH = 3;
const int EXPECTED_FIRST_RESULT_ID = 59;
const int EXECUTION_REPEAT_COUNT = 3;
-static void DumpTop10Results(
- const std::vector<ISocControlWrapper::ByteArray>& outputs) {
- CHECK(outputs.size() == 1);
- const int byte_size = std::get<1>(outputs.at(0));
+static void DumpTop10Results(const int byte_size,
+ const float* const float_array) {
const int element_count = byte_size / sizeof(float);
- const float* float_array =
- reinterpret_cast<float*>(std::get<0>(outputs.at(0)));
const string label_filename =
"/data/local/tmp/imagenet_comp_graph_label_strings.txt";
string label_str;
@@ -68,6 +72,15 @@ static void DumpTop10Results(
10 /* show top_n results */);
}
+static void DumpTop10Results(
+ const std::vector<ISocControlWrapper::ByteArray>& outputs) {
+ CHECK(outputs.size() == 1);
+ const int byte_size = std::get<1>(outputs.at(0));
+ const float* float_array =
+ reinterpret_cast<float*>(std::get<0>(outputs.at(0)));
+ DumpTop10Results(byte_size, float_array);
+}
+
static void CheckFirstResult(
const std::vector<ISocControlWrapper::ByteArray>& outputs,
const int expected_first_id) {
@@ -85,41 +98,14 @@ static void CheckFirstResult(
EXPECT_EQ(expected_first_id, std::get<1>(entry));
}
-// CAVEAT: This test only runs when you specify hexagon library using
-// makefile.
-// TODO(satok): Make this generic so that this can run without any
-// additionanl steps.
-#ifdef USE_HEXAGON_LIBS
-TEST(GraphTransferer, RunInceptionV3OnHexagonExample) {
- const string image_filename = "/data/local/tmp/img_299x299.bmp";
- const string model_filename =
- "/data/local/tmp/tensorflow_inception_v3_stripped_optimized_quantized.pb";
- const IGraphTransferOpsDefinitions* ops_definitions =
- &HexagonOpsDefinitions::getInstance();
- std::vector<GraphTransferer::InputNodeInfo> input_node_info_list = {
- GraphTransferer::InputNodeInfo{
- "Mul", Tensor{DT_FLOAT, {1, WIDTH, HEIGHT, DEPTH}}}};
- std::vector<string> output_node_names = {"softmax"};
- const bool is_text_proto = false;
-
- GraphTransferer::OutputTensorInfo output_tensor_info;
- GraphTransferer gt;
- gt.EnableStrictCheckMode(false);
- Status status = gt.LoadGraphFromProtoFile(
- *ops_definitions, model_filename, input_node_info_list, output_node_names,
- is_text_proto, true /* dry_run_for_unknown_shape */, &output_tensor_info);
- ASSERT_TRUE(status.ok()) << status;
-
- HexagonControlWrapper hexagon_control_wrapper;
- const int version = hexagon_control_wrapper.GetVersion();
- ASSERT_GE(version, 1);
- LOG(INFO) << "Hexagon controller version is " << version;
-
+static void LoadImage(std::vector<float>* img_floats_ptr) {
+ CHECK(img_floats_ptr != nullptr);
+ std::vector<float>& img_floats = *img_floats_ptr;
// Read the data from the bitmap file into memory
string bmp;
- TF_CHECK_OK(ReadFileToString(Env::Default(), image_filename, &bmp));
+ TF_CHECK_OK(ReadFileToString(Env::Default(), IMAGE_FILENAME, &bmp));
const int fsize = bmp.size();
- LOG(INFO) << "Read " << image_filename << ", size = " << fsize << "bytes";
+ LOG(INFO) << "Read " << IMAGE_FILENAME << ", size = " << fsize << "bytes";
const int64 pixel_count = WIDTH * HEIGHT * DEPTH;
CHECK(fsize >= 22 /* pos of height */ + sizeof(int));
CHECK(bmp.data() != nullptr);
@@ -136,7 +122,7 @@ TEST(GraphTransferer, RunInceptionV3OnHexagonExample) {
uint8* const bmp_pixels = &img_bytes[header_size];
- std::vector<float> img_floats(pixel_count);
+ img_floats.resize(pixel_count);
int src_pixel_index = 0;
CHECK(pixel_count % 3 == 0);
for (int i = 0; i < pixel_count / 3; ++i) {
@@ -164,10 +150,18 @@ TEST(GraphTransferer, RunInceptionV3OnHexagonExample) {
++src_pixel_index;
}
}
- const ByteArray ba =
- std::make_tuple(reinterpret_cast<uint8*>(img_floats.data()),
- pixel_count * sizeof(float), DT_FLOAT);
+}
+
+static void RunInferenceByHexagonControlWrapper(
+ const GraphTransferer& gt, const std::vector<float>& img_floats) {
+ const ConstByteArray ba =
+ std::make_tuple(reinterpret_cast<const uint8*>(img_floats.data()),
+ img_floats.size() * sizeof(float), DT_FLOAT);
+ HexagonControlWrapper hexagon_control_wrapper;
+ const int version = hexagon_control_wrapper.GetVersion();
+ ASSERT_GE(version, 1);
+ LOG(INFO) << "Hexagon controller version is " << version;
// 1. Initialize hexagon
hexagon_control_wrapper.Init();
@@ -201,6 +195,103 @@ TEST(GraphTransferer, RunInceptionV3OnHexagonExample) {
// 7. Finalize hexagon
hexagon_control_wrapper.Finalize();
}
+
+// CAVEAT: This test only runs when you specify hexagon library using
+// makefile.
+// TODO(satok): Make this generic so that this can run without any
+// additional steps.
+#ifdef USE_HEXAGON_LIBS
+TEST(GraphTransferer, RunInceptionV3OnHexagonExample) {
+ if (USE_TF_RUNTIME) return;
+ const IGraphTransferOpsDefinitions* ops_definitions =
+ &HexagonOpsDefinitions::getInstance();
+ std::vector<GraphTransferer::InputNodeInfo> input_node_info_list = {
+ GraphTransferer::InputNodeInfo{
+ "Mul", Tensor{DT_FLOAT, {1, WIDTH, HEIGHT, DEPTH}}}};
+ std::vector<string> output_node_names = {"softmax"};
+ const bool is_text_proto = false;
+
+ GraphTransferer::OutputTensorInfo output_tensor_info;
+ GraphTransferer gt;
+ gt.EnableStrictCheckMode(false);
+ Status status = gt.LoadGraphFromProtoFile(
+ *ops_definitions, MODEL_FILENAME, input_node_info_list, output_node_names,
+ is_text_proto, true /* dry_run_for_unknown_shape */, &output_tensor_info);
+ ASSERT_TRUE(status.ok()) << status;
+
+ std::vector<float> img_floats;
+ LoadImage(&img_floats);
+ RunInferenceByHexagonControlWrapper(gt, img_floats);
+}
+
+TEST(GraphTransferer, RunInceptionV3OnHexagonExampleWithTfRuntime) {
+ if (!USE_TF_RUNTIME) return;
+ const IGraphTransferOpsDefinitions* ops_definitions =
+ &HexagonOpsDefinitions::getInstance();
+ std::vector<GraphTransferer::InputNodeInfo> inputs = {
+ GraphTransferer::InputNodeInfo{
+ "Mul", Tensor{DT_FLOAT, {1, WIDTH, HEIGHT, DEPTH}}}};
+ std::vector<string> outputs = {"softmax"};
+ const bool is_text_proto = false;
+
+ std::vector<float> img_floats;
+ LoadImage(&img_floats);
+
+ LOG(INFO) << "Ioading image finished.";
+
+ Tensor img_tensor(DT_FLOAT, {1, WIDTH, HEIGHT, DEPTH});
+ ASSERT_EQ(WIDTH * HEIGHT * DEPTH, img_floats.size());
+ ASSERT_EQ(img_tensor.TotalBytes(), img_floats.size() * sizeof(float));
+
+ LOG(INFO) << "Copy data to tensor.";
+
+ std::memcpy(img_tensor.flat<float>().data(), img_floats.data(),
+ img_tensor.TotalBytes());
+
+ GraphDef graph_def;
+
+ Status status = ReadBinaryProto(Env::Default(), MODEL_FILENAME, &graph_def);
+
+ ASSERT_TRUE(status.ok());
+
+ LOG(INFO) << "Build fused graph";
+ GraphTransferer gt;
+ gt.EnableStrictCheckMode(false);
+ GraphDef fused_graph_def = GraphTransferUtils::BuildFusedGraphDef(
+ HexagonOpsDefinitions::getInstance(), "remote_fused_graph_execute_node",
+ inputs, outputs, graph_def, &gt);
+
+ // Setup session
+ std::vector<Tensor> output_tensors;
+ SessionOptions session_options;
+ session_options.env = Env::Default();
+ std::unique_ptr<Session> session =
+ std::unique_ptr<Session>(NewSession(session_options));
+ status = session->Create(fused_graph_def);
+ ASSERT_TRUE(status.ok());
+
+ // Setup session arguments
+ RunOptions run_options;
+ run_options.set_trace_level(RunOptions::FULL_TRACE);
+ RunMetadata run_metadata;
+
+ std::vector<std::pair<string, tensorflow::Tensor>> input_tensors;
+ input_tensors.emplace_back("Mul", img_tensor);
+ std::vector<string> output_node_names;
+ output_node_names.emplace_back("remote_fused_graph_execute_node");
+
+ LOG(INFO) << "Run graph";
+ // Run inference with all node as output
+ status = session->Run(run_options, input_tensors, output_node_names, {},
+ &output_tensors, &run_metadata);
+ ASSERT_TRUE(status.ok());
+ ASSERT_EQ(1, output_tensors.size());
+ const Tensor& output_tensor = output_tensors.at(0);
+ LOG(INFO) << "Output byte size = " << output_tensor.TotalBytes();
+ LOG(INFO) << "Output shape = " << output_tensor.shape().DebugString();
+ DumpTop10Results(output_tensor.TotalBytes(),
+ output_tensor.flat<float>().data());
+}
#endif
} // namespace tensorflow
diff --git a/tensorflow/core/kernels/hexagon/hexagon_ops_definitions.cc b/tensorflow/core/kernels/hexagon/hexagon_ops_definitions.cc
index f170a4d556..1ceb8d6b52 100644
--- a/tensorflow/core/kernels/hexagon/hexagon_ops_definitions.cc
+++ b/tensorflow/core/kernels/hexagon/hexagon_ops_definitions.cc
@@ -117,4 +117,9 @@ int HexagonOpsDefinitions::GetOpIdFor(const string& op_type) const {
}
return IGraphTransferOpsDefinitions::INVALID_OP_ID;
}
+
+GraphTransferInfo::Destination HexagonOpsDefinitions::GetTransferDestination()
+ const {
+ return GraphTransferInfo::HEXAGON;
+}
};
diff --git a/tensorflow/core/kernels/hexagon/hexagon_ops_definitions.h b/tensorflow/core/kernels/hexagon/hexagon_ops_definitions.h
index e20dc867c7..097aba9898 100644
--- a/tensorflow/core/kernels/hexagon/hexagon_ops_definitions.h
+++ b/tensorflow/core/kernels/hexagon/hexagon_ops_definitions.h
@@ -32,6 +32,7 @@ class HexagonOpsDefinitions final : public IGraphTransferOpsDefinitions {
int GetInputNodeOpId() const final;
int GetOutputNodeOpId() const final;
int GetOpIdFor(const string& op_type) const final;
+ GraphTransferInfo::Destination GetTransferDestination() const final;
private:
HexagonOpsDefinitions() = default;
diff --git a/tensorflow/core/kernels/hexagon/i_graph_transfer_ops_definitions.h b/tensorflow/core/kernels/hexagon/i_graph_transfer_ops_definitions.h
index 7e733e1f63..62cab7d5c1 100644
--- a/tensorflow/core/kernels/hexagon/i_graph_transfer_ops_definitions.h
+++ b/tensorflow/core/kernels/hexagon/i_graph_transfer_ops_definitions.h
@@ -16,6 +16,7 @@ limitations under the License.
#ifndef THIRD_PARTY_TENSORFLOW_CORE_KERNELS_HEXAGON_I_GRAPH_TRANSFER_OPS_DEFINITIONS_H_
#define THIRD_PARTY_TENSORFLOW_CORE_KERNELS_HEXAGON_I_GRAPH_TRANSFER_OPS_DEFINITIONS_H_
+#include "tensorflow/core/framework/graph_transfer_info.pb.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/platform/macros.h"
@@ -47,6 +48,8 @@ class IGraphTransferOpsDefinitions {
virtual int GetOutputNodeOpId() const = 0;
// Return op id for given string op name
virtual int GetOpIdFor(const string& op_name) const = 0;
+ // Return destination of transfer
+ virtual GraphTransferInfo::Destination GetTransferDestination() const = 0;
private:
TF_DISALLOW_COPY_AND_ASSIGN(IGraphTransferOpsDefinitions);
diff --git a/tensorflow/core/kernels/random_op.cc b/tensorflow/core/kernels/random_op.cc
index 0a1de11162..f3c7e0f26b 100644
--- a/tensorflow/core/kernels/random_op.cc
+++ b/tensorflow/core/kernels/random_op.cc
@@ -541,7 +541,7 @@ TF_CALL_int64(REGISTER_INT);
PhiloxRandomOp< \
GPUDevice, \
random::TruncatedNormalDistribution< \
- random::SingleSampleAdapter<random::PhiloxRandom>, TYPE> >)
+ random::SingleSampleAdapter<random::PhiloxRandom>, TYPE> >);
#define REGISTER_INT(IntType) \
REGISTER_KERNEL_BUILDER(Name("RandomUniformInt") \
diff --git a/tensorflow/core/kernels/random_poisson_op.cc b/tensorflow/core/kernels/random_poisson_op.cc
new file mode 100644
index 0000000000..553a4a7f93
--- /dev/null
+++ b/tensorflow/core/kernels/random_poisson_op.cc
@@ -0,0 +1,357 @@
+/* Copyright 2016 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.
+==============================================================================*/
+
+// See docs in ../ops/random_ops.cc.
+
+#define EIGEN_USE_THREADS
+
+#include "tensorflow/core/kernels/random_poisson_op.h"
+
+#include <algorithm>
+#include <cmath>
+#include <memory>
+
+#include "tensorflow/core/framework/op_kernel.h"
+#include "tensorflow/core/framework/register_types.h"
+#include "tensorflow/core/framework/tensor.h"
+#include "tensorflow/core/framework/tensor_shape.h"
+#include "tensorflow/core/lib/random/random_distributions.h"
+#include "tensorflow/core/lib/random/simple_philox.h"
+#include "tensorflow/core/util/guarded_philox_random.h"
+#include "tensorflow/core/util/work_sharder.h"
+
+#if EIGEN_COMP_GNUC && __cplusplus > 199711L
+#define DISABLE_FLOAT_EQUALITY_WARNING \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"")
+#define ENABLE_FLOAT_EQUALITY_WARNING _Pragma("GCC diagnostic pop")
+#else
+#define DISABLE_FLOAT_EQUALITY_WARNING
+#define ENABLE_FLOAT_EQUALITY_WARNING
+#endif
+
+#define UNIFORM(X) \
+ if (uniform_remaining == 0) { \
+ uniform_remaining = Uniform::kResultElementCount; \
+ uniform_result = uniform(&gen); \
+ } \
+ uniform_remaining--; \
+ CT X = uniform_result[uniform_remaining]
+
+namespace tensorflow {
+namespace {
+
+static constexpr int kReservedSamplesPerOutput = 256;
+
+typedef Eigen::ThreadPoolDevice CPUDevice;
+
+// We will compute half-precision Poisson samples with float precision
+// intermediate calculations.
+template <typename T>
+struct PoissonComputeType {
+ typedef T ComputeType;
+};
+
+template <>
+struct PoissonComputeType<Eigen::half> {
+ typedef float ComputeType;
+};
+
+} // namespace
+
+namespace functor {
+
+template <typename Device, typename T>
+struct PoissonFunctor {
+ void operator()(OpKernelContext* ctx, const Device& d, const T* rate_flat,
+ int num_rate, int num_samples,
+ const random::PhiloxRandom& rng, T* samples_flat);
+};
+
+template <typename T>
+struct PoissonFunctor<CPUDevice, T> {
+ void operator()(OpKernelContext* ctx, const CPUDevice& d, const T* rate_flat,
+ int num_rate, int num_samples,
+ const random::PhiloxRandom& rng, T* samples_flat) {
+ // Two different algorithms are employed, depending on the size of
+ // rate.
+ // If rate < 10, we use an algorithm attributed to Knuth:
+ // Seminumerical Algorithms. Art of Computer Programming, Volume 2.
+ //
+ // This algorithm runs in O(rate) time, and will require O(rate)
+ // uniform
+ // variates.
+ //
+ // If rate >= 10 we use a transformation-rejection algorithm from
+ // pairs
+ // of uniform random variables due to Hormann.
+ // http://www.sciencedirect.com/science/article/pii/0167668793909974
+ //
+ // The algorithm has an acceptance rate of ~89% for the smallest rate
+ // (~10),
+ // and higher accept rates for higher rate, so runtime is
+ // O(NumRate * NumSamples * k) with k ~ 1 / 0.89.
+ //
+ // We partition work first across rates then across
+ // samples-per-rate to
+ // avoid a couple flops which can be done on a per-rate basis.
+
+ typedef random::UniformDistribution<random::PhiloxRandom, CT> Uniform;
+
+ auto DoWork = [num_samples, num_rate, &rng, samples_flat, rate_flat](
+ int start_output, int limit_output) {
+ // Capturing "rng" by value would only make a copy for the _shared_
+ // lambda. Since we want to let each worker have its own copy, we pass
+ // "rng" by reference and explicitly do a copy assignment.
+
+ Uniform uniform;
+ typename Uniform::ResultType uniform_result;
+ for (int64 output_idx = start_output; output_idx < limit_output;
+ /* output_idx incremented within inner loop below */) {
+ const int64 rate_idx = output_idx / num_samples;
+
+ // Several calculations can be done on a per-rate basis.
+ const CT rate = CT(rate_flat[rate_idx]);
+
+ auto samples_rate_output = samples_flat + rate_idx;
+
+ if (rate < CT(10)) {
+ // Knuth's algorithm for generating Poisson random variates.
+ // Given a Poisson process, the time between events is exponentially
+ // distributed. If we have a Poisson process with rate lambda, then,
+ // the time between events is distributed Exp(lambda). If X ~
+ // Uniform(0, 1), then Y ~ Exp(lambda), where Y = -log(X) / lambda.
+ // Thus to simulate a Poisson draw, we can draw X_i ~ Exp(lambda),
+ // and N ~ Poisson(lambda), where N is the least number such that
+ // \sum_i^N X_i > 1.
+ const CT exp_neg_rate = Eigen::numext::exp(-rate);
+
+ // Compute the rest of the samples for the current rate value.
+ for (int64 sample_idx = output_idx % num_samples;
+ sample_idx < num_samples && output_idx < limit_output;
+ sample_idx++, output_idx++) {
+ random::PhiloxRandom gen = rng;
+ gen.Skip(kReservedSamplesPerOutput * output_idx);
+ int16 uniform_remaining = 0;
+
+ CT prod = 1;
+ CT x = 0;
+
+ // Keep trying until we surpass e^(-rate). This will take
+ // expected time proportional to rate.
+ while (true) {
+ UNIFORM(u);
+ prod = prod * u;
+ if (prod <= exp_neg_rate) {
+ samples_rate_output[sample_idx * num_rate] = T(x);
+ break;
+ }
+ x += 1;
+ }
+ }
+ continue;
+ }
+ // Transformed rejection due to Hormann.
+ //
+ // Given a CDF F(x), and G(x), a dominating distribution chosen such
+ // that it is close to the inverse CDF F^-1(x), compute the following
+ // steps:
+ //
+ // 1) Generate U and V, two independent random variates. Set U = U - 0.5
+ // (this step isn't strictly necessary, but is done to make some
+ // calculations symmetric and convenient. Henceforth, G is defined on
+ // [-0.5, 0.5]).
+ //
+ // 2) If V <= alpha * F'(G(U)) * G'(U), return floor(G(U)), else return
+ // to step 1. alpha is the acceptance probability of the rejection
+ // algorithm.
+ //
+ // For more details on transformed rejection, see:
+ // http://citeseer.ist.psu.edu/viewdoc/citations;jsessionid=1BEB35946CC807879F55D42512E5490C?doi=10.1.1.48.3054.
+ //
+ // The dominating distribution in this case:
+ //
+ // G(u) = (2 * a / (2 - |u|) + b) * u + c
+
+ using Eigen::numext::log;
+ const CT log_rate = log(rate);
+
+ // Constants used to define the dominating distribution. Names taken
+ // from Hormann's paper. Constants were chosen to define the tightest
+ // G(u) for the inverse Poisson CDF.
+ const CT b = CT(0.931) + CT(2.53) * Eigen::numext::sqrt(rate);
+ const CT a = CT(-0.059) + CT(0.02483) * b;
+
+ // This is the inverse acceptance rate. At a minimum (when rate = 10),
+ // this corresponds to ~75% acceptance. As the rate becomes larger, this
+ // approaches ~89%.
+ const CT inv_alpha = CT(1.1239) + CT(1.1328) / (b - CT(3.4));
+
+ // Compute the rest of the samples for the current rate value.
+ for (int64 sample_idx = output_idx % num_samples;
+ sample_idx < num_samples && output_idx < limit_output;
+ sample_idx++, output_idx++) {
+ random::PhiloxRandom gen = rng;
+ gen.Skip(kReservedSamplesPerOutput * output_idx);
+ int16 uniform_remaining = 0;
+
+ while (true) {
+ UNIFORM(u);
+ u -= CT(0.5);
+ UNIFORM(v);
+
+ CT u_shifted = CT(0.5) - Eigen::numext::abs(u);
+ CT k = Eigen::numext::floor((CT(2) * a / u_shifted + b) * u + rate +
+ CT(0.43));
+
+ // When alpha * f(G(U)) * G'(U) is close to 1, it is possible to
+ // find a rectangle (-u_r, u_r) x (0, v_r) under the curve, such
+ // that if v <= v_r and |u| <= u_r, then we can accept.
+ // Here v_r = 0.9227 - 3.6224 / (b - 2) and u_r = 0.43.
+ if (u_shifted >= CT(0.07) &&
+ v <= CT(0.9277) - CT(3.6224) / (b - CT(2))) {
+ samples_rate_output[sample_idx * num_rate] = T(k);
+ break;
+ }
+
+ if (k < 0 || (u_shifted < CT(0.013) && v > u_shifted)) {
+ continue;
+ }
+
+ // The expression below is equivalent to the computation of step 2)
+ // in transformed rejection (v <= alpha * F'(G(u)) * G'(u)).
+ CT s = log(v * inv_alpha / (a / (u_shifted * u_shifted) + b));
+ CT t = -rate + k * log_rate - Eigen::numext::lgamma(k + 1);
+ if (s <= t) {
+ samples_rate_output[sample_idx * num_rate] = T(k);
+ break;
+ }
+ }
+ }
+ }
+ };
+
+ // This will depend on rate.
+ // For rate < 10, on average, O(rate) calls to uniform are
+ // needed, with that
+ // many multiplies. ~10 uniform calls on average with ~25 cost op calls.
+ //
+ // Very roughly, for rate >= 10, the single call to log + call to
+ // lgamma
+ // occur for ~60 percent of samples.
+ // 2 x 100 (64-bit cycles per log) * 0.62 = ~124
+ // Additionally, there are ~10 other ops (+, *, /, ...) at 3-6 cycles each:
+ // 40 * .62 = ~25.
+ //
+ // Finally, there are several other ops that are done every loop along with
+ // 2 uniform generations along with 5 other ops at 3-6 cycles each.
+ // ~15 / .89 = ~16
+ //
+ // In total this should be ~165 + 2 * Uniform::kElementCost.
+ // We assume that half the tensor has rate < 10, so on average 6
+ // uniform's
+ // will be needed. We will upper bound the other op cost by the one for
+ // rate > 10.
+ static const int kElementCost = 165 + 6 * Uniform::kElementCost +
+ 6 * random::PhiloxRandom::kElementCost;
+ auto worker_threads = *(ctx->device()->tensorflow_cpu_worker_threads());
+ Shard(worker_threads.num_threads, worker_threads.workers,
+ num_rate * num_samples, kElementCost, DoWork);
+ }
+
+ private:
+ typedef typename PoissonComputeType<T>::ComputeType CT;
+};
+
+} // namespace functor
+
+namespace {
+
+// Samples from one or more Poisson distributions.
+template <typename T>
+class RandomPoissonOp : public OpKernel {
+ public:
+ explicit RandomPoissonOp(OpKernelConstruction* context) : OpKernel(context) {
+ OP_REQUIRES_OK(context, generator_.Init(context));
+ }
+
+ void Compute(OpKernelContext* ctx) override {
+ const Tensor& shape_t = ctx->input(0);
+ const Tensor& rate_t = ctx->input(1);
+
+ OP_REQUIRES(ctx,
+ TensorShapeUtils::IsVector(shape_t.shape()) &&
+ (shape_t.dtype() == DataType::DT_INT32 ||
+ shape_t.dtype() == DataType::DT_INT64),
+ errors::InvalidArgument(
+ "shape must be a vector of {int32,int64}, got shape: ",
+ shape_t.DebugString()));
+ TensorShape samples_shape;
+ if (shape_t.dtype() == DataType::DT_INT32) {
+ auto vec = shape_t.flat<int32>();
+ OP_REQUIRES_OK(ctx, TensorShapeUtils::MakeShape(vec.data(), vec.size(),
+ &samples_shape));
+ } else if (shape_t.dtype() == DataType::DT_INT64) {
+ auto vec = shape_t.flat<int64>();
+ OP_REQUIRES_OK(ctx, TensorShapeUtils::MakeShape(vec.data(), vec.size(),
+ &samples_shape));
+ }
+ const int64 num_samples = samples_shape.num_elements();
+ OP_REQUIRES(ctx, num_samples > 0,
+ errors::InvalidArgument(
+ "Input shape should have non-zero element count, got: ",
+ num_samples));
+
+ samples_shape.AppendShape(rate_t.shape());
+ // Allocate output samples.
+ Tensor* samples_t = nullptr;
+ OP_REQUIRES_OK(ctx, ctx->allocate_output(0, samples_shape, &samples_t));
+
+ const auto rate_flat = rate_t.flat<T>().data();
+ const int64 num_rate = rate_t.NumElements();
+ OP_REQUIRES(
+ ctx, num_rate > 0,
+ errors::InvalidArgument(
+ "Input rate should have non-zero element count, got: ", num_rate));
+ auto samples_flat = samples_t->flat<T>().data();
+ random::PhiloxRandom rng = generator_.ReserveRandomOutputs(
+ num_samples * num_rate, kReservedSamplesPerOutput);
+
+ functor::PoissonFunctor<CPUDevice, T>()(ctx, ctx->eigen_device<CPUDevice>(),
+ rate_flat, num_rate, num_samples,
+ rng, samples_flat);
+ }
+
+ private:
+ GuardedPhiloxRandom generator_;
+
+ TF_DISALLOW_COPY_AND_ASSIGN(RandomPoissonOp);
+};
+} // namespace
+
+#undef UNIFORM
+
+#define REGISTER(TYPE) \
+ REGISTER_KERNEL_BUILDER( \
+ Name("RandomPoisson").Device(DEVICE_CPU).TypeConstraint<TYPE>("dtype"), \
+ RandomPoissonOp<TYPE>);
+
+TF_CALL_half(REGISTER);
+TF_CALL_float(REGISTER);
+TF_CALL_double(REGISTER);
+
+#undef REGISTER
+
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/random_poisson_op.h b/tensorflow/core/kernels/random_poisson_op.h
new file mode 100644
index 0000000000..6c49acc800
--- /dev/null
+++ b/tensorflow/core/kernels/random_poisson_op.h
@@ -0,0 +1,31 @@
+/* Copyright 2016 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_KERNELS_RANDOM_POISSON_OP_H_
+#define TENSORFLOW_KERNELS_RANDOM_POISSON_OP_H_
+
+namespace tensorflow {
+
+namespace functor {
+
+// Generic helper functor for the Random Poisson Op.
+template <typename Device, typename T>
+struct PoissonFunctor;
+
+} // namespace functor
+
+} // namespace tensorflow
+
+#endif // TENSORFLOW_KERNELS_RANDOM_POISSON_OP_H_
diff --git a/tensorflow/core/kernels/random_poisson_op_test.cc b/tensorflow/core/kernels/random_poisson_op_test.cc
new file mode 100644
index 0000000000..bccdbf6c7f
--- /dev/null
+++ b/tensorflow/core/kernels/random_poisson_op_test.cc
@@ -0,0 +1,82 @@
+/* Copyright 2015 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 <random>
+
+#include "tensorflow/core/common_runtime/kernel_benchmark_testlib.h"
+#include "tensorflow/core/framework/tensor.h"
+#include "tensorflow/core/platform/test.h"
+#include "tensorflow/core/platform/test_benchmark.h"
+
+namespace tensorflow {
+namespace {
+
+Tensor VecShape(int64 v) {
+ if (v >= std::numeric_limits<int32>::max()) {
+ Tensor shape(DT_INT64, TensorShape({1}));
+ shape.vec<int64>()(0) = v;
+ return shape;
+ } else {
+ Tensor shape(DT_INT32, TensorShape({1}));
+ shape.vec<int32>()(0) = v;
+ return shape;
+ }
+}
+
+Tensor VecLam32(int64 n, int magnitude) {
+ std::mt19937 gen(0x12345);
+ std::uniform_real_distribution<float> dist(0.0, 1.0);
+ Tensor lams(DT_FLOAT, TensorShape({n}));
+ for (int i = 0; i < n; i++) {
+ // Generate in range (magnitude, 2 * magnitude)
+ lams.vec<float>()(i) = magnitude * (1 + dist(gen));
+ }
+ return lams;
+}
+
+Tensor VecLam64(int64 n, int magnitude) {
+ std::mt19937 gen(0x12345);
+ std::uniform_real_distribution<double> dist(0.0, 1.0);
+ Tensor lams(DT_DOUBLE, TensorShape({n}));
+ for (int i = 0; i < n; i++) {
+ // Generate in range (magnitude, 2 * magnitude)
+ lams.vec<double>()(i) = magnitude * (1 + dist(gen));
+ }
+ return lams;
+}
+
+#define BM_Poisson(DEVICE, BITS, MAGNITUDE) \
+ static void BM_##DEVICE##_RandomPoisson_lam_##MAGNITUDE##_##BITS( \
+ int iters, int nsamp, int nlam) { \
+ testing::ItemsProcessed(static_cast<int64>(iters) * nsamp * nlam); \
+ Graph* g = new Graph(OpRegistry::Global()); \
+ test::graph::RandomPoisson( \
+ g, test::graph::Constant(g, VecShape(nsamp)), \
+ test::graph::Constant(g, VecLam##BITS(nlam, MAGNITUDE))); \
+ test::Benchmark(#DEVICE, g).Run(iters); \
+ } \
+ BENCHMARK(BM_##DEVICE##_RandomPoisson_lam_##MAGNITUDE##_##BITS) \
+ ->RangePair(1, 64, 2, 50);
+
+BM_Poisson(cpu, 32, 1);
+BM_Poisson(cpu, 32, 8);
+BM_Poisson(cpu, 32, 32);
+
+BM_Poisson(cpu, 64, 1);
+BM_Poisson(cpu, 64, 8);
+BM_Poisson(cpu, 64, 32);
+
+} // namespace
+} // namespace tensorflow
diff --git a/tensorflow/core/kernels/remote_fused_graph_execute_op.cc b/tensorflow/core/kernels/remote_fused_graph_execute_op.cc
index fc7350d54c..8d1dacfc2e 100644
--- a/tensorflow/core/kernels/remote_fused_graph_execute_op.cc
+++ b/tensorflow/core/kernels/remote_fused_graph_execute_op.cc
@@ -65,7 +65,9 @@ class RemoteFusedGraphExecuteOp : public OpKernel {
CHECK(ctx != nullptr);
const int input_count = ctx->num_inputs();
const GraphTransferInfo& gt_info = graph_transferer_.GetGraphTransferInfo();
- CHECK(input_count == gt_info.graph_input_node_info_size());
+ CHECK(input_count == gt_info.graph_input_node_info_size())
+ << "input_count = " << input_count
+ << ", gt input count = " << gt_info.graph_input_node_info_size();
// 3. Send inputs into remote processor
for (int i = 0; i < input_count; ++i) {
@@ -102,8 +104,10 @@ class RemoteFusedGraphExecuteOp : public OpKernel {
// for each output node
CHECK(outputs.size() <= 1);
if (!outputs.empty()) {
- std::memcpy(output->vec<uint8>().data(), std::get<0>(outputs[0]),
- std::get<1>(outputs[2]));
+ CHECK(output->TotalBytes() >= std::get<1>(outputs[0]));
+ // TODO(satok): Avoid specifying float
+ std::memcpy(output->flat<float>().data(), std::get<0>(outputs[0]),
+ std::get<1>(outputs[0]));
}
}
}
diff --git a/tensorflow/core/ops/array_ops.cc b/tensorflow/core/ops/array_ops.cc
index a03f910c14..631440402d 100644
--- a/tensorflow/core/ops/array_ops.cc
+++ b/tensorflow/core/ops/array_ops.cc
@@ -4911,9 +4911,8 @@ REGISTER_OP("FakeQuantWithMinMaxVars")
return Status::OK();
})
.Doc(R"doc(
-Fake-quantize the 'inputs' tensor of type float and shape `[b, h, w, d]` via
-global float scalars `min` and `max` to 'outputs' tensor of same shape as
-`inputs`.
+Fake-quantize the 'inputs' tensor of type float via global float scalars `min`
+and `max` to 'outputs' tensor of same shape as `inputs`.
[min; max] is the clamping range for the 'inputs' data. Op divides this range
into 255 steps (total of 256 values), then replaces each 'inputs' value with the
diff --git a/tensorflow/core/ops/compat/ops_history.v0.pbtxt b/tensorflow/core/ops/compat/ops_history.v0.pbtxt
index 516cdfbdd9..38e91085d2 100644
--- a/tensorflow/core/ops/compat/ops_history.v0.pbtxt
+++ b/tensorflow/core/ops/compat/ops_history.v0.pbtxt
@@ -22618,6 +22618,57 @@ op {
is_stateful: true
}
op {
+ name: "RandomPoisson"
+ input_arg {
+ name: "shape"
+ type_attr: "S"
+ }
+ input_arg {
+ name: "rate"
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "S"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
name: "RandomShuffle"
input_arg {
name: "value"
diff --git a/tensorflow/core/ops/compat/ops_history.v1.pbtxt b/tensorflow/core/ops/compat/ops_history.v1.pbtxt
new file mode 100644
index 0000000000..90f53f6dd8
--- /dev/null
+++ b/tensorflow/core/ops/compat/ops_history.v1.pbtxt
@@ -0,0 +1,22366 @@
+op {
+ name: "Abort"
+ attr {
+ name: "error_msg"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "exit_without_error"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "Abs"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "AccumulatorApplyGradient"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "local_step"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "gradient"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "AccumulatorNumAccumulated"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "num_accumulated"
+ type: DT_INT32
+ }
+}
+op {
+ name: "AccumulatorSetGlobalStep"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "new_global_step"
+ type: DT_INT64
+ }
+}
+op {
+ name: "AccumulatorTakeGradient"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "num_required"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "average"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "Acos"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Add"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_STRING
+ }
+ }
+ }
+}
+op {
+ name: "AddManySparseToTensorsMap"
+ input_arg {
+ name: "sparse_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "sparse_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "sparse_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sparse_handles"
+ type: DT_INT64
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "AddN"
+ input_arg {
+ name: "inputs"
+ type_attr: "T"
+ number_attr: "N"
+ }
+ output_arg {
+ name: "sum"
+ type_attr: "T"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ is_aggregate: true
+ is_commutative: true
+}
+op {
+ name: "AddSparseToTensorsMap"
+ input_arg {
+ name: "sparse_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "sparse_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "sparse_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sparse_handle"
+ type: DT_INT64
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "AdjustContrast"
+ input_arg {
+ name: "images"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "contrast_factor"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min_value"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_value"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ deprecation {
+ version: 2
+ }
+}
+op {
+ name: "AdjustContrastv2"
+ input_arg {
+ name: "images"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "contrast_factor"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type: DT_FLOAT
+ }
+}
+op {
+ name: "AdjustHue"
+ input_arg {
+ name: "images"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "delta"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type: DT_FLOAT
+ }
+}
+op {
+ name: "AdjustSaturation"
+ input_arg {
+ name: "images"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "scale"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type: DT_FLOAT
+ }
+}
+op {
+ name: "All"
+ input_arg {
+ name: "input"
+ type: DT_BOOL
+ }
+ input_arg {
+ name: "reduction_indices"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type: DT_BOOL
+ }
+ attr {
+ name: "keep_dims"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "AllCandidateSampler"
+ input_arg {
+ name: "true_classes"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sampled_candidates"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "true_expected_count"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "sampled_expected_count"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "num_true"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "num_sampled"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "unique"
+ type: "bool"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "Any"
+ input_arg {
+ name: "input"
+ type: DT_BOOL
+ }
+ input_arg {
+ name: "reduction_indices"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type: DT_BOOL
+ }
+ attr {
+ name: "keep_dims"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "ApplyAdadelta"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum_update"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ApplyAdagrad"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ApplyAdagradDA"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "gradient_accumulator"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "gradient_squared_accumulator"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "global_step"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ApplyAdam"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "m"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "v"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "beta1_power"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "beta2_power"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "beta1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "beta2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ApplyCenteredRMSProp"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "mg"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "ms"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "mom"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ApplyFtrl"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "linear"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lr_power"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ApplyGradientDescent"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "alpha"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "delta"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ApplyMomentum"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "use_nesterov"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ApplyProximalAdagrad"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ApplyProximalGradientDescent"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "alpha"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "delta"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ApplyRMSProp"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "ms"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "mom"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ArgMax"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "dimension"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type: DT_INT64
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "ArgMin"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "dimension"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type: DT_INT64
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "AsString"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type: DT_STRING
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_BOOL
+ type: DT_INT8
+ }
+ }
+ }
+ attr {
+ name: "precision"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "scientific"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "shortest"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "width"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "fill"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+}
+op {
+ name: "Asin"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Assert"
+ input_arg {
+ name: "condition"
+ type: DT_BOOL
+ }
+ input_arg {
+ name: "data"
+ type_list_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "summarize"
+ type: "int"
+ default_value {
+ i: 3
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Assign"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "validate_shape"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ allows_uninitialized_input: true
+}
+op {
+ name: "AssignAdd"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "AssignSub"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "Atan"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "AudioSummary"
+ input_arg {
+ name: "tag"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "tensor"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "summary"
+ type: DT_STRING
+ }
+ attr {
+ name: "sample_rate"
+ type: "float"
+ }
+ attr {
+ name: "max_outputs"
+ type: "int"
+ default_value {
+ i: 3
+ }
+ has_minimum: true
+ minimum: 1
+ }
+ deprecation {
+ version: 15
+ }
+}
+op {
+ name: "AudioSummaryV2"
+ input_arg {
+ name: "tag"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "tensor"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "sample_rate"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "summary"
+ type: DT_STRING
+ }
+ attr {
+ name: "max_outputs"
+ type: "int"
+ default_value {
+ i: 3
+ }
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "AvgPool"
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ allowed_values {
+ list {
+ s: "NHWC"
+ s: "NCHW"
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "AvgPool3D"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "AvgPool3DGrad"
+ input_arg {
+ name: "orig_input_shape"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "AvgPoolGrad"
+ input_arg {
+ name: "orig_input_shape"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ allowed_values {
+ list {
+ s: "NHWC"
+ s: "NCHW"
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Barrier"
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "shapes"
+ type: "list(shape)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "capacity"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "BarrierClose"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "cancel_pending_enqueues"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "BarrierIncompleteSize"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "size"
+ type: DT_INT32
+ }
+}
+op {
+ name: "BarrierInsertMany"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "keys"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "values"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "component_index"
+ type: "int"
+ }
+}
+op {
+ name: "BarrierReadySize"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "size"
+ type: DT_INT32
+ }
+}
+op {
+ name: "BarrierTakeMany"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "num_elements"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "keys"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "values"
+ type_list_attr: "component_types"
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "allow_small_batch"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "wait_for_incomplete"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+}
+op {
+ name: "BatchCholesky"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+ deprecation {
+ version: 13
+ }
+}
+op {
+ name: "BatchCholeskyGrad"
+ input_arg {
+ name: "l"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ deprecation {
+ version: 13
+ }
+}
+op {
+ name: "BatchFFT"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+ deprecation {
+ version: 15
+ }
+}
+op {
+ name: "BatchFFT2D"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+ deprecation {
+ version: 15
+ }
+}
+op {
+ name: "BatchFFT3D"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+ deprecation {
+ version: 15
+ }
+}
+op {
+ name: "BatchIFFT"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+ deprecation {
+ version: 15
+ }
+}
+op {
+ name: "BatchIFFT2D"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+ deprecation {
+ version: 15
+ }
+}
+op {
+ name: "BatchIFFT3D"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+ deprecation {
+ version: 15
+ }
+}
+op {
+ name: "BatchMatMul"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ attr {
+ name: "adj_x"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "adj_y"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "BatchMatrixBandPart"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "num_lower"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "num_upper"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "band"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ deprecation {
+ version: 14
+ }
+}
+op {
+ name: "BatchMatrixDeterminant"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ deprecation {
+ version: 13
+ }
+}
+op {
+ name: "BatchMatrixDiag"
+ input_arg {
+ name: "diagonal"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ deprecation {
+ version: 14
+ }
+}
+op {
+ name: "BatchMatrixDiagPart"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "diagonal"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ deprecation {
+ version: 14
+ }
+}
+op {
+ name: "BatchMatrixInverse"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "adjoint"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+ deprecation {
+ version: 13
+ }
+}
+op {
+ name: "BatchMatrixSetDiag"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "diagonal"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ deprecation {
+ version: 14
+ }
+}
+op {
+ name: "BatchMatrixSolve"
+ input_arg {
+ name: "matrix"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rhs"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "adjoint"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+ deprecation {
+ version: 13
+ }
+}
+op {
+ name: "BatchMatrixSolveLs"
+ input_arg {
+ name: "matrix"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rhs"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2_regularizer"
+ type: DT_DOUBLE
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+ attr {
+ name: "fast"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ deprecation {
+ version: 13
+ }
+}
+op {
+ name: "BatchMatrixTriangularSolve"
+ input_arg {
+ name: "matrix"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rhs"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "lower"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "adjoint"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+ deprecation {
+ version: 13
+ }
+}
+op {
+ name: "BatchNormWithGlobalNormalization"
+ input_arg {
+ name: "t"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "m"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "v"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "beta"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "gamma"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "result"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "variance_epsilon"
+ type: "float"
+ }
+ attr {
+ name: "scale_after_normalization"
+ type: "bool"
+ }
+ deprecation {
+ version: 9
+ }
+}
+op {
+ name: "BatchNormWithGlobalNormalizationGrad"
+ input_arg {
+ name: "t"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "m"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "v"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "gamma"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "dx"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "dm"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "dv"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "db"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "dg"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "variance_epsilon"
+ type: "float"
+ }
+ attr {
+ name: "scale_after_normalization"
+ type: "bool"
+ }
+ deprecation {
+ version: 9
+ }
+}
+op {
+ name: "BatchSelfAdjointEig"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+ deprecation {
+ version: 11
+ }
+}
+op {
+ name: "BatchSelfAdjointEigV2"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "e"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "v"
+ type_attr: "T"
+ }
+ attr {
+ name: "compute_v"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+ deprecation {
+ version: 13
+ }
+}
+op {
+ name: "BatchSvd"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "s"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "u"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "v"
+ type_attr: "T"
+ }
+ attr {
+ name: "compute_uv"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "full_matrices"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ deprecation {
+ version: 13
+ }
+}
+op {
+ name: "BatchToSpace"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "crops"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "block_size"
+ type: "int"
+ has_minimum: true
+ minimum: 2
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "BatchToSpaceND"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "block_shape"
+ type_attr: "Tblock_shape"
+ }
+ input_arg {
+ name: "crops"
+ type_attr: "Tcrops"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tblock_shape"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "Tcrops"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Betainc"
+ input_arg {
+ name: "a"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "b"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "BiasAdd"
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "bias"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ allowed_values {
+ list {
+ s: "NHWC"
+ s: "NCHW"
+ }
+ }
+ }
+}
+op {
+ name: "BiasAddGrad"
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ allowed_values {
+ list {
+ s: "NHWC"
+ s: "NCHW"
+ }
+ }
+ }
+}
+op {
+ name: "BiasAddV1"
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "bias"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "Bitcast"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "type"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "type"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "BroadcastArgs"
+ input_arg {
+ name: "s0"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "s1"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "r0"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "BroadcastGradientArgs"
+ input_arg {
+ name: "s0"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "s1"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "r0"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "r1"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "CTCBeamSearchDecoder"
+ input_arg {
+ name: "inputs"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "sequence_length"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "decoded_indices"
+ type: DT_INT64
+ number_attr: "top_paths"
+ }
+ output_arg {
+ name: "decoded_values"
+ type: DT_INT64
+ number_attr: "top_paths"
+ }
+ output_arg {
+ name: "decoded_shape"
+ type: DT_INT64
+ number_attr: "top_paths"
+ }
+ output_arg {
+ name: "log_probability"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "beam_width"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "top_paths"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "merge_repeated"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+}
+op {
+ name: "CTCGreedyDecoder"
+ input_arg {
+ name: "inputs"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "sequence_length"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "decoded_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "decoded_values"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "decoded_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "log_probability"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "merge_repeated"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "CTCLoss"
+ input_arg {
+ name: "inputs"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "labels_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "labels_values"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "sequence_length"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "loss"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "gradient"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "preprocess_collapse_repeated"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "ctc_merge_repeated"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+}
+op {
+ name: "Cast"
+ input_arg {
+ name: "x"
+ type_attr: "SrcT"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "DstT"
+ }
+ attr {
+ name: "SrcT"
+ type: "type"
+ }
+ attr {
+ name: "DstT"
+ type: "type"
+ }
+}
+op {
+ name: "Ceil"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "CheckNumerics"
+ input_arg {
+ name: "tensor"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "message"
+ type: "string"
+ }
+}
+op {
+ name: "Cholesky"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+}
+op {
+ name: "CholeskyGrad"
+ input_arg {
+ name: "l"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Complex"
+ input_arg {
+ name: "real"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "imag"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "Tout"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "Tout"
+ type: "type"
+ default_value {
+ type: DT_COMPLEX64
+ }
+ allowed_values {
+ list {
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "ComplexAbs"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "Tout"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_COMPLEX64
+ }
+ allowed_values {
+ list {
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ attr {
+ name: "Tout"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "ComputeAccidentalHits"
+ input_arg {
+ name: "true_classes"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "sampled_candidates"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "indices"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "ids"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "weights"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "num_true"
+ type: "int"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "Concat"
+ input_arg {
+ name: "concat_dim"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "values"
+ type_attr: "T"
+ number_attr: "N"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 2
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "ConcatOffset"
+ input_arg {
+ name: "concat_dim"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "shape"
+ type: DT_INT32
+ number_attr: "N"
+ }
+ output_arg {
+ name: "offset"
+ type: DT_INT32
+ number_attr: "N"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 2
+ }
+}
+op {
+ name: "ConcatV2"
+ input_arg {
+ name: "values"
+ type_attr: "T"
+ number_attr: "N"
+ }
+ input_arg {
+ name: "axis"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 2
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "ConditionalAccumulator"
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "shape"
+ type: "shape"
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Conj"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_COMPLEX64
+ }
+ allowed_values {
+ list {
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Const"
+ output_arg {
+ name: "output"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "value"
+ type: "tensor"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+}
+op {
+ name: "ControlTrigger"
+}
+op {
+ name: "Conv2D"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "use_cudnn_on_gpu"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ allowed_values {
+ list {
+ s: "NHWC"
+ s: "NCHW"
+ }
+ }
+ }
+}
+op {
+ name: "Conv2DBackpropFilter"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter_sizes"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "use_cudnn_on_gpu"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ allowed_values {
+ list {
+ s: "NHWC"
+ s: "NCHW"
+ }
+ }
+ }
+}
+op {
+ name: "Conv2DBackpropInput"
+ input_arg {
+ name: "input_sizes"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "use_cudnn_on_gpu"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ allowed_values {
+ list {
+ s: "NHWC"
+ s: "NCHW"
+ }
+ }
+ }
+}
+op {
+ name: "Conv3D"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "Conv3DBackpropFilter"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ deprecation {
+ version: 10
+ }
+}
+op {
+ name: "Conv3DBackpropFilterV2"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter_sizes"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "Conv3DBackpropInput"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ deprecation {
+ version: 10
+ }
+}
+op {
+ name: "Conv3DBackpropInputV2"
+ input_arg {
+ name: "input_sizes"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "Copy"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "tensor_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ allows_uninitialized_input: true
+}
+op {
+ name: "CopyHost"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "tensor_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ allows_uninitialized_input: true
+}
+op {
+ name: "Cos"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "CountUpTo"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "limit"
+ type: "int"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "CropAndResize"
+ input_arg {
+ name: "image"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "boxes"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "box_ind"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "crop_size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "crops"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "method"
+ type: "string"
+ default_value {
+ s: "bilinear"
+ }
+ allowed_values {
+ list {
+ s: "bilinear"
+ }
+ }
+ }
+ attr {
+ name: "extrapolation_value"
+ type: "float"
+ default_value {
+ f: 0
+ }
+ }
+}
+op {
+ name: "CropAndResizeGradBoxes"
+ input_arg {
+ name: "grads"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "image"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "boxes"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "box_ind"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "method"
+ type: "string"
+ default_value {
+ s: "bilinear"
+ }
+ allowed_values {
+ list {
+ s: "bilinear"
+ }
+ }
+ }
+}
+op {
+ name: "CropAndResizeGradImage"
+ input_arg {
+ name: "grads"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "boxes"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "box_ind"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "image_size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "method"
+ type: "string"
+ default_value {
+ s: "bilinear"
+ }
+ allowed_values {
+ list {
+ s: "bilinear"
+ }
+ }
+ }
+}
+op {
+ name: "Cross"
+ input_arg {
+ name: "a"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "b"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "product"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "Cumprod"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "axis"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ }
+ attr {
+ name: "exclusive"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "reverse"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Cumsum"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "axis"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ }
+ attr {
+ name: "exclusive"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "reverse"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "DebugIdentity"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "tensor_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "debug_urls"
+ type: "list(string)"
+ default_value {
+ list {
+ }
+ }
+ }
+ allows_uninitialized_input: true
+}
+op {
+ name: "DebugNanCount"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type: DT_INT64
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "tensor_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "debug_urls"
+ type: "list(string)"
+ default_value {
+ list {
+ }
+ }
+ }
+ allows_uninitialized_input: true
+}
+op {
+ name: "DebugNumericSummary"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type: DT_DOUBLE
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "tensor_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "debug_urls"
+ type: "list(string)"
+ default_value {
+ list {
+ }
+ }
+ }
+ allows_uninitialized_input: true
+}
+op {
+ name: "DecodeBase64"
+ input_arg {
+ name: "input"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "output"
+ type: DT_STRING
+ }
+}
+op {
+ name: "DecodeCSV"
+ input_arg {
+ name: "records"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "record_defaults"
+ type_list_attr: "OUT_TYPE"
+ }
+ output_arg {
+ name: "output"
+ type_list_attr: "OUT_TYPE"
+ }
+ attr {
+ name: "OUT_TYPE"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_STRING
+ }
+ }
+ }
+ attr {
+ name: "field_delim"
+ type: "string"
+ default_value {
+ s: ","
+ }
+ }
+}
+op {
+ name: "DecodeGif"
+ input_arg {
+ name: "contents"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "image"
+ type: DT_UINT8
+ }
+}
+op {
+ name: "DecodeJSONExample"
+ input_arg {
+ name: "json_examples"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "binary_examples"
+ type: DT_STRING
+ }
+}
+op {
+ name: "DecodeJpeg"
+ input_arg {
+ name: "contents"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "image"
+ type: DT_UINT8
+ }
+ attr {
+ name: "channels"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "ratio"
+ type: "int"
+ default_value {
+ i: 1
+ }
+ }
+ attr {
+ name: "fancy_upscaling"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "try_recover_truncated"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "acceptable_fraction"
+ type: "float"
+ default_value {
+ f: 1
+ }
+ }
+ attr {
+ name: "dct_method"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+}
+op {
+ name: "DecodePng"
+ input_arg {
+ name: "contents"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "image"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "channels"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ default_value {
+ type: DT_UINT8
+ }
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_UINT16
+ }
+ }
+ }
+}
+op {
+ name: "DecodeRaw"
+ input_arg {
+ name: "bytes"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "output"
+ type_attr: "out_type"
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "little_endian"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+}
+op {
+ name: "DeleteSessionTensor"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+}
+op {
+ name: "DenseToDenseSetOperation"
+ input_arg {
+ name: "set1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "set2"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "result_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "result_values"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "result_shape"
+ type: DT_INT64
+ }
+ attr {
+ name: "set_operation"
+ type: "string"
+ }
+ attr {
+ name: "validate_indices"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_STRING
+ }
+ }
+ }
+}
+op {
+ name: "DenseToSparseSetOperation"
+ input_arg {
+ name: "set1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "set2_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "set2_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "set2_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "result_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "result_values"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "result_shape"
+ type: DT_INT64
+ }
+ attr {
+ name: "set_operation"
+ type: "string"
+ }
+ attr {
+ name: "validate_indices"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_STRING
+ }
+ }
+ }
+}
+op {
+ name: "DepthToSpace"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "block_size"
+ type: "int"
+ has_minimum: true
+ minimum: 2
+ }
+}
+op {
+ name: "DepthwiseConv2dNative"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "DepthwiseConv2dNativeBackpropFilter"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter_sizes"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "DepthwiseConv2dNativeBackpropInput"
+ input_arg {
+ name: "input_sizes"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "Dequantize"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "min_range"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_range"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "mode"
+ type: "string"
+ default_value {
+ s: "MIN_COMBINED"
+ }
+ allowed_values {
+ list {
+ s: "MIN_COMBINED"
+ s: "MIN_FIRST"
+ }
+ }
+ }
+}
+op {
+ name: "DeserializeManySparse"
+ input_arg {
+ name: "serialized_sparse"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "sparse_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sparse_values"
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "sparse_shape"
+ type: DT_INT64
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+}
+op {
+ name: "DestroyTemporaryVariable"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ output_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "var_name"
+ type: "string"
+ }
+}
+op {
+ name: "Diag"
+ input_arg {
+ name: "diagonal"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "DiagPart"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "diagonal"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Digamma"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Dilation2D"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "rates"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "Dilation2DBackpropFilter"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "filter_backprop"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "rates"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "Dilation2DBackpropInput"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "in_backprop"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "rates"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "Div"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "DrawBoundingBoxes"
+ input_arg {
+ name: "images"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "boxes"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "DynamicPartition"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "partitions"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "outputs"
+ type_attr: "T"
+ number_attr: "num_partitions"
+ }
+ attr {
+ name: "num_partitions"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "DynamicStitch"
+ input_arg {
+ name: "indices"
+ type: DT_INT32
+ number_attr: "N"
+ }
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ number_attr: "N"
+ }
+ output_arg {
+ name: "merged"
+ type_attr: "T"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "EditDistance"
+ input_arg {
+ name: "hypothesis_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "hypothesis_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "hypothesis_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "truth_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "truth_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "truth_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "normalize"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "Elu"
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "activations"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "EluGrad"
+ input_arg {
+ name: "gradients"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "outputs"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "backprops"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "EncodeBase64"
+ input_arg {
+ name: "input"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "output"
+ type: DT_STRING
+ }
+ attr {
+ name: "pad"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "EncodeJpeg"
+ input_arg {
+ name: "image"
+ type: DT_UINT8
+ }
+ output_arg {
+ name: "contents"
+ type: DT_STRING
+ }
+ attr {
+ name: "format"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ allowed_values {
+ list {
+ s: ""
+ s: "grayscale"
+ s: "rgb"
+ }
+ }
+ }
+ attr {
+ name: "quality"
+ type: "int"
+ default_value {
+ i: 95
+ }
+ }
+ attr {
+ name: "progressive"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "optimize_size"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "chroma_downsampling"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "density_unit"
+ type: "string"
+ default_value {
+ s: "in"
+ }
+ allowed_values {
+ list {
+ s: "in"
+ s: "cm"
+ }
+ }
+ }
+ attr {
+ name: "x_density"
+ type: "int"
+ default_value {
+ i: 300
+ }
+ }
+ attr {
+ name: "y_density"
+ type: "int"
+ default_value {
+ i: 300
+ }
+ }
+ attr {
+ name: "xmp_metadata"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+}
+op {
+ name: "EncodePng"
+ input_arg {
+ name: "image"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "contents"
+ type: DT_STRING
+ }
+ attr {
+ name: "compression"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_UINT8
+ }
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_UINT16
+ }
+ }
+ }
+}
+op {
+ name: "Enter"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "frame_name"
+ type: "string"
+ }
+ attr {
+ name: "is_constant"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "parallel_iterations"
+ type: "int"
+ default_value {
+ i: 10
+ }
+ }
+}
+op {
+ name: "Equal"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type: DT_BOOL
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_QUINT8
+ type: DT_QINT8
+ type: DT_QINT32
+ type: DT_STRING
+ type: DT_BOOL
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ is_commutative: true
+}
+op {
+ name: "Erf"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Erfc"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Exit"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "Exp"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "ExpandDims"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "dim"
+ type_attr: "Tdim"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tdim"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Expm1"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "ExtractGlimpse"
+ input_arg {
+ name: "input"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "offsets"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "glimpse"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "centered"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "normalized"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "uniform_noise"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+}
+op {
+ name: "ExtractImagePatches"
+ input_arg {
+ name: "images"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "patches"
+ type_attr: "T"
+ }
+ attr {
+ name: "ksizes"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "rates"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "FFT"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+}
+op {
+ name: "FFT2D"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+}
+op {
+ name: "FFT3D"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+}
+op {
+ name: "FIFOQueue"
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "shapes"
+ type: "list(shape)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "capacity"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "FIFOQueueV2"
+ output_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "shapes"
+ type: "list(shape)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "capacity"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Fact"
+ output_arg {
+ name: "fact"
+ type: DT_STRING
+ }
+}
+op {
+ name: "FakeQuantWithMinMaxArgs"
+ input_arg {
+ name: "inputs"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "outputs"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "min"
+ type: "float"
+ default_value {
+ f: -6
+ }
+ }
+ attr {
+ name: "max"
+ type: "float"
+ default_value {
+ f: 6
+ }
+ }
+}
+op {
+ name: "FakeQuantWithMinMaxArgsGradient"
+ input_arg {
+ name: "gradients"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "inputs"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "backprops"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "min"
+ type: "float"
+ default_value {
+ f: -6
+ }
+ }
+ attr {
+ name: "max"
+ type: "float"
+ default_value {
+ f: 6
+ }
+ }
+}
+op {
+ name: "FakeQuantWithMinMaxVars"
+ input_arg {
+ name: "inputs"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "outputs"
+ type: DT_FLOAT
+ }
+}
+op {
+ name: "FakeQuantWithMinMaxVarsGradient"
+ input_arg {
+ name: "gradients"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "inputs"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "backprops_wrt_input"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "backprop_wrt_min"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "backprop_wrt_max"
+ type: DT_FLOAT
+ }
+}
+op {
+ name: "FakeQuantWithMinMaxVarsPerChannel"
+ input_arg {
+ name: "inputs"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "outputs"
+ type: DT_FLOAT
+ }
+}
+op {
+ name: "FakeQuantWithMinMaxVarsPerChannelGradient"
+ input_arg {
+ name: "gradients"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "inputs"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "backprops_wrt_input"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "backprop_wrt_min"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "backprop_wrt_max"
+ type: DT_FLOAT
+ }
+}
+op {
+ name: "FakeQueue"
+ input_arg {
+ name: "resource"
+ type: DT_RESOURCE
+ }
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ is_stateful: true
+}
+op {
+ name: "Fill"
+ input_arg {
+ name: "dims"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "FixedLengthRecordReader"
+ output_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "header_bytes"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "record_bytes"
+ type: "int"
+ }
+ attr {
+ name: "footer_bytes"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "FixedLengthRecordReaderV2"
+ output_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ attr {
+ name: "header_bytes"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "record_bytes"
+ type: "int"
+ }
+ attr {
+ name: "footer_bytes"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "FixedUnigramCandidateSampler"
+ input_arg {
+ name: "true_classes"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sampled_candidates"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "true_expected_count"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "sampled_expected_count"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "num_true"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "num_sampled"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "unique"
+ type: "bool"
+ }
+ attr {
+ name: "range_max"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "vocab_file"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "distortion"
+ type: "float"
+ default_value {
+ f: 1
+ }
+ }
+ attr {
+ name: "num_reserved_ids"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "num_shards"
+ type: "int"
+ default_value {
+ i: 1
+ }
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "shard"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "unigrams"
+ type: "list(float)"
+ default_value {
+ list {
+ }
+ }
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "Floor"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "FloorDiv"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "FloorMod"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "FractionalAvgPool"
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "row_pooling_sequence"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "col_pooling_sequence"
+ type: DT_INT64
+ }
+ attr {
+ name: "pooling_ratio"
+ type: "list(float)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "pseudo_random"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "overlapping"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "deterministic"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "FractionalAvgPoolGrad"
+ input_arg {
+ name: "orig_input_tensor_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "row_pooling_sequence"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "col_pooling_sequence"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "overlapping"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "FractionalMaxPool"
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "row_pooling_sequence"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "col_pooling_sequence"
+ type: DT_INT64
+ }
+ attr {
+ name: "pooling_ratio"
+ type: "list(float)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "pseudo_random"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "overlapping"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "deterministic"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "FractionalMaxPoolGrad"
+ input_arg {
+ name: "orig_input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "orig_output"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "out_backprop"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "row_pooling_sequence"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "col_pooling_sequence"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "overlapping"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "FusedBatchNorm"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "scale"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "offset"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "mean"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "variance"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "batch_mean"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "batch_variance"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "reserve_space_1"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "reserve_space_2"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "epsilon"
+ type: "float"
+ default_value {
+ f: 0.0001
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ }
+ attr {
+ name: "is_training"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+}
+op {
+ name: "FusedBatchNormGrad"
+ input_arg {
+ name: "y_backprop"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "scale"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "reserve_space_1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "reserve_space_2"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "x_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "scale_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "offset_backprop"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "reserve_space_3"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "reserve_space_4"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "epsilon"
+ type: "float"
+ default_value {
+ f: 0.0001
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ }
+ attr {
+ name: "is_training"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+}
+op {
+ name: "FusedPadConv2D"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "paddings"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "mode"
+ type: "string"
+ allowed_values {
+ list {
+ s: "REFLECT"
+ s: "SYMMETRIC"
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "FusedResizeAndPadConv2D"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "paddings"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "resize_align_corners"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "mode"
+ type: "string"
+ allowed_values {
+ list {
+ s: "REFLECT"
+ s: "SYMMETRIC"
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "Gather"
+ input_arg {
+ name: "params"
+ type_attr: "Tparams"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "Tparams"
+ }
+ attr {
+ name: "validate_indices"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "Tparams"
+ type: "type"
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "GatherNd"
+ input_arg {
+ name: "params"
+ type_attr: "Tparams"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "Tparams"
+ }
+ attr {
+ name: "Tparams"
+ type: "type"
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "GetSessionHandle"
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "GetSessionTensor"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+}
+op {
+ name: "Greater"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type: DT_BOOL
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "GreaterEqual"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type: DT_BOOL
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "HSVToRGB"
+ input_arg {
+ name: "images"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "HashTable"
+ output_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "use_node_name_sharing"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "key_dtype"
+ type: "type"
+ }
+ attr {
+ name: "value_dtype"
+ type: "type"
+ }
+ is_stateful: true
+}
+op {
+ name: "HistogramSummary"
+ input_arg {
+ name: "tag"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "values"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "summary"
+ type: DT_STRING
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "IFFT"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+}
+op {
+ name: "IFFT2D"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+}
+op {
+ name: "IFFT3D"
+ input_arg {
+ name: "input"
+ type: DT_COMPLEX64
+ }
+ output_arg {
+ name: "output"
+ type: DT_COMPLEX64
+ }
+}
+op {
+ name: "Identity"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "IdentityReader"
+ output_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "IdentityReaderV2"
+ output_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Igamma"
+ input_arg {
+ name: "a"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Igammac"
+ input_arg {
+ name: "a"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Imag"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "Tout"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_COMPLEX64
+ }
+ allowed_values {
+ list {
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ attr {
+ name: "Tout"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "ImageSummary"
+ input_arg {
+ name: "tag"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "tensor"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "summary"
+ type: DT_STRING
+ }
+ attr {
+ name: "max_images"
+ type: "int"
+ default_value {
+ i: 3
+ }
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_FLOAT
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "bad_color"
+ type: "tensor"
+ default_value {
+ tensor {
+ dtype: DT_UINT8
+ tensor_shape {
+ dim {
+ size: 4
+ }
+ }
+ int_val: 255
+ int_val: 0
+ int_val: 0
+ int_val: 255
+ }
+ }
+ }
+}
+op {
+ name: "ImmutableConst"
+ output_arg {
+ name: "tensor"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "shape"
+ type: "shape"
+ }
+ attr {
+ name: "memory_region_name"
+ type: "string"
+ }
+}
+op {
+ name: "InTopK"
+ input_arg {
+ name: "predictions"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "targets"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "precision"
+ type: DT_BOOL
+ }
+ attr {
+ name: "k"
+ type: "int"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "InitializeTable"
+ input_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "keys"
+ type_attr: "Tkey"
+ }
+ input_arg {
+ name: "values"
+ type_attr: "Tval"
+ }
+ attr {
+ name: "Tkey"
+ type: "type"
+ }
+ attr {
+ name: "Tval"
+ type: "type"
+ }
+}
+op {
+ name: "InitializeTableFromTextFile"
+ input_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "filename"
+ type: DT_STRING
+ }
+ attr {
+ name: "key_index"
+ type: "int"
+ has_minimum: true
+ minimum: -2
+ }
+ attr {
+ name: "value_index"
+ type: "int"
+ has_minimum: true
+ minimum: -2
+ }
+ attr {
+ name: "vocab_size"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ has_minimum: true
+ minimum: -1
+ }
+ attr {
+ name: "delimiter"
+ type: "string"
+ default_value {
+ s: "\t"
+ }
+ }
+}
+op {
+ name: "Inv"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ deprecation {
+ version: 17
+ }
+}
+op {
+ name: "InvGrad"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ deprecation {
+ version: 17
+ }
+}
+op {
+ name: "InvertPermutation"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "IsFinite"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type: DT_BOOL
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "IsInf"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type: DT_BOOL
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "IsNan"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type: DT_BOOL
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "IsVariableInitialized"
+ input_arg {
+ name: "ref"
+ type_attr: "dtype"
+ is_ref: true
+ }
+ output_arg {
+ name: "is_initialized"
+ type: DT_BOOL
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ allows_uninitialized_input: true
+}
+op {
+ name: "L2Loss"
+ input_arg {
+ name: "t"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "LRN"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "depth_radius"
+ type: "int"
+ default_value {
+ i: 5
+ }
+ }
+ attr {
+ name: "bias"
+ type: "float"
+ default_value {
+ f: 1
+ }
+ }
+ attr {
+ name: "alpha"
+ type: "float"
+ default_value {
+ f: 1
+ }
+ }
+ attr {
+ name: "beta"
+ type: "float"
+ default_value {
+ f: 0.5
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "LRNGrad"
+ input_arg {
+ name: "input_grads"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "input_image"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "output_image"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "depth_radius"
+ type: "int"
+ default_value {
+ i: 5
+ }
+ }
+ attr {
+ name: "bias"
+ type: "float"
+ default_value {
+ f: 1
+ }
+ }
+ attr {
+ name: "alpha"
+ type: "float"
+ default_value {
+ f: 1
+ }
+ }
+ attr {
+ name: "beta"
+ type: "float"
+ default_value {
+ f: 0.5
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "LearnedUnigramCandidateSampler"
+ input_arg {
+ name: "true_classes"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sampled_candidates"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "true_expected_count"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "sampled_expected_count"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "num_true"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "num_sampled"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "unique"
+ type: "bool"
+ }
+ attr {
+ name: "range_max"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "Less"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type: DT_BOOL
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "LessEqual"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type: DT_BOOL
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "Lgamma"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "LinSpace"
+ input_arg {
+ name: "start"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "stop"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "num"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "ListDiff"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "idx"
+ type_attr: "out_idx"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "out_idx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Log"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Log1p"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "LogSoftmax"
+ input_arg {
+ name: "logits"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "logsoftmax"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "LogUniformCandidateSampler"
+ input_arg {
+ name: "true_classes"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sampled_candidates"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "true_expected_count"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "sampled_expected_count"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "num_true"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "num_sampled"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "unique"
+ type: "bool"
+ }
+ attr {
+ name: "range_max"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "LogicalAnd"
+ input_arg {
+ name: "x"
+ type: DT_BOOL
+ }
+ input_arg {
+ name: "y"
+ type: DT_BOOL
+ }
+ output_arg {
+ name: "z"
+ type: DT_BOOL
+ }
+ is_commutative: true
+}
+op {
+ name: "LogicalNot"
+ input_arg {
+ name: "x"
+ type: DT_BOOL
+ }
+ output_arg {
+ name: "y"
+ type: DT_BOOL
+ }
+}
+op {
+ name: "LogicalOr"
+ input_arg {
+ name: "x"
+ type: DT_BOOL
+ }
+ input_arg {
+ name: "y"
+ type: DT_BOOL
+ }
+ output_arg {
+ name: "z"
+ type: DT_BOOL
+ }
+ is_commutative: true
+}
+op {
+ name: "LookupTableExport"
+ input_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "keys"
+ type_attr: "Tkeys"
+ }
+ output_arg {
+ name: "values"
+ type_attr: "Tvalues"
+ }
+ attr {
+ name: "Tkeys"
+ type: "type"
+ }
+ attr {
+ name: "Tvalues"
+ type: "type"
+ }
+}
+op {
+ name: "LookupTableFind"
+ input_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "keys"
+ type_attr: "Tin"
+ }
+ input_arg {
+ name: "default_value"
+ type_attr: "Tout"
+ }
+ output_arg {
+ name: "values"
+ type_attr: "Tout"
+ }
+ attr {
+ name: "Tin"
+ type: "type"
+ }
+ attr {
+ name: "Tout"
+ type: "type"
+ }
+}
+op {
+ name: "LookupTableImport"
+ input_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "keys"
+ type_attr: "Tin"
+ }
+ input_arg {
+ name: "values"
+ type_attr: "Tout"
+ }
+ attr {
+ name: "Tin"
+ type: "type"
+ }
+ attr {
+ name: "Tout"
+ type: "type"
+ }
+}
+op {
+ name: "LookupTableInsert"
+ input_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "keys"
+ type_attr: "Tin"
+ }
+ input_arg {
+ name: "values"
+ type_attr: "Tout"
+ }
+ attr {
+ name: "Tin"
+ type: "type"
+ }
+ attr {
+ name: "Tout"
+ type: "type"
+ }
+}
+op {
+ name: "LookupTableSize"
+ input_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "size"
+ type: DT_INT64
+ }
+}
+op {
+ name: "LoopCond"
+ input_arg {
+ name: "input"
+ type: DT_BOOL
+ }
+ output_arg {
+ name: "output"
+ type: DT_BOOL
+ }
+}
+op {
+ name: "MatMul"
+ input_arg {
+ name: "a"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "b"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "product"
+ type_attr: "T"
+ }
+ attr {
+ name: "transpose_a"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "transpose_b"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "MatchingFiles"
+ input_arg {
+ name: "pattern"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "filenames"
+ type: DT_STRING
+ }
+}
+op {
+ name: "MatrixBandPart"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "num_lower"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "num_upper"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "band"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "MatrixDeterminant"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "MatrixDiag"
+ input_arg {
+ name: "diagonal"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "MatrixDiagPart"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "diagonal"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "MatrixInverse"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "adjoint"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+}
+op {
+ name: "MatrixSetDiag"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "diagonal"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "MatrixSolve"
+ input_arg {
+ name: "matrix"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rhs"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "adjoint"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "MatrixSolveLs"
+ input_arg {
+ name: "matrix"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rhs"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2_regularizer"
+ type: DT_DOUBLE
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+ attr {
+ name: "fast"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+}
+op {
+ name: "MatrixTriangularSolve"
+ input_arg {
+ name: "matrix"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rhs"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "lower"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "adjoint"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+}
+op {
+ name: "Max"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "reduction_indices"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "keep_dims"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "MaxPool"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ allowed_values {
+ list {
+ s: "NHWC"
+ s: "NCHW"
+ }
+ }
+ }
+}
+op {
+ name: "MaxPool3D"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "MaxPool3DGrad"
+ input_arg {
+ name: "orig_input"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "orig_output"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 5
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "MaxPoolGrad"
+ input_arg {
+ name: "orig_input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "orig_output"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "data_format"
+ type: "string"
+ default_value {
+ s: "NHWC"
+ }
+ allowed_values {
+ list {
+ s: "NHWC"
+ s: "NCHW"
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "MaxPoolGradWithArgmax"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "argmax"
+ type_attr: "Targmax"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "Targmax"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "MaxPoolWithArgmax"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "argmax"
+ type_attr: "Targmax"
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ has_minimum: true
+ minimum: 4
+ }
+ attr {
+ name: "Targmax"
+ type: "type"
+ default_value {
+ type: DT_INT64
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "Maximum"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ is_commutative: true
+}
+op {
+ name: "Mean"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "reduction_indices"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "keep_dims"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Merge"
+ input_arg {
+ name: "inputs"
+ type_attr: "T"
+ number_attr: "N"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "value_index"
+ type: DT_INT32
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "MergeSummary"
+ input_arg {
+ name: "inputs"
+ type: DT_STRING
+ number_attr: "N"
+ }
+ output_arg {
+ name: "summary"
+ type: DT_STRING
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "MergeV2Checkpoints"
+ input_arg {
+ name: "checkpoint_prefixes"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "destination_prefix"
+ type: DT_STRING
+ }
+ attr {
+ name: "delete_old_dirs"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+}
+op {
+ name: "Min"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "reduction_indices"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "keep_dims"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Minimum"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ is_commutative: true
+}
+op {
+ name: "MirrorPad"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "paddings"
+ type_attr: "Tpaddings"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tpaddings"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "mode"
+ type: "string"
+ allowed_values {
+ list {
+ s: "REFLECT"
+ s: "SYMMETRIC"
+ }
+ }
+ }
+}
+op {
+ name: "MirrorPadGrad"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "paddings"
+ type_attr: "Tpaddings"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tpaddings"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "mode"
+ type: "string"
+ allowed_values {
+ list {
+ s: "REFLECT"
+ s: "SYMMETRIC"
+ }
+ }
+ }
+}
+op {
+ name: "Mod"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Mul"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ is_commutative: true
+}
+op {
+ name: "Multinomial"
+ input_arg {
+ name: "logits"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "num_samples"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type: DT_INT64
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "MutableDenseHashTable"
+ input_arg {
+ name: "empty_key"
+ type_attr: "key_dtype"
+ }
+ output_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "use_node_name_sharing"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "key_dtype"
+ type: "type"
+ }
+ attr {
+ name: "value_dtype"
+ type: "type"
+ }
+ attr {
+ name: "value_shape"
+ type: "shape"
+ default_value {
+ shape {
+ }
+ }
+ }
+ attr {
+ name: "initial_num_buckets"
+ type: "int"
+ default_value {
+ i: 131072
+ }
+ }
+ attr {
+ name: "max_load_factor"
+ type: "float"
+ default_value {
+ f: 0.8
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "MutableHashTable"
+ output_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "use_node_name_sharing"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "key_dtype"
+ type: "type"
+ }
+ attr {
+ name: "value_dtype"
+ type: "type"
+ }
+ is_stateful: true
+}
+op {
+ name: "MutableHashTableOfTensors"
+ output_arg {
+ name: "table_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "use_node_name_sharing"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "key_dtype"
+ type: "type"
+ }
+ attr {
+ name: "value_dtype"
+ type: "type"
+ }
+ attr {
+ name: "value_shape"
+ type: "shape"
+ default_value {
+ shape {
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Neg"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "NegTrain"
+ input_arg {
+ name: "w_in"
+ type: DT_FLOAT
+ is_ref: true
+ }
+ input_arg {
+ name: "w_out"
+ type: DT_FLOAT
+ is_ref: true
+ }
+ input_arg {
+ name: "examples"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "labels"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "lr"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "vocab_count"
+ type: "list(int)"
+ }
+ attr {
+ name: "num_negative_samples"
+ type: "int"
+ }
+ deprecation {
+ version: 19
+ }
+ is_stateful: true
+}
+op {
+ name: "NextIteration"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "NoOp"
+}
+op {
+ name: "NonMaxSuppression"
+ input_arg {
+ name: "boxes"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "scores"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_output_size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "selected_indices"
+ type: DT_INT32
+ }
+ attr {
+ name: "iou_threshold"
+ type: "float"
+ default_value {
+ f: 0.5
+ }
+ }
+}
+op {
+ name: "NotEqual"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type: DT_BOOL
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_QUINT8
+ type: DT_QINT8
+ type: DT_QINT32
+ type: DT_STRING
+ type: DT_BOOL
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ is_commutative: true
+}
+op {
+ name: "OneHot"
+ input_arg {
+ name: "indices"
+ type_attr: "TI"
+ }
+ input_arg {
+ name: "depth"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "on_value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "off_value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "axis"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "TI"
+ type: "type"
+ default_value {
+ type: DT_INT64
+ }
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Pack"
+ input_arg {
+ name: "values"
+ type_attr: "T"
+ number_attr: "N"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "axis"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "Pad"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "paddings"
+ type_attr: "Tpaddings"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tpaddings"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "PaddingFIFOQueue"
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "shapes"
+ type: "list(shape)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "capacity"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "PaddingFIFOQueueV2"
+ output_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "shapes"
+ type: "list(shape)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "capacity"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ParallelConcat"
+ input_arg {
+ name: "values"
+ type_attr: "T"
+ number_attr: "N"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "shape"
+ type: "shape"
+ }
+}
+op {
+ name: "ParameterizedTruncatedNormal"
+ input_arg {
+ name: "shape"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "means"
+ type_attr: "dtype"
+ }
+ input_arg {
+ name: "stdevs"
+ type_attr: "dtype"
+ }
+ input_arg {
+ name: "minvals"
+ type_attr: "dtype"
+ }
+ input_arg {
+ name: "maxvals"
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ParseExample"
+ input_arg {
+ name: "serialized"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "names"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "sparse_keys"
+ type: DT_STRING
+ number_attr: "Nsparse"
+ }
+ input_arg {
+ name: "dense_keys"
+ type: DT_STRING
+ number_attr: "Ndense"
+ }
+ input_arg {
+ name: "dense_defaults"
+ type_list_attr: "Tdense"
+ }
+ output_arg {
+ name: "sparse_indices"
+ type: DT_INT64
+ number_attr: "Nsparse"
+ }
+ output_arg {
+ name: "sparse_values"
+ type_list_attr: "sparse_types"
+ }
+ output_arg {
+ name: "sparse_shapes"
+ type: DT_INT64
+ number_attr: "Nsparse"
+ }
+ output_arg {
+ name: "dense_values"
+ type_list_attr: "Tdense"
+ }
+ attr {
+ name: "Nsparse"
+ type: "int"
+ has_minimum: true
+ }
+ attr {
+ name: "Ndense"
+ type: "int"
+ has_minimum: true
+ }
+ attr {
+ name: "sparse_types"
+ type: "list(type)"
+ has_minimum: true
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_INT64
+ type: DT_STRING
+ }
+ }
+ }
+ attr {
+ name: "Tdense"
+ type: "list(type)"
+ has_minimum: true
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_INT64
+ type: DT_STRING
+ }
+ }
+ }
+ attr {
+ name: "dense_shapes"
+ type: "list(shape)"
+ has_minimum: true
+ }
+}
+op {
+ name: "ParseSingleSequenceExample"
+ input_arg {
+ name: "serialized"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "feature_list_dense_missing_assumed_empty"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "context_sparse_keys"
+ type: DT_STRING
+ number_attr: "Ncontext_sparse"
+ }
+ input_arg {
+ name: "context_dense_keys"
+ type: DT_STRING
+ number_attr: "Ncontext_dense"
+ }
+ input_arg {
+ name: "feature_list_sparse_keys"
+ type: DT_STRING
+ number_attr: "Nfeature_list_sparse"
+ }
+ input_arg {
+ name: "feature_list_dense_keys"
+ type: DT_STRING
+ number_attr: "Nfeature_list_dense"
+ }
+ input_arg {
+ name: "context_dense_defaults"
+ type_list_attr: "Tcontext_dense"
+ }
+ input_arg {
+ name: "debug_name"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "context_sparse_indices"
+ type: DT_INT64
+ number_attr: "Ncontext_sparse"
+ }
+ output_arg {
+ name: "context_sparse_values"
+ type_list_attr: "context_sparse_types"
+ }
+ output_arg {
+ name: "context_sparse_shapes"
+ type: DT_INT64
+ number_attr: "Ncontext_sparse"
+ }
+ output_arg {
+ name: "context_dense_values"
+ type_list_attr: "Tcontext_dense"
+ }
+ output_arg {
+ name: "feature_list_sparse_indices"
+ type: DT_INT64
+ number_attr: "Nfeature_list_sparse"
+ }
+ output_arg {
+ name: "feature_list_sparse_values"
+ type_list_attr: "feature_list_sparse_types"
+ }
+ output_arg {
+ name: "feature_list_sparse_shapes"
+ type: DT_INT64
+ number_attr: "Nfeature_list_sparse"
+ }
+ output_arg {
+ name: "feature_list_dense_values"
+ type_list_attr: "feature_list_dense_types"
+ }
+ attr {
+ name: "Ncontext_sparse"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "Ncontext_dense"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "Nfeature_list_sparse"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "Nfeature_list_dense"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "context_sparse_types"
+ type: "list(type)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_INT64
+ type: DT_STRING
+ }
+ }
+ }
+ attr {
+ name: "Tcontext_dense"
+ type: "list(type)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_INT64
+ type: DT_STRING
+ }
+ }
+ }
+ attr {
+ name: "feature_list_dense_types"
+ type: "list(type)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_INT64
+ type: DT_STRING
+ }
+ }
+ }
+ attr {
+ name: "context_dense_shapes"
+ type: "list(shape)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "feature_list_sparse_types"
+ type: "list(type)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_INT64
+ type: DT_STRING
+ }
+ }
+ }
+ attr {
+ name: "feature_list_dense_shapes"
+ type: "list(shape)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+}
+op {
+ name: "ParseTensor"
+ input_arg {
+ name: "serialized"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "output"
+ type_attr: "out_type"
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ }
+}
+op {
+ name: "Placeholder"
+ output_arg {
+ name: "output"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "shape"
+ type: "shape"
+ default_value {
+ shape {
+ }
+ }
+ }
+}
+op {
+ name: "PlaceholderV2"
+ output_arg {
+ name: "output"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "shape"
+ type: "shape"
+ }
+}
+op {
+ name: "PlaceholderWithDefault"
+ input_arg {
+ name: "input"
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "shape"
+ type: "shape"
+ }
+}
+op {
+ name: "Polygamma"
+ input_arg {
+ name: "a"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Pow"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "PreventGradient"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "message"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+}
+op {
+ name: "Print"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "data"
+ type_list_attr: "U"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "U"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "message"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "first_n"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "summarize"
+ type: "int"
+ default_value {
+ i: 3
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "PriorityQueue"
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "shapes"
+ type: "list(shape)"
+ has_minimum: true
+ }
+ attr {
+ name: "capacity"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "PriorityQueueV2"
+ output_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "shapes"
+ type: "list(shape)"
+ has_minimum: true
+ }
+ attr {
+ name: "capacity"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Prod"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "reduction_indices"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "keep_dims"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "PyFunc"
+ input_arg {
+ name: "input"
+ type_list_attr: "Tin"
+ }
+ output_arg {
+ name: "output"
+ type_list_attr: "Tout"
+ }
+ attr {
+ name: "token"
+ type: "string"
+ }
+ attr {
+ name: "Tin"
+ type: "list(type)"
+ has_minimum: true
+ }
+ attr {
+ name: "Tout"
+ type: "list(type)"
+ has_minimum: true
+ }
+ is_stateful: true
+}
+op {
+ name: "PyFuncStateless"
+ input_arg {
+ name: "input"
+ type_list_attr: "Tin"
+ }
+ output_arg {
+ name: "output"
+ type_list_attr: "Tout"
+ }
+ attr {
+ name: "token"
+ type: "string"
+ }
+ attr {
+ name: "Tin"
+ type: "list(type)"
+ has_minimum: true
+ }
+ attr {
+ name: "Tout"
+ type: "list(type)"
+ has_minimum: true
+ }
+}
+op {
+ name: "Qr"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "q"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "r"
+ type_attr: "T"
+ }
+ attr {
+ name: "full_matrices"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "QuantizeAndDequantize"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "signed_input"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "num_bits"
+ type: "int"
+ default_value {
+ i: 8
+ }
+ }
+ attr {
+ name: "range_given"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "input_min"
+ type: "float"
+ default_value {
+ f: 0
+ }
+ }
+ attr {
+ name: "input_max"
+ type: "float"
+ default_value {
+ f: 0
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "QuantizeDownAndShrinkRange"
+ input_arg {
+ name: "input"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "input_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "input_max"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type_attr: "out_type"
+ }
+ output_arg {
+ name: "output_min"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output_max"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "Tinput"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+}
+op {
+ name: "QuantizeV2"
+ input_arg {
+ name: "input"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min_range"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_range"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_min"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output_max"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "mode"
+ type: "string"
+ default_value {
+ s: "MIN_COMBINED"
+ }
+ allowed_values {
+ list {
+ s: "MIN_COMBINED"
+ s: "MIN_FIRST"
+ }
+ }
+ }
+}
+op {
+ name: "QuantizedAvgPool"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "min_input"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_input"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "min_output"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "max_output"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "QuantizedBatchNormWithGlobalNormalization"
+ input_arg {
+ name: "t"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "t_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "t_max"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "m"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "m_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "m_max"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "v"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "v_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "v_max"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "beta"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "beta_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "beta_max"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "gamma"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "gamma_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "gamma_max"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "result"
+ type_attr: "out_type"
+ }
+ output_arg {
+ name: "result_min"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "result_max"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "Tinput"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "variance_epsilon"
+ type: "float"
+ }
+ attr {
+ name: "scale_after_normalization"
+ type: "bool"
+ }
+}
+op {
+ name: "QuantizedBiasAdd"
+ input_arg {
+ name: "input"
+ type_attr: "T1"
+ }
+ input_arg {
+ name: "bias"
+ type_attr: "T2"
+ }
+ input_arg {
+ name: "min_input"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_input"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min_bias"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_bias"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type_attr: "out_type"
+ }
+ output_arg {
+ name: "min_out"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "max_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T1"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "T2"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+}
+op {
+ name: "QuantizedConcat"
+ input_arg {
+ name: "concat_dim"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "values"
+ type_attr: "T"
+ number_attr: "N"
+ }
+ input_arg {
+ name: "input_mins"
+ type: DT_FLOAT
+ number_attr: "N"
+ }
+ input_arg {
+ name: "input_maxes"
+ type: DT_FLOAT
+ number_attr: "N"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_min"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output_max"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 2
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "QuantizedConv2D"
+ input_arg {
+ name: "input"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "filter"
+ type_attr: "Tfilter"
+ }
+ input_arg {
+ name: "min_input"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_input"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min_filter"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_filter"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type_attr: "out_type"
+ }
+ output_arg {
+ name: "min_output"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "max_output"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "Tinput"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "Tfilter"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ default_value {
+ type: DT_QINT32
+ }
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "QuantizedInstanceNorm"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "x_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "x_max"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y_min"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "y_max"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "output_range_given"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "given_y_min"
+ type: "float"
+ default_value {
+ f: 0
+ }
+ }
+ attr {
+ name: "given_y_max"
+ type: "float"
+ default_value {
+ f: 0
+ }
+ }
+ attr {
+ name: "variance_epsilon"
+ type: "float"
+ default_value {
+ f: 1e-05
+ }
+ }
+ attr {
+ name: "min_separation"
+ type: "float"
+ default_value {
+ f: 0.001
+ }
+ }
+}
+op {
+ name: "QuantizedMatMul"
+ input_arg {
+ name: "a"
+ type_attr: "T1"
+ }
+ input_arg {
+ name: "b"
+ type_attr: "T2"
+ }
+ input_arg {
+ name: "min_a"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_a"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min_b"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_b"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "out"
+ type_attr: "Toutput"
+ }
+ output_arg {
+ name: "min_out"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "max_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T1"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "T2"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "Toutput"
+ type: "type"
+ default_value {
+ type: DT_QINT32
+ }
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "transpose_a"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "transpose_b"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "Tactivation"
+ type: "type"
+ default_value {
+ type: DT_QUINT8
+ }
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+}
+op {
+ name: "QuantizedMaxPool"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "min_input"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_input"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "min_output"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "max_output"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "ksize"
+ type: "list(int)"
+ }
+ attr {
+ name: "strides"
+ type: "list(int)"
+ }
+ attr {
+ name: "padding"
+ type: "string"
+ allowed_values {
+ list {
+ s: "SAME"
+ s: "VALID"
+ }
+ }
+ }
+}
+op {
+ name: "QuantizedMul"
+ input_arg {
+ name: "x"
+ type_attr: "T1"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T2"
+ }
+ input_arg {
+ name: "min_x"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_x"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min_y"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_y"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "z"
+ type_attr: "Toutput"
+ }
+ output_arg {
+ name: "min_z"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "max_z"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T1"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "T2"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "Toutput"
+ type: "type"
+ default_value {
+ type: DT_QINT32
+ }
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ is_commutative: true
+}
+op {
+ name: "QuantizedRelu"
+ input_arg {
+ name: "features"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "min_features"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_features"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "activations"
+ type_attr: "out_type"
+ }
+ output_arg {
+ name: "min_activations"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "max_activations"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "Tinput"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ default_value {
+ type: DT_QUINT8
+ }
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+}
+op {
+ name: "QuantizedRelu6"
+ input_arg {
+ name: "features"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "min_features"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_features"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "activations"
+ type_attr: "out_type"
+ }
+ output_arg {
+ name: "min_activations"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "max_activations"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "Tinput"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ default_value {
+ type: DT_QUINT8
+ }
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+}
+op {
+ name: "QuantizedReluX"
+ input_arg {
+ name: "features"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "max_value"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "min_features"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "max_features"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "activations"
+ type_attr: "out_type"
+ }
+ output_arg {
+ name: "min_activations"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "max_activations"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "Tinput"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ default_value {
+ type: DT_QUINT8
+ }
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+}
+op {
+ name: "QuantizedReshape"
+ input_arg {
+ name: "tensor"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "shape"
+ type_attr: "Tshape"
+ }
+ input_arg {
+ name: "input_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "input_max"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_min"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output_max"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tshape"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "QueueClose"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "cancel_pending_enqueues"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "QueueCloseV2"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ attr {
+ name: "cancel_pending_enqueues"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "QueueDequeue"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "components"
+ type_list_attr: "component_types"
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+}
+op {
+ name: "QueueDequeueMany"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "n"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "components"
+ type_list_attr: "component_types"
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+}
+op {
+ name: "QueueDequeueManyV2"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "n"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "components"
+ type_list_attr: "component_types"
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "QueueDequeueUpTo"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "n"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "components"
+ type_list_attr: "component_types"
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+}
+op {
+ name: "QueueDequeueUpToV2"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "n"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "components"
+ type_list_attr: "component_types"
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "QueueDequeueV2"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ output_arg {
+ name: "components"
+ type_list_attr: "component_types"
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "QueueEnqueue"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "components"
+ type_list_attr: "Tcomponents"
+ }
+ attr {
+ name: "Tcomponents"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+}
+op {
+ name: "QueueEnqueueMany"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "components"
+ type_list_attr: "Tcomponents"
+ }
+ attr {
+ name: "Tcomponents"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+}
+op {
+ name: "QueueEnqueueManyV2"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "components"
+ type_list_attr: "Tcomponents"
+ }
+ attr {
+ name: "Tcomponents"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "QueueEnqueueV2"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "components"
+ type_list_attr: "Tcomponents"
+ }
+ attr {
+ name: "Tcomponents"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "timeout_ms"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "QueueSize"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "size"
+ type: DT_INT32
+ }
+}
+op {
+ name: "QueueSizeV2"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ output_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ is_stateful: true
+}
+op {
+ name: "RGBToHSV"
+ input_arg {
+ name: "images"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "RandomCrop"
+ input_arg {
+ name: "image"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "size"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ deprecation {
+ version: 8
+ }
+ is_stateful: true
+}
+op {
+ name: "RandomGamma"
+ input_arg {
+ name: "shape"
+ type_attr: "S"
+ }
+ input_arg {
+ name: "alpha"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "S"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "RandomPoisson"
+ input_arg {
+ name: "shape"
+ type_attr: "S"
+ }
+ input_arg {
+ name: "rate"
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "S"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "RandomShuffle"
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ is_stateful: true
+}
+op {
+ name: "RandomShuffleQueue"
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "shapes"
+ type: "list(shape)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "capacity"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "min_after_dequeue"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "RandomShuffleQueueV2"
+ output_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ attr {
+ name: "component_types"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "shapes"
+ type: "list(shape)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+ attr {
+ name: "capacity"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+ attr {
+ name: "min_after_dequeue"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "RandomStandardNormal"
+ input_arg {
+ name: "shape"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "RandomUniform"
+ input_arg {
+ name: "shape"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "RandomUniformInt"
+ input_arg {
+ name: "shape"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "minval"
+ type_attr: "Tout"
+ }
+ input_arg {
+ name: "maxval"
+ type_attr: "Tout"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "Tout"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "Tout"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Range"
+ input_arg {
+ name: "start"
+ type_attr: "Tidx"
+ }
+ input_arg {
+ name: "limit"
+ type_attr: "Tidx"
+ }
+ input_arg {
+ name: "delta"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "Tidx"
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Rank"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type: DT_INT32
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "ReadFile"
+ input_arg {
+ name: "filename"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "contents"
+ type: DT_STRING
+ }
+}
+op {
+ name: "ReaderNumRecordsProduced"
+ input_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "records_produced"
+ type: DT_INT64
+ }
+}
+op {
+ name: "ReaderNumRecordsProducedV2"
+ input_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ output_arg {
+ name: "records_produced"
+ type: DT_INT64
+ }
+ is_stateful: true
+}
+op {
+ name: "ReaderNumWorkUnitsCompleted"
+ input_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "units_completed"
+ type: DT_INT64
+ }
+}
+op {
+ name: "ReaderNumWorkUnitsCompletedV2"
+ input_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ output_arg {
+ name: "units_completed"
+ type: DT_INT64
+ }
+ is_stateful: true
+}
+op {
+ name: "ReaderRead"
+ input_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "queue_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "key"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "value"
+ type: DT_STRING
+ }
+}
+op {
+ name: "ReaderReadUpTo"
+ input_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "queue_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "num_records"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "keys"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "values"
+ type: DT_STRING
+ }
+}
+op {
+ name: "ReaderReadUpToV2"
+ input_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "queue_handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "num_records"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "keys"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "values"
+ type: DT_STRING
+ }
+ is_stateful: true
+}
+op {
+ name: "ReaderReadV2"
+ input_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "queue_handle"
+ type: DT_RESOURCE
+ }
+ output_arg {
+ name: "key"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "value"
+ type: DT_STRING
+ }
+ is_stateful: true
+}
+op {
+ name: "ReaderReset"
+ input_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+}
+op {
+ name: "ReaderResetV2"
+ input_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ is_stateful: true
+}
+op {
+ name: "ReaderRestoreState"
+ input_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "state"
+ type: DT_STRING
+ }
+}
+op {
+ name: "ReaderRestoreStateV2"
+ input_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "state"
+ type: DT_STRING
+ }
+ is_stateful: true
+}
+op {
+ name: "ReaderSerializeState"
+ input_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "state"
+ type: DT_STRING
+ }
+}
+op {
+ name: "ReaderSerializeStateV2"
+ input_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ output_arg {
+ name: "state"
+ type: DT_STRING
+ }
+ is_stateful: true
+}
+op {
+ name: "Real"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "Tout"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ default_value {
+ type: DT_COMPLEX64
+ }
+ allowed_values {
+ list {
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ attr {
+ name: "Tout"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "RealDiv"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Reciprocal"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "ReciprocalGrad"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "RecordInput"
+ output_arg {
+ name: "records"
+ type: DT_STRING
+ }
+ attr {
+ name: "file_pattern"
+ type: "string"
+ }
+ attr {
+ name: "file_random_seed"
+ type: "int"
+ default_value {
+ i: 301
+ }
+ }
+ attr {
+ name: "file_shuffle_shift_ratio"
+ type: "float"
+ default_value {
+ f: 0
+ }
+ }
+ attr {
+ name: "file_buffer_size"
+ type: "int"
+ default_value {
+ i: 10000
+ }
+ }
+ attr {
+ name: "file_parallelism"
+ type: "int"
+ default_value {
+ i: 16
+ }
+ }
+ attr {
+ name: "batch_size"
+ type: "int"
+ default_value {
+ i: 32
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ReduceJoin"
+ input_arg {
+ name: "inputs"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "reduction_indices"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type: DT_STRING
+ }
+ attr {
+ name: "keep_dims"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "separator"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+}
+op {
+ name: "RefEnter"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ is_ref: true
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "frame_name"
+ type: "string"
+ }
+ attr {
+ name: "is_constant"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "parallel_iterations"
+ type: "int"
+ default_value {
+ i: 10
+ }
+ }
+}
+op {
+ name: "RefExit"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ is_ref: true
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "RefIdentity"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ is_ref: true
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ allows_uninitialized_input: true
+}
+op {
+ name: "RefMerge"
+ input_arg {
+ name: "inputs"
+ type_attr: "T"
+ number_attr: "N"
+ is_ref: true
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ is_ref: true
+ }
+ output_arg {
+ name: "value_index"
+ type: DT_INT32
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "RefNextIteration"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ is_ref: true
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "RefSelect"
+ input_arg {
+ name: "index"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "inputs"
+ type_attr: "T"
+ number_attr: "N"
+ is_ref: true
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "RefSwitch"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "pred"
+ type: DT_BOOL
+ }
+ output_arg {
+ name: "output_false"
+ type_attr: "T"
+ is_ref: true
+ }
+ output_arg {
+ name: "output_true"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ allows_uninitialized_input: true
+}
+op {
+ name: "Relu"
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "activations"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "Relu6"
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "activations"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "Relu6Grad"
+ input_arg {
+ name: "gradients"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "backprops"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "ReluGrad"
+ input_arg {
+ name: "gradients"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "backprops"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "RequantizationRange"
+ input_arg {
+ name: "input"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "input_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "input_max"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output_min"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output_max"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "Tinput"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+}
+op {
+ name: "Requantize"
+ input_arg {
+ name: "input"
+ type_attr: "Tinput"
+ }
+ input_arg {
+ name: "input_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "input_max"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "requested_output_min"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "requested_output_max"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output"
+ type_attr: "out_type"
+ }
+ output_arg {
+ name: "output_min"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "output_max"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "Tinput"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT16
+ type: DT_QUINT16
+ type: DT_QINT32
+ }
+ }
+ }
+}
+op {
+ name: "Reshape"
+ input_arg {
+ name: "tensor"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "shape"
+ type_attr: "Tshape"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tshape"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "ResizeArea"
+ input_arg {
+ name: "images"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "resized_images"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "align_corners"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ResizeBicubic"
+ input_arg {
+ name: "images"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "resized_images"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "align_corners"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ResizeBilinear"
+ input_arg {
+ name: "images"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "resized_images"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "align_corners"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ResizeBilinearGrad"
+ input_arg {
+ name: "grads"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "original_image"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_HALF
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "align_corners"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ResizeNearestNeighbor"
+ input_arg {
+ name: "images"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "resized_images"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "align_corners"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ResizeNearestNeighborGrad"
+ input_arg {
+ name: "grads"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT32
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "align_corners"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ResourceApplyAdadelta"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum_update"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceApplyAdagrad"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceApplyAdagradDA"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "gradient_accumulator"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "gradient_squared_accumulator"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "global_step"
+ type: DT_INT64
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceApplyAdam"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "m"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "v"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "beta1_power"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "beta2_power"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "beta1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "beta2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceApplyCenteredRMSProp"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "mg"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "ms"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "mom"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceApplyFtrl"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "linear"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lr_power"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceApplyGradientDescent"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "alpha"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "delta"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceApplyMomentum"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "use_nesterov"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceApplyProximalAdagrad"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceApplyProximalGradientDescent"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "alpha"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "delta"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceApplyRMSProp"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "ms"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "mom"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceSparseApplyAdadelta"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum_update"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceSparseApplyAdagrad"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceSparseApplyAdagradDA"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "gradient_accumulator"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "gradient_squared_accumulator"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "global_step"
+ type: DT_INT64
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceSparseApplyCenteredRMSProp"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "mg"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "ms"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "mom"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceSparseApplyFtrl"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "linear"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lr_power"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceSparseApplyMomentum"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "use_nesterov"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceSparseApplyProximalAdagrad"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "accum"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceSparseApplyProximalGradientDescent"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "alpha"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ResourceSparseApplyRMSProp"
+ input_arg {
+ name: "var"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "ms"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "mom"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Restore"
+ input_arg {
+ name: "file_pattern"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "tensor_name"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "tensor"
+ type_attr: "dt"
+ }
+ attr {
+ name: "dt"
+ type: "type"
+ }
+ attr {
+ name: "preferred_shard"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+}
+op {
+ name: "RestoreSlice"
+ input_arg {
+ name: "file_pattern"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "tensor_name"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "shape_and_slice"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "tensor"
+ type_attr: "dt"
+ }
+ attr {
+ name: "dt"
+ type: "type"
+ }
+ attr {
+ name: "preferred_shard"
+ type: "int"
+ default_value {
+ i: -1
+ }
+ }
+}
+op {
+ name: "RestoreV2"
+ input_arg {
+ name: "prefix"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "tensor_names"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "shape_and_slices"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "tensors"
+ type_list_attr: "dtypes"
+ }
+ attr {
+ name: "dtypes"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "Reverse"
+ input_arg {
+ name: "tensor"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "dims"
+ type: DT_BOOL
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_BOOL
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "ReverseSequence"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "seq_lengths"
+ type_attr: "Tlen"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "seq_dim"
+ type: "int"
+ }
+ attr {
+ name: "batch_dim"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tlen"
+ type: "type"
+ default_value {
+ type: DT_INT64
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "ReverseV2"
+ input_arg {
+ name: "tensor"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "axis"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_BOOL
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Rint"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Round"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Rsqrt"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "RsqrtGrad"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "SampleDistortedBoundingBox"
+ input_arg {
+ name: "image_size"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "bounding_boxes"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "begin"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "size"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "bboxes"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "min_object_covered"
+ type: "float"
+ default_value {
+ f: 0.1
+ }
+ }
+ attr {
+ name: "aspect_ratio_range"
+ type: "list(float)"
+ default_value {
+ list {
+ f: 0.75
+ f: 1.33
+ }
+ }
+ }
+ attr {
+ name: "area_range"
+ type: "list(float)"
+ default_value {
+ list {
+ f: 0.05
+ f: 1
+ }
+ }
+ }
+ attr {
+ name: "max_attempts"
+ type: "int"
+ default_value {
+ i: 100
+ }
+ }
+ attr {
+ name: "use_image_if_no_bounding_boxes"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Save"
+ input_arg {
+ name: "filename"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "tensor_names"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "data"
+ type_list_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "SaveSlices"
+ input_arg {
+ name: "filename"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "tensor_names"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "shapes_and_slices"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "data"
+ type_list_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "SaveV2"
+ input_arg {
+ name: "prefix"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "tensor_names"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "shape_and_slices"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "tensors"
+ type_list_attr: "dtypes"
+ }
+ attr {
+ name: "dtypes"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "ScalarSummary"
+ input_arg {
+ name: "tags"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "values"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "summary"
+ type: DT_STRING
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "ScatterAdd"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "updates"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ScatterDiv"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "updates"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ScatterMul"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "updates"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ScatterNd"
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "updates"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "shape"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "ScatterNdAdd"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "updates"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ScatterNdSub"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "updates"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ScatterNdUpdate"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "updates"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+}
+op {
+ name: "ScatterSub"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "updates"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "ScatterUpdate"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "updates"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+}
+op {
+ name: "SdcaFprint"
+ input_arg {
+ name: "input"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "output"
+ type: DT_INT64
+ }
+}
+op {
+ name: "SdcaOptimizer"
+ input_arg {
+ name: "sparse_example_indices"
+ type: DT_INT64
+ number_attr: "num_sparse_features"
+ }
+ input_arg {
+ name: "sparse_feature_indices"
+ type: DT_INT64
+ number_attr: "num_sparse_features"
+ }
+ input_arg {
+ name: "sparse_feature_values"
+ type: DT_FLOAT
+ number_attr: "num_sparse_features_with_values"
+ }
+ input_arg {
+ name: "dense_features"
+ type: DT_FLOAT
+ number_attr: "num_dense_features"
+ }
+ input_arg {
+ name: "example_weights"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "example_labels"
+ type: DT_FLOAT
+ }
+ input_arg {
+ name: "sparse_indices"
+ type: DT_INT64
+ number_attr: "num_sparse_features"
+ }
+ input_arg {
+ name: "sparse_weights"
+ type: DT_FLOAT
+ number_attr: "num_sparse_features"
+ }
+ input_arg {
+ name: "dense_weights"
+ type: DT_FLOAT
+ number_attr: "num_dense_features"
+ }
+ input_arg {
+ name: "example_state_data"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "out_example_state_data"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "out_delta_sparse_weights"
+ type: DT_FLOAT
+ number_attr: "num_sparse_features"
+ }
+ output_arg {
+ name: "out_delta_dense_weights"
+ type: DT_FLOAT
+ number_attr: "num_dense_features"
+ }
+ attr {
+ name: "loss_type"
+ type: "string"
+ allowed_values {
+ list {
+ s: "logistic_loss"
+ s: "squared_loss"
+ s: "hinge_loss"
+ s: "smooth_hinge_loss"
+ }
+ }
+ }
+ attr {
+ name: "adaptative"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "num_sparse_features"
+ type: "int"
+ has_minimum: true
+ }
+ attr {
+ name: "num_sparse_features_with_values"
+ type: "int"
+ has_minimum: true
+ }
+ attr {
+ name: "num_dense_features"
+ type: "int"
+ has_minimum: true
+ }
+ attr {
+ name: "l1"
+ type: "float"
+ }
+ attr {
+ name: "l2"
+ type: "float"
+ }
+ attr {
+ name: "num_loss_partitions"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "num_inner_iterations"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "SdcaShrinkL1"
+ input_arg {
+ name: "weights"
+ type: DT_FLOAT
+ number_attr: "num_features"
+ is_ref: true
+ }
+ attr {
+ name: "num_features"
+ type: "int"
+ has_minimum: true
+ }
+ attr {
+ name: "l1"
+ type: "float"
+ }
+ attr {
+ name: "l2"
+ type: "float"
+ }
+}
+op {
+ name: "SegmentMax"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "segment_ids"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SegmentMean"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "segment_ids"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SegmentMin"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "segment_ids"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SegmentProd"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "segment_ids"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SegmentSum"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "segment_ids"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Select"
+ input_arg {
+ name: "condition"
+ type: DT_BOOL
+ }
+ input_arg {
+ name: "t"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "e"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "SelfAdjointEig"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+ deprecation {
+ version: 11
+ }
+}
+op {
+ name: "SelfAdjointEigV2"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "e"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "v"
+ type_attr: "T"
+ }
+ attr {
+ name: "compute_v"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ }
+ }
+ }
+}
+op {
+ name: "SerializeManySparse"
+ input_arg {
+ name: "sparse_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "sparse_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "sparse_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "serialized_sparse"
+ type: DT_STRING
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "SerializeSparse"
+ input_arg {
+ name: "sparse_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "sparse_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "sparse_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "serialized_sparse"
+ type: DT_STRING
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "SetSize"
+ input_arg {
+ name: "set_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "set_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "set_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ attr {
+ name: "validate_indices"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_STRING
+ }
+ }
+ }
+}
+op {
+ name: "Shape"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "out_type"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "ShapeN"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ number_attr: "N"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "out_type"
+ number_attr: "N"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "ShardedFilename"
+ input_arg {
+ name: "basename"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "shard"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "num_shards"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "filename"
+ type: DT_STRING
+ }
+}
+op {
+ name: "ShardedFilespec"
+ input_arg {
+ name: "basename"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "num_shards"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "filename"
+ type: DT_STRING
+ }
+}
+op {
+ name: "Sigmoid"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "SigmoidGrad"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Sign"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Sin"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Size"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "out_type"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Skipgram"
+ output_arg {
+ name: "vocab_word"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "vocab_freq"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "words_per_epoch"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "current_epoch"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "total_words_processed"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "examples"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "labels"
+ type: DT_INT32
+ }
+ attr {
+ name: "filename"
+ type: "string"
+ }
+ attr {
+ name: "batch_size"
+ type: "int"
+ }
+ attr {
+ name: "window_size"
+ type: "int"
+ default_value {
+ i: 5
+ }
+ }
+ attr {
+ name: "min_count"
+ type: "int"
+ default_value {
+ i: 5
+ }
+ }
+ attr {
+ name: "subsample"
+ type: "float"
+ default_value {
+ f: 0.001
+ }
+ }
+ deprecation {
+ version: 19
+ }
+ is_stateful: true
+}
+op {
+ name: "Slice"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "begin"
+ type_attr: "Index"
+ }
+ input_arg {
+ name: "size"
+ type_attr: "Index"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Index"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Softmax"
+ input_arg {
+ name: "logits"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "softmax"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "SoftmaxCrossEntropyWithLogits"
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "labels"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "loss"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "backprop"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "Softplus"
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "activations"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SoftplusGrad"
+ input_arg {
+ name: "gradients"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "backprops"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "Softsign"
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "activations"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SoftsignGrad"
+ input_arg {
+ name: "gradients"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "backprops"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SpaceToBatch"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "paddings"
+ type_attr: "Tpaddings"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tpaddings"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "block_size"
+ type: "int"
+ has_minimum: true
+ minimum: 2
+ }
+}
+op {
+ name: "SpaceToBatchND"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "block_shape"
+ type_attr: "Tblock_shape"
+ }
+ input_arg {
+ name: "paddings"
+ type_attr: "Tpaddings"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tblock_shape"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "Tpaddings"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SpaceToDepth"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "block_size"
+ type: "int"
+ has_minimum: true
+ minimum: 2
+ }
+}
+op {
+ name: "SparseAccumulatorApplyGradient"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "local_step"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "gradient_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "gradient_values"
+ type_attr: "dtype"
+ }
+ input_arg {
+ name: "gradient_shape"
+ type: DT_INT64
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "has_known_shape"
+ type: "bool"
+ }
+}
+op {
+ name: "SparseAccumulatorTakeGradient"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "num_required"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "values"
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "shape"
+ type: DT_INT64
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SparseAdd"
+ input_arg {
+ name: "a_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "a_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "a_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "b_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "b_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "b_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "thresh"
+ type_attr: "Treal"
+ }
+ output_arg {
+ name: "sum_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sum_values"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "sum_shape"
+ type: DT_INT64
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Treal"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SparseAddGrad"
+ input_arg {
+ name: "backprop_val_grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "a_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "b_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "sum_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "a_val_grad"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "b_val_grad"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SparseApplyAdadelta"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum_update"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "SparseApplyAdagrad"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "SparseApplyAdagradDA"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "gradient_accumulator"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "gradient_squared_accumulator"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "global_step"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "SparseApplyCenteredRMSProp"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "mg"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "ms"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "mom"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "SparseApplyFtrl"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "linear"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lr_power"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "SparseApplyMomentum"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "use_nesterov"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "SparseApplyProximalAdagrad"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "accum"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "SparseApplyProximalGradientDescent"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "alpha"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l1"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "l2"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "SparseApplyRMSProp"
+ input_arg {
+ name: "var"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "ms"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "mom"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "lr"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "rho"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "momentum"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "epsilon"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tindices"
+ }
+ output_arg {
+ name: "out"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "use_locking"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "SparseConcat"
+ input_arg {
+ name: "indices"
+ type: DT_INT64
+ number_attr: "N"
+ }
+ input_arg {
+ name: "values"
+ type_attr: "T"
+ number_attr: "N"
+ }
+ input_arg {
+ name: "shapes"
+ type: DT_INT64
+ number_attr: "N"
+ }
+ output_arg {
+ name: "output_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_values"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_shape"
+ type: DT_INT64
+ }
+ attr {
+ name: "concat_dim"
+ type: "int"
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 2
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "SparseConditionalAccumulator"
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "shape"
+ type: "shape"
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "SparseDenseCwiseAdd"
+ input_arg {
+ name: "sp_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "sp_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "sp_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "dense"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SparseDenseCwiseDiv"
+ input_arg {
+ name: "sp_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "sp_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "sp_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "dense"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SparseDenseCwiseMul"
+ input_arg {
+ name: "sp_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "sp_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "sp_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "dense"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SparseMatMul"
+ input_arg {
+ name: "a"
+ type_attr: "Ta"
+ }
+ input_arg {
+ name: "b"
+ type_attr: "Tb"
+ }
+ output_arg {
+ name: "product"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "transpose_a"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "transpose_b"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "a_is_sparse"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "b_is_sparse"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "Ta"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_BFLOAT16
+ }
+ }
+ }
+ attr {
+ name: "Tb"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_BFLOAT16
+ }
+ }
+ }
+}
+op {
+ name: "SparseReduceSum"
+ input_arg {
+ name: "input_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "input_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "input_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "reduction_axes"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "keep_dims"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SparseReduceSumSparse"
+ input_arg {
+ name: "input_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "input_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "input_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "reduction_axes"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_values"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_shape"
+ type: DT_INT64
+ }
+ attr {
+ name: "keep_dims"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SparseReorder"
+ input_arg {
+ name: "input_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "input_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "input_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_values"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "SparseReshape"
+ input_arg {
+ name: "input_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "input_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "new_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_shape"
+ type: DT_INT64
+ }
+}
+op {
+ name: "SparseSegmentMean"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tidx"
+ }
+ input_arg {
+ name: "segment_ids"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SparseSegmentMeanGrad"
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tidx"
+ }
+ input_arg {
+ name: "segment_ids"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "output_dim0"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SparseSegmentSqrtN"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tidx"
+ }
+ input_arg {
+ name: "segment_ids"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SparseSegmentSqrtNGrad"
+ input_arg {
+ name: "grad"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tidx"
+ }
+ input_arg {
+ name: "segment_ids"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "output_dim0"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SparseSegmentSum"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "indices"
+ type_attr: "Tidx"
+ }
+ input_arg {
+ name: "segment_ids"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SparseSoftmax"
+ input_arg {
+ name: "sp_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "sp_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "sp_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "SparseSoftmaxCrossEntropyWithLogits"
+ input_arg {
+ name: "features"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "labels"
+ type_attr: "Tlabels"
+ }
+ output_arg {
+ name: "loss"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "backprop"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "Tlabels"
+ type: "type"
+ default_value {
+ type: DT_INT64
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SparseSparseMaximum"
+ input_arg {
+ name: "a_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "a_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "a_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "b_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "b_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "b_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_values"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SparseSparseMinimum"
+ input_arg {
+ name: "a_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "a_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "a_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "b_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "b_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "b_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_values"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "SparseSplit"
+ input_arg {
+ name: "split_dim"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "output_indices"
+ type: DT_INT64
+ number_attr: "num_split"
+ }
+ output_arg {
+ name: "output_values"
+ type_attr: "T"
+ number_attr: "num_split"
+ }
+ output_arg {
+ name: "output_shape"
+ type: DT_INT64
+ number_attr: "num_split"
+ }
+ attr {
+ name: "num_split"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "SparseTensorDenseAdd"
+ input_arg {
+ name: "a_indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "a_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "a_shape"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "b"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SparseTensorDenseMatMul"
+ input_arg {
+ name: "a_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "a_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "a_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "b"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "product"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "adjoint_a"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "adjoint_b"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "SparseToDense"
+ input_arg {
+ name: "sparse_indices"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "output_shape"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "sparse_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "default_value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "dense"
+ type_attr: "T"
+ }
+ attr {
+ name: "validate_indices"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "SparseToSparseSetOperation"
+ input_arg {
+ name: "set1_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "set1_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "set1_shape"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "set2_indices"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "set2_values"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "set2_shape"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "result_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "result_values"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "result_shape"
+ type: DT_INT64
+ }
+ attr {
+ name: "set_operation"
+ type: "string"
+ }
+ attr {
+ name: "validate_indices"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT8
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_STRING
+ }
+ }
+ }
+}
+op {
+ name: "Split"
+ input_arg {
+ name: "split_dim"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ number_attr: "num_split"
+ }
+ attr {
+ name: "num_split"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "SplitV"
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "size_splits"
+ type_attr: "Tlen"
+ }
+ input_arg {
+ name: "split_dim"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ number_attr: "num_split"
+ }
+ attr {
+ name: "num_split"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tlen"
+ type: "type"
+ default_value {
+ type: DT_INT64
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Sqrt"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "SqrtGrad"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Square"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "SquaredDifference"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+ is_commutative: true
+}
+op {
+ name: "Squeeze"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "squeeze_dims"
+ type: "list(int)"
+ default_value {
+ list {
+ }
+ }
+ has_minimum: true
+ }
+}
+op {
+ name: "Stack"
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "elem_type"
+ type: "type"
+ }
+ attr {
+ name: "stack_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "StackClose"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+}
+op {
+ name: "StackPop"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ output_arg {
+ name: "elem"
+ type_attr: "elem_type"
+ }
+ attr {
+ name: "elem_type"
+ type: "type"
+ }
+}
+op {
+ name: "StackPush"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "elem"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "swap_memory"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+}
+op {
+ name: "Stage"
+ input_arg {
+ name: "values"
+ type_list_attr: "dtypes"
+ }
+ attr {
+ name: "dtypes"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "StopGradient"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "StridedSlice"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "begin"
+ type_attr: "Index"
+ }
+ input_arg {
+ name: "end"
+ type_attr: "Index"
+ }
+ input_arg {
+ name: "strides"
+ type_attr: "Index"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Index"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "begin_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "end_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "ellipsis_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "new_axis_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "shrink_axis_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "StridedSliceAssign"
+ input_arg {
+ name: "ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ input_arg {
+ name: "begin"
+ type_attr: "Index"
+ }
+ input_arg {
+ name: "end"
+ type_attr: "Index"
+ }
+ input_arg {
+ name: "strides"
+ type_attr: "Index"
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_ref"
+ type_attr: "T"
+ is_ref: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Index"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "begin_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "end_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "ellipsis_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "new_axis_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "shrink_axis_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "StridedSliceGrad"
+ input_arg {
+ name: "shape"
+ type_attr: "Index"
+ }
+ input_arg {
+ name: "begin"
+ type_attr: "Index"
+ }
+ input_arg {
+ name: "end"
+ type_attr: "Index"
+ }
+ input_arg {
+ name: "strides"
+ type_attr: "Index"
+ }
+ input_arg {
+ name: "dy"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Index"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "begin_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "end_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "ellipsis_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "new_axis_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "shrink_axis_mask"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "StringJoin"
+ input_arg {
+ name: "inputs"
+ type: DT_STRING
+ number_attr: "N"
+ }
+ output_arg {
+ name: "output"
+ type: DT_STRING
+ }
+ attr {
+ name: "N"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "separator"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+}
+op {
+ name: "StringSplit"
+ input_arg {
+ name: "input"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "delimiter"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "values"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "shape"
+ type: DT_INT64
+ }
+}
+op {
+ name: "StringToHashBucket"
+ input_arg {
+ name: "string_tensor"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "output"
+ type: DT_INT64
+ }
+ attr {
+ name: "num_buckets"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "StringToHashBucketFast"
+ input_arg {
+ name: "input"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "output"
+ type: DT_INT64
+ }
+ attr {
+ name: "num_buckets"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+}
+op {
+ name: "StringToHashBucketStrong"
+ input_arg {
+ name: "input"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "output"
+ type: DT_INT64
+ }
+ attr {
+ name: "num_buckets"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "key"
+ type: "list(int)"
+ }
+}
+op {
+ name: "StringToNumber"
+ input_arg {
+ name: "string_tensor"
+ type: DT_STRING
+ }
+ output_arg {
+ name: "output"
+ type_attr: "out_type"
+ }
+ attr {
+ name: "out_type"
+ type: "type"
+ default_value {
+ type: DT_FLOAT
+ }
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_INT32
+ }
+ }
+ }
+}
+op {
+ name: "Sub"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Substr"
+ input_arg {
+ name: "input"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "pos"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "len"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type: DT_STRING
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Sum"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "reduction_indices"
+ type_attr: "Tidx"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "keep_dims"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tidx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Svd"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "s"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "u"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "v"
+ type_attr: "T"
+ }
+ attr {
+ name: "compute_uv"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "full_matrices"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_DOUBLE
+ type: DT_FLOAT
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Switch"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "pred"
+ type: DT_BOOL
+ }
+ output_arg {
+ name: "output_false"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output_true"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "SymbolicGradient"
+ input_arg {
+ name: "input"
+ type_list_attr: "Tin"
+ }
+ output_arg {
+ name: "output"
+ type_list_attr: "Tout"
+ }
+ attr {
+ name: "Tin"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "Tout"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "f"
+ type: "func"
+ }
+}
+op {
+ name: "TFRecordReader"
+ output_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "compression_type"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "TFRecordReaderV2"
+ output_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "compression_type"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "TakeManySparseFromTensorsMap"
+ input_arg {
+ name: "sparse_handles"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sparse_indices"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sparse_values"
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "sparse_shape"
+ type: DT_INT64
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Tan"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "Tanh"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "TanhGrad"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "TemporaryVariable"
+ output_arg {
+ name: "ref"
+ type_attr: "dtype"
+ is_ref: true
+ }
+ attr {
+ name: "shape"
+ type: "shape"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "var_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArray"
+ input_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "dynamic_size"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "clear_after_read"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "tensor_array_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "element_shape"
+ type: "shape"
+ default_value {
+ shape {
+ unknown_rank: true
+ }
+ }
+ }
+ deprecation {
+ version: 16
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayClose"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ deprecation {
+ version: 16
+ }
+}
+op {
+ name: "TensorArrayCloseV2"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+}
+op {
+ name: "TensorArrayCloseV3"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayConcat"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "lengths"
+ type: DT_INT64
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "element_shape_except0"
+ type: "shape"
+ default_value {
+ shape {
+ unknown_rank: true
+ }
+ }
+ }
+ deprecation {
+ version: 16
+ }
+}
+op {
+ name: "TensorArrayConcatV2"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "lengths"
+ type: DT_INT64
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "element_shape_except0"
+ type: "shape"
+ default_value {
+ shape {
+ unknown_rank: true
+ }
+ }
+ }
+}
+op {
+ name: "TensorArrayConcatV3"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "lengths"
+ type: DT_INT64
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "element_shape_except0"
+ type: "shape"
+ default_value {
+ shape {
+ unknown_rank: true
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayGather"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "indices"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "element_shape"
+ type: "shape"
+ default_value {
+ shape {
+ unknown_rank: true
+ }
+ }
+ }
+ deprecation {
+ version: 16
+ }
+}
+op {
+ name: "TensorArrayGatherV2"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "indices"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "element_shape"
+ type: "shape"
+ default_value {
+ shape {
+ unknown_rank: true
+ }
+ }
+ }
+}
+op {
+ name: "TensorArrayGatherV3"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "indices"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "element_shape"
+ type: "shape"
+ default_value {
+ shape {
+ unknown_rank: true
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayGrad"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "grad_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "source"
+ type: "string"
+ }
+ deprecation {
+ version: 16
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayGradV2"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "grad_handle"
+ type: DT_STRING
+ }
+ attr {
+ name: "source"
+ type: "string"
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayGradV3"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "grad_handle"
+ type: DT_RESOURCE
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "source"
+ type: "string"
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayPack"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "element_shape"
+ type: "shape"
+ default_value {
+ shape {
+ unknown_rank: true
+ }
+ }
+ }
+ deprecation {
+ version: 16
+ }
+}
+op {
+ name: "TensorArrayRead"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "index"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ deprecation {
+ version: 16
+ }
+}
+op {
+ name: "TensorArrayReadV2"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "index"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+}
+op {
+ name: "TensorArrayReadV3"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "index"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "value"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayScatter"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "indices"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ deprecation {
+ version: 19
+ }
+}
+op {
+ name: "TensorArrayScatterV2"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "indices"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "TensorArrayScatterV3"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "indices"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArraySize"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ deprecation {
+ version: 16
+ }
+}
+op {
+ name: "TensorArraySizeV2"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "size"
+ type: DT_INT32
+ }
+}
+op {
+ name: "TensorArraySizeV3"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArraySplit"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lengths"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ deprecation {
+ version: 16
+ }
+}
+op {
+ name: "TensorArraySplitV2"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lengths"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "TensorArraySplitV3"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "lengths"
+ type: DT_INT64
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayUnpack"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ deprecation {
+ version: 20
+ }
+}
+op {
+ name: "TensorArrayV2"
+ input_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "element_shape"
+ type: "shape"
+ default_value {
+ shape {
+ unknown_rank: true
+ }
+ }
+ }
+ attr {
+ name: "dynamic_size"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "clear_after_read"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "tensor_array_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayV3"
+ input_arg {
+ name: "size"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ output_arg {
+ name: "flow"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "element_shape"
+ type: "shape"
+ default_value {
+ shape {
+ unknown_rank: true
+ }
+ }
+ }
+ attr {
+ name: "dynamic_size"
+ type: "bool"
+ default_value {
+ b: false
+ }
+ }
+ attr {
+ name: "clear_after_read"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "tensor_array_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorArrayWrite"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ input_arg {
+ name: "index"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ deprecation {
+ version: 16
+ }
+}
+op {
+ name: "TensorArrayWriteV2"
+ input_arg {
+ name: "handle"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "index"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "TensorArrayWriteV3"
+ input_arg {
+ name: "handle"
+ type: DT_RESOURCE
+ }
+ input_arg {
+ name: "index"
+ type: DT_INT32
+ }
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "flow_in"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "flow_out"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ is_stateful: true
+}
+op {
+ name: "TensorSummary"
+ input_arg {
+ name: "tensor"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "summary"
+ type: DT_STRING
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "description"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "labels"
+ type: "list(string)"
+ default_value {
+ list {
+ }
+ }
+ }
+ attr {
+ name: "display_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+}
+op {
+ name: "TextLineReader"
+ output_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "skip_header_lines"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "TextLineReaderV2"
+ output_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ attr {
+ name: "skip_header_lines"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "ThreadUnsafeUnigramCandidateSampler"
+ input_arg {
+ name: "true_classes"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sampled_candidates"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "true_expected_count"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "sampled_expected_count"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "num_true"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "num_sampled"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "unique"
+ type: "bool"
+ }
+ attr {
+ name: "range_max"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "Tile"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "multiples"
+ type_attr: "Tmultiples"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tmultiples"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "TileGrad"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "multiples"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ deprecation {
+ version: 3
+ }
+}
+op {
+ name: "TopK"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "values"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "indices"
+ type: DT_INT32
+ }
+ attr {
+ name: "k"
+ type: "int"
+ has_minimum: true
+ }
+ attr {
+ name: "sorted"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ deprecation {
+ version: 7
+ }
+}
+op {
+ name: "TopKV2"
+ input_arg {
+ name: "input"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "k"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "values"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "indices"
+ type: DT_INT32
+ }
+ attr {
+ name: "sorted"
+ type: "bool"
+ default_value {
+ b: true
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+}
+op {
+ name: "Transpose"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "perm"
+ type_attr: "Tperm"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "Tperm"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "TruncateDiv"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_UINT8
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ }
+ }
+ }
+}
+op {
+ name: "TruncateMod"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
+op {
+ name: "TruncatedNormal"
+ input_arg {
+ name: "shape"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "dtype"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "UniformCandidateSampler"
+ input_arg {
+ name: "true_classes"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "sampled_candidates"
+ type: DT_INT64
+ }
+ output_arg {
+ name: "true_expected_count"
+ type: DT_FLOAT
+ }
+ output_arg {
+ name: "sampled_expected_count"
+ type: DT_FLOAT
+ }
+ attr {
+ name: "num_true"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "num_sampled"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "unique"
+ type: "bool"
+ }
+ attr {
+ name: "range_max"
+ type: "int"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "Unique"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "idx"
+ type_attr: "out_idx"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "out_idx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "UniqueWithCounts"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "idx"
+ type_attr: "out_idx"
+ }
+ output_arg {
+ name: "count"
+ type_attr: "out_idx"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "out_idx"
+ type: "type"
+ default_value {
+ type: DT_INT32
+ }
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Unpack"
+ input_arg {
+ name: "value"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ number_attr: "num"
+ }
+ attr {
+ name: "num"
+ type: "int"
+ has_minimum: true
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+ attr {
+ name: "axis"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ }
+}
+op {
+ name: "UnsortedSegmentMax"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "segment_ids"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "num_segments"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "UnsortedSegmentSum"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "segment_ids"
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "num_segments"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT64
+ type: DT_INT32
+ type: DT_UINT8
+ type: DT_UINT16
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_COMPLEX64
+ type: DT_COMPLEX128
+ type: DT_QINT8
+ type: DT_QUINT8
+ type: DT_QINT32
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+}
+op {
+ name: "Unstage"
+ output_arg {
+ name: "values"
+ type_list_attr: "dtypes"
+ }
+ attr {
+ name: "dtypes"
+ type: "list(type)"
+ has_minimum: true
+ minimum: 1
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Variable"
+ output_arg {
+ name: "ref"
+ type_attr: "dtype"
+ is_ref: true
+ }
+ attr {
+ name: "shape"
+ type: "shape"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "VariableV2"
+ output_arg {
+ name: "ref"
+ type_attr: "dtype"
+ is_ref: true
+ }
+ attr {
+ name: "shape"
+ type: "shape"
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "Where"
+ input_arg {
+ name: "input"
+ type: DT_BOOL
+ }
+ output_arg {
+ name: "index"
+ type: DT_INT64
+ }
+}
+op {
+ name: "WholeFileReader"
+ output_arg {
+ name: "reader_handle"
+ type: DT_STRING
+ is_ref: true
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "WholeFileReaderV2"
+ output_arg {
+ name: "reader_handle"
+ type: DT_RESOURCE
+ }
+ attr {
+ name: "container"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ attr {
+ name: "shared_name"
+ type: "string"
+ default_value {
+ s: ""
+ }
+ }
+ is_stateful: true
+}
+op {
+ name: "WriteFile"
+ input_arg {
+ name: "filename"
+ type: DT_STRING
+ }
+ input_arg {
+ name: "contents"
+ type: DT_STRING
+ }
+}
+op {
+ name: "ZerosLike"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "y"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ }
+}
+op {
+ name: "Zeta"
+ input_arg {
+ name: "x"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "q"
+ type_attr: "T"
+ }
+ output_arg {
+ name: "z"
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+}
diff --git a/tensorflow/core/ops/ops.pbtxt b/tensorflow/core/ops/ops.pbtxt
index c7e077a290..6212048f82 100644
--- a/tensorflow/core/ops/ops.pbtxt
+++ b/tensorflow/core/ops/ops.pbtxt
@@ -7109,8 +7109,8 @@ op {
name: "outputs"
type: DT_FLOAT
}
- summary: "Fake-quantize the \'inputs\' tensor of type float and shape `[b, h, w, d]` via"
- description: "global float scalars `min` and `max` to \'outputs\' tensor of same shape as\n`inputs`.\n\n[min; max] is the clamping range for the \'inputs\' data. Op divides this range\ninto 255 steps (total of 256 values), then replaces each \'inputs\' value with the\nclosest of the quantized step values.\n\nThis operation has a gradient and thus allows for training `min` and `max` values."
+ summary: "Fake-quantize the \'inputs\' tensor of type float via global float scalars `min`"
+ description: "and `max` to \'outputs\' tensor of same shape as `inputs`.\n\n[min; max] is the clamping range for the \'inputs\' data. Op divides this range\ninto 255 steps (total of 256 values), then replaces each \'inputs\' value with the\nclosest of the quantized step values.\n\nThis operation has a gradient and thus allows for training `min` and `max` values."
}
op {
name: "FakeQuantWithMinMaxVarsGradient"
@@ -11793,7 +11793,7 @@ op {
}
input_arg {
name: "dense_defaults"
- description: "A list of Ndense Tensors (some may be empty).\ndense_defaults[j] provides default values\nwhen the example\'s feature_map lacks dense_key[j]. If an empty Tensor is\nprovided for dense_defaults[j], then the Feature dense_keys[j] is required.\nThe input type is inferred from dense_defaults[j], even when it\'s empty.\nIf dense_defaults[j] is not empty, its shape must match dense_shapes[j]."
+ description: "A list of Ndense Tensors (some may be empty).\ndense_defaults[j] provides default values\nwhen the example\'s feature_map lacks dense_key[j]. If an empty Tensor is\nprovided for dense_defaults[j], then the Feature dense_keys[j] is required.\nThe input type is inferred from dense_defaults[j], even when it\'s empty.\nIf dense_defaults[j] is not empty, and dense_shapes[j] is fully defined,\nthen the shape of dense_defaults[j] must match that of dense_shapes[j].\nIf dense_shapes[j] has an undefined major dimension (variable strides dense\nfeature), dense_defaults[j] must contain a single element:\nthe padding element."
type_list_attr: "Tdense"
}
output_arg {
@@ -11852,7 +11852,7 @@ op {
attr {
name: "dense_shapes"
type: "list(shape)"
- description: "A list of Ndense shapes; the shapes of data in each Feature\ngiven in dense_keys.\nThe number of elements in the Feature corresponding to dense_key[j]\nmust always equal dense_shapes[j].NumEntries().\nIf dense_shapes[j] == (D0, D1, ..., DN) then the shape of output\nTensor dense_values[j] will be (|serialized|, D0, D1, ..., DN):\nThe dense outputs are just the inputs row-stacked by batch."
+ description: "A list of Ndense shapes; the shapes of data in each Feature\ngiven in dense_keys.\nThe number of elements in the Feature corresponding to dense_key[j]\nmust always equal dense_shapes[j].NumEntries().\nIf dense_shapes[j] == (D0, D1, ..., DN) then the shape of output\nTensor dense_values[j] will be (|serialized|, D0, D1, ..., DN):\nThe dense outputs are just the inputs row-stacked by batch.\nThis works for dense_shapes[j] = (-1, D1, ..., DN). In this case\nthe shape of the output Tensor dense_values[j] will be\n(|serialized|, M, D1, .., DN), where M is the maximum number of blocks\nof elements of length D1 * .... * DN, across all minibatch entries\nin the input. Any minibatch entry with less than M blocks of elements of\nlength D1 * ... * DN will be padded with the corresponding default_value\nscalar element along the second dimension."
has_minimum: true
}
summary: "Transforms a vector of brain.Example protos (as strings) into typed tensors."
@@ -14326,6 +14326,64 @@ op {
is_stateful: true
}
op {
+ name: "RandomPoisson"
+ input_arg {
+ name: "shape"
+ description: "1-D integer tensor. Shape of independent samples to draw from each\ndistribution described by the shape parameters given in rate."
+ type_attr: "S"
+ }
+ input_arg {
+ name: "rate"
+ description: "A tensor in which each scalar is a \"rate\" parameter describing the\nassociated poisson distribution."
+ type_attr: "dtype"
+ }
+ output_arg {
+ name: "output"
+ description: "A tensor with shape `shape + shape(rate)`. Each slice\n`[:, ..., :, i0, i1, ...iN]` contains the samples drawn for\n`rate[i0, i1, ...iN]`. The dtype of the output matches the dtype of\nrate."
+ type_attr: "dtype"
+ }
+ attr {
+ name: "seed"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ description: "If either `seed` or `seed2` are set to be non-zero, the random number\ngenerator is seeded by the given seed. Otherwise, it is seeded by a\nrandom seed."
+ }
+ attr {
+ name: "seed2"
+ type: "int"
+ default_value {
+ i: 0
+ }
+ description: "A second seed to avoid seed collision."
+ }
+ attr {
+ name: "S"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ attr {
+ name: "dtype"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_HALF
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ }
+ }
+ }
+ summary: "Outputs random values from the Poisson distribution(s) described by rate."
+ description: "This op uses two algorithms, depending on rate. If rate >= 10, then\nthe algorithm by Hormann is used to acquire samples via\ntransformation-rejection.\nSee http://www.sciencedirect.com/science/article/pii/0167668793909974.\n\nOtherwise, Knuth\'s algorithm is used to acquire samples via multiplying uniform\nrandom variables.\nSee Donald E. Knuth (1969). Seminumerical Algorithms. The Art of Computer\nProgramming, Volume 2. Addison Wesley"
+ is_stateful: true
+}
+op {
name: "RandomShuffle"
input_arg {
name: "value"
@@ -25149,6 +25207,56 @@ op {
description: "Unpacks `num` tensors from `value` by chipping it along the `axis` dimension.\nFor example, given a tensor of shape `(A, B, C, D)`;\n\nIf `axis == 0` then the i\'th tensor in `output` is the slice `value[i, :, :, :]`\n and each tensor in `output` will have shape `(B, C, D)`. (Note that the\n dimension unpacked along is gone, unlike `split`).\n\nIf `axis == 1` then the i\'th tensor in `output` is the slice `value[:, i, :, :]`\n and each tensor in `output` will have shape `(A, C, D)`.\nEtc.\n\nThis is the opposite of `pack`."
}
op {
+ name: "UnsortedSegmentMax"
+ input_arg {
+ name: "data"
+ type_attr: "T"
+ }
+ input_arg {
+ name: "segment_ids"
+ description: "A 1-D tensor whose rank is equal to the rank of `data`\'s\nfirst dimension."
+ type_attr: "Tindices"
+ }
+ input_arg {
+ name: "num_segments"
+ type: DT_INT32
+ }
+ output_arg {
+ name: "output"
+ description: "Has same shape as data, except for dimension 0 which\nhas size `num_segments`."
+ type_attr: "T"
+ }
+ attr {
+ name: "T"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_FLOAT
+ type: DT_DOUBLE
+ type: DT_INT32
+ type: DT_INT64
+ type: DT_UINT8
+ type: DT_INT16
+ type: DT_INT8
+ type: DT_UINT16
+ type: DT_HALF
+ }
+ }
+ }
+ attr {
+ name: "Tindices"
+ type: "type"
+ allowed_values {
+ list {
+ type: DT_INT32
+ type: DT_INT64
+ }
+ }
+ }
+ summary: "Computes the Max along segments of a tensor."
+ description: "Read [the section on\nSegmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation\nof segments.\n\nThis operator is similar to the [unsorted segment sum operator](../../api_docs/python/math_ops.md#UnsortedSegmentSum).\nInstead of computing the sum over segments, it computes the maximum\nsuch that:\n\n\\\\(output_i = \\max_j data_j\\\\) where max is over `j` such\nthat `segment_ids[j] == i`.\n\nIf the maximum is empty for a given segment ID `i`, it outputs the smallest possible value for specific numeric type,\n `output[i] = numeric_limits<T>::min()`.\n\n<div style=\"width:70%; margin:auto; margin-bottom:10px; margin-top:20px;\">\n<img style=\"width:100%\" src=\"../../images/UnsortedSegmentSum.png\" alt>\n</div>"
+}
+op {
name: "UnsortedSegmentSum"
input_arg {
name: "data"
diff --git a/tensorflow/core/ops/parsing_ops.cc b/tensorflow/core/ops/parsing_ops.cc
index 4ca3f2e07e..b563656f39 100644
--- a/tensorflow/core/ops/parsing_ops.cc
+++ b/tensorflow/core/ops/parsing_ops.cc
@@ -113,7 +113,11 @@ dense_defaults: A list of Ndense Tensors (some may be empty).
when the example's feature_map lacks dense_key[j]. If an empty Tensor is
provided for dense_defaults[j], then the Feature dense_keys[j] is required.
The input type is inferred from dense_defaults[j], even when it's empty.
- If dense_defaults[j] is not empty, its shape must match dense_shapes[j].
+ If dense_defaults[j] is not empty, and dense_shapes[j] is fully defined,
+ then the shape of dense_defaults[j] must match that of dense_shapes[j].
+ If dense_shapes[j] has an undefined major dimension (variable strides dense
+ feature), dense_defaults[j] must contain a single element:
+ the padding element.
dense_shapes: A list of Ndense shapes; the shapes of data in each Feature
given in dense_keys.
The number of elements in the Feature corresponding to dense_key[j]
@@ -121,6 +125,13 @@ dense_shapes: A list of Ndense shapes; the shapes of data in each Feature
If dense_shapes[j] == (D0, D1, ..., DN) then the shape of output
Tensor dense_values[j] will be (|serialized|, D0, D1, ..., DN):
The dense outputs are just the inputs row-stacked by batch.
+ This works for dense_shapes[j] = (-1, D1, ..., DN). In this case
+ the shape of the output Tensor dense_values[j] will be
+ (|serialized|, M, D1, .., DN), where M is the maximum number of blocks
+ of elements of length D1 * .... * DN, across all minibatch entries
+ in the input. Any minibatch entry with less than M blocks of elements of
+ length D1 * ... * DN will be padded with the corresponding default_value
+ scalar element along the second dimension.
sparse_keys: A list of Nsparse string Tensors (scalars).
The keys expected in the Examples' features associated with sparse values.
sparse_types: A list of Nsparse types; the data types of data in each Feature
diff --git a/tensorflow/core/ops/parsing_ops_test.cc b/tensorflow/core/ops/parsing_ops_test.cc
index 6167c136b1..dc2aa19ee1 100644
--- a/tensorflow/core/ops/parsing_ops_test.cc
+++ b/tensorflow/core/ops/parsing_ops_test.cc
@@ -61,11 +61,19 @@ TEST(ParsingOpsTest, DecodeCSV_ShapeFn) {
}
static std::vector<TensorShapeProto> MakeDenseShapes(int size,
- bool add_extra_shape) {
+ bool add_extra_shape,
+ int unknown_outer_dims) {
std::vector<TensorShapeProto> shapes(size);
for (int i = 0; i < size; ++i) {
- // Make shapes be the sequence [1]; [1,2], [1,2,3]...
- if (i > 0) shapes[i] = shapes[i - 1];
+ // Make shapes be the sequence [?,1]; [?,1,2], [?,1,2,3]...
+ // where the number of prefixed ? depends on unknown_outer_dims.
+ if (i == 0) {
+ for (int d = 0; d < unknown_outer_dims; ++d) {
+ shapes[i].add_dim()->set_size(-1);
+ }
+ } else {
+ shapes[i] = shapes[i - 1];
+ }
shapes[i].add_dim()->set_size(i + 1);
}
if (add_extra_shape) {
@@ -77,7 +85,8 @@ static std::vector<TensorShapeProto> MakeDenseShapes(int size,
TEST(ParsingOpsTest, ParseExample_ShapeFn) {
ShapeInferenceTestOp op("ParseExample");
auto set_outputs = [&op](int num_sparse, int num_dense,
- bool add_extra_shape = false) {
+ bool add_extra_shape = false,
+ int unknown_outer_dims = 0) {
using NodeOutList = std::vector<NodeDefBuilder::NodeOut>;
using DataTypeList = std::vector<DataType>;
NodeDefBuilder::NodeOut string_in{"a", 0, DT_STRING};
@@ -91,7 +100,8 @@ TEST(ParsingOpsTest, ParseExample_ShapeFn) {
.Input(NodeOutList(num_dense, string_in))
.Attr("sparse_types", DataTypeList(num_sparse, DT_FLOAT))
.Attr("dense_types", DataTypeList(num_dense, DT_FLOAT))
- .Attr("dense_shapes", MakeDenseShapes(num_dense, add_extra_shape))
+ .Attr("dense_shapes", MakeDenseShapes(num_dense, add_extra_shape,
+ unknown_outer_dims))
.Finalize(&op.node_def));
};
@@ -115,6 +125,24 @@ TEST(ParsingOpsTest, ParseExample_ShapeFn) {
set_outputs(2, 3, true /* add_extra_shape */);
INFER_ERROR("len(dense_keys) != len(dense_shapes)", op,
"?;?;?;?;?;?;?;?;?;?");
+
+ // Allow variable strides
+ set_outputs(2, 3, false /* add_extra_shape */, 1 /* unknown_outer_dims */);
+ INFER_OK(op, "?;?;?;?;?;?;?;?;?;?",
+ ("[?,2];[?,2];[?];[?];[2];[2];" // sparse outputs
+ "[?,?,1];[?,?,1,2];[?,?,1,2,3]")); // dense outputs
+ INFER_OK(op, "[10];?;?;?;?;?;?;?;?;?",
+ ("[?,2];[?,2];[?];[?];[2];[2];" // sparse outputs
+ "[d0_0,?,1];[d0_0,?,1,2];[d0_0,?,1,2,3]")); // dense outputs
+
+ set_outputs(2, 3, true /* add_extra_shape */, 1 /* unknown_outer_dims */);
+ INFER_ERROR("len(dense_keys) != len(dense_shapes)", op,
+ "?;?;?;?;?;?;?;?;?;?");
+
+ // Variable inner dimensions are not supported
+ set_outputs(2, 3, false /* add_extra_shape */, 2 /* unknown_outer_dims */);
+ INFER_ERROR("shapes[0] has unknown rank or unknown inner dimensions", op,
+ "?;?;?;?;?;?;?;?;?;?");
}
TEST(ParsingOpsTest, ParseSingleSequenceExample_ShapeFn) {
@@ -142,13 +170,13 @@ TEST(ParsingOpsTest, ParseSingleSequenceExample_ShapeFn) {
.Attr("context_dense_types",
DataTypeList(num_context_dense, DT_FLOAT))
.Attr("context_dense_shapes",
- MakeDenseShapes(num_context_dense, add_extra_shape))
+ MakeDenseShapes(num_context_dense, add_extra_shape, 0))
.Attr("feature_list_sparse_types",
DataTypeList(num_feature_list_sparse, DT_FLOAT))
.Attr("feature_list_dense_types",
DataTypeList(num_feature_list_dense, DT_FLOAT))
.Attr("feature_list_dense_shapes",
- MakeDenseShapes(num_feature_list_dense, add_extra_shape))
+ MakeDenseShapes(num_feature_list_dense, add_extra_shape, 0))
.Finalize(&op.node_def));
};
diff --git a/tensorflow/core/ops/random_ops.cc b/tensorflow/core/ops/random_ops.cc
index 776523f33f..7b2da9d8e6 100644
--- a/tensorflow/core/ops/random_ops.cc
+++ b/tensorflow/core/ops/random_ops.cc
@@ -276,4 +276,48 @@ output: A tensor with shape `shape + shape(alpha)`. Each slice
`alpha[i0, i1, ...iN]`. The dtype of the output matches the dtype of alpha.
)doc");
+REGISTER_OP("RandomPoisson")
+ .SetIsStateful()
+ .Input("shape: S")
+ .Input("rate: dtype")
+ .Output("output: dtype")
+ .Attr("seed: int = 0")
+ .Attr("seed2: int = 0")
+ .Attr("S: {int32, int64}")
+ .Attr("dtype: {half, float, double}")
+ .SetShapeFn([](InferenceContext* c) {
+ ShapeHandle out;
+ TF_RETURN_IF_ERROR(c->MakeShapeFromShapeTensor(0, &out));
+ TF_RETURN_IF_ERROR(c->Concatenate(out, c->input(1), &out));
+ c->set_output(0, out);
+ return Status::OK();
+ })
+ .Doc(R"doc(
+Outputs random values from the Poisson distribution(s) described by rate.
+
+This op uses two algorithms, depending on rate. If rate >= 10, then
+the algorithm by Hormann is used to acquire samples via
+transformation-rejection.
+See http://www.sciencedirect.com/science/article/pii/0167668793909974.
+
+Otherwise, Knuth's algorithm is used to acquire samples via multiplying uniform
+random variables.
+See Donald E. Knuth (1969). Seminumerical Algorithms. The Art of Computer
+Programming, Volume 2. Addison Wesley
+
+shape: 1-D integer tensor. Shape of independent samples to draw from each
+ distribution described by the shape parameters given in rate.
+rate: A tensor in which each scalar is a "rate" parameter describing the
+ associated poisson distribution.
+seed: If either `seed` or `seed2` are set to be non-zero, the random number
+ generator is seeded by the given seed. Otherwise, it is seeded by a
+ random seed.
+seed2: A second seed to avoid seed collision.
+
+output: A tensor with shape `shape + shape(rate)`. Each slice
+ `[:, ..., :, i0, i1, ...iN]` contains the samples drawn for
+ `rate[i0, i1, ...iN]`. The dtype of the output matches the dtype of
+ rate.
+)doc");
+
} // namespace tensorflow
diff --git a/tensorflow/core/ops/random_ops_test.cc b/tensorflow/core/ops/random_ops_test.cc
index 524e107998..b0aa565485 100644
--- a/tensorflow/core/ops/random_ops_test.cc
+++ b/tensorflow/core/ops/random_ops_test.cc
@@ -53,4 +53,19 @@ TEST(RandomOpsTest, RandomGamma_ShapeFn) {
INFER_OK(op, "[3];[]", "[1,2,3]");
}
+TEST(RandomOpsTest, RandomPoisson_ShapeFn) {
+ ShapeInferenceTestOp op("RandomPoisson");
+ op.input_tensors.resize(2);
+
+ INFER_OK(op, "?;?", "?");
+ INFER_OK(op, "?;[3]", "?");
+ INFER_OK(op, "[1];?", "?");
+ INFER_ERROR("Shape must be rank 1 but is rank 2", op, "[1,2];[3,4]");
+ Tensor shape = test::AsTensor<int32>({1, 2, 3});
+ op.input_tensors[0] = &shape;
+ INFER_OK(op, "[3];[4,?]", "[1,2,3,d1_0,d1_1]");
+ INFER_OK(op, "[3];[4,5]", "[1,2,3,d1_0,d1_1]");
+ INFER_OK(op, "[3];[]", "[1,2,3]");
+}
+
} // end namespace tensorflow
diff --git a/tensorflow/core/protobuf/debug.proto b/tensorflow/core/protobuf/debug.proto
index 5b32f9fc0b..f35d7569be 100644
--- a/tensorflow/core/protobuf/debug.proto
+++ b/tensorflow/core/protobuf/debug.proto
@@ -27,6 +27,13 @@ message DebugTensorWatch {
// E.g., "file:///foo/tfdbg_dump", "grpc://localhost:11011"
// Each debug op listed in debug_ops will publish its output tensor (debug
// signal) to all URLs in debug_urls.
+ //
+ // N.B. Session::Run() supports concurrent invocations of the same inputs
+ // (feed keys), outputs and target nodes. If such concurrent invocations
+ // are to be debugged, the callers of Session::Run() must use distinct
+ // debug_urls to make sure that the streamed or dumped events do not overlap
+ // among the invocations.
+ // TODO(cais): More visible documentation of this in g3docs.
repeated string debug_urls = 4;
}
@@ -34,4 +41,9 @@ message DebugTensorWatch {
message DebugOptions {
// Debugging options
repeated DebugTensorWatch debug_tensor_watch_opts = 4;
+
+ // Caller-specified global step count.
+ // Note that this is distinct from the session run count and the executor
+ // step count.
+ int64 global_step = 10;
}
diff --git a/tensorflow/core/util/example_proto_fast_parsing.cc b/tensorflow/core/util/example_proto_fast_parsing.cc
index e14f50551e..6336cd951e 100644
--- a/tensorflow/core/util/example_proto_fast_parsing.cc
+++ b/tensorflow/core/util/example_proto_fast_parsing.cc
@@ -215,6 +215,31 @@ using Example = std::vector<FeatureMapEntry>;
} // namespace parsed
+inline bool SkipExtraneousTag(protobuf::io::CodedInputStream* stream) {
+ uint32 data;
+ protobuf_uint64 dummy;
+ switch (stream->ReadTag() & 0x7) {
+ case 0: // varint
+ if (!stream->ReadVarint32(&data)) return false;
+ return true;
+ case 1: // fixed64
+ if (!stream->ReadLittleEndian64(&dummy)) return false;
+ return true;
+ case 2: // length delimited
+ if (!stream->ReadVarint32(&data)) return false;
+ stream->Skip(data);
+ return true;
+ case 3: // group begin
+ return false; // groups not supported.
+ case 4: // group end
+ return false; // groups not supported.
+ case 5: // fixed32
+ if (!stream->ReadLittleEndian32(&data)) return false;
+ return true;
+ }
+ return false; // unrecognized tag type
+}
+
bool ParseString(protobuf::io::CodedInputStream* stream, StringPiece* result) {
DCHECK(stream != nullptr);
DCHECK(result != nullptr);
@@ -278,7 +303,10 @@ bool ParseExample(protobuf::io::CodedInputStream* stream,
// protos merged together as strings. This behavior is consistent with Proto's
// ParseFromString when string representations are concatenated.
while (!stream->ExpectAtEnd()) {
- if (!stream->ExpectTag(kDelimitedTag(1))) return false;
+ if (!stream->ExpectTag(kDelimitedTag(1))) {
+ if (!SkipExtraneousTag(stream)) return false;
+ continue;
+ }
if (!ParseFeatures(stream, example)) return false;
}
return true;
@@ -424,6 +452,7 @@ Status FastParseSerializedExample(
const size_t example_index, const Config& config,
const PresizedCuckooMap<std::pair<size_t, Type>>& config_index,
SeededHasher hasher, std::vector<Tensor>* output_dense,
+ std::vector<SparseBuffer>* output_varlen_dense,
std::vector<SparseBuffer>* output_sparse) {
DCHECK(output_dense != nullptr);
DCHECK(output_sparse != nullptr);
@@ -463,9 +492,9 @@ Status FastParseSerializedExample(
}
auto example_error = [&](StringPiece suffix) {
- return errors::InvalidArgument("Name: ", example_name, ", Key: ",
- feature_name, ", Index: ", example_index,
- ". ", suffix);
+ return errors::InvalidArgument("Name: ", example_name,
+ ", Key: ", feature_name,
+ ", Index: ", example_index, ". ", suffix);
};
auto parse_error = [&] {
@@ -494,54 +523,117 @@ Status FastParseSerializedExample(
dense_feature_last_example[d] = example_index;
if (example_dtype != config.dense[d].dtype) {
- return example_error(
- strings::StrCat("Data types don't match. Data type: ",
- DataTypeString(example_dtype), "Expected type: ",
- DataTypeString(config.dense[d].dtype)));
+ return example_error(strings::StrCat(
+ "Data types don't match. Data type: ",
+ DataTypeString(example_dtype),
+ "Expected type: ", DataTypeString(config.dense[d].dtype)));
}
- Tensor& out = (*output_dense)[d];
+ if (!config.dense[d].variable_length) {
+ Tensor& out = (*output_dense)[d];
+
+ const std::size_t num_elements = config.dense[d].elements_per_stride;
+ const std::size_t offset = example_index * num_elements;
+
+ auto shape_error = [&](size_t size, StringPiece type_str) {
+ return example_error(strings::StrCat(
+ "Number of ", type_str,
+ " values != expected. "
+ "Values size: ",
+ size,
+ " but output shape: ", config.dense[d].shape.DebugString()));
+ };
+
+ switch (config.dense[d].dtype) {
+ case DT_INT64: {
+ auto out_p = out.flat<int64>().data() + offset;
+ LimitedArraySlice<int64> slice(out_p, num_elements);
+ if (!feature.ParseInt64List(&slice)) return parse_error();
+ if (slice.EndDistance() != 0) {
+ return shape_error(num_elements - slice.EndDistance(), "int64");
+ }
+ break;
+ }
+ case DT_FLOAT: {
+ auto out_p = out.flat<float>().data() + offset;
+ LimitedArraySlice<float> slice(out_p, num_elements);
+ if (!feature.ParseFloatList(&slice)) return parse_error();
+ if (slice.EndDistance() != 0) {
+ return shape_error(num_elements - slice.EndDistance(), "float");
+ }
+ break;
+ }
+ case DT_STRING: {
+ auto out_p = out.flat<string>().data() + offset;
+ LimitedArraySlice<string> slice(out_p, num_elements);
+ if (!feature.ParseBytesList(&slice)) return parse_error();
+ if (slice.EndDistance() != 0) {
+ return shape_error(num_elements - slice.EndDistance(), "bytes");
+ }
+ break;
+ }
+ default:
+ CHECK(false) << "Should not happen.";
+ }
+ } else { // if variable length
+ SparseBuffer& out = (*output_varlen_dense)[d];
- const std::size_t num_elements = config.dense[d].elements_per_stride;
- const std::size_t offset = example_index * num_elements;
+ const std::size_t num_elements = config.dense[d].elements_per_stride;
- auto shape_error = [&](size_t size, StringPiece type_str) {
- return example_error(strings::StrCat(
- "Number of ", type_str,
- " values != expected. "
- "Values size: ",
- size, " but output shape: ", config.dense[d].shape.DebugString()));
- };
+ if (example_dtype != DT_INVALID &&
+ example_dtype != config.dense[d].dtype) {
+ return example_error(strings::StrCat(
+ "Data types don't match. ",
+ "Expected type: ", DataTypeString(config.dense[d].dtype)));
+ }
- switch (config.dense[d].dtype) {
- case DT_INT64: {
- auto out_p = out.flat<int64>().data() + offset;
- LimitedArraySlice<int64> slice(out_p, num_elements);
- if (!feature.ParseInt64List(&slice)) return parse_error();
- if (slice.EndDistance() != 0) {
- return shape_error(num_elements - slice.EndDistance(), "int64");
+ auto shape_error = [&](size_t size, StringPiece type_str) {
+ return example_error(strings::StrCat(
+ "Number of ", type_str,
+ " values is not a multiple of stride length. Saw ", size,
+ " values but output shape is: ",
+ config.dense[d].shape.DebugString()));
+ };
+
+ switch (config.dense[d].dtype) {
+ case DT_INT64: {
+ if (example_dtype != DT_INVALID) {
+ if (!feature.ParseInt64List(&out.int64_list)) {
+ return parse_error();
+ }
+ if (out.int64_list.size() % num_elements != 0) {
+ return shape_error(out.int64_list.size(), "int64");
+ }
+ }
+ out.example_end_indices.push_back(out.int64_list.size());
+ break;
}
- break;
- }
- case DT_FLOAT: {
- auto out_p = out.flat<float>().data() + offset;
- LimitedArraySlice<float> slice(out_p, num_elements);
- if (!feature.ParseFloatList(&slice)) return parse_error();
- if (slice.EndDistance() != 0) {
- return shape_error(num_elements - slice.EndDistance(), "float");
+ case DT_FLOAT: {
+ if (example_dtype != DT_INVALID) {
+ if (!feature.ParseFloatList(&out.float_list)) {
+ return parse_error();
+ }
+ if (out.float_list.size() % num_elements != 0) {
+ return shape_error(out.float_list.size(), "float");
+ }
+ }
+ out.example_end_indices.push_back(out.float_list.size());
+ break;
}
- break;
- }
- case DT_STRING: {
- auto out_p = out.flat<string>().data() + offset;
- LimitedArraySlice<string> slice(out_p, num_elements);
- if (!feature.ParseBytesList(&slice)) return parse_error();
- if (slice.EndDistance() != 0) {
- return shape_error(num_elements - slice.EndDistance(), "bytes");
+ case DT_STRING: {
+ if (example_dtype != DT_INVALID) {
+ if (!feature.ParseBytesList(&out.bytes_list)) {
+ return parse_error();
+ }
+ if (out.bytes_list.size() % num_elements != 0) {
+ return shape_error(out.bytes_list.size(), "bytes");
+ }
+ }
+ out.example_end_indices.push_back(out.bytes_list.size());
+ break;
}
- break;
+ default:
+ CHECK(false) << "Should not happen.";
}
- default:
- CHECK(false) << "Should not happen.";
}
} else {
// If feature was already visited, skip.
@@ -563,9 +655,9 @@ Status FastParseSerializedExample(
SparseBuffer& out = (*output_sparse)[d];
if (example_dtype != DT_INVALID &&
example_dtype != config.sparse[d].dtype) {
- return example_error(
- strings::StrCat("Data types don't match. ", "Expected type: ",
- DataTypeString(config.sparse[d].dtype)));
+ return example_error(strings::StrCat(
+ "Data types don't match. ",
+ "Expected type: ", DataTypeString(config.sparse[d].dtype)));
}
switch (config.sparse[d].dtype) {
@@ -602,8 +694,9 @@ Status FastParseSerializedExample(
}
}
- // Handle missing dense features.
+ // Handle missing dense features for fixed strides.
for (size_t d = 0; d < config.dense.size(); ++d) {
+ if (config.dense[d].variable_length) continue;
if (dense_feature_last_example[d] == example_index) continue;
if (config.dense[d].default_value.NumElements() == 0) {
return errors::InvalidArgument(
@@ -637,6 +730,16 @@ Status FastParseSerializedExample(
}
}
+ // Handle missing varlen dense features.
+ for (size_t d = 0; d < config.dense.size(); ++d) {
+ if (!config.dense[d].variable_length) continue;
+ if (dense_feature_last_example[d] == example_index) continue;
+ SparseBuffer& out = (*output_varlen_dense)[d];
+ size_t prev_example_end_index =
+ out.example_end_indices.empty() ? 0 : out.example_end_indices.back();
+ out.example_end_indices.push_back(prev_example_end_index);
+ }
+
// Handle missing sparse features.
for (size_t d = 0; d < config.sparse.size(); ++d) {
if (sparse_feature_last_example[d] == example_index) continue;
@@ -661,6 +764,65 @@ Status CheckConfigDataType(DataType dtype) {
}
}
+template <typename T>
+const SmallVector<T>& GetListFromBuffer(const SparseBuffer& buffer);
+
+template <>
+const SmallVector<int64>& GetListFromBuffer<int64>(const SparseBuffer& buffer) {
+ return buffer.int64_list;
+}
+template <>
+const SmallVector<float>& GetListFromBuffer<float>(const SparseBuffer& buffer) {
+ return buffer.float_list;
+}
+template <>
+const SmallVector<string>& GetListFromBuffer<string>(
+ const SparseBuffer& buffer) {
+ return buffer.bytes_list;
+}
+
+template <typename T>
+void CopyOrMoveBlock(const T* b, const T* e, T* t) {
+ std::copy(b, e, t);
+}
+template <>
+void CopyOrMoveBlock(const string* b, const string* e, string* t) {
+ std::move(b, e, t);
+}
+
+template <typename T>
+void FillAndCopyVarLen(
+ const int d, const size_t num_elements,
+ const size_t num_elements_per_minibatch, const size_t data_stride_size,
+ const Config& config,
+ const std::vector<std::vector<SparseBuffer>>& varlen_dense_buffers,
+ Tensor* values) {
+ const Tensor& default_value = config.dense[d].default_value;
+
+ // Copy-fill the tensors (creating the zero/fill-padding)
+ std::fill(values->flat<T>().data(), values->flat<T>().data() + num_elements,
+ default_value.flat<T>()(0));
+
+ // Iterate over minibatch elements
+ for (size_t i = 0; i < varlen_dense_buffers.size(); ++i) {
+ const SparseBuffer& buffer = varlen_dense_buffers[i][d];
+ const size_t offset = i * num_elements_per_minibatch;
+ const size_t stride_size = config.dense[d].elements_per_stride;
+
+ // Copy values over.
+ auto& list = GetListFromBuffer<T>(buffer);
+ auto list_ptr = list.begin();
+ auto data = values->flat<T>().data() + offset;
+ DCHECK(list.size() % stride_size == 0);
+ const size_t num_entries = list.size() / stride_size;
+ for (size_t j = 0; j < num_entries; ++j) {
+ CopyOrMoveBlock(list_ptr, list_ptr + stride_size, data);
+ list_ptr += stride_size;
+ data += data_stride_size;
+ }
+ }
+}
+
} // namespace
Status FastParseExample(const Config& config,
@@ -701,14 +863,17 @@ Status FastParseExample(const Config& config,
"Could not avoid collision. This should not happen.");
}
- // Allocate dense output (sparse have to be buffered).
+ // Allocate dense output for fixed length dense values
+ // (variable-length dense and sparse have to be buffered).
+ std::vector<Tensor> fixed_dense_values(config.dense.size());
for (size_t d = 0; d < config.dense.size(); ++d) {
+ if (config.dense[d].variable_length) continue;
TensorShape out_shape;
out_shape.AddDim(serialized.size());
for (const int64 dim : config.dense[d].shape.dim_sizes()) {
out_shape.AddDim(dim);
}
- result->dense_values.emplace_back(config.dense[d].dtype, out_shape);
+ fixed_dense_values[d] = Tensor(config.dense[d].dtype, out_shape);
}
// This parameter affects performance in a big and data-dependent way.
@@ -750,17 +915,19 @@ Status FastParseExample(const Config& config,
// Do minibatches in parallel.
std::vector<std::vector<SparseBuffer>> sparse_buffers(num_minibatches);
+ std::vector<std::vector<SparseBuffer>> varlen_dense_buffers(num_minibatches);
std::vector<Status> status_of_minibatch(num_minibatches);
auto ProcessMiniBatch = [&](size_t minibatch) {
sparse_buffers[minibatch].resize(config.sparse.size());
+ varlen_dense_buffers[minibatch].resize(config.dense.size());
size_t start = first_example_of_minibatch(minibatch);
size_t end = first_example_of_minibatch(minibatch + 1);
for (size_t e = start; e < end; ++e) {
status_of_minibatch[minibatch] = FastParseSerializedExample(
serialized[e],
(example_names.size() > 0 ? example_names[e] : "<unknown>"), e,
- config, config_index, hasher, &result->dense_values,
- &sparse_buffers[minibatch]);
+ config, config_index, hasher, &fixed_dense_values,
+ &varlen_dense_buffers[minibatch], &sparse_buffers[minibatch]);
if (!status_of_minibatch[minibatch].ok()) break;
}
};
@@ -771,8 +938,12 @@ Status FastParseExample(const Config& config,
TF_RETURN_IF_ERROR(status);
}
+ for (size_t d = 0; d < config.dense.size(); ++d) {
+ result->dense_values.push_back(std::move(fixed_dense_values[d]));
+ }
+
// Merge SparseBuffers from all minibatches for every config.sparse.
- auto MergeMinibatches = [&](size_t d) {
+ auto MergeSparseMinibatches = [&](size_t d) {
// Loop over minibatches
size_t total_num_features = 0;
size_t max_num_features = 0;
@@ -849,8 +1020,76 @@ Status FastParseExample(const Config& config,
}
};
+ // Merge SparseBuffers from all minibatches for every config.dense having
+ // variable_length.
+ auto MergeDenseVarLenMinibatches = [&](size_t d) {
+ if (!config.dense[d].variable_length) return;
+
+ // Loop over minibatches
+ size_t max_num_features = 0;
+ for (auto& dense_values_tmp : varlen_dense_buffers) {
+ std::vector<size_t>& end_indices =
+ dense_values_tmp[d].example_end_indices;
+ max_num_features = std::max(max_num_features, end_indices[0]);
+ for (size_t i = 1; i < end_indices.size(); ++i) {
+ size_t example_size = end_indices[i] - end_indices[i - 1];
+ max_num_features = std::max(max_num_features, example_size);
+ }
+ }
+
+ const size_t stride_size = config.dense[d].elements_per_stride;
+ const size_t max_num_elements = max_num_features / stride_size;
+ TensorShape values_shape;
+ DCHECK(max_num_features % config.dense[d].elements_per_stride == 0);
+ const size_t batch_size = serialized.size();
+ values_shape.AddDim(batch_size);
+ values_shape.AddDim(max_num_elements);
+ for (int i = 1; i < config.dense[d].shape.dims(); ++i) {
+ values_shape.AddDim(config.dense[d].shape.dim_size(i));
+ }
+ Tensor values(config.dense[d].dtype, values_shape);
+ result->dense_values[d] = values;
+ const size_t num_elements = values.NumElements();
+
+ // Nothing to write, exit early.
+ if (num_elements == 0) return;
+
+ const size_t num_elements_per_minibatch = num_elements / batch_size;
+ const size_t data_stride_size =
+ (max_num_elements == 0)
+ ? 0
+ : (num_elements_per_minibatch / max_num_elements);
+
+ switch (config.dense[d].dtype) {
+ case DT_INT64: {
+ FillAndCopyVarLen<int64>(d, num_elements, num_elements_per_minibatch,
+ data_stride_size, config, varlen_dense_buffers,
+ &values);
+ break;
+ }
+ case DT_FLOAT: {
+ FillAndCopyVarLen<float>(d, num_elements, num_elements_per_minibatch,
+ data_stride_size, config, varlen_dense_buffers,
+ &values);
+ break;
+ }
+ case DT_STRING: {
+ FillAndCopyVarLen<string>(d, num_elements, num_elements_per_minibatch,
+ data_stride_size, config,
+ varlen_dense_buffers, &values);
+ break;
+ }
+ default:
+ CHECK(false) << "Should not happen.";
+ }
+ };
+
+ for (size_t d = 0; d < config.dense.size(); ++d) {
+ MergeDenseVarLenMinibatches(d);
+ }
+
for (size_t d = 0; d < config.sparse.size(); ++d) {
- MergeMinibatches(d);
+ MergeSparseMinibatches(d);
}
return Status::OK();
diff --git a/tensorflow/core/util/example_proto_fast_parsing.h b/tensorflow/core/util/example_proto_fast_parsing.h
index 4878199802..5f8b4af5fe 100644
--- a/tensorflow/core/util/example_proto_fast_parsing.h
+++ b/tensorflow/core/util/example_proto_fast_parsing.h
@@ -48,6 +48,7 @@ struct FastParseExampleConfig {
// Documentation is avaliable in: tensorflow/core/ops/parsing_ops.cc
PartialTensorShape shape;
Tensor default_value;
+ bool variable_length;
std::size_t elements_per_stride;
};
diff --git a/tensorflow/core/util/example_proto_fast_parsing_test.cc b/tensorflow/core/util/example_proto_fast_parsing_test.cc
index 8809839c56..5ab09e6af2 100644
--- a/tensorflow/core/util/example_proto_fast_parsing_test.cc
+++ b/tensorflow/core/util/example_proto_fast_parsing_test.cc
@@ -20,6 +20,7 @@ limitations under the License.
#include "tensorflow/core/platform/protobuf.h"
#include "tensorflow/core/platform/test.h"
#include "tensorflow/core/platform/test_benchmark.h"
+#include "tensorflow/core/util/example_proto_fast_parsing_test.pb.h"
namespace tensorflow {
namespace example {
@@ -42,7 +43,8 @@ string SerializedToReadable(string serialized) {
return result;
}
-string Serialize(const Example& example) {
+template <class T>
+string Serialize(const T& example) {
string serialized;
example.SerializeToString(&serialized);
return serialized;
@@ -67,6 +69,54 @@ void TestCorrectness(const string& serialized) {
// TestCorrectness(example);
// }
+TEST(FastParse, IgnoresPrecedingUnknownTopLevelFields) {
+ ExampleWithExtras example;
+ (*example.mutable_features()->mutable_feature())["age"]
+ .mutable_int64_list()
+ ->add_value(13);
+ example.set_extra1("some_str");
+ example.set_extra2(123);
+ example.set_extra3(234);
+ example.set_extra4(345);
+ example.set_extra5(4.56);
+ example.add_extra6(5.67);
+ example.add_extra6(6.78);
+ (*example.mutable_extra7()->mutable_feature())["extra7"]
+ .mutable_int64_list()
+ ->add_value(1337);
+
+ Example context;
+ (*context.mutable_features()->mutable_feature())["zipcode"]
+ .mutable_int64_list()
+ ->add_value(94043);
+
+ TestCorrectness(strings::StrCat(Serialize(example), Serialize(context)));
+}
+
+TEST(FastParse, IgnoresTrailingUnknownTopLevelFields) {
+ Example example;
+ (*example.mutable_features()->mutable_feature())["age"]
+ .mutable_int64_list()
+ ->add_value(13);
+
+ ExampleWithExtras context;
+ (*context.mutable_features()->mutable_feature())["zipcode"]
+ .mutable_int64_list()
+ ->add_value(94043);
+ context.set_extra1("some_str");
+ context.set_extra2(123);
+ context.set_extra3(234);
+ context.set_extra4(345);
+ context.set_extra5(4.56);
+ context.add_extra6(5.67);
+ context.add_extra6(6.78);
+ (*context.mutable_extra7()->mutable_feature())["extra7"]
+ .mutable_int64_list()
+ ->add_value(1337);
+
+ TestCorrectness(strings::StrCat(Serialize(example), Serialize(context)));
+}
+
TEST(FastParse, SingleInt64WithContext) {
Example example;
(*example.mutable_features()->mutable_feature())["age"]
diff --git a/tensorflow/core/util/example_proto_fast_parsing_test.proto b/tensorflow/core/util/example_proto_fast_parsing_test.proto
new file mode 100644
index 0000000000..ebd4af47e3
--- /dev/null
+++ b/tensorflow/core/util/example_proto_fast_parsing_test.proto
@@ -0,0 +1,21 @@
+// Protocol message for the fast Example parse unit test.
+syntax = "proto3";
+
+import "tensorflow/core/example/feature.proto";
+option cc_enable_arenas = true;
+
+package tensorflow;
+
+// This message is parallel to Example, but with additional fields to test
+// unknown fields handling in example_proto_fast_parsing_test.cc.
+message ExampleWithExtras {
+ Features features = 1;
+
+ string extra1 = 1337;
+ int64 extra2 = 1338;
+ fixed32 extra3 = 1339;
+ fixed64 extra4 = 1340;
+ double extra5 = 1341;
+ repeated float extra6 = 1342;
+ Features extra7 = 1343;
+};
diff --git a/tensorflow/core/util/example_proto_helper.h b/tensorflow/core/util/example_proto_helper.h
index 971d97266c..44838d2e54 100644
--- a/tensorflow/core/util/example_proto_helper.h
+++ b/tensorflow/core/util/example_proto_helper.h
@@ -161,13 +161,32 @@ class ParseSingleExampleAttrs {
// Temporary check until we start allowing a variable length outer
// dimension.
for (int i = 0; i < dense_shapes.size(); ++i) {
- if (!dense_shapes[i].IsFullyDefined()) {
+ bool shape_ok = true;
+ if (dense_shapes[i].dims() == -1) {
+ shape_ok = false;
+ } else {
+ for (int d = 1; d < dense_shapes[i].dims(); ++d) {
+ if (dense_shapes[i].dim_size(d) == -1) {
+ shape_ok = false;
+ }
+ }
+ }
+ if (!shape_ok) {
return errors::InvalidArgument(
"dense_shapes[", i,
- "] is not fully defined: ", dense_shapes[i].DebugString());
+ "] has unknown rank or unknown inner dimensions: ",
+ dense_shapes[i].DebugString());
}
TensorShape dense_shape;
- dense_shapes[i].AsTensorShape(&dense_shape);
+ if (dense_shapes[i].dims() > 0 && dense_shapes[i].dim_size(0) == -1) {
+ variable_length.push_back(true);
+ for (int d = 1; d < dense_shapes[i].dims(); ++d) {
+ dense_shape.AddDim(dense_shapes[i].dim_size(d));
+ }
+ } else {
+ variable_length.push_back(false);
+ dense_shapes[i].AsTensorShape(&dense_shape);
+ }
elements_per_stride.push_back(dense_shape.num_elements());
}
return FinishInit();
@@ -178,6 +197,7 @@ class ParseSingleExampleAttrs {
std::vector<DataType> sparse_types;
std::vector<DataType> dense_types;
std::vector<PartialTensorShape> dense_shapes;
+ std::vector<bool> variable_length;
std::vector<std::size_t> elements_per_stride;
private:
diff --git a/tensorflow/g3doc/api_docs/python/array_ops.md b/tensorflow/g3doc/api_docs/python/array_ops.md
index 6f87d3b2d1..1c7749edfd 100644
--- a/tensorflow/g3doc/api_docs/python/array_ops.md
+++ b/tensorflow/g3doc/api_docs/python/array_ops.md
@@ -3016,10 +3016,9 @@ Compute gradients for a FakeQuantWithMinMaxArgs operation.
### `tf.fake_quant_with_min_max_vars(inputs, min, max, name=None)` {#fake_quant_with_min_max_vars}
-Fake-quantize the 'inputs' tensor of type float and shape `[b, h, w, d]` via
+Fake-quantize the 'inputs' tensor of type float via global float scalars `min`
-global float scalars `min` and `max` to 'outputs' tensor of same shape as
-`inputs`.
+and `max` to 'outputs' tensor of same shape as `inputs`.
[min; max] is the clamping range for the 'inputs' data. Op divides this range
into 255 steps (total of 256 values), then replaces each 'inputs' value with the
@@ -3135,13 +3134,6 @@ Compute gradients for a FakeQuantWithMinMaxVarsPerChannel operation.
## Other Functions and Classes
- - -
-### `tf.concat_v2(values, axis, name='concat_v2')` {#concat_v2}
-
-
-
-
-- - -
-
### `tf.contrib.graph_editor.copy(sgv, dst_graph=None, dst_scope='', src_scope='', reuse_dst_scope=False)` {#copy}
Copy a subgraph.
diff --git a/tensorflow/g3doc/api_docs/python/constant_op.md b/tensorflow/g3doc/api_docs/python/constant_op.md
index 561e6c8d6c..62654874f4 100644
--- a/tensorflow/g3doc/api_docs/python/constant_op.md
+++ b/tensorflow/g3doc/api_docs/python/constant_op.md
@@ -633,6 +633,47 @@ Example:
- - -
+### `tf.random_poisson(lam, shape, dtype=tf.float32, seed=None, name=None)` {#random_poisson}
+
+Draws `shape` samples from each of the given Poisson distribution(s).
+
+`lam` is the rate parameter describing the distribution(s).
+
+Example:
+
+ samples = tf.random_poisson([0.5, 1.5], [10])
+ # samples has shape [10, 2], where each slice [:, 0] and [:, 1] represents
+ # the samples drawn from each distribution
+
+ samples = tf.random_poisson([12.2, 3.3], [7, 5])
+ # samples has shape [7, 5, 2], where each slice [:, :, 0] and [:, :, 1]
+ # represents the 7x5 samples drawn from each of the two distributions
+
+##### Args:
+
+
+* <b>`lam`</b>: A Tensor or Python value or N-D array of type `dtype`.
+ `lam` provides the rate parameter(s) describing the poisson
+ distribution(s) to sample.
+* <b>`shape`</b>: A 1-D integer Tensor or Python array. The shape of the output samples
+ to be drawn per "rate"-parameterized distribution.
+* <b>`dtype`</b>: The type of `lam` and the output: `float16`, `float32`, or
+ `float64`.
+* <b>`seed`</b>: A Python integer. Used to create a random seed for the distributions.
+ See
+ [`set_random_seed`](../../api_docs/python/constant_op.md#set_random_seed)
+ for behavior.
+* <b>`name`</b>: Optional name for the operation.
+
+##### Returns:
+
+
+* <b>`samples`</b>: a `Tensor` of shape `tf.concat(shape, tf.shape(lam))` with
+ values of type `dtype`.
+
+
+- - -
+
### `tf.set_random_seed(seed)` {#set_random_seed}
Sets the graph-level random seed.
diff --git a/tensorflow/g3doc/api_docs/python/contrib.distributions.bijector.md b/tensorflow/g3doc/api_docs/python/contrib.distributions.bijector.md
index 5b669c2f18..d41e254fb4 100644
--- a/tensorflow/g3doc/api_docs/python/contrib.distributions.bijector.md
+++ b/tensorflow/g3doc/api_docs/python/contrib.distributions.bijector.md
@@ -1640,10 +1640,10 @@ Examples:
```python
bijector.CholeskyOuterProduct(event_ndims=2).forward(x=[[1., 0], [2, 1]])
-# Result: [[1, 1], [1, 5]], i.e., x x.T
+# Result: [[1., 2], [2, 5]], i.e., x @ x.T
-bijector.SoftmaxCentered(event_ndims=2).inverse(y=[[1., 1], [1, 5]])
-# Result: [[1, 0], [2, 1]], i.e., chol(y).
+bijector.CholeskyOuterProduct(event_ndims=2).inverse(y=[[1., 2], [2, 5]])
+# Result: [[1., 0], [2, 1]], i.e., cholesky(y).
```
- - -
@@ -2851,8 +2851,8 @@ models `Y=log(X)` where `X ~ Gamma`.
```python
exp_gamma_distribution = TransformedDistribution(
- Gamma(alpha=1., beta=2.),
- bijector.Invert(bijector.Exp())
+ distribution=Gamma(concentration=1., rate=2.),
+ bijector=bijector.Invert(bijector.Exp())
```
- - -
diff --git a/tensorflow/g3doc/api_docs/python/contrib.layers.md b/tensorflow/g3doc/api_docs/python/contrib.layers.md
index ea20efccd6..12370048d8 100644
--- a/tensorflow/g3doc/api_docs/python/contrib.layers.md
+++ b/tensorflow/g3doc/api_docs/python/contrib.layers.md
@@ -1449,11 +1449,12 @@ Checks the validity of the set of FeatureColumns.
##### Args:
-* <b>`feature_columns`</b>: A set of instances or subclasses of FeatureColumn.
+* <b>`feature_columns`</b>: An iterable of instances or subclasses of FeatureColumn.
##### Raises:
+* <b>`ValueError`</b>: If `feature_columns` is a dict.
* <b>`ValueError`</b>: If there are duplicate feature column keys.
diff --git a/tensorflow/g3doc/api_docs/python/contrib.learn.md b/tensorflow/g3doc/api_docs/python/contrib.learn.md
index d90b6b1a53..13f2f8c9d4 100644
--- a/tensorflow/g3doc/api_docs/python/contrib.learn.md
+++ b/tensorflow/g3doc/api_docs/python/contrib.learn.md
@@ -5360,6 +5360,90 @@ Export utilities
- - -
+### `class tf.contrib.learn.InputFnOps` {#InputFnOps}
+
+A return type for an input_fn.
+
+This return type is currently only supported for serving input_fn.
+Training and eval input_fn should return a `(features, labels)` tuple.
+
+The expected return values are:
+ features: A dict of string to `Tensor` or `SparseTensor`, specifying the
+ features to be passed to the model.
+ labels: A `Tensor`, `SparseTensor`, or a dict of string to `Tensor` or
+ `SparseTensor`, specifying labels for training or eval. For serving, set
+ `labels` to `None`.
+ default_inputs: a dict of string to `Tensor` or `SparseTensor`, specifying
+ the input placeholders (if any) that this input_fn expects to be fed.
+ Typically, this is used by a serving input_fn, which expects to be fed
+ serialized `tf.Example` protos.
+- - -
+
+#### `tf.contrib.learn.InputFnOps.__getnewargs__()` {#InputFnOps.__getnewargs__}
+
+Return self as a plain tuple. Used by copy and pickle.
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.__getstate__()` {#InputFnOps.__getstate__}
+
+Exclude the OrderedDict from pickling
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.__new__(_cls, features, labels, default_inputs)` {#InputFnOps.__new__}
+
+Create new instance of InputFnOps(features, labels, default_inputs)
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.__repr__()` {#InputFnOps.__repr__}
+
+Return a nicely formatted representation string
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.default_inputs` {#InputFnOps.default_inputs}
+
+Alias for field number 2
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.features` {#InputFnOps.features}
+
+Alias for field number 0
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.labels` {#InputFnOps.labels}
+
+Alias for field number 1
+
+
+
+- - -
+
+### `class tf.contrib.learn.ProblemType` {#ProblemType}
+
+Enum-like values for the type of problem that the model solves.
+
+These values are used when exporting the model to produce the appropriate
+signature function for serving.
+
+The following values are supported:
+ UNSPECIFIED: Produces a predict signature_fn.
+ CLASSIFICATION: Produces a classify signature_fn.
+ LINEAR_REGRESSION: Produces a regression signature_fn.
+ LOGISTIC_REGRESSION: Produces a classify signature_fn.
+
+- - -
+
### `tf.contrib.learn.build_parsing_serving_input_fn(feature_spec, default_batch_size=None)` {#build_parsing_serving_input_fn}
Build an input_fn appropriate for serving, expecting fed tf.Examples.
@@ -5383,8 +5467,33 @@ for use at serving time, so the labels return value is always None.
- - -
-### `class tf.contrib.learn.ProblemType` {#ProblemType}
+### `tf.contrib.learn.make_export_strategy(serving_input_fn, default_output_alternative_key=None, assets_extra=None, as_text=False, exports_to_keep=5)` {#make_export_strategy}
+
+Create an ExportStrategy for use with Experiment.
+
+##### Args:
+
+
+* <b>`serving_input_fn`</b>: A function that takes no arguments and returns an
+ `InputFnOps`.
+* <b>`default_output_alternative_key`</b>: the name of the head to serve when an
+ incoming serving request does not explicitly request a specific head.
+ Not needed for single-headed models.
+* <b>`assets_extra`</b>: A dict specifying how to populate the assets.extra directory
+ within the exported SavedModel. Each key should give the destination
+ path (including the filename) relative to the assets.extra directory.
+ The corresponding value gives the full path of the source file to be
+ copied. For example, the simple case of copying a single file without
+ renaming it is specified as
+ `{'my_asset_file.txt': '/path/to/my_asset_file.txt'}`.
+* <b>`as_text`</b>: whether to write the SavedModel proto in text format.
+* <b>`exports_to_keep`</b>: Number of exports to keep. Older exports will be
+ garbage-collected. Defaults to 5. Set to None to disable garbage
+ collection.
+
+##### Returns:
+ An ExportStrategy that can be passed to the Experiment constructor.
diff --git a/tensorflow/g3doc/api_docs/python/framework.md b/tensorflow/g3doc/api_docs/python/framework.md
index c5db4fc909..3256c7014b 100644
--- a/tensorflow/g3doc/api_docs/python/framework.md
+++ b/tensorflow/g3doc/api_docs/python/framework.md
@@ -2629,14 +2629,15 @@ after calling this function will result in undefined behavior.
### `tf.import_graph_def(graph_def, input_map=None, return_elements=None, name=None, op_dict=None, producer_op_list=None)` {#import_graph_def}
-Imports the TensorFlow graph in `graph_def` into the Python `Graph`.
+Imports the graph from `graph_def` into the current default `Graph`.
This function provides a way to import a serialized TensorFlow
[`GraphDef`](https://www.tensorflow.org/code/tensorflow/core/framework/graph.proto)
protocol buffer, and extract individual objects in the `GraphDef` as
-[`Tensor`](#Tensor) and [`Operation`](#Operation) objects. See
-[`Graph.as_graph_def()`](#Graph.as_graph_def) for a way to create a
-`GraphDef` proto.
+[`Tensor`](#Tensor) and [`Operation`](#Operation) objects. Once extracted,
+these objects are placed into the current default `Graph`. See
+[`Graph.as_graph_def()`](#Graph.as_graph_def) for a way to create a `GraphDef`
+proto.
##### Args:
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.distributions.bijector.CholeskyOuterProduct.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.distributions.bijector.CholeskyOuterProduct.md
index 689176cd1e..c3ca4f5131 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.distributions.bijector.CholeskyOuterProduct.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.distributions.bijector.CholeskyOuterProduct.md
@@ -8,10 +8,10 @@ Examples:
```python
bijector.CholeskyOuterProduct(event_ndims=2).forward(x=[[1., 0], [2, 1]])
-# Result: [[1, 1], [1, 5]], i.e., x x.T
+# Result: [[1., 2], [2, 5]], i.e., x @ x.T
-bijector.SoftmaxCentered(event_ndims=2).inverse(y=[[1., 1], [1, 5]])
-# Result: [[1, 0], [2, 1]], i.e., chol(y).
+bijector.CholeskyOuterProduct(event_ndims=2).inverse(y=[[1., 2], [2, 5]])
+# Result: [[1., 0], [2, 1]], i.e., cholesky(y).
```
- - -
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.learn.make_export_strategy.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.learn.make_export_strategy.md
new file mode 100644
index 0000000000..ab4b3a86c6
--- /dev/null
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.learn.make_export_strategy.md
@@ -0,0 +1,28 @@
+### `tf.contrib.learn.make_export_strategy(serving_input_fn, default_output_alternative_key=None, assets_extra=None, as_text=False, exports_to_keep=5)` {#make_export_strategy}
+
+Create an ExportStrategy for use with Experiment.
+
+##### Args:
+
+
+* <b>`serving_input_fn`</b>: A function that takes no arguments and returns an
+ `InputFnOps`.
+* <b>`default_output_alternative_key`</b>: the name of the head to serve when an
+ incoming serving request does not explicitly request a specific head.
+ Not needed for single-headed models.
+* <b>`assets_extra`</b>: A dict specifying how to populate the assets.extra directory
+ within the exported SavedModel. Each key should give the destination
+ path (including the filename) relative to the assets.extra directory.
+ The corresponding value gives the full path of the source file to be
+ copied. For example, the simple case of copying a single file without
+ renaming it is specified as
+ `{'my_asset_file.txt': '/path/to/my_asset_file.txt'}`.
+* <b>`as_text`</b>: whether to write the SavedModel proto in text format.
+* <b>`exports_to_keep`</b>: Number of exports to keep. Older exports will be
+ garbage-collected. Defaults to 5. Set to None to disable garbage
+ collection.
+
+##### Returns:
+
+ An ExportStrategy that can be passed to the Experiment constructor.
+
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf_debug.watch_graph_with_blacklists.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf_debug.watch_graph_with_blacklists.md
index 64e084af3d..72af627344 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf_debug.watch_graph_with_blacklists.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf_debug.watch_graph_with_blacklists.md
@@ -1,4 +1,4 @@
-### `tf_debug.watch_graph_with_blacklists(run_options, graph, debug_ops='DebugIdentity', debug_urls=None, node_name_regex_blacklist=None, op_type_regex_blacklist=None)` {#watch_graph_with_blacklists}
+### `tf_debug.watch_graph_with_blacklists(run_options, graph, debug_ops='DebugIdentity', debug_urls=None, node_name_regex_blacklist=None, op_type_regex_blacklist=None, global_step=-1)` {#watch_graph_with_blacklists}
Add debug tensor watches, blacklisting nodes and op types.
@@ -26,4 +26,6 @@ N.B.: Under certain circumstances, not all specified `Tensor`s will be
relation. In other words, a node will be excluded if it hits either of
the two blacklists; a node will be included if and only if it hits
neither of the blacklists.
+* <b>`global_step`</b>: (`int`) Optional global_step count for this debug tensor
+ watch.
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.unsorted_segment_max.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.unsorted_segment_max.md
new file mode 100644
index 0000000000..655f08dbe9
--- /dev/null
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.unsorted_segment_max.md
@@ -0,0 +1,38 @@
+### `tf.unsorted_segment_max(data, segment_ids, num_segments, name=None)` {#unsorted_segment_max}
+
+Computes the Max along segments of a tensor.
+
+Read [the section on
+Segmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation
+of segments.
+
+This operator is similar to the [unsorted segment sum operator](../../api_docs/python/math_ops.md#UnsortedSegmentSum).
+Instead of computing the sum over segments, it computes the maximum
+such that:
+
+\\(output_i = \max_j data_j\\) where max is over `j` such
+that `segment_ids[j] == i`.
+
+If the maximum is empty for a given segment ID `i`, it outputs the smallest possible value for specific numeric type,
+ `output[i] = numeric_limits<T>::min()`.
+
+<div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
+<img style="width:100%" src="../../images/UnsortedSegmentSum.png" alt>
+</div>
+
+##### Args:
+
+
+* <b>`data`</b>: A `Tensor`. Must be one of the following types: `float32`, `float64`, `int32`, `int64`, `uint8`, `int16`, `int8`, `uint16`, `half`.
+* <b>`segment_ids`</b>: A `Tensor`. Must be one of the following types: `int32`, `int64`.
+ A 1-D tensor whose rank is equal to the rank of `data`'s
+ first dimension.
+* <b>`num_segments`</b>: A `Tensor` of type `int32`.
+* <b>`name`</b>: A name for the operation (optional).
+
+##### Returns:
+
+ A `Tensor`. Has the same type as `data`.
+ Has same shape as data, except for dimension 0 which
+ has size `num_segments`.
+
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.contrib.learn.ProblemType.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.contrib.learn.ProblemType.md
index 8b13789179..20be4db791 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.contrib.learn.ProblemType.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.contrib.learn.ProblemType.md
@@ -1 +1,10 @@
+Enum-like values for the type of problem that the model solves.
+These values are used when exporting the model to produce the appropriate
+signature function for serving.
+
+The following values are supported:
+ UNSPECIFIED: Produces a predict signature_fn.
+ CLASSIFICATION: Produces a classify signature_fn.
+ LINEAR_REGRESSION: Produces a regression signature_fn.
+ LOGISTIC_REGRESSION: Produces a classify signature_fn.
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.test.TestCase.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.test.TestCase.md
index d912d0e153..0e63e0d708 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.test.TestCase.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.test.TestCase.md
@@ -95,7 +95,7 @@ Asserts that two numpy arrays have near values.
- - -
-#### `tf.test.TestCase.assertAllCloseAccordingToType(a, b, rtol=1e-06, atol=1e-06)` {#TestCase.assertAllCloseAccordingToType}
+#### `tf.test.TestCase.assertAllCloseAccordingToType(a, b, rtol=1e-06, atol=1e-06, float_rtol=1e-06, float_atol=1e-06, half_rtol=0.001, half_atol=0.001)` {#TestCase.assertAllCloseAccordingToType}
Like assertAllClose, but also suitable for comparing fp16 arrays.
@@ -109,6 +109,10 @@ one of the arguments is of type float16.
* <b>`b`</b>: a numpy ndarray or anything can be converted to one.
* <b>`rtol`</b>: relative tolerance
* <b>`atol`</b>: absolute tolerance
+* <b>`float_rtol`</b>: relative tolerance for float32
+* <b>`float_atol`</b>: absolute tolerance for float32
+* <b>`half_rtol`</b>: relative tolerance for float16
+* <b>`half_atol`</b>: absolute tolerance for float16
- - -
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.fake_quant_with_min_max_vars.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.fake_quant_with_min_max_vars.md
index d7815f0414..74ed0e0242 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.fake_quant_with_min_max_vars.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.fake_quant_with_min_max_vars.md
@@ -1,9 +1,8 @@
### `tf.fake_quant_with_min_max_vars(inputs, min, max, name=None)` {#fake_quant_with_min_max_vars}
-Fake-quantize the 'inputs' tensor of type float and shape `[b, h, w, d]` via
+Fake-quantize the 'inputs' tensor of type float via global float scalars `min`
-global float scalars `min` and `max` to 'outputs' tensor of same shape as
-`inputs`.
+and `max` to 'outputs' tensor of same shape as `inputs`.
[min; max] is the clamping range for the 'inputs' data. Op divides this range
into 255 steps (total of 256 values), then replaces each 'inputs' value with the
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf_debug.add_debug_tensor_watch.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf_debug.add_debug_tensor_watch.md
index 91ce5083e5..1c79b12669 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf_debug.add_debug_tensor_watch.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf_debug.add_debug_tensor_watch.md
@@ -1,4 +1,4 @@
-### `tf_debug.add_debug_tensor_watch(run_options, node_name, output_slot=0, debug_ops='DebugIdentity', debug_urls=None)` {#add_debug_tensor_watch}
+### `tf_debug.add_debug_tensor_watch(run_options, node_name, output_slot=0, debug_ops='DebugIdentity', debug_urls=None, global_step=-1)` {#add_debug_tensor_watch}
Add watch on a `Tensor` to `RunOptions`.
@@ -16,4 +16,6 @@ N.B.: Under certain circumstances, the `Tensor` may not be actually watched
`list` of `str` with only one element.
* <b>`debug_urls`</b>: (`str` or `list` of `str`) URL(s) to send debug values to,
e.g., `file:///tmp/tfdbg_dump_1`, `grpc://localhost:12345`.
+* <b>`global_step`</b>: (`int`) Optional global_step count for this debug tensor
+ watch.
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.contrib.distributions.bijector.Invert.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.contrib.distributions.bijector.Invert.md
index 7a375cfd20..43a32752d6 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.contrib.distributions.bijector.Invert.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.contrib.distributions.bijector.Invert.md
@@ -6,8 +6,8 @@ models `Y=log(X)` where `X ~ Gamma`.
```python
exp_gamma_distribution = TransformedDistribution(
- Gamma(alpha=1., beta=2.),
- bijector.Invert(bijector.Exp())
+ distribution=Gamma(concentration=1., rate=2.),
+ bijector=bijector.Invert(bijector.Exp())
```
- - -
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.contrib.layers.check_feature_columns.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.contrib.layers.check_feature_columns.md
index e484ee865b..4b725e57d8 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.contrib.layers.check_feature_columns.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.contrib.layers.check_feature_columns.md
@@ -5,10 +5,11 @@ Checks the validity of the set of FeatureColumns.
##### Args:
-* <b>`feature_columns`</b>: A set of instances or subclasses of FeatureColumn.
+* <b>`feature_columns`</b>: An iterable of instances or subclasses of FeatureColumn.
##### Raises:
+* <b>`ValueError`</b>: If `feature_columns` is a dict.
* <b>`ValueError`</b>: If there are duplicate feature column keys.
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf_debug.DebugDumpDir.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf_debug.DebugDumpDir.md
index 6a7a6088c9..4b60562c32 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf_debug.DebugDumpDir.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf_debug.DebugDumpDir.md
@@ -25,6 +25,38 @@ in a tfdbg dump root directory.
- - -
+#### `tf_debug.DebugDumpDir.core_metadata` {#DebugDumpDir.core_metadata}
+
+Metadata about the `Session.run()` call from the core runtime.
+
+Of the three counters available in the return value, `global_step` is
+supplied by the caller of the debugged `Session.run()`, while
+`session_run_count` and `executor_step_count` are determined by the state
+of the core runtime, automatically. For the same fetch list, feed keys and
+debug tensor watch options, the same executor will be used and
+`executor_step_count` should increase by one at a time. However, runs with
+different fetch lists, feed keys and debug_tensor watch options that all
+share the same `Session` object can lead to gaps in `session_run_count`.
+
+##### Returns:
+
+ If core metadata are loaded, a `namedtuple` with the fields:
+ `global_step`: A global step count supplied by the caller of
+ `Session.run()`. It is optional to the caller. If the caller did not
+ supply this parameter, its value will be -1.
+ `session_run_count`: A counter for Run() calls to the underlying
+ TensorFlow `Session` object.
+ `executor_step_count`: A counter for invocations of a given runtime
+ executor. The same executor is re-used for the same fetched tensors,
+ target nodes, input feed keys and debug tensor watch options.
+ `input_names`: Names of the input (feed) Tensors.
+ `output_names`: Names of the output (fetched) Tensors.
+ `target_nodes`: Names of the target nodes.
+ If the core metadata have not been loaded, `None`.
+
+
+- - -
+
#### `tf_debug.DebugDumpDir.debug_watch_keys(node_name)` {#DebugDumpDir.debug_watch_keys}
Get all tensor watch keys of given node according to partition graphs.
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.import_graph_def.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.import_graph_def.md
index 0ff3d621d4..6afe7e1fc5 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.import_graph_def.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.import_graph_def.md
@@ -1,13 +1,14 @@
### `tf.import_graph_def(graph_def, input_map=None, return_elements=None, name=None, op_dict=None, producer_op_list=None)` {#import_graph_def}
-Imports the TensorFlow graph in `graph_def` into the Python `Graph`.
+Imports the graph from `graph_def` into the current default `Graph`.
This function provides a way to import a serialized TensorFlow
[`GraphDef`](https://www.tensorflow.org/code/tensorflow/core/framework/graph.proto)
protocol buffer, and extract individual objects in the `GraphDef` as
-[`Tensor`](#Tensor) and [`Operation`](#Operation) objects. See
-[`Graph.as_graph_def()`](#Graph.as_graph_def) for a way to create a
-`GraphDef` proto.
+[`Tensor`](#Tensor) and [`Operation`](#Operation) objects. Once extracted,
+these objects are placed into the current default `Graph`. See
+[`Graph.as_graph_def()`](#Graph.as_graph_def) for a way to create a `GraphDef`
+proto.
##### Args:
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf_debug.watch_graph.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf_debug.watch_graph.md
index 94f3489f06..5f206435bd 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf_debug.watch_graph.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf_debug.watch_graph.md
@@ -1,4 +1,4 @@
-### `tf_debug.watch_graph(run_options, graph, debug_ops='DebugIdentity', debug_urls=None, node_name_regex_whitelist=None, op_type_regex_whitelist=None)` {#watch_graph}
+### `tf_debug.watch_graph(run_options, graph, debug_ops='DebugIdentity', debug_urls=None, node_name_regex_whitelist=None, op_type_regex_whitelist=None, global_step=-1)` {#watch_graph}
Add debug watches to `RunOptions` for a TensorFlow graph.
@@ -27,4 +27,6 @@ N.B.: Under certain circumstances, not all specified `Tensor`s will be
are set, the two filtering operations will occur in a logical `AND`
relation. In other words, a node will be included if and only if it
hits both whitelists.
+* <b>`global_step`</b>: (`int`) Optional global_step count for this debug tensor
+ watch.
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.contrib.learn.InputFnOps.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.contrib.learn.InputFnOps.md
new file mode 100644
index 0000000000..4d65b070a1
--- /dev/null
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.contrib.learn.InputFnOps.md
@@ -0,0 +1,64 @@
+A return type for an input_fn.
+
+This return type is currently only supported for serving input_fn.
+Training and eval input_fn should return a `(features, labels)` tuple.
+
+The expected return values are:
+ features: A dict of string to `Tensor` or `SparseTensor`, specifying the
+ features to be passed to the model.
+ labels: A `Tensor`, `SparseTensor`, or a dict of string to `Tensor` or
+ `SparseTensor`, specifying labels for training or eval. For serving, set
+ `labels` to `None`.
+ default_inputs: a dict of string to `Tensor` or `SparseTensor`, specifying
+ the input placeholders (if any) that this input_fn expects to be fed.
+ Typically, this is used by a serving input_fn, which expects to be fed
+ serialized `tf.Example` protos.
+- - -
+
+#### `tf.contrib.learn.InputFnOps.__getnewargs__()` {#InputFnOps.__getnewargs__}
+
+Return self as a plain tuple. Used by copy and pickle.
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.__getstate__()` {#InputFnOps.__getstate__}
+
+Exclude the OrderedDict from pickling
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.__new__(_cls, features, labels, default_inputs)` {#InputFnOps.__new__}
+
+Create new instance of InputFnOps(features, labels, default_inputs)
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.__repr__()` {#InputFnOps.__repr__}
+
+Return a nicely formatted representation string
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.default_inputs` {#InputFnOps.default_inputs}
+
+Alias for field number 2
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.features` {#InputFnOps.features}
+
+Alias for field number 0
+
+
+- - -
+
+#### `tf.contrib.learn.InputFnOps.labels` {#InputFnOps.labels}
+
+Alias for field number 1
+
+
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.concat_v2.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.concat_v2.md
deleted file mode 100644
index 1b96b857b2..0000000000
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.concat_v2.md
+++ /dev/null
@@ -1,4 +0,0 @@
-### `tf.concat_v2(values, axis, name='concat_v2')` {#concat_v2}
-
-
-
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.contrib.learn.InputFnOps.__new__.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.contrib.learn.InputFnOps.__new__.md
new file mode 100644
index 0000000000..147c6e6ed8
--- /dev/null
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.contrib.learn.InputFnOps.__new__.md
@@ -0,0 +1,4 @@
+#### `tf.contrib.learn.InputFnOps.__new__(_cls, features, labels, default_inputs)` {#InputFnOps.__new__}
+
+Create new instance of InputFnOps(features, labels, default_inputs)
+
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.random_poisson.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.random_poisson.md
new file mode 100644
index 0000000000..d56c967168
--- /dev/null
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.random_poisson.md
@@ -0,0 +1,38 @@
+### `tf.random_poisson(lam, shape, dtype=tf.float32, seed=None, name=None)` {#random_poisson}
+
+Draws `shape` samples from each of the given Poisson distribution(s).
+
+`lam` is the rate parameter describing the distribution(s).
+
+Example:
+
+ samples = tf.random_poisson([0.5, 1.5], [10])
+ # samples has shape [10, 2], where each slice [:, 0] and [:, 1] represents
+ # the samples drawn from each distribution
+
+ samples = tf.random_poisson([12.2, 3.3], [7, 5])
+ # samples has shape [7, 5, 2], where each slice [:, :, 0] and [:, :, 1]
+ # represents the 7x5 samples drawn from each of the two distributions
+
+##### Args:
+
+
+* <b>`lam`</b>: A Tensor or Python value or N-D array of type `dtype`.
+ `lam` provides the rate parameter(s) describing the poisson
+ distribution(s) to sample.
+* <b>`shape`</b>: A 1-D integer Tensor or Python array. The shape of the output samples
+ to be drawn per "rate"-parameterized distribution.
+* <b>`dtype`</b>: The type of `lam` and the output: `float16`, `float32`, or
+ `float64`.
+* <b>`seed`</b>: A Python integer. Used to create a random seed for the distributions.
+ See
+ [`set_random_seed`](../../api_docs/python/constant_op.md#set_random_seed)
+ for behavior.
+* <b>`name`</b>: Optional name for the operation.
+
+##### Returns:
+
+
+* <b>`samples`</b>: a `Tensor` of shape `tf.concat(shape, tf.shape(lam))` with
+ values of type `dtype`.
+
diff --git a/tensorflow/g3doc/api_docs/python/index.md b/tensorflow/g3doc/api_docs/python/index.md
index 1f123c90bd..4043d66ae1 100644
--- a/tensorflow/g3doc/api_docs/python/index.md
+++ b/tensorflow/g3doc/api_docs/python/index.md
@@ -64,6 +64,7 @@
* [`random_crop`](../../api_docs/python/constant_op.md#random_crop)
* [`random_gamma`](../../api_docs/python/constant_op.md#random_gamma)
* [`random_normal`](../../api_docs/python/constant_op.md#random_normal)
+ * [`random_poisson`](../../api_docs/python/constant_op.md#random_poisson)
* [`random_shuffle`](../../api_docs/python/constant_op.md#random_shuffle)
* [`random_uniform`](../../api_docs/python/constant_op.md#random_uniform)
* [`range`](../../api_docs/python/constant_op.md#range)
@@ -141,7 +142,6 @@
* [`broadcast_static_shape`](../../api_docs/python/array_ops.md#broadcast_static_shape)
* [`cast`](../../api_docs/python/array_ops.md#cast)
* [`concat`](../../api_docs/python/array_ops.md#concat)
- * [`concat_v2`](../../api_docs/python/array_ops.md#concat_v2)
* [`copy`](../../api_docs/python/array_ops.md#copy)
* [`depth_to_space`](../../api_docs/python/array_ops.md#depth_to_space)
* [`dequantize`](../../api_docs/python/array_ops.md#dequantize)
@@ -307,6 +307,7 @@
* [`truncatediv`](../../api_docs/python/math_ops.md#truncatediv)
* [`truncatemod`](../../api_docs/python/math_ops.md#truncatemod)
* [`unique`](../../api_docs/python/math_ops.md#unique)
+ * [`unsorted_segment_max`](../../api_docs/python/math_ops.md#unsorted_segment_max)
* [`unsorted_segment_sum`](../../api_docs/python/math_ops.md#unsorted_segment_sum)
* [`where`](../../api_docs/python/math_ops.md#where)
* [`zeta`](../../api_docs/python/math_ops.md#zeta)
@@ -1008,10 +1009,12 @@
* [`infer`](../../api_docs/python/contrib.learn.md#infer)
* [`infer_real_valued_columns_from_input`](../../api_docs/python/contrib.learn.md#infer_real_valued_columns_from_input)
* [`infer_real_valued_columns_from_input_fn`](../../api_docs/python/contrib.learn.md#infer_real_valued_columns_from_input_fn)
+ * [`InputFnOps`](../../api_docs/python/contrib.learn.md#InputFnOps)
* [`KMeansClustering`](../../api_docs/python/contrib.learn.md#KMeansClustering)
* [`LinearClassifier`](../../api_docs/python/contrib.learn.md#LinearClassifier)
* [`LinearRegressor`](../../api_docs/python/contrib.learn.md#LinearRegressor)
* [`LogisticRegressor`](../../api_docs/python/contrib.learn.md#LogisticRegressor)
+ * [`make_export_strategy`](../../api_docs/python/contrib.learn.md#make_export_strategy)
* [`MetricSpec`](../../api_docs/python/contrib.learn.md#MetricSpec)
* [`ModeKeys`](../../api_docs/python/contrib.learn.md#ModeKeys)
* [`ModelFnOps`](../../api_docs/python/contrib.learn.md#ModelFnOps)
diff --git a/tensorflow/g3doc/api_docs/python/math_ops.md b/tensorflow/g3doc/api_docs/python/math_ops.md
index 76636dc6f0..8a4a117907 100644
--- a/tensorflow/g3doc/api_docs/python/math_ops.md
+++ b/tensorflow/g3doc/api_docs/python/math_ops.md
@@ -3323,6 +3323,47 @@ If the sum is empty for a given segment ID `i`, `output[i] = 0`.
`num_segments`.
+- - -
+
+### `tf.unsorted_segment_max(data, segment_ids, num_segments, name=None)` {#unsorted_segment_max}
+
+Computes the Max along segments of a tensor.
+
+Read [the section on
+Segmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation
+of segments.
+
+This operator is similar to the [unsorted segment sum operator](../../api_docs/python/math_ops.md#UnsortedSegmentSum).
+Instead of computing the sum over segments, it computes the maximum
+such that:
+
+\\(output_i = \max_j data_j\\) where max is over `j` such
+that `segment_ids[j] == i`.
+
+If the maximum is empty for a given segment ID `i`, it outputs the smallest possible value for specific numeric type,
+ `output[i] = numeric_limits<T>::min()`.
+
+<div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
+<img style="width:100%" src="../../images/UnsortedSegmentSum.png" alt>
+</div>
+
+##### Args:
+
+
+* <b>`data`</b>: A `Tensor`. Must be one of the following types: `float32`, `float64`, `int32`, `int64`, `uint8`, `int16`, `int8`, `uint16`, `half`.
+* <b>`segment_ids`</b>: A `Tensor`. Must be one of the following types: `int32`, `int64`.
+ A 1-D tensor whose rank is equal to the rank of `data`'s
+ first dimension.
+* <b>`num_segments`</b>: A `Tensor` of type `int32`.
+* <b>`name`</b>: A name for the operation (optional).
+
+##### Returns:
+
+ A `Tensor`. Has the same type as `data`.
+ Has same shape as data, except for dimension 0 which
+ has size `num_segments`.
+
+
- - -
diff --git a/tensorflow/g3doc/api_docs/python/test.md b/tensorflow/g3doc/api_docs/python/test.md
index 7daf59dcda..f3276b77c1 100644
--- a/tensorflow/g3doc/api_docs/python/test.md
+++ b/tensorflow/g3doc/api_docs/python/test.md
@@ -135,7 +135,7 @@ Asserts that two numpy arrays have near values.
- - -
-#### `tf.test.TestCase.assertAllCloseAccordingToType(a, b, rtol=1e-06, atol=1e-06)` {#TestCase.assertAllCloseAccordingToType}
+#### `tf.test.TestCase.assertAllCloseAccordingToType(a, b, rtol=1e-06, atol=1e-06, float_rtol=1e-06, float_atol=1e-06, half_rtol=0.001, half_atol=0.001)` {#TestCase.assertAllCloseAccordingToType}
Like assertAllClose, but also suitable for comparing fp16 arrays.
@@ -149,6 +149,10 @@ one of the arguments is of type float16.
* <b>`b`</b>: a numpy ndarray or anything can be converted to one.
* <b>`rtol`</b>: relative tolerance
* <b>`atol`</b>: absolute tolerance
+* <b>`float_rtol`</b>: relative tolerance for float32
+* <b>`float_atol`</b>: absolute tolerance for float32
+* <b>`half_rtol`</b>: relative tolerance for float16
+* <b>`half_atol`</b>: absolute tolerance for float16
- - -
diff --git a/tensorflow/g3doc/api_docs/python/tf_debug.md b/tensorflow/g3doc/api_docs/python/tf_debug.md
index fb5e10fb7d..3e0cc273bf 100644
--- a/tensorflow/g3doc/api_docs/python/tf_debug.md
+++ b/tensorflow/g3doc/api_docs/python/tf_debug.md
@@ -12,7 +12,7 @@ be watched when the TensorFlow graph is executed at runtime.
- - -
-### `tf_debug.add_debug_tensor_watch(run_options, node_name, output_slot=0, debug_ops='DebugIdentity', debug_urls=None)` {#add_debug_tensor_watch}
+### `tf_debug.add_debug_tensor_watch(run_options, node_name, output_slot=0, debug_ops='DebugIdentity', debug_urls=None, global_step=-1)` {#add_debug_tensor_watch}
Add watch on a `Tensor` to `RunOptions`.
@@ -30,11 +30,13 @@ N.B.: Under certain circumstances, the `Tensor` may not be actually watched
`list` of `str` with only one element.
* <b>`debug_urls`</b>: (`str` or `list` of `str`) URL(s) to send debug values to,
e.g., `file:///tmp/tfdbg_dump_1`, `grpc://localhost:12345`.
+* <b>`global_step`</b>: (`int`) Optional global_step count for this debug tensor
+ watch.
- - -
-### `tf_debug.watch_graph(run_options, graph, debug_ops='DebugIdentity', debug_urls=None, node_name_regex_whitelist=None, op_type_regex_whitelist=None)` {#watch_graph}
+### `tf_debug.watch_graph(run_options, graph, debug_ops='DebugIdentity', debug_urls=None, node_name_regex_whitelist=None, op_type_regex_whitelist=None, global_step=-1)` {#watch_graph}
Add debug watches to `RunOptions` for a TensorFlow graph.
@@ -63,11 +65,13 @@ N.B.: Under certain circumstances, not all specified `Tensor`s will be
are set, the two filtering operations will occur in a logical `AND`
relation. In other words, a node will be included if and only if it
hits both whitelists.
+* <b>`global_step`</b>: (`int`) Optional global_step count for this debug tensor
+ watch.
- - -
-### `tf_debug.watch_graph_with_blacklists(run_options, graph, debug_ops='DebugIdentity', debug_urls=None, node_name_regex_blacklist=None, op_type_regex_blacklist=None)` {#watch_graph_with_blacklists}
+### `tf_debug.watch_graph_with_blacklists(run_options, graph, debug_ops='DebugIdentity', debug_urls=None, node_name_regex_blacklist=None, op_type_regex_blacklist=None, global_step=-1)` {#watch_graph_with_blacklists}
Add debug tensor watches, blacklisting nodes and op types.
@@ -95,6 +99,8 @@ N.B.: Under certain circumstances, not all specified `Tensor`s will be
relation. In other words, a node will be excluded if it hits either of
the two blacklists; a node will be included if and only if it hits
neither of the blacklists.
+* <b>`global_step`</b>: (`int`) Optional global_step count for this debug tensor
+ watch.
@@ -286,6 +292,38 @@ in a tfdbg dump root directory.
- - -
+#### `tf_debug.DebugDumpDir.core_metadata` {#DebugDumpDir.core_metadata}
+
+Metadata about the `Session.run()` call from the core runtime.
+
+Of the three counters available in the return value, `global_step` is
+supplied by the caller of the debugged `Session.run()`, while
+`session_run_count` and `executor_step_count` are determined by the state
+of the core runtime, automatically. For the same fetch list, feed keys and
+debug tensor watch options, the same executor will be used and
+`executor_step_count` should increase by one at a time. However, runs with
+different fetch lists, feed keys and debug_tensor watch options that all
+share the same `Session` object can lead to gaps in `session_run_count`.
+
+##### Returns:
+
+ If core metadata are loaded, a `namedtuple` with the fields:
+ `global_step`: A global step count supplied by the caller of
+ `Session.run()`. It is optional to the caller. If the caller did not
+ supply this parameter, its value will be -1.
+ `session_run_count`: A counter for Run() calls to the underlying
+ TensorFlow `Session` object.
+ `executor_step_count`: A counter for invocations of a given runtime
+ executor. The same executor is re-used for the same fetched tensors,
+ target nodes, input feed keys and debug tensor watch options.
+ `input_names`: Names of the input (feed) Tensors.
+ `output_names`: Names of the output (fetched) Tensors.
+ `target_nodes`: Names of the target nodes.
+ If the core metadata have not been loaded, `None`.
+
+
+- - -
+
#### `tf_debug.DebugDumpDir.debug_watch_keys(node_name)` {#DebugDumpDir.debug_watch_keys}
Get all tensor watch keys of given node according to partition graphs.
diff --git a/tensorflow/g3doc/how_tos/new_data_formats/index.md b/tensorflow/g3doc/how_tos/new_data_formats/index.md
index 4f66d6d140..254e1b39b7 100644
--- a/tensorflow/g3doc/how_tos/new_data_formats/index.md
+++ b/tensorflow/g3doc/how_tos/new_data_formats/index.md
@@ -96,8 +96,8 @@ are:
To register the op, you will use a `REGISTER_OP` call defined in
[`tensorflow/core/framework/op.h`](https://www.tensorflow.org/code/tensorflow/core/framework/op.h).
Reader ops never take any input and always have a single output with type
-`Ref(string)`. They should always call `SetIsStateful()`, and have a string
-`container` and `shared_name` attrs. You may optionally define additional attrs
+`resource`. They should have string `container` and `shared_name` attrs.
+You may optionally define additional attrs
for configuration or include documentation in a `Doc`. For examples, see
[`tensorflow/core/ops/io_ops.cc`](https://www.tensorflow.org/code/tensorflow/core/ops/io_ops.cc),
e.g.:
@@ -106,11 +106,12 @@ e.g.:
#include "tensorflow/core/framework/op.h"
REGISTER_OP("TextLineReader")
- .Output("reader_handle: Ref(string)")
+ .Output("reader_handle: resource")
.Attr("skip_header_lines: int = 0")
.Attr("container: string = ''")
.Attr("shared_name: string = ''")
.SetIsStateful()
+ .SetShapeFn(shape_inference::ScalarShape)
.Doc(R"doc(
A Reader that outputs the lines of a file delimited by '\n'.
)doc");
@@ -165,8 +166,11 @@ REGISTER_KERNEL_BUILDER(Name("TextLineReader").Device(DEVICE_CPU),
TextLineReaderOp);
```
-The last step is to add the Python wrapper. You will import
-`tensorflow.python.ops.io_ops` in
+The last step is to add the Python wrapper. You can either do this by
+[compiling a dynamic
+library](../../how_tos/adding_an_op/#building_the_op_library)
+or, if you are building TensorFlow from source, adding to `user_ops.py`.
+For the latter, you will import `tensorflow.python.ops.io_ops` in
[`tensorflow/python/user_ops/user_ops.py`](https://www.tensorflow.org/code/tensorflow/python/user_ops/user_ops.py)
and add a descendant of [`io_ops.ReaderBase`](https://www.tensorflow.org/code/tensorflow/python/ops/io_ops.py).
@@ -183,7 +187,6 @@ class SomeReader(io_ops.ReaderBase):
ops.NotDifferentiable("SomeReader")
-ops.RegisterShape("SomeReader")(common_shapes.scalar_shape)
```
You can see some examples in
@@ -192,10 +195,10 @@ You can see some examples in
## Writing an Op for a record format
Generally this is an ordinary op that takes a scalar string record as input, and
-so follow [the instructions to add an Op](../../how_tos/adding_an_op/index.md). You may
-optionally take a scalar string key as input, and include that in error messages
-reporting improperly formatted data. That way users can more easily track down
-where the bad data came from.
+so follow [the instructions to add an Op](../../how_tos/adding_an_op/index.md).
+You may optionally take a scalar string key as input, and include that in error
+messages reporting improperly formatted data. That way users can more easily
+track down where the bad data came from.
Examples of Ops useful for decoding records:
diff --git a/tensorflow/g3doc/tutorials/image_recognition/index.md b/tensorflow/g3doc/tutorials/image_recognition/index.md
index d4fa5ba780..0915000953 100644
--- a/tensorflow/g3doc/tutorials/image_recognition/index.md
+++ b/tensorflow/g3doc/tutorials/image_recognition/index.md
@@ -254,7 +254,7 @@ definition with the `ToGraphDef()` function.
TF_RETURN_IF_ERROR(session->Run({}, {output_name}, {}, out_tensors));
return Status::OK();
```
-Then we create a [`Session`](http://www.tensorflow.org/versions/master/api_docs/cc/ClassSession.html#class-tensorflow-session)
+Then we create a [`Session`](../../api_docs/cc/class/tensorflow/session)
object, which is the interface to actually running the graph, and run it,
specifying which node we want to get the output from, and where to put the
output data.
diff --git a/tensorflow/g3doc/tutorials/input_fn/index.md b/tensorflow/g3doc/tutorials/input_fn/index.md
index 6b94fd82e1..1c16684848 100644
--- a/tensorflow/g3doc/tutorials/input_fn/index.md
+++ b/tensorflow/g3doc/tutorials/input_fn/index.md
@@ -384,7 +384,7 @@ following resources:
creating `FeatureColumn`s and an `input_fn` for a linear classification
model that predicts income range based on census data.
-* [TensorFlow Wide & Deep Learning Tutorial](../wide/index.md): Building on
+* [TensorFlow Wide & Deep Learning Tutorial](../wide_and_deep/index.md): Building on
the [Linear Model Tutorial](../wide/index.md), this tutorial covers
`FeatureColumn` and `input_fn` creation for a "wide and deep" model that
combines a linear model and a neural network using
diff --git a/tensorflow/go/genop/internal/genop.go b/tensorflow/go/genop/internal/genop.go
index d9ebec0f8c..16e4d0e512 100644
--- a/tensorflow/go/genop/internal/genop.go
+++ b/tensorflow/go/genop/internal/genop.go
@@ -212,6 +212,10 @@ func {{$.Op.Name}}{{CamelCase .Name}}(value {{GoType .Type}}) {{$.Op.Name}}Attr
{{- end -}}
{{- end -}}
+{{- if (not .Op.OutputArg) }}
+//
+// Returns the created operation.
+{{- else }}
{{- if .DescribeOutputs}}
//
{{- if ((len .Op.OutputArg) eq 1) }}
@@ -223,6 +227,7 @@ func {{$.Op.Name}}{{CamelCase .Name}}(value {{GoType .Type}}) {{$.Op.Name}}Attr
{{- end -}}
{{- end -}}
{{- end -}}
+{{- end -}}
{{- /*
The function signature.
@@ -244,10 +249,12 @@ func {{.Op.Name}}
{{if .OptionalAttrs}}, optional ...{{.Op.Name}}Attr{{end -}}
)
-{{- /* Construct outputs: len(OpDef.OutputArg) */ -}}
+{{- /* Construct outputs: len(OpDef.OutputArg) or a *tf.Operation */ -}}
{{if .Op.OutputArg -}}
({{range $i,$a := .Op.OutputArg}}{{if $i}}, {{end}}{{Identifier $a.Name}} {{if IsListArg $a}}[]{{end}}tf.Output{{end -}})
+{{- else -}}
+(o *tf.Operation)
{{- end }} {
if scope.Err() != nil {
return
@@ -295,7 +302,7 @@ func {{.Op.Name}}
return {{range $i, $a := .Op.OutputArg}}{{if $i}}, {{end}}op.Output({{$i}}){{end}}
{{- end }}{{- /* if .HasListOutput */}}
{{- else }}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
{{- end }}{{- /* if .Op.OutputArg */}}
}
`))
diff --git a/tensorflow/go/genop/internal/genop_test.go b/tensorflow/go/genop/internal/genop_test.go
index c3057e9119..c66e38fce0 100644
--- a/tensorflow/go/genop/internal/genop_test.go
+++ b/tensorflow/go/genop/internal/genop_test.go
@@ -39,14 +39,16 @@ summary: "No. Op."
`,
wanted: `
// No. Op.
-func NoOp(scope *Scope) {
+//
+// Returns the created operation.
+func NoOp(scope *Scope) (o *tf.Operation) {
if scope.Err() != nil {
return
}
opspec := tf.OpSpec{
Type: "NoOp",
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
`,
},
diff --git a/tensorflow/go/op/wrappers.go b/tensorflow/go/op/wrappers.go
index b3989e30d3..4a4d2cbe66 100644
--- a/tensorflow/go/op/wrappers.go
+++ b/tensorflow/go/op/wrappers.go
@@ -64,7 +64,9 @@ func makeOutputList(op *tf.Operation, start int, output string) ([]tf.Output, in
// resource: Should be from a `Variable` node.
// indices: A tensor of indices into the first dimension of `ref`.
// updates: A tensor of updated values to add to `ref`.
-func ResourceScatterAdd(scope *Scope, resource tf.Output, indices tf.Output, updates tf.Output) {
+//
+// Returns the created operation.
+func ResourceScatterAdd(scope *Scope, resource tf.Output, indices tf.Output, updates tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -74,7 +76,7 @@ func ResourceScatterAdd(scope *Scope, resource tf.Output, indices tf.Output, upd
resource, indices, updates,
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Checks whether a resource handle-based variable has been initialized.
@@ -109,7 +111,9 @@ func VarIsInitializedOp(scope *Scope, resource tf.Output) (is_initialized tf.Out
// Arguments:
// resource: handle to the resource in which to store the variable.
// value: the value by which the variable will be incremented.
-func AssignSubVariableOp(scope *Scope, resource tf.Output, value tf.Output) {
+//
+// Returns the created operation.
+func AssignSubVariableOp(scope *Scope, resource tf.Output, value tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -119,7 +123,7 @@ func AssignSubVariableOp(scope *Scope, resource tf.Output, value tf.Output) {
resource, value,
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Adds a value to the current value of a variable.
@@ -133,7 +137,9 @@ func AssignSubVariableOp(scope *Scope, resource tf.Output, value tf.Output) {
// Arguments:
// resource: handle to the resource in which to store the variable.
// value: the value by which the variable will be incremented.
-func AssignAddVariableOp(scope *Scope, resource tf.Output, value tf.Output) {
+//
+// Returns the created operation.
+func AssignAddVariableOp(scope *Scope, resource tf.Output, value tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -143,7 +149,7 @@ func AssignAddVariableOp(scope *Scope, resource tf.Output, value tf.Output) {
resource, value,
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Assigns a new value to a variable.
@@ -154,7 +160,9 @@ func AssignAddVariableOp(scope *Scope, resource tf.Output, value tf.Output) {
// Arguments:
// resource: handle to the resource in which to store the variable.
// value: the value to set the new tensor to use.
-func AssignVariableOp(scope *Scope, resource tf.Output, value tf.Output) {
+//
+// Returns the created operation.
+func AssignVariableOp(scope *Scope, resource tf.Output, value tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -164,7 +172,7 @@ func AssignVariableOp(scope *Scope, resource tf.Output, value tf.Output) {
resource, value,
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// VarHandleOpAttr is an optional argument to VarHandleOp.
@@ -420,10 +428,9 @@ func DebugNumericSummary(scope *Scope, input tf.Output, optional ...DebugNumeric
return op.Output(0)
}
-// Fake-quantize the 'inputs' tensor of type float and shape `[b, h, w, d]` via
+// Fake-quantize the 'inputs' tensor of type float via global float scalars `min`
//
-// global float scalars `min` and `max` to 'outputs' tensor of same shape as
-// `inputs`.
+// and `max` to 'outputs' tensor of same shape as `inputs`.
//
// [min; max] is the clamping range for the 'inputs' data. Op divides this range
// into 255 steps (total of 256 values), then replaces each 'inputs' value with the
@@ -3018,7 +3025,9 @@ func AbortExitWithoutError(value bool) AbortAttr {
// Raise a exception to abort the process when called. If exit_without_error is true, the process will exit normally, otherwise it will exit with a SIGABORT signal.
//
// Returns nothing but an exception.
-func Abort(scope *Scope, optional ...AbortAttr) {
+//
+// Returns the created operation.
+func Abort(scope *Scope, optional ...AbortAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -3031,20 +3040,22 @@ func Abort(scope *Scope, optional ...AbortAttr) {
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Does nothing. Serves as a control trigger for scheduling.
//
// Only useful as a placeholder for control edges.
-func ControlTrigger(scope *Scope) {
+//
+// Returns the created operation.
+func ControlTrigger(scope *Scope) (o *tf.Operation) {
if scope.Err() != nil {
return
}
opspec := tf.OpSpec{
Type: "ControlTrigger",
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// SpaceToDepth for tensors of type T.
@@ -3509,7 +3520,9 @@ func StageSharedName(value string) StageAttr {
//
// Arguments:
// values: a list of tensors
-func Stage(scope *Scope, values []tf.Output, optional ...StageAttr) {
+//
+// Returns the created operation.
+func Stage(scope *Scope, values []tf.Output, optional ...StageAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -3524,7 +3537,7 @@ func Stage(scope *Scope, values []tf.Output, optional ...StageAttr) {
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// FakeQuantWithMinMaxArgsAttr is an optional argument to FakeQuantWithMinMaxArgs.
@@ -3685,7 +3698,9 @@ func ResourceGather(scope *Scope, resource tf.Output, indices tf.Output, dtype t
//
// Arguments:
// handle: The handle to a TensorArray (output of TensorArray or TensorArrayGrad).
-func TensorArrayCloseV3(scope *Scope, handle tf.Output) {
+//
+// Returns the created operation.
+func TensorArrayCloseV3(scope *Scope, handle tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -3695,7 +3710,7 @@ func TensorArrayCloseV3(scope *Scope, handle tf.Output) {
handle,
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Get the current size of the TensorArray.
@@ -4141,7 +4156,9 @@ func QueueCloseV2CancelPendingEnqueues(value bool) QueueCloseV2Attr {
//
// Arguments:
// handle: The handle to a queue.
-func QueueCloseV2(scope *Scope, handle tf.Output, optional ...QueueCloseV2Attr) {
+//
+// Returns the created operation.
+func QueueCloseV2(scope *Scope, handle tf.Output, optional ...QueueCloseV2Attr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -4156,7 +4173,7 @@ func QueueCloseV2(scope *Scope, handle tf.Output, optional ...QueueCloseV2Attr)
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Concatenates tensors along one dimension.
@@ -4254,7 +4271,9 @@ func QueueDequeueUpToV2(scope *Scope, handle tf.Output, n tf.Output, component_t
}
// Deprecated. Use TensorArrayCloseV3
-func TensorArrayCloseV2(scope *Scope, handle tf.Output) {
+//
+// Returns the created operation.
+func TensorArrayCloseV2(scope *Scope, handle tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -4264,7 +4283,7 @@ func TensorArrayCloseV2(scope *Scope, handle tf.Output) {
handle,
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// QueueDequeueManyV2Attr is an optional argument to QueueDequeueManyV2.
@@ -4358,7 +4377,9 @@ func QueueEnqueueV2TimeoutMs(value int64) QueueEnqueueV2Attr {
// Arguments:
// handle: The handle to a queue.
// components: One or more tensors from which the enqueued tensors should be taken.
-func QueueEnqueueV2(scope *Scope, handle tf.Output, components []tf.Output, optional ...QueueEnqueueV2Attr) {
+//
+// Returns the created operation.
+func QueueEnqueueV2(scope *Scope, handle tf.Output, components []tf.Output, optional ...QueueEnqueueV2Attr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -4373,7 +4394,7 @@ func QueueEnqueueV2(scope *Scope, handle tf.Output, components []tf.Output, opti
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// UnstageAttr is an optional argument to Unstage.
@@ -4587,19 +4608,75 @@ func PaddingFIFOQueueV2(scope *Scope, component_types []tf.DataType, optional ..
return op.Output(0)
}
-// Computes the gradient for the inverse of `x` wrt its input.
+// FIFOQueueV2Attr is an optional argument to FIFOQueueV2.
+type FIFOQueueV2Attr func(optionalAttr)
+
+// FIFOQueueV2Shapes sets the optional shapes attribute to value.
//
-// Specifically, `grad = -dy * y*y`, where `y = 1/x`, and `dy`
-// is the corresponding input gradient.
-func ReciprocalGrad(scope *Scope, x tf.Output, y tf.Output) (z tf.Output) {
+// value: The shape of each component in a value. The length of this attr must
+// be either 0 or the same as the length of component_types. If the length of
+// this attr is 0, the shapes of queue elements are not constrained, and
+// only one element may be dequeued at a time.
+// If not specified, defaults to list:<>
+//
+// REQUIRES: len(value) >= 0
+func FIFOQueueV2Shapes(value []tf.Shape) FIFOQueueV2Attr {
+ return func(m optionalAttr) {
+ m["shapes"] = value
+ }
+}
+
+// FIFOQueueV2Capacity sets the optional capacity attribute to value.
+//
+// value: The upper bound on the number of elements in this queue.
+// Negative numbers mean no limit.
+// If not specified, defaults to i:-1
+func FIFOQueueV2Capacity(value int64) FIFOQueueV2Attr {
+ return func(m optionalAttr) {
+ m["capacity"] = value
+ }
+}
+
+// FIFOQueueV2Container sets the optional container attribute to value.
+//
+// value: If non-empty, this queue is placed in the given container.
+// Otherwise, a default container is used.
+// If not specified, defaults to s:""
+func FIFOQueueV2Container(value string) FIFOQueueV2Attr {
+ return func(m optionalAttr) {
+ m["container"] = value
+ }
+}
+
+// FIFOQueueV2SharedName sets the optional shared_name attribute to value.
+//
+// value: If non-empty, this queue will be shared under the given name
+// across multiple sessions.
+// If not specified, defaults to s:""
+func FIFOQueueV2SharedName(value string) FIFOQueueV2Attr {
+ return func(m optionalAttr) {
+ m["shared_name"] = value
+ }
+}
+
+// A queue that produces elements in first-in first-out order.
+//
+// Arguments:
+// component_types: The type of each component in a value.
+//
+// Returns The handle to the queue.
+func FIFOQueueV2(scope *Scope, component_types []tf.DataType, optional ...FIFOQueueV2Attr) (handle tf.Output) {
if scope.Err() != nil {
return
}
+ attrs := map[string]interface{}{"component_types": component_types}
+ for _, a := range optional {
+ a(attrs)
+ }
opspec := tf.OpSpec{
- Type: "ReciprocalGrad",
- Input: []tf.Input{
- x, y,
- },
+ Type: "FIFOQueueV2",
+
+ Attrs: attrs,
}
op := scope.AddOperation(opspec)
return op.Output(0)
@@ -4668,6 +4745,35 @@ func Cumsum(scope *Scope, x tf.Output, axis tf.Output, optional ...CumsumAttr) (
return op.Output(0)
}
+// Produces the max pool of the input tensor for quantized types.
+//
+// Arguments:
+// input: The 4D (batch x rows x cols x depth) Tensor to MaxReduce over.
+// min_input: The float value that the lowest quantized input value represents.
+// max_input: The float value that the highest quantized input value represents.
+// ksize: The size of the window for each dimension of the input tensor.
+// The length must be 4 to match the number of dimensions of the input.
+// strides: The stride of the sliding window for each dimension of the input
+// tensor. The length must be 4 to match the number of dimensions of the input.
+// padding: The type of padding algorithm to use.
+//
+// Returns The float value that the lowest quantized output value represents.The float value that the highest quantized output value represents.
+func QuantizedMaxPool(scope *Scope, input tf.Output, min_input tf.Output, max_input tf.Output, ksize []int64, strides []int64, padding string) (output tf.Output, min_output tf.Output, max_output tf.Output) {
+ if scope.Err() != nil {
+ return
+ }
+ attrs := map[string]interface{}{"ksize": ksize, "strides": strides, "padding": padding}
+ opspec := tf.OpSpec{
+ Type: "QuantizedMaxPool",
+ Input: []tf.Input{
+ input, min_input, max_input,
+ },
+ Attrs: attrs,
+ }
+ op := scope.AddOperation(opspec)
+ return op.Output(0), op.Output(1), op.Output(2)
+}
+
// Performs 3D average pooling on the input.
//
// Arguments:
@@ -5703,14 +5809,16 @@ func NextIteration(scope *Scope, data tf.Output) (output tf.Output) {
}
// Does nothing. Only useful as a placeholder for control edges.
-func NoOp(scope *Scope) {
+//
+// Returns the created operation.
+func NoOp(scope *Scope) (o *tf.Operation) {
if scope.Err() != nil {
return
}
opspec := tf.OpSpec{
Type: "NoOp",
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Computes softsign: `features / (abs(features) + 1)`.
@@ -6192,7 +6300,9 @@ func ResourceApplyAdagradDAUseLocking(value bool) ResourceApplyAdagradDAAttr {
// l1: L1 regularization. Must be a scalar.
// l2: L2 regularization. Must be a scalar.
// global_step: Training step number. Must be a scalar.
-func ResourceApplyAdagradDA(scope *Scope, var_ tf.Output, gradient_accumulator tf.Output, gradient_squared_accumulator tf.Output, grad tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, global_step tf.Output, optional ...ResourceApplyAdagradDAAttr) {
+//
+// Returns the created operation.
+func ResourceApplyAdagradDA(scope *Scope, var_ tf.Output, gradient_accumulator tf.Output, gradient_squared_accumulator tf.Output, grad tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, global_step tf.Output, optional ...ResourceApplyAdagradDAAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -6207,7 +6317,7 @@ func ResourceApplyAdagradDA(scope *Scope, var_ tf.Output, gradient_accumulator t
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// ComputeAccidentalHitsAttr is an optional argument to ComputeAccidentalHits.
@@ -6381,7 +6491,9 @@ func SegmentMax(scope *Scope, data tf.Output, segment_ids tf.Output) (output tf.
// shapes_and_slices: Shape `[N]`. The shapes and slice specifications to use when
// saving the tensors.
// data: `N` tensors to save.
-func SaveSlices(scope *Scope, filename tf.Output, tensor_names tf.Output, shapes_and_slices tf.Output, data []tf.Output) {
+//
+// Returns the created operation.
+func SaveSlices(scope *Scope, filename tf.Output, tensor_names tf.Output, shapes_and_slices tf.Output, data []tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -6391,50 +6503,7 @@ func SaveSlices(scope *Scope, filename tf.Output, tensor_names tf.Output, shapes
filename, tensor_names, shapes_and_slices, tf.OutputList(data),
},
}
- scope.AddOperation(opspec)
-}
-
-// Writes contents to the file at input filename. Creates file if not existing.
-//
-// Arguments:
-// filename: scalar. The name of the file to which we write the contents.
-// contents: scalar. The content to be written to the output file.
-func WriteFile(scope *Scope, filename tf.Output, contents tf.Output) {
- if scope.Err() != nil {
- return
- }
- opspec := tf.OpSpec{
- Type: "WriteFile",
- Input: []tf.Input{
- filename, contents,
- },
- }
- scope.AddOperation(opspec)
-}
-
-// Computes the Cholesky decomposition of one or more square matrices.
-//
-// The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions
-// form square matrices, with the same constraints as the single matrix Cholesky
-// decomposition above. The output is a tensor of the same shape as the input
-// containing the Cholesky decompositions for all input submatrices `[..., :, :]`.
-//
-// Arguments:
-// input: Shape is `[..., M, M]`.
-//
-// Returns Shape is `[..., M, M]`.
-func Cholesky(scope *Scope, input tf.Output) (output tf.Output) {
- if scope.Err() != nil {
- return
- }
- opspec := tf.OpSpec{
- Type: "Cholesky",
- Input: []tf.Input{
- input,
- },
- }
- op := scope.AddOperation(opspec)
- return op.Output(0)
+ return scope.AddOperation(opspec)
}
// TensorArrayGatherV2Attr is an optional argument to TensorArrayGatherV2.
@@ -6726,21 +6795,6 @@ func Acos(scope *Scope, x tf.Output) (y tf.Output) {
return op.Output(0)
}
-// Computes exponential of x element-wise. \\(y = e^x\\).
-func Exp(scope *Scope, x tf.Output) (y tf.Output) {
- if scope.Err() != nil {
- return
- }
- opspec := tf.OpSpec{
- Type: "Exp",
- Input: []tf.Input{
- x,
- },
- }
- op := scope.AddOperation(opspec)
- return op.Output(0)
-}
-
// Copy a tensor setting everything outside a central band in each innermost matrix
//
// to zero.
@@ -8146,7 +8200,9 @@ func DestroyResourceOpIgnoreLookupError(value bool) DestroyResourceOpAttr {
//
// Arguments:
// resource: handle to the resource to delete.
-func DestroyResourceOp(scope *Scope, resource tf.Output, optional ...DestroyResourceOpAttr) {
+//
+// Returns the created operation.
+func DestroyResourceOp(scope *Scope, resource tf.Output, optional ...DestroyResourceOpAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -8161,7 +8217,7 @@ func DestroyResourceOp(scope *Scope, resource tf.Output, optional ...DestroyReso
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// ResourceApplyMomentumAttr is an optional argument to ResourceApplyMomentum.
@@ -8204,7 +8260,9 @@ func ResourceApplyMomentumUseNesterov(value bool) ResourceApplyMomentumAttr {
// lr: Scaling factor. Must be a scalar.
// grad: The gradient.
// momentum: Momentum. Must be a scalar.
-func ResourceApplyMomentum(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, grad tf.Output, momentum tf.Output, optional ...ResourceApplyMomentumAttr) {
+//
+// Returns the created operation.
+func ResourceApplyMomentum(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, grad tf.Output, momentum tf.Output, optional ...ResourceApplyMomentumAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -8219,7 +8277,7 @@ func ResourceApplyMomentum(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Returns element-wise integer closest to x.
@@ -8724,6 +8782,69 @@ func ReluGrad(scope *Scope, gradients tf.Output, features tf.Output) (backprops
return op.Output(0)
}
+// Computes the gradient for the inverse of `x` wrt its input.
+//
+// Specifically, `grad = -dy * y*y`, where `y = 1/x`, and `dy`
+// is the corresponding input gradient.
+func ReciprocalGrad(scope *Scope, x tf.Output, y tf.Output) (z tf.Output) {
+ if scope.Err() != nil {
+ return
+ }
+ opspec := tf.OpSpec{
+ Type: "ReciprocalGrad",
+ Input: []tf.Input{
+ x, y,
+ },
+ }
+ op := scope.AddOperation(opspec)
+ return op.Output(0)
+}
+
+// Computes the Cholesky decomposition of one or more square matrices.
+//
+// The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions
+// form square matrices, with the same constraints as the single matrix Cholesky
+// decomposition above. The output is a tensor of the same shape as the input
+// containing the Cholesky decompositions for all input submatrices `[..., :, :]`.
+//
+// Arguments:
+// input: Shape is `[..., M, M]`.
+//
+// Returns Shape is `[..., M, M]`.
+func Cholesky(scope *Scope, input tf.Output) (output tf.Output) {
+ if scope.Err() != nil {
+ return
+ }
+ opspec := tf.OpSpec{
+ Type: "Cholesky",
+ Input: []tf.Input{
+ input,
+ },
+ }
+ op := scope.AddOperation(opspec)
+ return op.Output(0)
+}
+
+// Writes contents to the file at input filename. Creates file if not existing.
+//
+// Arguments:
+// filename: scalar. The name of the file to which we write the contents.
+// contents: scalar. The content to be written to the output file.
+//
+// Returns the created operation.
+func WriteFile(scope *Scope, filename tf.Output, contents tf.Output) (o *tf.Operation) {
+ if scope.Err() != nil {
+ return
+ }
+ opspec := tf.OpSpec{
+ Type: "WriteFile",
+ Input: []tf.Input{
+ filename, contents,
+ },
+ }
+ return scope.AddOperation(opspec)
+}
+
// Reverses specific dimensions of a tensor.
//
// NOTE `tf.reverse` has now changed behavior in preparation for 1.0.
@@ -8838,7 +8959,9 @@ func ResourceApplyCenteredRMSPropUseLocking(value bool) ResourceApplyCenteredRMS
//
// epsilon: Ridge term. Must be a scalar.
// grad: The gradient.
-func ResourceApplyCenteredRMSProp(scope *Scope, var_ tf.Output, mg tf.Output, ms tf.Output, mom tf.Output, lr tf.Output, rho tf.Output, momentum tf.Output, epsilon tf.Output, grad tf.Output, optional ...ResourceApplyCenteredRMSPropAttr) {
+//
+// Returns the created operation.
+func ResourceApplyCenteredRMSProp(scope *Scope, var_ tf.Output, mg tf.Output, ms tf.Output, mom tf.Output, lr tf.Output, rho tf.Output, momentum tf.Output, epsilon tf.Output, grad tf.Output, optional ...ResourceApplyCenteredRMSPropAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -8853,7 +8976,7 @@ func ResourceApplyCenteredRMSProp(scope *Scope, var_ tf.Output, mg tf.Output, ms
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Given a quantized tensor described by (input, input_min, input_max), outputs a
@@ -9013,7 +9136,9 @@ func ResourceApplyProximalGradientDescentUseLocking(value bool) ResourceApplyPro
// l1: L1 regularization. Must be a scalar.
// l2: L2 regularization. Must be a scalar.
// delta: The change.
-func ResourceApplyProximalGradientDescent(scope *Scope, var_ tf.Output, alpha tf.Output, l1 tf.Output, l2 tf.Output, delta tf.Output, optional ...ResourceApplyProximalGradientDescentAttr) {
+//
+// Returns the created operation.
+func ResourceApplyProximalGradientDescent(scope *Scope, var_ tf.Output, alpha tf.Output, l1 tf.Output, l2 tf.Output, delta tf.Output, optional ...ResourceApplyProximalGradientDescentAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -9028,7 +9153,7 @@ func ResourceApplyProximalGradientDescent(scope *Scope, var_ tf.Output, alpha tf
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// ResourceApplyProximalAdagradAttr is an optional argument to ResourceApplyProximalAdagrad.
@@ -9058,7 +9183,9 @@ func ResourceApplyProximalAdagradUseLocking(value bool) ResourceApplyProximalAda
// l1: L1 regularization. Must be a scalar.
// l2: L2 regularization. Must be a scalar.
// grad: The gradient.
-func ResourceApplyProximalAdagrad(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, grad tf.Output, optional ...ResourceApplyProximalAdagradAttr) {
+//
+// Returns the created operation.
+func ResourceApplyProximalAdagrad(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, grad tf.Output, optional ...ResourceApplyProximalAdagradAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -9073,7 +9200,7 @@ func ResourceApplyProximalAdagrad(scope *Scope, var_ tf.Output, accum tf.Output,
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Adds Tensor 'bias' to Tensor 'input' for Quantized types.
@@ -9204,7 +9331,9 @@ func ResourceApplyGradientDescentUseLocking(value bool) ResourceApplyGradientDes
// var_: Should be from a Variable().
// alpha: Scaling factor. Must be a scalar.
// delta: The change.
-func ResourceApplyGradientDescent(scope *Scope, var_ tf.Output, alpha tf.Output, delta tf.Output, optional ...ResourceApplyGradientDescentAttr) {
+//
+// Returns the created operation.
+func ResourceApplyGradientDescent(scope *Scope, var_ tf.Output, alpha tf.Output, delta tf.Output, optional ...ResourceApplyGradientDescentAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -9219,7 +9348,7 @@ func ResourceApplyGradientDescent(scope *Scope, var_ tf.Output, alpha tf.Output,
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// MultinomialAttr is an optional argument to Multinomial.
@@ -9300,7 +9429,9 @@ func ResourceSparseApplyAdagradDAUseLocking(value bool) ResourceSparseApplyAdagr
// l1: L1 regularization. Must be a scalar.
// l2: L2 regularization. Must be a scalar.
// global_step: Training step number. Must be a scalar.
-func ResourceSparseApplyAdagradDA(scope *Scope, var_ tf.Output, gradient_accumulator tf.Output, gradient_squared_accumulator tf.Output, grad tf.Output, indices tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, global_step tf.Output, optional ...ResourceSparseApplyAdagradDAAttr) {
+//
+// Returns the created operation.
+func ResourceSparseApplyAdagradDA(scope *Scope, var_ tf.Output, gradient_accumulator tf.Output, gradient_squared_accumulator tf.Output, grad tf.Output, indices tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, global_step tf.Output, optional ...ResourceSparseApplyAdagradDAAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -9315,7 +9446,7 @@ func ResourceSparseApplyAdagradDA(scope *Scope, var_ tf.Output, gradient_accumul
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// SparseToSparseSetOperationAttr is an optional argument to SparseToSparseSetOperation.
@@ -9566,7 +9697,9 @@ func ResourceSparseApplyCenteredRMSPropUseLocking(value bool) ResourceSparseAppl
// epsilon: Ridge term. Must be a scalar.
// grad: The gradient.
// indices: A vector of indices into the first dimension of var, ms and mom.
-func ResourceSparseApplyCenteredRMSProp(scope *Scope, var_ tf.Output, mg tf.Output, ms tf.Output, mom tf.Output, lr tf.Output, rho tf.Output, momentum tf.Output, epsilon tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyCenteredRMSPropAttr) {
+//
+// Returns the created operation.
+func ResourceSparseApplyCenteredRMSProp(scope *Scope, var_ tf.Output, mg tf.Output, ms tf.Output, mom tf.Output, lr tf.Output, rho tf.Output, momentum tf.Output, epsilon tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyCenteredRMSPropAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -9581,7 +9714,7 @@ func ResourceSparseApplyCenteredRMSProp(scope *Scope, var_ tf.Output, mg tf.Outp
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Computes the mean along segments of a tensor.
@@ -10064,7 +10197,11 @@ func StringJoin(scope *Scope, inputs []tf.Output, optional ...StringJoinAttr) (o
// when the example's feature_map lacks dense_key[j]. If an empty Tensor is
// provided for dense_defaults[j], then the Feature dense_keys[j] is required.
// The input type is inferred from dense_defaults[j], even when it's empty.
-// If dense_defaults[j] is not empty, its shape must match dense_shapes[j].
+// If dense_defaults[j] is not empty, and dense_shapes[j] is fully defined,
+// then the shape of dense_defaults[j] must match that of dense_shapes[j].
+// If dense_shapes[j] has an undefined major dimension (variable strides dense
+// feature), dense_defaults[j] must contain a single element:
+// the padding element.
// sparse_types: A list of Nsparse types; the data types of data in each Feature
// given in sparse_keys.
// Currently the ParseExample supports DT_FLOAT (FloatList),
@@ -10076,6 +10213,13 @@ func StringJoin(scope *Scope, inputs []tf.Output, optional ...StringJoinAttr) (o
// If dense_shapes[j] == (D0, D1, ..., DN) then the shape of output
// Tensor dense_values[j] will be (|serialized|, D0, D1, ..., DN):
// The dense outputs are just the inputs row-stacked by batch.
+// This works for dense_shapes[j] = (-1, D1, ..., DN). In this case
+// the shape of the output Tensor dense_values[j] will be
+// (|serialized|, M, D1, .., DN), where M is the maximum number of blocks
+// of elements of length D1 * .... * DN, across all minibatch entries
+// in the input. Any minibatch entry with less than M blocks of elements of
+// length D1 * ... * DN will be padded with the corresponding default_value
+// scalar element along the second dimension.
func ParseExample(scope *Scope, serialized tf.Output, names tf.Output, sparse_keys []tf.Output, dense_keys []tf.Output, dense_defaults []tf.Output, sparse_types []tf.DataType, dense_shapes []tf.Shape) (sparse_indices []tf.Output, sparse_values []tf.Output, sparse_shapes []tf.Output, dense_values []tf.Output) {
if scope.Err() != nil {
return
@@ -10163,7 +10307,9 @@ func ResourceApplyAdagradUseLocking(value bool) ResourceApplyAdagradAttr {
// accum: Should be from a Variable().
// lr: Scaling factor. Must be a scalar.
// grad: The gradient.
-func ResourceApplyAdagrad(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, grad tf.Output, optional ...ResourceApplyAdagradAttr) {
+//
+// Returns the created operation.
+func ResourceApplyAdagrad(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, grad tf.Output, optional ...ResourceApplyAdagradAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -10178,7 +10324,7 @@ func ResourceApplyAdagrad(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.O
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Converts each string in the input Tensor to its hash mod by a number of buckets.
@@ -10497,7 +10643,9 @@ func ResourceSparseApplyRMSPropUseLocking(value bool) ResourceSparseApplyRMSProp
// epsilon: Ridge term. Must be a scalar.
// grad: The gradient.
// indices: A vector of indices into the first dimension of var, ms and mom.
-func ResourceSparseApplyRMSProp(scope *Scope, var_ tf.Output, ms tf.Output, mom tf.Output, lr tf.Output, rho tf.Output, momentum tf.Output, epsilon tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyRMSPropAttr) {
+//
+// Returns the created operation.
+func ResourceSparseApplyRMSProp(scope *Scope, var_ tf.Output, ms tf.Output, mom tf.Output, lr tf.Output, rho tf.Output, momentum tf.Output, epsilon tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyRMSPropAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -10512,7 +10660,7 @@ func ResourceSparseApplyRMSProp(scope *Scope, var_ tf.Output, ms tf.Output, mom
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// QuantizeV2Attr is an optional argument to QuantizeV2.
@@ -10689,7 +10837,9 @@ func ResourceSparseApplyFtrlUseLocking(value bool) ResourceSparseApplyFtrlAttr {
// l1: L1 regularization. Must be a scalar.
// l2: L2 regularization. Must be a scalar.
// lr_power: Scaling factor. Must be a scalar.
-func ResourceSparseApplyFtrl(scope *Scope, var_ tf.Output, accum tf.Output, linear tf.Output, grad tf.Output, indices tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, lr_power tf.Output, optional ...ResourceSparseApplyFtrlAttr) {
+//
+// Returns the created operation.
+func ResourceSparseApplyFtrl(scope *Scope, var_ tf.Output, accum tf.Output, linear tf.Output, grad tf.Output, indices tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, lr_power tf.Output, optional ...ResourceSparseApplyFtrlAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -10704,7 +10854,7 @@ func ResourceSparseApplyFtrl(scope *Scope, var_ tf.Output, accum tf.Output, line
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Computes a 3-D convolution given 5-D `input` and `filter` tensors.
@@ -11044,7 +11194,9 @@ func ResourceSparseApplyProximalAdagradUseLocking(value bool) ResourceSparseAppl
// l2: L2 regularization. Must be a scalar.
// grad: The gradient.
// indices: A vector of indices into the first dimension of var and accum.
-func ResourceSparseApplyProximalAdagrad(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyProximalAdagradAttr) {
+//
+// Returns the created operation.
+func ResourceSparseApplyProximalAdagrad(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyProximalAdagradAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -11059,7 +11211,7 @@ func ResourceSparseApplyProximalAdagrad(scope *Scope, var_ tf.Output, accum tf.O
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Store the input tensor in the state of the current session.
@@ -11382,7 +11534,9 @@ func ResourceApplyRMSPropUseLocking(value bool) ResourceApplyRMSPropAttr {
//
// epsilon: Ridge term. Must be a scalar.
// grad: The gradient.
-func ResourceApplyRMSProp(scope *Scope, var_ tf.Output, ms tf.Output, mom tf.Output, lr tf.Output, rho tf.Output, momentum tf.Output, epsilon tf.Output, grad tf.Output, optional ...ResourceApplyRMSPropAttr) {
+//
+// Returns the created operation.
+func ResourceApplyRMSProp(scope *Scope, var_ tf.Output, ms tf.Output, mom tf.Output, lr tf.Output, rho tf.Output, momentum tf.Output, epsilon tf.Output, grad tf.Output, optional ...ResourceApplyRMSPropAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -11397,7 +11551,7 @@ func ResourceApplyRMSProp(scope *Scope, var_ tf.Output, ms tf.Output, mom tf.Out
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Output a fact about factorials.
@@ -11578,7 +11732,9 @@ func ResourceSparseApplyAdagradUseLocking(value bool) ResourceSparseApplyAdagrad
// lr: Learning rate. Must be a scalar.
// grad: The gradient.
// indices: A vector of indices into the first dimension of var and accum.
-func ResourceSparseApplyAdagrad(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyAdagradAttr) {
+//
+// Returns the created operation.
+func ResourceSparseApplyAdagrad(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyAdagradAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -11593,7 +11749,7 @@ func ResourceSparseApplyAdagrad(scope *Scope, var_ tf.Output, accum tf.Output, l
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// LRNGradAttr is an optional argument to LRNGrad.
@@ -12341,7 +12497,9 @@ func MergeV2CheckpointsDeleteOldDirs(value bool) MergeV2CheckpointsAttr {
// checkpoint_prefixes: prefixes of V2 checkpoints to merge.
// destination_prefix: scalar. The desired final prefix. Allowed to be the same
// as one of the checkpoint_prefixes.
-func MergeV2Checkpoints(scope *Scope, checkpoint_prefixes tf.Output, destination_prefix tf.Output, optional ...MergeV2CheckpointsAttr) {
+//
+// Returns the created operation.
+func MergeV2Checkpoints(scope *Scope, checkpoint_prefixes tf.Output, destination_prefix tf.Output, optional ...MergeV2CheckpointsAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -12356,7 +12514,7 @@ func MergeV2Checkpoints(scope *Scope, checkpoint_prefixes tf.Output, destination
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Reads the value of a variable.
@@ -12531,7 +12689,9 @@ func Abs(scope *Scope, x tf.Output) (y tf.Output) {
// reader_handle: Handle to a Reader.
// state: Result of a ReaderSerializeState of a Reader with type
// matching reader_handle.
-func ReaderRestoreStateV2(scope *Scope, reader_handle tf.Output, state tf.Output) {
+//
+// Returns the created operation.
+func ReaderRestoreStateV2(scope *Scope, reader_handle tf.Output, state tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -12541,7 +12701,7 @@ func ReaderRestoreStateV2(scope *Scope, reader_handle tf.Output, state tf.Output
reader_handle, state,
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Draw bounding boxes on a batch of images.
@@ -12606,7 +12766,9 @@ func ResourceSparseApplyProximalGradientDescentUseLocking(value bool) ResourceSp
// l2: L2 regularization. Must be a scalar.
// grad: The gradient.
// indices: A vector of indices into the first dimension of var and accum.
-func ResourceSparseApplyProximalGradientDescent(scope *Scope, var_ tf.Output, alpha tf.Output, l1 tf.Output, l2 tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyProximalGradientDescentAttr) {
+//
+// Returns the created operation.
+func ResourceSparseApplyProximalGradientDescent(scope *Scope, var_ tf.Output, alpha tf.Output, l1 tf.Output, l2 tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyProximalGradientDescentAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -12621,7 +12783,7 @@ func ResourceSparseApplyProximalGradientDescent(scope *Scope, var_ tf.Output, al
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// UnpackAttr is an optional argument to Unpack.
@@ -12980,7 +13142,9 @@ func ResourceApplyFtrlUseLocking(value bool) ResourceApplyFtrlAttr {
// l1: L1 regulariation. Must be a scalar.
// l2: L2 regulariation. Must be a scalar.
// lr_power: Scaling factor. Must be a scalar.
-func ResourceApplyFtrl(scope *Scope, var_ tf.Output, accum tf.Output, linear tf.Output, grad tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, lr_power tf.Output, optional ...ResourceApplyFtrlAttr) {
+//
+// Returns the created operation.
+func ResourceApplyFtrl(scope *Scope, var_ tf.Output, accum tf.Output, linear tf.Output, grad tf.Output, lr tf.Output, l1 tf.Output, l2 tf.Output, lr_power tf.Output, optional ...ResourceApplyFtrlAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -12995,7 +13159,7 @@ func ResourceApplyFtrl(scope *Scope, var_ tf.Output, accum tf.Output, linear tf.
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// AnyAttr is an optional argument to Any.
@@ -13181,7 +13345,9 @@ func TopKV2(scope *Scope, input tf.Output, k tf.Output, optional ...TopKV2Attr)
//
// Arguments:
// handle: The handle for a tensor stored in the session state.
-func DeleteSessionTensor(scope *Scope, handle tf.Output) {
+//
+// Returns the created operation.
+func DeleteSessionTensor(scope *Scope, handle tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -13191,7 +13357,7 @@ func DeleteSessionTensor(scope *Scope, handle tf.Output) {
handle,
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// DenseToDenseSetOperationAttr is an optional argument to DenseToDenseSetOperation.
@@ -13331,6 +13497,72 @@ func DeserializeManySparse(scope *Scope, serialized_sparse tf.Output, dtype tf.D
return op.Output(0), op.Output(1), op.Output(2)
}
+// RandomPoissonAttr is an optional argument to RandomPoisson.
+type RandomPoissonAttr func(optionalAttr)
+
+// RandomPoissonSeed sets the optional seed attribute to value.
+//
+// value: If either `seed` or `seed2` are set to be non-zero, the random number
+// generator is seeded by the given seed. Otherwise, it is seeded by a
+// random seed.
+// If not specified, defaults to i:0
+func RandomPoissonSeed(value int64) RandomPoissonAttr {
+ return func(m optionalAttr) {
+ m["seed"] = value
+ }
+}
+
+// RandomPoissonSeed2 sets the optional seed2 attribute to value.
+//
+// value: A second seed to avoid seed collision.
+// If not specified, defaults to i:0
+func RandomPoissonSeed2(value int64) RandomPoissonAttr {
+ return func(m optionalAttr) {
+ m["seed2"] = value
+ }
+}
+
+// Outputs random values from the Poisson distribution(s) described by rate.
+//
+// This op uses two algorithms, depending on rate. If rate >= 10, then
+// the algorithm by Hormann is used to acquire samples via
+// transformation-rejection.
+// See http://www.sciencedirect.com/science/article/pii/0167668793909974.
+//
+// Otherwise, Knuth's algorithm is used to acquire samples via multiplying uniform
+// random variables.
+// See Donald E. Knuth (1969). Seminumerical Algorithms. The Art of Computer
+// Programming, Volume 2. Addison Wesley
+//
+// Arguments:
+// shape: 1-D integer tensor. Shape of independent samples to draw from each
+// distribution described by the shape parameters given in rate.
+// rate: A tensor in which each scalar is a "rate" parameter describing the
+// associated poisson distribution.
+//
+// Returns A tensor with shape `shape + shape(rate)`. Each slice
+// `[:, ..., :, i0, i1, ...iN]` contains the samples drawn for
+// `rate[i0, i1, ...iN]`. The dtype of the output matches the dtype of
+// rate.
+func RandomPoisson(scope *Scope, shape tf.Output, rate tf.Output, optional ...RandomPoissonAttr) (output tf.Output) {
+ if scope.Err() != nil {
+ return
+ }
+ attrs := map[string]interface{}{}
+ for _, a := range optional {
+ a(attrs)
+ }
+ opspec := tf.OpSpec{
+ Type: "RandomPoisson",
+ Input: []tf.Input{
+ shape, rate,
+ },
+ Attrs: attrs,
+ }
+ op := scope.AddOperation(opspec)
+ return op.Output(0)
+}
+
// Applies softmax to a batched N-D `SparseTensor`.
//
// The inputs represent an N-D SparseTensor with logical shape `[..., B, C]`
@@ -13538,6 +13770,118 @@ func IdentityReaderV2(scope *Scope, optional ...IdentityReaderV2Attr) (reader_ha
return op.Output(0)
}
+// NonMaxSuppressionAttr is an optional argument to NonMaxSuppression.
+type NonMaxSuppressionAttr func(optionalAttr)
+
+// NonMaxSuppressionIouThreshold sets the optional iou_threshold attribute to value.
+//
+// value: A float representing the threshold for deciding whether boxes
+// overlap too much with respect to IOU.
+// If not specified, defaults to f:0.5
+func NonMaxSuppressionIouThreshold(value float32) NonMaxSuppressionAttr {
+ return func(m optionalAttr) {
+ m["iou_threshold"] = value
+ }
+}
+
+// Greedily selects a subset of bounding boxes in descending order of score,
+//
+// pruning away boxes that have high intersection-over-union (IOU) overlap
+// with previously selected boxes. Bounding boxes are supplied as
+// [y1, x1, y2, x2], where (y1, x1) and (y2, x2) are the coordinates of any
+// diagonal pair of box corners and the coordinates can be provided as normalized
+// (i.e., lying in the interval [0, 1]) or absolute. Note that this algorithm
+// is agnostic to where the origin is in the coordinate system. Note that this
+// algorithm is invariant to orthogonal transformations and translations
+// of the coordinate system; thus translating or reflections of the coordinate
+// system result in the same boxes being selected by the algorithm.
+//
+// The output of this operation is a set of integers indexing into the input
+// collection of bounding boxes representing the selected boxes. The bounding
+// box coordinates corresponding to the selected indices can then be obtained
+// using the `tf.gather operation`. For example:
+//
+// selected_indices = tf.image.non_max_suppression(
+// boxes, scores, max_output_size, iou_threshold)
+// selected_boxes = tf.gather(boxes, selected_indices)
+//
+// Arguments:
+// boxes: A 2-D float tensor of shape `[num_boxes, 4]`.
+// scores: A 1-D float tensor of shape `[num_boxes]` representing a single
+// score corresponding to each box (each row of boxes).
+// max_output_size: A scalar integer tensor representing the maximum number of
+// boxes to be selected by non max suppression.
+//
+// Returns A 1-D integer tensor of shape `[M]` representing the selected
+// indices from the boxes tensor, where `M <= max_output_size`.
+func NonMaxSuppression(scope *Scope, boxes tf.Output, scores tf.Output, max_output_size tf.Output, optional ...NonMaxSuppressionAttr) (selected_indices tf.Output) {
+ if scope.Err() != nil {
+ return
+ }
+ attrs := map[string]interface{}{}
+ for _, a := range optional {
+ a(attrs)
+ }
+ opspec := tf.OpSpec{
+ Type: "NonMaxSuppression",
+ Input: []tf.Input{
+ boxes, scores, max_output_size,
+ },
+ Attrs: attrs,
+ }
+ op := scope.AddOperation(opspec)
+ return op.Output(0)
+}
+
+// ResourceApplyAdadeltaAttr is an optional argument to ResourceApplyAdadelta.
+type ResourceApplyAdadeltaAttr func(optionalAttr)
+
+// ResourceApplyAdadeltaUseLocking sets the optional use_locking attribute to value.
+//
+// value: If True, updating of the var, accum and update_accum tensors will be protected by
+// a lock; otherwise the behavior is undefined, but may exhibit less contention.
+// If not specified, defaults to b:false
+func ResourceApplyAdadeltaUseLocking(value bool) ResourceApplyAdadeltaAttr {
+ return func(m optionalAttr) {
+ m["use_locking"] = value
+ }
+}
+
+// Update '*var' according to the adadelta scheme.
+//
+// accum = rho() * accum + (1 - rho()) * grad.square();
+// update = (update_accum + epsilon).sqrt() * (accum + epsilon()).rsqrt() * grad;
+// update_accum = rho() * update_accum + (1 - rho()) * update.square();
+// var -= update;
+//
+// Arguments:
+// var_: Should be from a Variable().
+// accum: Should be from a Variable().
+// accum_update: Should be from a Variable().
+// lr: Scaling factor. Must be a scalar.
+// rho: Decay factor. Must be a scalar.
+// epsilon: Constant factor. Must be a scalar.
+// grad: The gradient.
+//
+// Returns the created operation.
+func ResourceApplyAdadelta(scope *Scope, var_ tf.Output, accum tf.Output, accum_update tf.Output, lr tf.Output, rho tf.Output, epsilon tf.Output, grad tf.Output, optional ...ResourceApplyAdadeltaAttr) (o *tf.Operation) {
+ if scope.Err() != nil {
+ return
+ }
+ attrs := map[string]interface{}{}
+ for _, a := range optional {
+ a(attrs)
+ }
+ opspec := tf.OpSpec{
+ Type: "ResourceApplyAdadelta",
+ Input: []tf.Input{
+ var_, accum, accum_update, lr, rho, epsilon, grad,
+ },
+ Attrs: attrs,
+ }
+ return scope.AddOperation(opspec)
+}
+
// Shuffle dimensions of x according to a permutation.
//
// The output `y` has the same rank as `x`. The shapes of `x` and `y` satisfy:
@@ -13752,7 +14096,9 @@ func QuantizedBatchNormWithGlobalNormalization(scope *Scope, t tf.Output, t_min
// the tensor.
// tensor_names: Shape `[N]`. The names of the tensors to be saved.
// data: `N` tensors to save.
-func Save(scope *Scope, filename tf.Output, tensor_names tf.Output, data []tf.Output) {
+//
+// Returns the created operation.
+func Save(scope *Scope, filename tf.Output, tensor_names tf.Output, data []tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -13762,7 +14108,7 @@ func Save(scope *Scope, filename tf.Output, tensor_names tf.Output, data []tf.Ou
filename, tensor_names, tf.OutputList(data),
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Generate a glob pattern matching all sharded file names.
@@ -13864,7 +14210,9 @@ func ResourceApplyAdamUseLocking(value bool) ResourceApplyAdamAttr {
// beta2: Momentum factor. Must be a scalar.
// epsilon: Ridge term. Must be a scalar.
// grad: The gradient.
-func ResourceApplyAdam(scope *Scope, var_ tf.Output, m tf.Output, v tf.Output, beta1_power tf.Output, beta2_power tf.Output, lr tf.Output, beta1 tf.Output, beta2 tf.Output, epsilon tf.Output, grad tf.Output, optional ...ResourceApplyAdamAttr) {
+//
+// Returns the created operation.
+func ResourceApplyAdam(scope *Scope, var_ tf.Output, m tf.Output, v tf.Output, beta1_power tf.Output, beta2_power tf.Output, lr tf.Output, beta1 tf.Output, beta2 tf.Output, epsilon tf.Output, grad tf.Output, optional ...ResourceApplyAdamAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -13879,7 +14227,7 @@ func ResourceApplyAdam(scope *Scope, var_ tf.Output, m tf.Output, v tf.Output, b
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Constructs a tensor by tiling a given tensor.
@@ -15353,7 +15701,9 @@ func ResourceSparseApplyAdadeltaUseLocking(value bool) ResourceSparseApplyAdadel
// epsilon: Constant factor. Must be a scalar.
// grad: The gradient.
// indices: A vector of indices into the first dimension of var and accum.
-func ResourceSparseApplyAdadelta(scope *Scope, var_ tf.Output, accum tf.Output, accum_update tf.Output, lr tf.Output, rho tf.Output, epsilon tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyAdadeltaAttr) {
+//
+// Returns the created operation.
+func ResourceSparseApplyAdadelta(scope *Scope, var_ tf.Output, accum tf.Output, accum_update tf.Output, lr tf.Output, rho tf.Output, epsilon tf.Output, grad tf.Output, indices tf.Output, optional ...ResourceSparseApplyAdadeltaAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -15368,7 +15718,7 @@ func ResourceSparseApplyAdadelta(scope *Scope, var_ tf.Output, accum tf.Output,
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Returns which elements of x are NaN.
@@ -15424,6 +15774,63 @@ func Ceil(scope *Scope, x tf.Output) (y tf.Output) {
return op.Output(0)
}
+// Computes exponential of x element-wise. \\(y = e^x\\).
+func Exp(scope *Scope, x tf.Output) (y tf.Output) {
+ if scope.Err() != nil {
+ return
+ }
+ opspec := tf.OpSpec{
+ Type: "Exp",
+ Input: []tf.Input{
+ x,
+ },
+ }
+ op := scope.AddOperation(opspec)
+ return op.Output(0)
+}
+
+// Computes the Max along segments of a tensor.
+//
+// Read [the section on
+// Segmentation](../../api_docs/python/math_ops.md#segmentation) for an explanation
+// of segments.
+//
+// This operator is similar to the [unsorted segment sum operator](../../api_docs/python/math_ops.md#UnsortedSegmentSum).
+// Instead of computing the sum over segments, it computes the maximum
+// such that:
+//
+// \\(output_i = \max_j data_j\\) where max is over `j` such
+// that `segment_ids[j] == i`.
+//
+// If the maximum is empty for a given segment ID `i`, it outputs the smallest possible value for specific numeric type,
+// `output[i] = numeric_limits<T>::min()`.
+//
+// <div style="width:70%; margin:auto; margin-bottom:10px; margin-top:20px;">
+// <img style="width:100%" src="../../images/UnsortedSegmentSum.png" alt>
+// </div>
+//
+// Arguments:
+//
+// segment_ids: A 1-D tensor whose rank is equal to the rank of `data`'s
+// first dimension.
+//
+//
+// Returns Has same shape as data, except for dimension 0 which
+// has size `num_segments`.
+func UnsortedSegmentMax(scope *Scope, data tf.Output, segment_ids tf.Output, num_segments tf.Output) (output tf.Output) {
+ if scope.Err() != nil {
+ return
+ }
+ opspec := tf.OpSpec{
+ Type: "UnsortedSegmentMax",
+ Input: []tf.Input{
+ data, segment_ids, num_segments,
+ },
+ }
+ op := scope.AddOperation(opspec)
+ return op.Output(0)
+}
+
// Returns x + y element-wise.
//
// *NOTE*: `Add` supports broadcasting. `AddN` does not. More about broadcasting
@@ -15775,7 +16182,9 @@ func AssertSummarize(value int64) AssertAttr {
// Arguments:
// condition: The condition to evaluate.
// data: The tensors to print out when condition is false.
-func Assert(scope *Scope, condition tf.Output, data []tf.Output, optional ...AssertAttr) {
+//
+// Returns the created operation.
+func Assert(scope *Scope, condition tf.Output, data []tf.Output, optional ...AssertAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -15790,7 +16199,7 @@ func Assert(scope *Scope, condition tf.Output, data []tf.Output, optional ...Ass
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Computes the power of one value to another.
@@ -16326,80 +16735,6 @@ func MatMul(scope *Scope, a tf.Output, b tf.Output, optional ...MatMulAttr) (pro
return op.Output(0)
}
-// FIFOQueueV2Attr is an optional argument to FIFOQueueV2.
-type FIFOQueueV2Attr func(optionalAttr)
-
-// FIFOQueueV2Shapes sets the optional shapes attribute to value.
-//
-// value: The shape of each component in a value. The length of this attr must
-// be either 0 or the same as the length of component_types. If the length of
-// this attr is 0, the shapes of queue elements are not constrained, and
-// only one element may be dequeued at a time.
-// If not specified, defaults to list:<>
-//
-// REQUIRES: len(value) >= 0
-func FIFOQueueV2Shapes(value []tf.Shape) FIFOQueueV2Attr {
- return func(m optionalAttr) {
- m["shapes"] = value
- }
-}
-
-// FIFOQueueV2Capacity sets the optional capacity attribute to value.
-//
-// value: The upper bound on the number of elements in this queue.
-// Negative numbers mean no limit.
-// If not specified, defaults to i:-1
-func FIFOQueueV2Capacity(value int64) FIFOQueueV2Attr {
- return func(m optionalAttr) {
- m["capacity"] = value
- }
-}
-
-// FIFOQueueV2Container sets the optional container attribute to value.
-//
-// value: If non-empty, this queue is placed in the given container.
-// Otherwise, a default container is used.
-// If not specified, defaults to s:""
-func FIFOQueueV2Container(value string) FIFOQueueV2Attr {
- return func(m optionalAttr) {
- m["container"] = value
- }
-}
-
-// FIFOQueueV2SharedName sets the optional shared_name attribute to value.
-//
-// value: If non-empty, this queue will be shared under the given name
-// across multiple sessions.
-// If not specified, defaults to s:""
-func FIFOQueueV2SharedName(value string) FIFOQueueV2Attr {
- return func(m optionalAttr) {
- m["shared_name"] = value
- }
-}
-
-// A queue that produces elements in first-in first-out order.
-//
-// Arguments:
-// component_types: The type of each component in a value.
-//
-// Returns The handle to the queue.
-func FIFOQueueV2(scope *Scope, component_types []tf.DataType, optional ...FIFOQueueV2Attr) (handle tf.Output) {
- if scope.Err() != nil {
- return
- }
- attrs := map[string]interface{}{"component_types": component_types}
- for _, a := range optional {
- a(attrs)
- }
- opspec := tf.OpSpec{
- Type: "FIFOQueueV2",
-
- Attrs: attrs,
- }
- op := scope.AddOperation(opspec)
- return op.Output(0)
-}
-
// MeanAttr is an optional argument to Mean.
type MeanAttr func(optionalAttr)
@@ -17118,7 +17453,9 @@ func ResourceSparseApplyMomentumUseNesterov(value bool) ResourceSparseApplyMomen
// grad: The gradient.
// indices: A vector of indices into the first dimension of var and accum.
// momentum: Momentum. Must be a scalar.
-func ResourceSparseApplyMomentum(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, grad tf.Output, indices tf.Output, momentum tf.Output, optional ...ResourceSparseApplyMomentumAttr) {
+//
+// Returns the created operation.
+func ResourceSparseApplyMomentum(scope *Scope, var_ tf.Output, accum tf.Output, lr tf.Output, grad tf.Output, indices tf.Output, momentum tf.Output, optional ...ResourceSparseApplyMomentumAttr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -17133,7 +17470,7 @@ func ResourceSparseApplyMomentum(scope *Scope, var_ tf.Output, accum tf.Output,
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Returns the complex conjugate of a complex number.
@@ -17546,7 +17883,9 @@ func QueueEnqueueManyV2TimeoutMs(value int64) QueueEnqueueManyV2Attr {
// handle: The handle to a queue.
// components: One or more tensors from which the enqueued tensors should
// be taken.
-func QueueEnqueueManyV2(scope *Scope, handle tf.Output, components []tf.Output, optional ...QueueEnqueueManyV2Attr) {
+//
+// Returns the created operation.
+func QueueEnqueueManyV2(scope *Scope, handle tf.Output, components []tf.Output, optional ...QueueEnqueueManyV2Attr) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -17561,7 +17900,7 @@ func QueueEnqueueManyV2(scope *Scope, handle tf.Output, components []tf.Output,
},
Attrs: attrs,
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Forwards the input to the output.
@@ -18187,7 +18526,9 @@ func MatrixSolve(scope *Scope, matrix tf.Output, rhs tf.Output, optional ...Matr
// shape_and_slices: shape {N}. The slice specs of the tensors to be saved.
// Empty strings indicate that they are non-partitioned tensors.
// tensors: `N` tensors to save.
-func SaveV2(scope *Scope, prefix tf.Output, tensor_names tf.Output, shape_and_slices tf.Output, tensors []tf.Output) {
+//
+// Returns the created operation.
+func SaveV2(scope *Scope, prefix tf.Output, tensor_names tf.Output, shape_and_slices tf.Output, tensors []tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -18197,7 +18538,7 @@ func SaveV2(scope *Scope, prefix tf.Output, tensor_names tf.Output, shape_and_sl
prefix, tensor_names, shape_and_slices, tf.OutputList(tensors),
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// MatrixTriangularSolveAttr is an optional argument to MatrixTriangularSolve.
@@ -19308,7 +19649,9 @@ func AdjustContrast(scope *Scope, images tf.Output, contrast_factor tf.Output, m
//
// Arguments:
// reader_handle: Handle to a Reader.
-func ReaderResetV2(scope *Scope, reader_handle tf.Output) {
+//
+// Returns the created operation.
+func ReaderResetV2(scope *Scope, reader_handle tf.Output) (o *tf.Operation) {
if scope.Err() != nil {
return
}
@@ -19318,7 +19661,7 @@ func ReaderResetV2(scope *Scope, reader_handle tf.Output) {
reader_handle,
},
}
- scope.AddOperation(opspec)
+ return scope.AddOperation(opspec)
}
// Adjust the hue of one or more images.
@@ -19792,116 +20135,6 @@ func CropAndResize(scope *Scope, image tf.Output, boxes tf.Output, box_ind tf.Ou
return op.Output(0)
}
-// ResourceApplyAdadeltaAttr is an optional argument to ResourceApplyAdadelta.
-type ResourceApplyAdadeltaAttr func(optionalAttr)
-
-// ResourceApplyAdadeltaUseLocking sets the optional use_locking attribute to value.
-//
-// value: If True, updating of the var, accum and update_accum tensors will be protected by
-// a lock; otherwise the behavior is undefined, but may exhibit less contention.
-// If not specified, defaults to b:false
-func ResourceApplyAdadeltaUseLocking(value bool) ResourceApplyAdadeltaAttr {
- return func(m optionalAttr) {
- m["use_locking"] = value
- }
-}
-
-// Update '*var' according to the adadelta scheme.
-//
-// accum = rho() * accum + (1 - rho()) * grad.square();
-// update = (update_accum + epsilon).sqrt() * (accum + epsilon()).rsqrt() * grad;
-// update_accum = rho() * update_accum + (1 - rho()) * update.square();
-// var -= update;
-//
-// Arguments:
-// var_: Should be from a Variable().
-// accum: Should be from a Variable().
-// accum_update: Should be from a Variable().
-// lr: Scaling factor. Must be a scalar.
-// rho: Decay factor. Must be a scalar.
-// epsilon: Constant factor. Must be a scalar.
-// grad: The gradient.
-func ResourceApplyAdadelta(scope *Scope, var_ tf.Output, accum tf.Output, accum_update tf.Output, lr tf.Output, rho tf.Output, epsilon tf.Output, grad tf.Output, optional ...ResourceApplyAdadeltaAttr) {
- if scope.Err() != nil {
- return
- }
- attrs := map[string]interface{}{}
- for _, a := range optional {
- a(attrs)
- }
- opspec := tf.OpSpec{
- Type: "ResourceApplyAdadelta",
- Input: []tf.Input{
- var_, accum, accum_update, lr, rho, epsilon, grad,
- },
- Attrs: attrs,
- }
- scope.AddOperation(opspec)
-}
-
-// NonMaxSuppressionAttr is an optional argument to NonMaxSuppression.
-type NonMaxSuppressionAttr func(optionalAttr)
-
-// NonMaxSuppressionIouThreshold sets the optional iou_threshold attribute to value.
-//
-// value: A float representing the threshold for deciding whether boxes
-// overlap too much with respect to IOU.
-// If not specified, defaults to f:0.5
-func NonMaxSuppressionIouThreshold(value float32) NonMaxSuppressionAttr {
- return func(m optionalAttr) {
- m["iou_threshold"] = value
- }
-}
-
-// Greedily selects a subset of bounding boxes in descending order of score,
-//
-// pruning away boxes that have high intersection-over-union (IOU) overlap
-// with previously selected boxes. Bounding boxes are supplied as
-// [y1, x1, y2, x2], where (y1, x1) and (y2, x2) are the coordinates of any
-// diagonal pair of box corners and the coordinates can be provided as normalized
-// (i.e., lying in the interval [0, 1]) or absolute. Note that this algorithm
-// is agnostic to where the origin is in the coordinate system. Note that this
-// algorithm is invariant to orthogonal transformations and translations
-// of the coordinate system; thus translating or reflections of the coordinate
-// system result in the same boxes being selected by the algorithm.
-//
-// The output of this operation is a set of integers indexing into the input
-// collection of bounding boxes representing the selected boxes. The bounding
-// box coordinates corresponding to the selected indices can then be obtained
-// using the `tf.gather operation`. For example:
-//
-// selected_indices = tf.image.non_max_suppression(
-// boxes, scores, max_output_size, iou_threshold)
-// selected_boxes = tf.gather(boxes, selected_indices)
-//
-// Arguments:
-// boxes: A 2-D float tensor of shape `[num_boxes, 4]`.
-// scores: A 1-D float tensor of shape `[num_boxes]` representing a single
-// score corresponding to each box (each row of boxes).
-// max_output_size: A scalar integer tensor representing the maximum number of
-// boxes to be selected by non max suppression.
-//
-// Returns A 1-D integer tensor of shape `[M]` representing the selected
-// indices from the boxes tensor, where `M <= max_output_size`.
-func NonMaxSuppression(scope *Scope, boxes tf.Output, scores tf.Output, max_output_size tf.Output, optional ...NonMaxSuppressionAttr) (selected_indices tf.Output) {
- if scope.Err() != nil {
- return
- }
- attrs := map[string]interface{}{}
- for _, a := range optional {
- a(attrs)
- }
- opspec := tf.OpSpec{
- Type: "NonMaxSuppression",
- Input: []tf.Input{
- boxes, scores, max_output_size,
- },
- Attrs: attrs,
- }
- op := scope.AddOperation(opspec)
- return op.Output(0)
-}
-
// Returns x / y element-wise for integer types.
//
// Truncation designates that negative numbers will round fractional quantities
@@ -19975,32 +20208,3 @@ func RestoreV2(scope *Scope, prefix tf.Output, tensor_names tf.Output, shape_and
}
return tensors
}
-
-// Produces the max pool of the input tensor for quantized types.
-//
-// Arguments:
-// input: The 4D (batch x rows x cols x depth) Tensor to MaxReduce over.
-// min_input: The float value that the lowest quantized input value represents.
-// max_input: The float value that the highest quantized input value represents.
-// ksize: The size of the window for each dimension of the input tensor.
-// The length must be 4 to match the number of dimensions of the input.
-// strides: The stride of the sliding window for each dimension of the input
-// tensor. The length must be 4 to match the number of dimensions of the input.
-// padding: The type of padding algorithm to use.
-//
-// Returns The float value that the lowest quantized output value represents.The float value that the highest quantized output value represents.
-func QuantizedMaxPool(scope *Scope, input tf.Output, min_input tf.Output, max_input tf.Output, ksize []int64, strides []int64, padding string) (output tf.Output, min_output tf.Output, max_output tf.Output) {
- if scope.Err() != nil {
- return
- }
- attrs := map[string]interface{}{"ksize": ksize, "strides": strides, "padding": padding}
- opspec := tf.OpSpec{
- Type: "QuantizedMaxPool",
- Input: []tf.Input{
- input, min_input, max_input,
- },
- Attrs: attrs,
- }
- op := scope.AddOperation(opspec)
- return op.Output(0), op.Output(1), op.Output(2)
-}
diff --git a/tensorflow/go/operation.go b/tensorflow/go/operation.go
index df41c40a2b..9c035e5e18 100644
--- a/tensorflow/go/operation.go
+++ b/tensorflow/go/operation.go
@@ -75,6 +75,11 @@ type Output struct {
Index int
}
+// DataType returns the type of elements in the tensor produced by p.
+func (p Output) DataType() DataType {
+ return DataType(C.TF_OperationOutputType(p.c()))
+}
+
// Shape returns the (possibly incomplete) shape of the tensor produced p.
func (p Output) Shape() Shape {
status := newStatus()
diff --git a/tensorflow/go/operation_test.go b/tensorflow/go/operation_test.go
index 32e2989179..a5e36f6683 100644
--- a/tensorflow/go/operation_test.go
+++ b/tensorflow/go/operation_test.go
@@ -96,19 +96,22 @@ func TestOperationShapeAttribute(t *testing.T) {
// If and when the API to get attributes is added, check that here.
}
-func TestOutputShape(t *testing.T) {
+func TestOutputDataTypeAndShape(t *testing.T) {
graph := NewGraph()
testdata := []struct {
Value interface{}
Shape []int64
+ dtype DataType
}{
{ // Scalar
int64(0),
[]int64{},
+ Int64,
},
{ // Vector
- []int64{1, 2, 3},
+ []int32{1, 2, 3},
[]int64{3},
+ Int32,
},
{ // Matrix
[][]float64{
@@ -116,6 +119,7 @@ func TestOutputShape(t *testing.T) {
{4, 5, 6},
},
[]int64{2, 3},
+ Double,
},
}
for idx, test := range testdata {
@@ -124,6 +128,9 @@ func TestOutputShape(t *testing.T) {
if err != nil {
t.Fatal(err)
}
+ if got, want := c.DataType(), test.dtype; got != want {
+ t.Errorf("Got DataType %v, want %v", got, want)
+ }
shape := c.Shape()
if got, want := shape.NumDimensions(), len(test.Shape); got != want {
t.Fatalf("Got a shape with %d dimensions, want %d", got, want)
diff --git a/tensorflow/go/session.go b/tensorflow/go/session.go
index dd629441ef..c29b6e0b76 100644
--- a/tensorflow/go/session.go
+++ b/tensorflow/go/session.go
@@ -59,6 +59,44 @@ func NewSession(graph *Graph, options *SessionOptions) (*Session, error) {
return s, nil
}
+// LoadSavedModel creates a new Session from a model previously exported to a
+// directory on disk.
+//
+// Exported models contain a set of graphs and variable values. Tags in the
+// model identify a single graph. LoadSessionFromSavedModel initializes a
+// session with the identified graph and with variables initialized to saved
+// values.
+//
+// The tensorflow package currently does not have the ability to export a model
+// to a directory from Go. This function thus currently targets loading models
+// exported in other languages, such as using tf.saved_model.builder in Python.
+// See:
+// https://www.tensorflow.org/code/tensorflow/python/saved_model/
+func LoadSavedModel(exportDir string, tags []string, options *SessionOptions) (*Session, *Graph, error) {
+ status := newStatus()
+ cOpt := options.c()
+ cExportDir := C.CString(exportDir)
+ cTags := make([]*C.char, len(tags))
+ for i := range tags {
+ cTags[i] = C.CString(tags[i])
+ }
+ graph := NewGraph()
+ // TODO(jhseu): Add support for run_options and meta_graph_def.
+ cSess := C.TF_LoadSessionFromSavedModel(cOpt, nil, cExportDir, (**C.char)(unsafe.Pointer(&cTags[0])), C.int(len(cTags)), graph.c, nil, status.c)
+ for i := range cTags {
+ C.free(unsafe.Pointer(cTags[i]))
+ }
+ C.free(unsafe.Pointer(cExportDir))
+ C.TF_DeleteSessionOptions(cOpt)
+
+ if err := status.Err(); err != nil {
+ return nil, nil, err
+ }
+ s := &Session{c: cSess}
+ runtime.SetFinalizer(s, func(s *Session) { s.Close() })
+ return s, graph, nil
+}
+
// Run the graph with the associated session starting with the supplied inputs.
// inputs and outputs may be set to nil. Runs, but does not return Tensors
// for operations specified in targets.
diff --git a/tensorflow/go/session_test.go b/tensorflow/go/session_test.go
index 14ecca402b..ccd7d85295 100644
--- a/tensorflow/go/session_test.go
+++ b/tensorflow/go/session_test.go
@@ -181,3 +181,15 @@ func TestConcurrency(t *testing.T) {
t.Errorf("Close() 2: %v", err)
}
}
+
+func TestSavedModel(t *testing.T) {
+ _, graph, err := LoadSavedModel("../cc/saved_model/testdata/half_plus_two/00000123", []string{"serve"}, nil)
+ if err != nil {
+ t.Fatalf("LoadSavedModel(): %v", err)
+ }
+ if op := graph.Operation("y"); op == nil {
+ t.Fatalf("\"y\" not found in graph")
+ }
+ // TODO(jhseu): half_plus_two has a tf.Example proto dependency to run. Add a
+ // more thorough test when the generated protobufs are available.
+}
diff --git a/tensorflow/python/debug/BUILD b/tensorflow/python/debug/BUILD
index 339a6a72e0..4a83e33ae1 100644
--- a/tensorflow/python/debug/BUILD
+++ b/tensorflow/python/debug/BUILD
@@ -436,6 +436,7 @@ cuda_py_test(
"//tensorflow/python:platform_test",
"//tensorflow/python:variables",
],
+ tags = ["notsan"],
)
py_test(
diff --git a/tensorflow/python/debug/debug_data.py b/tensorflow/python/debug/debug_data.py
index 110ce37607..9b1796eb49 100644
--- a/tensorflow/python/debug/debug_data.py
+++ b/tensorflow/python/debug/debug_data.py
@@ -19,6 +19,7 @@ from __future__ import division
from __future__ import print_function
import collections
+import json
import os
import numpy as np
@@ -31,6 +32,7 @@ from tensorflow.python.platform import gfile
METADATA_FILE_PREFIX = "_tfdbg_"
+CORE_METADATA_TAG = "core_metadata_"
GRAPH_FILE_TAG = "graph_"
FETCHES_INFO_FILE_TAG = "fetches_info_"
FEED_KEYS_INFO_FILE_TAG = "feed_keys_info_"
@@ -110,6 +112,10 @@ def parse_node_or_tensor_name(name):
return name, None
+def _is_core_metadata_file(file_name):
+ return file_name.startswith(METADATA_FILE_PREFIX + CORE_METADATA_TAG)
+
+
def _is_graph_file(file_name):
return file_name.startswith(METADATA_FILE_PREFIX + GRAPH_FILE_TAG)
@@ -274,6 +280,20 @@ def has_inf_or_nan(datum, tensor):
return False
+def extract_core_metadata_from_event_proto(event):
+ json_metadata = json.loads(event.log_message.message)
+ core_metadata = collections.namedtuple("CoreMetadata", [
+ "global_step", "session_run_count", "executor_step_count", "input_names",
+ "output_names", "target_nodes"
+ ])
+ return core_metadata(json_metadata["global_step"],
+ json_metadata["session_run_count"],
+ json_metadata["executor_step_count"],
+ json_metadata["input_names"],
+ json_metadata["output_names"],
+ json_metadata["target_nodes"])
+
+
class DebugTensorDatum(object):
"""A single tensor dumped by TensorFlow Debugger (tfdbg).
@@ -455,6 +475,7 @@ class DebugDumpDir(object):
if not gfile.IsDirectory(dump_root):
raise IOError("Dump root directory %s does not exist" % dump_root)
+ self._core_metadata = None
self._load_dumps(dump_root)
self._create_tensor_watch_maps()
self._load_partition_graphs(partition_graphs, validate)
@@ -498,6 +519,9 @@ class DebugDumpDir(object):
for root, _, files in gfile.Walk(self._dump_root):
for f in files:
if f.startswith(METADATA_FILE_PREFIX):
+ if _is_core_metadata_file(f):
+ self._load_core_metadata(os.path.join(self._dump_root, root, f))
+
if _is_graph_file(f):
self._dump_graph_file_paths.append(
os.path.join(self._dump_root, root, f))
@@ -526,6 +550,12 @@ class DebugDumpDir(object):
else:
self._t0 = None
+ def _load_core_metadata(self, event_file_path):
+ event = event_pb2.Event()
+ with gfile.Open(event_file_path, "rb") as f:
+ event.ParseFromString(f.read())
+ self._core_metadata = extract_core_metadata_from_event_proto(event)
+
def _dump_file_name_to_datum(self, dir_name, file_name):
"""Obtain a DebugTensorDatum from the directory and file name.
@@ -588,6 +618,37 @@ class DebugDumpDir(object):
self._node_traceback[op.name] = op.traceback
@property
+ def core_metadata(self):
+ """Metadata about the `Session.run()` call from the core runtime.
+
+ Of the three counters available in the return value, `global_step` is
+ supplied by the caller of the debugged `Session.run()`, while
+ `session_run_count` and `executor_step_count` are determined by the state
+ of the core runtime, automatically. For the same fetch list, feed keys and
+ debug tensor watch options, the same executor will be used and
+ `executor_step_count` should increase by one at a time. However, runs with
+ different fetch lists, feed keys and debug_tensor watch options that all
+ share the same `Session` object can lead to gaps in `session_run_count`.
+
+ Returns:
+ If core metadata are loaded, a `namedtuple` with the fields:
+ `global_step`: A global step count supplied by the caller of
+ `Session.run()`. It is optional to the caller. If the caller did not
+ supply this parameter, its value will be -1.
+ `session_run_count`: A counter for Run() calls to the underlying
+ TensorFlow `Session` object.
+ `executor_step_count`: A counter for invocations of a given runtime
+ executor. The same executor is re-used for the same fetched tensors,
+ target nodes, input feed keys and debug tensor watch options.
+ `input_names`: Names of the input (feed) Tensors.
+ `output_names`: Names of the output (fetched) Tensors.
+ `target_nodes`: Names of the target nodes.
+ If the core metadata have not been loaded, `None`.
+ """
+
+ return self._core_metadata
+
+ @property
def dumped_tensor_data(self):
return self._dump_tensor_data
diff --git a/tensorflow/python/debug/debug_utils.py b/tensorflow/python/debug/debug_utils.py
index 3d6d5ad447..2b8e95b99e 100644
--- a/tensorflow/python/debug/debug_utils.py
+++ b/tensorflow/python/debug/debug_utils.py
@@ -27,7 +27,8 @@ def add_debug_tensor_watch(run_options,
node_name,
output_slot=0,
debug_ops="DebugIdentity",
- debug_urls=None):
+ debug_urls=None,
+ global_step=-1):
"""Add watch on a `Tensor` to `RunOptions`.
N.B.: Under certain circumstances, the `Tensor` may not be actually watched
@@ -42,9 +43,12 @@ def add_debug_tensor_watch(run_options,
`list` of `str` with only one element.
debug_urls: (`str` or `list` of `str`) URL(s) to send debug values to,
e.g., `file:///tmp/tfdbg_dump_1`, `grpc://localhost:12345`.
+ global_step: (`int`) Optional global_step count for this debug tensor
+ watch.
"""
watch_opts = run_options.debug_options.debug_tensor_watch_opts
+ run_options.debug_options.global_step = global_step
watch = watch_opts.add()
watch.node_name = node_name
@@ -67,7 +71,8 @@ def watch_graph(run_options,
debug_ops="DebugIdentity",
debug_urls=None,
node_name_regex_whitelist=None,
- op_type_regex_whitelist=None):
+ op_type_regex_whitelist=None,
+ global_step=-1):
"""Add debug watches to `RunOptions` for a TensorFlow graph.
To watch all `Tensor`s on the graph, let both `node_name_regex_whitelist`
@@ -93,6 +98,8 @@ def watch_graph(run_options,
are set, the two filtering operations will occur in a logical `AND`
relation. In other words, a node will be included if and only if it
hits both whitelists.
+ global_step: (`int`) Optional global_step count for this debug tensor
+ watch.
"""
if isinstance(debug_ops, str):
@@ -128,7 +135,8 @@ def watch_graph(run_options,
node_name,
output_slot=slot,
debug_ops=debug_ops,
- debug_urls=debug_urls)
+ debug_urls=debug_urls,
+ global_step=global_step)
def watch_graph_with_blacklists(run_options,
@@ -136,7 +144,8 @@ def watch_graph_with_blacklists(run_options,
debug_ops="DebugIdentity",
debug_urls=None,
node_name_regex_blacklist=None,
- op_type_regex_blacklist=None):
+ op_type_regex_blacklist=None,
+ global_step=-1):
"""Add debug tensor watches, blacklisting nodes and op types.
This is similar to `watch_graph()`, but the node names and op types are
@@ -161,6 +170,8 @@ def watch_graph_with_blacklists(run_options,
relation. In other words, a node will be excluded if it hits either of
the two blacklists; a node will be included if and only if it hits
neither of the blacklists.
+ global_step: (`int`) Optional global_step count for this debug tensor
+ watch.
"""
if isinstance(debug_ops, str):
@@ -196,4 +207,5 @@ def watch_graph_with_blacklists(run_options,
node_name,
output_slot=slot,
debug_ops=debug_ops,
- debug_urls=debug_urls)
+ debug_urls=debug_urls,
+ global_step=global_step)
diff --git a/tensorflow/python/debug/session_debug_file_test.py b/tensorflow/python/debug/session_debug_file_test.py
index 8acd3975b7..ca403e0017 100644
--- a/tensorflow/python/debug/session_debug_file_test.py
+++ b/tensorflow/python/debug/session_debug_file_test.py
@@ -18,6 +18,8 @@ from __future__ import division
from __future__ import print_function
import os
+import shutil
+import tempfile
from tensorflow.core.protobuf import config_pb2
from tensorflow.python.client import session
@@ -25,6 +27,7 @@ from tensorflow.python.debug import debug_data
from tensorflow.python.debug import debug_utils
from tensorflow.python.debug import session_debug_testlib
from tensorflow.python.framework import constant_op
+from tensorflow.python.framework import ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import variables
from tensorflow.python.platform import googletest
@@ -108,5 +111,25 @@ class SessionDebugTest(session_debug_testlib.SessionDebugTestBase):
dump.get_rel_timestamps("%s/read" % v_name, 0,
"DebugIdentity")[0], 0)
+
+class SessionDebugConcurrentTest(
+ session_debug_testlib.DebugConcurrentRunCallsTest):
+
+ def setUp(self):
+ self._num_concurrent_runs = 3
+ self._dump_roots = []
+ for _ in range(self._num_concurrent_runs):
+ self._dump_roots.append(tempfile.mkdtemp())
+
+ def tearDown(self):
+ ops.reset_default_graph()
+ for dump_root in self._dump_roots:
+ if os.path.isdir(dump_root):
+ shutil.rmtree(dump_root)
+
+ def _get_concurrent_debug_urls(self):
+ return [("file://%s" % dump_root) for dump_root in self._dump_roots]
+
+
if __name__ == "__main__":
googletest.main()
diff --git a/tensorflow/python/debug/session_debug_testlib.py b/tensorflow/python/debug/session_debug_testlib.py
index ba453ef7e0..0306ace88c 100644
--- a/tensorflow/python/debug/session_debug_testlib.py
+++ b/tensorflow/python/debug/session_debug_testlib.py
@@ -18,14 +18,18 @@ from __future__ import division
from __future__ import print_function
import collections
+import functools
+import glob
import os
import shutil
import tempfile
+import threading
import numpy as np
from six.moves import xrange # pylint: disable=redefined-builtin
from tensorflow.core.protobuf import config_pb2
+from tensorflow.core.util import event_pb2
from tensorflow.python.client import session
from tensorflow.python.debug import debug_data
from tensorflow.python.debug import debug_utils
@@ -134,6 +138,15 @@ class SessionDebugTestBase(test_util.TensorFlowTestCase):
results = self._generate_dump_from_simple_addition_graph()
self.assertTrue(results.dump.loaded_partition_graphs())
+ # Since global_step is not explicitly specified, it should take its default
+ # value: -1.
+ self.assertEqual(-1, results.dump.core_metadata.global_step)
+ self.assertGreaterEqual(results.dump.core_metadata.session_run_count, 0)
+ self.assertGreaterEqual(results.dump.core_metadata.executor_step_count, 0)
+ self.assertEqual([], results.dump.core_metadata.input_names)
+ self.assertEqual([results.w.name], results.dump.core_metadata.output_names)
+ self.assertEqual([], results.dump.core_metadata.target_nodes)
+
# Verify the dumped tensor values for u and v.
self.assertEqual(2, results.dump.size)
@@ -869,6 +882,63 @@ class SessionDebugTestBase(test_util.TensorFlowTestCase):
self.assertAllClose([0, 0, 1, 2, 2],
unique_x_slot_1_dumps[0].get_tensor())
+ def testSuccessiveDebuggingRunsIncreasesCounters(self):
+ """Test repeated Session.run() calls with debugger increments counters."""
+
+ with session.Session() as sess:
+ ph = array_ops.placeholder(dtypes.float32, name="successive/ph")
+ x = array_ops.transpose(ph, name="mismatch/x")
+ y = array_ops.squeeze(ph, name="mismatch/y")
+
+ run_options = config_pb2.RunOptions(output_partition_graphs=True)
+ debug_utils.watch_graph(
+ run_options, sess.graph, debug_urls=self._debug_urls(), global_step=1)
+
+ sess.run(x, feed_dict={ph: np.array([[7.0, 8.0]])}, options=run_options)
+ dump1 = debug_data.DebugDumpDir(self._dump_root)
+ self.assertEqual(1, dump1.core_metadata.global_step)
+ self.assertGreaterEqual(dump1.core_metadata.session_run_count, 0)
+ self.assertEqual(0, dump1.core_metadata.executor_step_count)
+ self.assertEqual([ph.name], dump1.core_metadata.input_names)
+ self.assertEqual([x.name], dump1.core_metadata.output_names)
+ self.assertEqual([], dump1.core_metadata.target_nodes)
+ shutil.rmtree(self._dump_root)
+
+ run_options = config_pb2.RunOptions(output_partition_graphs=True)
+ debug_utils.watch_graph(
+ run_options, sess.graph, debug_urls=self._debug_urls(), global_step=2)
+
+ # Calling run() with the same feed, same output and same debug watch
+ # options should increment both session_run_count and
+ # executor_step_count.
+ sess.run(x, feed_dict={ph: np.array([[7.0, 8.0]])}, options=run_options)
+ dump2 = debug_data.DebugDumpDir(self._dump_root)
+ self.assertEqual(2, dump2.core_metadata.global_step)
+ self.assertEqual(dump1.core_metadata.session_run_count + 1,
+ dump2.core_metadata.session_run_count)
+ self.assertEqual(dump1.core_metadata.executor_step_count + 1,
+ dump2.core_metadata.executor_step_count)
+ self.assertEqual([ph.name], dump2.core_metadata.input_names)
+ self.assertEqual([x.name], dump2.core_metadata.output_names)
+ self.assertEqual([], dump2.core_metadata.target_nodes)
+ shutil.rmtree(self._dump_root)
+
+ run_options = config_pb2.RunOptions(output_partition_graphs=True)
+ debug_utils.watch_graph(
+ run_options, sess.graph, debug_urls=self._debug_urls(), global_step=3)
+
+ # Calling run() with a different output should increment
+ # session_run_count, but not executor_step_count.
+ sess.run(y, feed_dict={ph: np.array([[7.0, 8.0]])}, options=run_options)
+ dump3 = debug_data.DebugDumpDir(self._dump_root)
+ self.assertEqual(3, dump3.core_metadata.global_step)
+ self.assertEqual(dump2.core_metadata.session_run_count + 1,
+ dump3.core_metadata.session_run_count)
+ self.assertEqual(0, dump3.core_metadata.executor_step_count)
+ self.assertEqual([ph.name], dump3.core_metadata.input_names)
+ self.assertEqual([y.name], dump3.core_metadata.output_names)
+ self.assertEqual([], dump3.core_metadata.target_nodes)
+
def testDebuggingDuringOpError(self):
"""Test the debug tensor dumping when error occurs in graph runtime."""
@@ -894,6 +964,12 @@ class SessionDebugTestBase(test_util.TensorFlowTestCase):
dump = debug_data.DebugDumpDir(self._dump_root)
+ self.assertGreaterEqual(dump.core_metadata.session_run_count, 0)
+ self.assertGreaterEqual(dump.core_metadata.executor_step_count, 0)
+ self.assertEqual([ph.name], dump.core_metadata.input_names)
+ self.assertEqual([y.name], dump.core_metadata.output_names)
+ self.assertEqual([], dump.core_metadata.target_nodes)
+
# Despite the fact that the run() call errored out and partition_graphs
# are not available via run_metadata, the partition graphs should still
# have been loaded from the dump directory.
@@ -1045,5 +1121,96 @@ class SessionDebugTestBase(test_util.TensorFlowTestCase):
self.assertIsInstance(trace, tuple)
+class DebugConcurrentRunCallsTest(test_util.TensorFlowTestCase):
+ """Test for debugging concurrent Session.run() calls."""
+
+ def _get_concurrent_debug_urls(self):
+ """Abstract method to generate debug URLs for concurrent debugged runs."""
+ raise NotImplementedError(
+ "_get_concurrent_debug_urls is not implemented in the base test class")
+
+ def testDebugConcurrentVariableUpdates(self):
+ if test.is_gpu_available():
+ self.skipTest("No testing concurrent runs on a single GPU.")
+
+ with session.Session() as sess:
+ v = variables.Variable(30.0, name="v")
+ constants = []
+ for i in xrange(self._num_concurrent_runs):
+ constants.append(constant_op.constant(1.0, name="c%d" % i))
+ incs = [
+ state_ops.assign_add(
+ v, c, use_locking=True, name=("inc%d" % i))
+ for (i, c) in enumerate(constants)
+ ]
+ sess.run(v.initializer)
+
+ concurrent_debug_urls = self._get_concurrent_debug_urls()
+
+ def inc_job(index):
+ run_options = config_pb2.RunOptions(output_partition_graphs=True)
+ debug_utils.watch_graph(
+ run_options, sess.graph, debug_urls=concurrent_debug_urls[index])
+ for _ in xrange(100):
+ sess.run(incs[index], options=run_options)
+
+ inc_threads = []
+ for index in xrange(self._num_concurrent_runs):
+ inc_thread = threading.Thread(target=functools.partial(inc_job, index))
+ inc_thread.start()
+ inc_threads.append(inc_thread)
+ for inc_thread in inc_threads:
+ inc_thread.join()
+
+ self.assertAllClose(30.0 + 1.0 * self._num_concurrent_runs * 100,
+ sess.run(v))
+
+ all_session_run_counts = []
+ for index in xrange(self._num_concurrent_runs):
+ dump = debug_data.DebugDumpDir(self._dump_roots[index])
+ self.assertTrue(dump.loaded_partition_graphs())
+
+ v_data = dump.get_tensors("v", 0, "DebugIdentity")
+ self.assertEqual(100, len(v_data))
+
+ # Examine all the core metadata files
+ core_metadata_files = glob.glob(
+ os.path.join(self._dump_roots[index], "_tfdbg_core*"))
+
+ timestamps = []
+ session_run_counts = []
+ executor_step_counts = []
+ for core_metadata_file in core_metadata_files:
+ with open(core_metadata_file, "rb") as f:
+ event = event_pb2.Event()
+ event.ParseFromString(f.read())
+ core_metadata = (
+ debug_data.extract_core_metadata_from_event_proto(event))
+ timestamps.append(event.wall_time)
+ session_run_counts.append(core_metadata.session_run_count)
+ executor_step_counts.append(core_metadata.executor_step_count)
+
+ all_session_run_counts.extend(session_run_counts)
+
+ # Assert that executor_step_count increases by one at a time.
+ executor_step_counts = zip(timestamps, executor_step_counts)
+ executor_step_counts = sorted(executor_step_counts, key=lambda x: x[0])
+ for i in xrange(len(executor_step_counts) - 1):
+ self.assertEquals(executor_step_counts[i][1] + 1,
+ executor_step_counts[i + 1][1])
+
+ # Assert that session_run_count increase monotonically.
+ session_run_counts = zip(timestamps, session_run_counts)
+ session_run_counts = sorted(session_run_counts, key=lambda x: x[0])
+ for i in xrange(len(session_run_counts) - 1):
+ self.assertGreater(session_run_counts[i + 1][1],
+ session_run_counts[i][1])
+
+ # Assert that the session_run_counts from the concurrent run() calls are
+ # all unique.
+ self.assertEqual(len(all_session_run_counts),
+ len(set(all_session_run_counts)))
+
+
if __name__ == "__main__":
googletest.main()
diff --git a/tensorflow/python/framework/constant_op.py b/tensorflow/python/framework/constant_op.py
index 3bcc537779..05a520850e 100644
--- a/tensorflow/python/framework/constant_op.py
+++ b/tensorflow/python/framework/constant_op.py
@@ -96,6 +96,7 @@ print(sess.run(var))
@@random_crop
@@multinomial
@@random_gamma
+@@random_poisson
@@set_random_seed
"""
diff --git a/tensorflow/python/kernel_tests/BUILD b/tensorflow/python/kernel_tests/BUILD
index 119cffe0e9..2ecbd08992 100644
--- a/tensorflow/python/kernel_tests/BUILD
+++ b/tensorflow/python/kernel_tests/BUILD
@@ -2113,6 +2113,21 @@ cuda_py_test(
)
cuda_py_test(
+ name = "random_poisson_test",
+ size = "medium",
+ srcs = ["random_poisson_test.py"],
+ additional_deps = [
+ "//third_party/py/numpy",
+ "//tensorflow/python:array_ops",
+ "//tensorflow/python:client_testlib",
+ "//tensorflow/python:framework",
+ "//tensorflow/python:framework_for_generated_wrappers",
+ "//tensorflow/python:platform",
+ "//tensorflow/python:random_ops",
+ ],
+)
+
+cuda_py_test(
name = "rnn_test",
size = "medium",
srcs = ["rnn_test.py"],
diff --git a/tensorflow/python/kernel_tests/parsing_ops_test.py b/tensorflow/python/kernel_tests/parsing_ops_test.py
index b66d271f3c..c19d5a9536 100644
--- a/tensorflow/python/kernel_tests/parsing_ops_test.py
+++ b/tensorflow/python/kernel_tests/parsing_ops_test.py
@@ -92,6 +92,7 @@ class ParseExampleTest(test.TestCase):
expected_err[1]):
out = parsing_ops.parse_example(**kwargs)
sess.run(flatten_values_tensors_or_sparse(out.values()))
+ return
else:
# Returns dict w/ Tensors and SparseTensors.
out = parsing_ops.parse_example(**kwargs)
@@ -636,6 +637,103 @@ class ParseExampleTest(test.TestCase):
}
}, expected_output)
+ def testSerializedContainingVarLenDense(self):
+ aname = "a"
+ bname = "b"
+ cname = "c"
+ dname = "d"
+ example_names = ["in1", "in2", "in3", "in4"]
+ original = [
+ example(features=features({
+ cname: int64_feature([2]),
+ })),
+ example(features=features({
+ aname: float_feature([1, 1]),
+ bname: bytes_feature([b"b0_str", b"b1_str"]),
+ })),
+ example(features=features({
+ aname: float_feature([-1, -1, 2, 2]),
+ bname: bytes_feature([b"b1"]),
+ })),
+ example(features=features({
+ aname: float_feature([]),
+ cname: int64_feature([3]),
+ })),
+ ]
+
+ serialized = [m.SerializeToString() for m in original]
+
+ expected_output = {
+ aname:
+ np.array(
+ [
+ [0, 0, 0, 0],
+ [1, 1, 0, 0],
+ [-1, -1, 2, 2],
+ [0, 0, 0, 0],
+ ],
+ dtype=np.float32).reshape(4, 2, 2, 1),
+ bname:
+ np.array(
+ [["", ""], ["b0_str", "b1_str"], ["b1", ""], ["", ""]],
+ dtype=bytes).reshape(4, 2, 1, 1, 1),
+ cname:
+ np.array([2, 0, 0, 3], dtype=np.int64).reshape(4, 1),
+ dname:
+ np.empty(shape=(4, 0), dtype=bytes),
+ }
+
+ self._test({
+ "example_names": example_names,
+ "serialized": ops.convert_to_tensor(serialized),
+ "features": {
+ aname:
+ parsing_ops.FixedLenFeature((None, 2, 1), dtype=dtypes.float32),
+ bname:
+ parsing_ops.FixedLenFeature(
+ (None, 1, 1, 1), dtype=dtypes.string),
+ cname:
+ parsing_ops.FixedLenFeature((None,), dtype=dtypes.int64),
+ dname:
+ parsing_ops.FixedLenFeature((None,), dtype=dtypes.string),
+ }
+ }, expected_output)
+
+ # Change number of required values so the inputs are not a
+ # multiple of this size.
+ self._test(
+ {
+ "example_names": example_names,
+ "serialized": ops.convert_to_tensor(serialized),
+ "features": {
+ aname:
+ parsing_ops.FixedLenFeature(
+ (None, 2, 1), dtype=dtypes.float32),
+ bname:
+ parsing_ops.FixedLenFeature(
+ (None, 2, 1, 1), dtype=dtypes.string),
+ }
+ },
+ expected_err=(
+ errors_impl.OpError, "Name: in3, Key: b, Index: 2. "
+ "Number of bytes values is not a multiple of stride length."))
+
+ self._test(
+ {
+ "example_names": example_names,
+ "serialized": ops.convert_to_tensor(serialized),
+ "features": {
+ aname:
+ parsing_ops.FixedLenFeature(
+ (None, 2, 1), dtype=dtypes.float32, default_value=[]),
+ bname:
+ parsing_ops.FixedLenFeature(
+ (None, 2, 1, 1), dtype=dtypes.string),
+ }
+ },
+ expected_err=(ValueError,
+ "Cannot reshape a tensor with 0 elements to shape"))
+
class ParseSingleExampleTest(test.TestCase):
diff --git a/tensorflow/python/kernel_tests/random_poisson_test.py b/tensorflow/python/kernel_tests/random_poisson_test.py
new file mode 100644
index 0000000000..01281b7bd0
--- /dev/null
+++ b/tensorflow/python/kernel_tests/random_poisson_test.py
@@ -0,0 +1,178 @@
+# Copyright 2016 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.
+# ==============================================================================
+"""Tests for tensorflow.ops.random_ops.random_poisson."""
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
+import numpy as np
+from six.moves import xrange # pylint: disable=redefined-builtin
+
+from tensorflow.python.framework import dtypes
+from tensorflow.python.framework import ops
+from tensorflow.python.ops import array_ops
+from tensorflow.python.ops import random_ops
+from tensorflow.python.platform import test
+from tensorflow.python.platform import tf_logging
+
+
+class RandomPoissonTest(test.TestCase):
+ """This is a large test due to the moments computation taking some time."""
+
+ def _Sampler(self, num, lam, dtype, use_gpu, seed=None):
+
+ def func():
+ with self.test_session(use_gpu=use_gpu, graph=ops.Graph()) as sess:
+ rng = random_ops.random_poisson(lam, [num], dtype=dtype, seed=seed)
+ ret = np.empty([10, num])
+ for i in xrange(10):
+ ret[i, :] = sess.run(rng)
+ return ret
+
+ return func
+
+ # TODO(srvasude): Factor this out along with the corresponding moment testing
+ # method in random_gamma_test into a single library.
+ def testMoments(self):
+ try:
+ from scipy import stats # pylint: disable=g-import-not-at-top
+ except ImportError as e:
+ tf_logging.warn("Cannot test moments: %s", e)
+ return
+ # The moments test is a z-value test. This is the largest z-value
+ # we want to tolerate. Since the z-test approximates a unit normal
+ # distribution, it should almost definitely never exceed 6.
+ z_limit = 6.0
+ for dt in dtypes.float16, dtypes.float32, dtypes.float64:
+ # Test when lam < 10 and when lam >= 10
+ for stride in 0, 4, 10:
+ for lam in (3., 20):
+ max_moment = 5
+ sampler = self._Sampler(10000, lam, dt, use_gpu=False, seed=12345)
+ moments = [0] * (max_moment + 1)
+ moments_sample_count = [0] * (max_moment + 1)
+ x = np.array(sampler().flat) # sampler does 10x samples
+ for k in range(len(x)):
+ moment = 1.
+ for i in range(max_moment + 1):
+ index = k + i * stride
+ if index >= len(x):
+ break
+ moments[i] += moment
+ moments_sample_count[i] += 1
+ moment *= x[index]
+ for i in range(max_moment + 1):
+ moments[i] /= moments_sample_count[i]
+ for i in range(1, max_moment + 1):
+ g = stats.poisson(lam)
+ if stride == 0:
+ moments_i_mean = g.moment(i)
+ moments_i_squared = g.moment(2 * i)
+ else:
+ moments_i_mean = pow(g.moment(1), i)
+ moments_i_squared = pow(g.moment(2), i)
+ moments_i_var = (
+ moments_i_squared - moments_i_mean * moments_i_mean)
+ # Assume every operation has a small numerical error.
+ # It takes i multiplications to calculate one i-th moment.
+ error_per_moment = i * 1e-6
+ total_variance = (
+ moments_i_var / moments_sample_count[i] + error_per_moment)
+ if not total_variance:
+ total_variance = 1e-10
+ # z_test is approximately a unit normal distribution.
+ z_test = abs(
+ (moments[i] - moments_i_mean) / np.sqrt(total_variance))
+ self.assertLess(z_test, z_limit)
+
+ # Checks that the CPU and GPU implementation returns the same results,
+ # given the same random seed
+ def testCPUGPUMatch(self):
+ for dt in dtypes.float16, dtypes.float32, dtypes.float64:
+ results = {}
+ for use_gpu in [False, True]:
+ sampler = self._Sampler(1000, 1.0, dt, use_gpu=use_gpu, seed=12345)
+ results[use_gpu] = sampler()
+ if dt == dtypes.float16:
+ self.assertAllClose(results[False], results[True], rtol=1e-3, atol=1e-3)
+ else:
+ self.assertAllClose(results[False], results[True], rtol=1e-6, atol=1e-6)
+
+ def testSeed(self):
+ for dt in dtypes.float16, dtypes.float32, dtypes.float64:
+ sx = self._Sampler(1000, 1.0, dt, use_gpu=True, seed=345)
+ sy = self._Sampler(1000, 1.0, dt, use_gpu=True, seed=345)
+ self.assertAllEqual(sx(), sy())
+
+ def testNoCSE(self):
+ """CSE = constant subexpression eliminator.
+
+ SetIsStateful() should prevent two identical random ops from getting
+ merged.
+ """
+ for dtype in dtypes.float16, dtypes.float32, dtypes.float64:
+ with self.test_session(use_gpu=True):
+ rnd1 = random_ops.random_poisson(2.0, [24], dtype=dtype)
+ rnd2 = random_ops.random_poisson(2.0, [24], dtype=dtype)
+ diff = rnd2 - rnd1
+ # Since these are all positive integers, the norm will
+ # be at least 1 if they are different.
+ self.assertGreaterEqual(np.linalg.norm(diff.eval()), 1)
+
+ def testShape(self):
+ # Fully known shape.
+ rnd = random_ops.random_poisson(2.0, [150], seed=12345)
+ self.assertEqual([150], rnd.get_shape().as_list())
+ rnd = random_ops.random_poisson(
+ lam=array_ops.ones([1, 2, 3]),
+ shape=[150],
+ seed=12345)
+ self.assertEqual([150, 1, 2, 3], rnd.get_shape().as_list())
+ rnd = random_ops.random_poisson(
+ lam=array_ops.ones([1, 2, 3]),
+ shape=[20, 30],
+ seed=12345)
+ self.assertEqual([20, 30, 1, 2, 3], rnd.get_shape().as_list())
+ rnd = random_ops.random_poisson(
+ lam=array_ops.placeholder(dtypes.float32, shape=(2,)),
+ shape=[12],
+ seed=12345)
+ self.assertEqual([12, 2], rnd.get_shape().as_list())
+ # Partially known shape.
+ rnd = random_ops.random_poisson(
+ lam=array_ops.ones([7, 3]),
+ shape=array_ops.placeholder(dtypes.int32, shape=(1,)),
+ seed=12345)
+ self.assertEqual([None, 7, 3], rnd.get_shape().as_list())
+ rnd = random_ops.random_poisson(
+ lam=array_ops.ones([9, 6]),
+ shape=array_ops.placeholder(dtypes.int32, shape=(3,)),
+ seed=12345)
+ self.assertEqual([None, None, None, 9, 6], rnd.get_shape().as_list())
+ # Unknown shape.
+ rnd = random_ops.random_poisson(
+ lam=array_ops.placeholder(dtypes.float32),
+ shape=array_ops.placeholder(dtypes.int32),
+ seed=12345)
+ self.assertIs(None, rnd.get_shape().ndims)
+ rnd = random_ops.random_poisson(
+ lam=array_ops.placeholder(dtypes.float32),
+ shape=[50],
+ seed=12345)
+ self.assertIs(None, rnd.get_shape().ndims)
+
+
+if __name__ == "__main__":
+ test.main()
diff --git a/tensorflow/python/ops/hidden_ops.txt b/tensorflow/python/ops/hidden_ops.txt
index dab15976b5..4937f1a50a 100644
--- a/tensorflow/python/ops/hidden_ops.txt
+++ b/tensorflow/python/ops/hidden_ops.txt
@@ -282,6 +282,7 @@ ParseSingleSequenceExample
# random_ops
RandomGamma
+RandomPoisson
RandomUniform
RandomUniformInt
RandomShuffle
diff --git a/tensorflow/python/ops/parsing_ops.py b/tensorflow/python/ops/parsing_ops.py
index 079837bce3..77c7cd397a 100644
--- a/tensorflow/python/ops/parsing_ops.py
+++ b/tensorflow/python/ops/parsing_ops.py
@@ -476,8 +476,13 @@ def _parse_example_raw(serialized,
The keys of the dict must match the dense_keys of the feature.
dense_shapes: A list of tuples with the same length as `dense_keys`.
The shape of the data for each dense feature referenced by `dense_keys`.
- Required for any input tensors identified by `dense_keys` whose shapes are
- anything other than `[]` or `[1]`.
+ Required for any input tensors identified by `dense_keys`. Must be
+ either fully defined, or may contain an unknown first dimension.
+ An unknown first dimension means the feature is treated as having
+ a variable number of blocks, and the output shape along this dimension
+ is considered unknown at graph build time. Padding is applied for
+ minibatch elements smaller than the maximum number of blocks for the
+ given feature along this dimension.
name: A name for this operation (optional).
Returns:
@@ -516,21 +521,42 @@ def _parse_example_raw(serialized,
"Dense and sparse keys must not intersect; intersection: %s" %
set(dense_keys).intersection(set(sparse_keys)))
+ # Convert dense_shapes to TensorShape object.
+ dense_shapes = [tensor_shape.as_shape(shape) for shape in dense_shapes]
+
dense_defaults_vec = []
for i, key in enumerate(dense_keys):
default_value = dense_defaults.get(key)
- if default_value is None:
- default_value = constant_op.constant([], dtype=dense_types[i])
- elif not isinstance(default_value, ops.Tensor):
- key_name = "key_" + re.sub("[^A-Za-z0-9_.\\-/]", "_", key)
- default_value = ops.convert_to_tensor(
- default_value, dtype=dense_types[i], name=key_name)
- default_value = array_ops.reshape(default_value, dense_shapes[i])
+ dense_shape = dense_shapes[i]
+ if (dense_shape.ndims is not None and dense_shape.ndims > 0 and
+ dense_shape[0].value is None):
+ # Variable stride dense shape, the default value should be a
+ # scalar padding value
+ if default_value is None:
+ default_value = ops.convert_to_tensor(
+ "" if dense_types[i] == dtypes.string else 0,
+ dtype=dense_types[i])
+ else:
+ # Reshape to a scalar to ensure user gets an error if they
+ # provide a tensor that's not intended to be a padding value
+ # (0 or 2+ elements).
+ key_name = "padding_" + re.sub("[^A-Za-z0-9_.\\-/]", "_", key)
+ default_value = ops.convert_to_tensor(
+ default_value, dtype=dense_types[i], name=key_name)
+ default_value = array_ops.reshape(default_value, [])
+ else:
+ if default_value is None:
+ default_value = constant_op.constant([], dtype=dense_types[i])
+ elif not isinstance(default_value, ops.Tensor):
+ key_name = "key_" + re.sub("[^A-Za-z0-9_.\\-/]", "_", key)
+ default_value = ops.convert_to_tensor(
+ default_value, dtype=dense_types[i], name=key_name)
+ default_value = array_ops.reshape(default_value, dense_shape)
dense_defaults_vec.append(default_value)
- dense_shapes = [tensor_shape.as_shape(shape).as_proto()
- for shape in dense_shapes]
+ # Finally, convert dense_shapes to TensorShapeProto
+ dense_shapes = [shape.as_proto() for shape in dense_shapes]
# pylint: disable=protected-access
outputs = gen_parsing_ops._parse_example(
diff --git a/tensorflow/python/ops/random_ops.py b/tensorflow/python/ops/random_ops.py
index 34b4d36102..5a753ae7a1 100644
--- a/tensorflow/python/ops/random_ops.py
+++ b/tensorflow/python/ops/random_ops.py
@@ -71,10 +71,8 @@ def random_normal(shape,
mean_tensor = ops.convert_to_tensor(mean, dtype=dtype, name="mean")
stddev_tensor = ops.convert_to_tensor(stddev, dtype=dtype, name="stddev")
seed1, seed2 = random_seed.get_seed(seed)
- rnd = gen_random_ops._random_standard_normal(shape_tensor,
- dtype,
- seed=seed1,
- seed2=seed2)
+ rnd = gen_random_ops._random_standard_normal(
+ shape_tensor, dtype, seed=seed1, seed2=seed2)
mul = rnd * stddev_tensor
value = math_ops.add(mul, mean_tensor, name=name)
return value
@@ -125,13 +123,14 @@ def parameterized_truncated_normal(shape,
minvals_tensor = ops.convert_to_tensor(minvals, dtype=dtype, name="minvals")
maxvals_tensor = ops.convert_to_tensor(maxvals, dtype=dtype, name="maxvals")
seed1, seed2 = random_seed.get_seed(seed)
- rnd = gen_random_ops._parameterized_truncated_normal(shape_tensor,
- means_tensor,
- stddevs_tensor,
- minvals_tensor,
- maxvals_tensor,
- seed=seed1,
- seed2=seed2)
+ rnd = gen_random_ops._parameterized_truncated_normal(
+ shape_tensor,
+ means_tensor,
+ stddevs_tensor,
+ minvals_tensor,
+ maxvals_tensor,
+ seed=seed1,
+ seed2=seed2)
return rnd
@@ -168,10 +167,8 @@ def truncated_normal(shape,
mean_tensor = ops.convert_to_tensor(mean, dtype=dtype, name="mean")
stddev_tensor = ops.convert_to_tensor(stddev, dtype=dtype, name="stddev")
seed1, seed2 = random_seed.get_seed(seed)
- rnd = gen_random_ops._truncated_normal(shape_tensor,
- dtype,
- seed=seed1,
- seed2=seed2)
+ rnd = gen_random_ops._truncated_normal(
+ shape_tensor, dtype, seed=seed1, seed2=seed2)
mul = rnd * stddev_tensor
value = math_ops.add(mul, mean_tensor, name=name)
return value
@@ -232,17 +229,11 @@ def random_uniform(shape,
maxval = ops.convert_to_tensor(maxval, dtype=dtype, name="max")
seed1, seed2 = random_seed.get_seed(seed)
if dtype.is_integer:
- return gen_random_ops._random_uniform_int(shape,
- minval,
- maxval,
- seed=seed1,
- seed2=seed2,
- name=name)
+ return gen_random_ops._random_uniform_int(
+ shape, minval, maxval, seed=seed1, seed2=seed2, name=name)
else:
- rnd = gen_random_ops._random_uniform(shape,
- dtype,
- seed=seed1,
- seed2=seed2)
+ rnd = gen_random_ops._random_uniform(
+ shape, dtype, seed=seed1, seed2=seed2)
return math_ops.add(rnd * (maxval - minval), minval, name=name)
@@ -275,10 +266,8 @@ def random_shuffle(value, seed=None, name=None):
dimension.
"""
seed1, seed2 = random_seed.get_seed(seed)
- return gen_random_ops._random_shuffle(value,
- seed=seed1,
- seed2=seed2,
- name=name)
+ return gen_random_ops._random_shuffle(
+ value, seed=seed1, seed2=seed2, name=name)
def random_crop(value, size, seed=None, name=None):
@@ -349,10 +338,8 @@ def multinomial(logits, num_samples, seed=None, name=None):
with ops.name_scope(name, "multinomial", [logits]):
logits = ops.convert_to_tensor(logits, name="logits")
seed1, seed2 = random_seed.get_seed(seed)
- return gen_random_ops.multinomial(logits,
- num_samples,
- seed=seed1,
- seed2=seed2)
+ return gen_random_ops.multinomial(
+ logits, num_samples, seed=seed1, seed2=seed2)
ops.NotDifferentiable("Multinomial")
@@ -426,15 +413,52 @@ def random_gamma(shape,
with ops.name_scope(name, "random_gamma", [shape, alpha, beta]):
shape = ops.convert_to_tensor(shape, name="shape", dtype=dtypes.int32)
alpha = ops.convert_to_tensor(alpha, name="alpha", dtype=dtype)
- beta = ops.convert_to_tensor(beta if beta is not None else 1,
- name="beta",
- dtype=dtype)
+ beta = ops.convert_to_tensor(
+ beta if beta is not None else 1, name="beta", dtype=dtype)
alpha_broadcast = alpha + array_ops.zeros_like(beta)
seed1, seed2 = random_seed.get_seed(seed)
- return gen_random_ops._random_gamma(shape,
- alpha_broadcast,
- seed=seed1,
- seed2=seed2) / beta
+ return gen_random_ops._random_gamma(
+ shape, alpha_broadcast, seed=seed1, seed2=seed2) / beta
ops.NotDifferentiable("RandomGamma")
+
+
+def random_poisson(lam, shape, dtype=dtypes.float32, seed=None, name=None):
+ """Draws `shape` samples from each of the given Poisson distribution(s).
+
+ `lam` is the rate parameter describing the distribution(s).
+
+ Example:
+
+ samples = tf.random_poisson([0.5, 1.5], [10])
+ # samples has shape [10, 2], where each slice [:, 0] and [:, 1] represents
+ # the samples drawn from each distribution
+
+ samples = tf.random_poisson([12.2, 3.3], [7, 5])
+ # samples has shape [7, 5, 2], where each slice [:, :, 0] and [:, :, 1]
+ # represents the 7x5 samples drawn from each of the two distributions
+
+ Args:
+ lam: A Tensor or Python value or N-D array of type `dtype`.
+ `lam` provides the rate parameter(s) describing the poisson
+ distribution(s) to sample.
+ shape: A 1-D integer Tensor or Python array. The shape of the output samples
+ to be drawn per "rate"-parameterized distribution.
+ dtype: The type of `lam` and the output: `float16`, `float32`, or
+ `float64`.
+ seed: A Python integer. Used to create a random seed for the distributions.
+ See
+ [`set_random_seed`](../../api_docs/python/constant_op.md#set_random_seed)
+ for behavior.
+ name: Optional name for the operation.
+
+ Returns:
+ samples: a `Tensor` of shape `tf.concat(shape, tf.shape(lam))` with
+ values of type `dtype`.
+ """
+ with ops.name_scope(name, "random_poisson", [lam, shape]):
+ lam = ops.convert_to_tensor(lam, name="lam", dtype=dtype)
+ shape = ops.convert_to_tensor(shape, name="shape", dtype=dtypes.int32)
+ seed1, seed2 = random_seed.get_seed(seed)
+ return gen_random_ops._random_poisson(shape, lam, seed=seed1, seed2=seed2)
diff --git a/tensorflow/stream_executor/lib/status_macros.h b/tensorflow/stream_executor/lib/status_macros.h
index a14ba73af3..6a8a11f083 100644
--- a/tensorflow/stream_executor/lib/status_macros.h
+++ b/tensorflow/stream_executor/lib/status_macros.h
@@ -59,7 +59,7 @@ limitations under the License.
#define SE_RETURN_STATUS_AS_BOOL(__status) \
do { \
auto status = __status; \
- if (__status.ok()) { \
+ if (status.ok()) { \
return true; \
} \
LOG(ERROR) << status; \
diff --git a/tensorflow/tensorboard/components/tf_audio_dashboard/test/audioDashboardTests.ts b/tensorflow/tensorboard/components/tf_audio_dashboard/test/audioDashboardTests.ts
index bd6f762710..937654c160 100644
--- a/tensorflow/tensorboard/components/tf_audio_dashboard/test/audioDashboardTests.ts
+++ b/tensorflow/tensorboard/components/tf_audio_dashboard/test/audioDashboardTests.ts
@@ -13,8 +13,11 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
declare function stub(el: string, obj: any): void;
+declare function fixture(id: string): void;
- describe('audio dashboard tests', function() {
+
+describe(
+ 'audio dashboard tests', function() {
var audioDash;
var reloadCount = 0;
beforeEach(function() {
diff --git a/tensorflow/tensorboard/components/tf_backend/BUILD b/tensorflow/tensorboard/components/tf_backend/BUILD
new file mode 100644
index 0000000000..22ab1faff0
--- /dev/null
+++ b/tensorflow/tensorboard/components/tf_backend/BUILD
@@ -0,0 +1,79 @@
+package(default_visibility = ["//tensorflow:internal"])
+
+load("@io_bazel_rules_closure//closure:defs.bzl", "webfiles")
+load("//tensorflow/tensorboard:defs.bzl", "tensorboard_ts_library")
+load("//tensorflow/tensorboard:defs.bzl", "tensorboard_typescript_genrule")
+load("//tensorflow/tensorboard:defs.bzl", "tensorboard_webcomponent_library")
+
+licenses(["notice"]) # Apache 2.0
+
+# TODO(dandelion): Add webfiles support for the test code.
+
+webfiles(
+ name = "tf_backend",
+ srcs = [
+ "tf-backend.html",
+ ":ts",
+ ],
+ path = "/tf-backend",
+ deps = [
+ "//tensorflow/tensorboard/components/tf_imports:d3",
+ "//tensorflow/tensorboard/components/tf_imports:lodash",
+ "//tensorflow/tensorboard/components/vz_sorting",
+ "@org_polymer",
+ ],
+)
+
+tensorboard_typescript_genrule(
+ name = "ts",
+ srcs = [
+ "backend.ts",
+ "behavior.ts",
+ "requestManager.ts",
+ "router.ts",
+ "urlPathHelpers.ts",
+ ],
+ typings = [
+ "@org_definitelytyped//:d3.d.ts",
+ "@org_definitelytyped//:lodash.d.ts",
+ "//tensorflow/tensorboard/components/vz_sorting:ts_typings",
+ ],
+)
+
+filegroup(
+ name = "all_files",
+ srcs = glob(["**"]),
+ tags = ["notsan"],
+)
+
+################################################################################
+# MARKED FOR DELETION
+
+tensorboard_webcomponent_library(
+ name = "legacy",
+ srcs = [
+ "tf-backend.html",
+ ":legacy_ts",
+ ],
+ visibility = ["//visibility:public"],
+ destdir = "tf-backend",
+ deps = [
+ "//tensorflow/tensorboard/components:tf_imports",
+ "//third_party/javascript/polymer/v1/polymer:lib",
+ ],
+)
+
+tensorboard_ts_library(
+ name = "legacy_ts",
+ srcs = [
+ "backend.ts",
+ "behavior.ts",
+ "requestManager.ts",
+ "router.ts",
+ "urlPathHelpers.ts",
+ ],
+ deps = [
+ "//tensorflow/tensorboard/components:common_deps",
+ "//tensorflow/tensorboard/components/vz_sorting:legacy_ts",
+ ],
+)
diff --git a/tensorflow/tensorboard/components/tf_backend/backend.ts b/tensorflow/tensorboard/components/tf_backend/backend.ts
index 28a5b2d0e1..b4be89163e 100644
--- a/tensorflow/tensorboard/components/tf_backend/backend.ts
+++ b/tensorflow/tensorboard/components/tf_backend/backend.ts
@@ -77,6 +77,8 @@ module TF.Backend {
output_slot: number;
value: number[];
};
+ // When updating this type, keep it consistent with the HealthPill interface
+ // in tf_graph_common/lib/scene/scene.ts.
export type HealthPillDatum = Datum & HealthPill;
// A health pill response is a mapping from node name to a list of health pill
// data entries.
diff --git a/tensorflow/tensorboard/components/tf_color_scale/BUILD b/tensorflow/tensorboard/components/tf_color_scale/BUILD
new file mode 100644
index 0000000000..75bf812fe5
--- /dev/null
+++ b/tensorflow/tensorboard/components/tf_color_scale/BUILD
@@ -0,0 +1,63 @@
+package(default_visibility = ["//tensorflow:internal"])
+
+load("@io_bazel_rules_closure//closure:defs.bzl", "webfiles")
+load("//tensorflow/tensorboard:defs.bzl", "tensorboard_ts_library")
+load("//tensorflow/tensorboard:defs.bzl", "tensorboard_typescript_genrule")
+load("//tensorflow/tensorboard:defs.bzl", "tensorboard_webcomponent_library")
+
+licenses(["notice"]) # Apache 2.0
+
+# TODO(dandelion): Add webfiles support for the test code.
+
+webfiles(
+ name = "tf_color_scale",
+ srcs = [
+ "tf-color-scale.html",
+ ":ts",
+ ],
+ path = "/tf-color-scale",
+ deps = [
+ "//tensorflow/tensorboard/components/tf_imports:d3",
+ "@org_polymer",
+ ],
+)
+
+tensorboard_typescript_genrule(
+ name = "ts",
+ srcs = [
+ "colorScale.ts",
+ "palettes.ts",
+ ],
+ typings = ["@org_definitelytyped//:d3.d.ts"],
+)
+
+filegroup(
+ name = "all_files",
+ srcs = glob(["**"]),
+ tags = ["notsan"],
+)
+
+################################################################################
+# MARKED FOR DELETION
+
+tensorboard_webcomponent_library(
+ name = "legacy",
+ srcs = [
+ "tf-color-scale.html",
+ ":legacy_ts",
+ ],
+ destdir = "tf-color-scale",
+ deps = [
+ "//tensorflow/tensorboard/components:tf_imports",
+ "//third_party/javascript/polymer/v1/polymer:lib",
+ ],
+)
+
+tensorboard_ts_library(
+ name = "legacy_ts",
+ srcs = [
+ "colorScale.ts",
+ "palettes.ts",
+ ],
+ deps = ["//tensorflow/tensorboard/components:common_deps"],
+)
diff --git a/tensorflow/tensorboard/components/tf_color_scale/demo/BUILD b/tensorflow/tensorboard/components/tf_color_scale/demo/BUILD
new file mode 100644
index 0000000000..00b8a033b8
--- /dev/null
+++ b/tensorflow/tensorboard/components/tf_color_scale/demo/BUILD
@@ -0,0 +1,26 @@
+package(default_visibility = ["//tensorflow:internal"])
+
+load("@io_bazel_rules_closure//closure:defs.bzl", "webfiles")
+
+licenses(["notice"]) # Apache 2.0
+
+# bazel run //third_party/tensorflow/tensorboard/components/tf_color_scale/demo
+webfiles(
+ name = "demo",
+ srcs = ["index.html"],
+ path = "/tf-color-scale/demo",
+ deps = [
+ "//tensorflow/tensorboard/components/tf_color_scale",
+ "//tensorflow/tensorboard/components/tf_imports:d3",
+ "@org_polymer_iron_demo_helpers",
+ "@org_polymer_paper_button",
+ "@org_polymer_paper_styles",
+ "@org_polymer_webcomponentsjs",
+ ],
+)
+
+filegroup(
+ name = "all_files",
+ srcs = glob(["**"]),
+ tags = ["notsan"],
+)
diff --git a/tensorflow/tensorboard/components/tf_color_scale/demo/index.html b/tensorflow/tensorboard/components/tf_color_scale/demo/index.html
new file mode 100644
index 0000000000..ad9edbda98
--- /dev/null
+++ b/tensorflow/tensorboard/components/tf_color_scale/demo/index.html
@@ -0,0 +1,94 @@
+<!doctype html>
+<!--
+@license
+Copyright 2016 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.
+-->
+
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>tf-color-scale demo</title>
+<script src="../../webcomponentsjs/webcomponents-lite.min.js"></script>
+<link rel="import" href="../tf-color-scale.html">
+<link rel="import" href="../../iron-demo-helpers/demo-snippet.html">
+<link rel="import" href="../../paper-styles/typography.html">
+<link rel="import" href="../../paper-button/paper-button.html">
+<link rel="import" href="../../tf-imports/d3.html">
+
+<style> body {font-family: "Roboto";}</style>
+<demo-snippet>
+ <template>
+ <dom-module id="color-scale-demo">
+ <template>
+ <paper-button raised id="button" on-tap="change">Change Runs</paper-button>
+ <tf-color-scale runs="[[runs]]" out-color-scale="{{scale}}"></tf-color-scale>
+ <div class="container">
+ <template is="dom-repeat" items="[[runs]]">
+ <div class="row">
+ <div class="circle" style$=[[_makeStyle(item)]]></div>
+ <span>[[item]]</span>
+ </div>
+ </template>
+ </div>
+ <style>
+ .circle {
+ width: 20px;
+ height: 20px;
+ border-radius: 10px;
+ display: inline-block;
+ }
+ .row {
+ height: 35px;
+ width: 200px;
+ display: inline-block;
+ }
+ .container {
+ height: 200px;
+ }
+ #button {
+ margin: 20px;
+ }
+ </style>
+ </template>
+ <script>
+ let fellowship = ["aragorn", "legolas", "gimli", "frodo",
+ "gandalf", "boromir", "merry", "pippin", "sam"];
+ let gems = ["garnet", "amethyst", "pearl", "and steven!"];
+ let numbers = d3.range(30).map(function(x) {return x.toString();});
+ let examples = [numbers, fellowship, gems];
+ Polymer({
+ is: "color-scale-demo",
+ properties: {
+ runs: {
+ type: Array,
+ value: examples[0],
+ },
+ i: {
+ type: Number,
+ value: 0,
+ },
+ },
+ _makeStyle: function(item) {
+ return "background-color: " + this.scale.scale(item);
+ },
+ change: function() {
+ this.i = (this.i + 1) % 3;
+ this.runs = examples[this.i];
+ },
+ });
+ </script>
+ </dom-module>
+ <color-scale-demo id="demo"></color-scale-demo>
+ </template>
+</demo-snippet>
diff --git a/tensorflow/tensorboard/components/tf_color_scale/tf-color-scale.html b/tensorflow/tensorboard/components/tf_color_scale/tf-color-scale.html
index 743996f624..79bee6d957 100644
--- a/tensorflow/tensorboard/components/tf_color_scale/tf-color-scale.html
+++ b/tensorflow/tensorboard/components/tf_color_scale/tf-color-scale.html
@@ -16,6 +16,7 @@ limitations under the License.
-->
<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../tf-imports/d3.html">
<!--
tf-color-scale is a plumbing component that takes in an array of runs, and produces
diff --git a/tensorflow/tensorboard/components/tf_globals/BUILD b/tensorflow/tensorboard/components/tf_globals/BUILD
new file mode 100644
index 0000000000..21724aa26b
--- /dev/null
+++ b/tensorflow/tensorboard/components/tf_globals/BUILD
@@ -0,0 +1,49 @@
+package(default_visibility = ["//tensorflow:internal"])
+
+load("@io_bazel_rules_closure//closure:defs.bzl", "webfiles")
+load("//tensorflow/tensorboard:defs.bzl", "tensorboard_ts_library")
+load("//tensorflow/tensorboard:defs.bzl", "tensorboard_typescript_genrule")
+load("//tensorflow/tensorboard:defs.bzl", "tensorboard_webcomponent_library")
+
+licenses(["notice"]) # Apache 2.0
+
+# TODO(dandelion): Add webfiles support for the test code.
+
+webfiles(
+ name = "tf_globals",
+ srcs = [
+ "tf-globals.html",
+ ":ts",
+ ],
+ path = "/tf-globals",
+)
+
+tensorboard_typescript_genrule(
+ name = "ts",
+ srcs = ["globals.ts"],
+)
+
+filegroup(
+ name = "all_files",
+ srcs = glob(["**"]),
+ tags = ["notsan"],
+)
+
+################################################################################
+# MARKED FOR DELETION
+
+tensorboard_webcomponent_library(
+ name = "legacy",
+ srcs = [
+ "tf-globals.html",
+ ":legacy_ts",
+ ],
+ destdir = "tf-globals",
+)
+
+tensorboard_ts_library(
+ name = "legacy_ts",
+ srcs = [
+ "globals.ts",
+ ],
+)
diff --git a/tensorflow/tensorboard/components/tf_graph/tf-graph-scene.html b/tensorflow/tensorboard/components/tf_graph/tf-graph-scene.html
index d0e42a36a0..8f1321138b 100644
--- a/tensorflow/tensorboard/components/tf_graph/tf-graph-scene.html
+++ b/tensorflow/tensorboard/components/tf_graph/tf-graph-scene.html
@@ -692,11 +692,26 @@ Polymer({
type: Number,
value: 18
},
- progress: Object
+ progress: Object,
+ /**
+ * A list of colors. Used to color the categories of values within tensor summaries. The
+ * categories (in order) are: negative_inf, negative_inf, zero, positive, positive_inf, NaN.
+ */
+ healthPillColors: {
+ type: Array,
+ readOnly: true,
+ value: ['#762a83', '#af8dc3', '#f7da0b', '#a2c96f', '#1f8926', '#0909c6'],
+ },
+ /**
+ * A mapping from node name to a list of tf.graph.scene.HealthPills. Updated when the client
+ * receives a health pills response.
+ */
+ nodeNamesToHealthPills: {},
},
observers: [
'_colorByChanged(colorBy)',
- '_buildAndFit(renderHierarchy)'
+ '_buildAndFit(renderHierarchy)',
+ '_updateHealthPills(nodeNamesToHealthPills)',
],
getNode: function(nodeName) {
return this.renderHierarchy.getRenderNodeByName(nodeName);
@@ -739,6 +754,7 @@ Polymer({
}.bind(this));
// Update the minimap again when the graph is done animating.
setTimeout(function() {
+ this._updateHealthPills(this.nodeNamesToHealthPills);
this.minimap.update();
}.bind(this), tf.graph.layout.PARAMS.animation.duration);
},
@@ -888,6 +904,9 @@ Polymer({
getEdgeGroup: function(e) {
return this._edgeGroupIndex[e];
},
+ _updateHealthPills: function(nodeNamesToHealthPills) {
+ tf.graph.scene.addHealthPills(this.$.svg, nodeNamesToHealthPills, this.healthPillColors);
+ },
/**
* Update node and annotation node of the given name.
* @param {String} n node name
diff --git a/tensorflow/tensorboard/components/tf_graph_common/lib/render.ts b/tensorflow/tensorboard/components/tf_graph_common/lib/render.ts
index f3a81587c7..ae5d1a7c57 100644
--- a/tensorflow/tensorboard/components/tf_graph_common/lib/render.ts
+++ b/tensorflow/tensorboard/components/tf_graph_common/lib/render.ts
@@ -157,6 +157,7 @@ export class RenderGraphInfo {
hierarchy: hierarchy.Hierarchy;
private displayingStats: boolean;
private index: {[nodeName: string]: RenderNodeInfo};
+ private renderedOpNames: string[];
private deviceColorMap: d3.scale.Ordinal<string, string>;
private memoryUsageScale: d3.scale.Linear<string, string>;
private computeTimeScale: d3.scale.Linear<string, string>;
@@ -175,6 +176,7 @@ export class RenderGraphInfo {
this.hierarchy = hierarchy;
this.displayingStats = displayingStats;
this.index = {};
+ this.renderedOpNames = [];
this.computeScales();
// Maps node name to whether the rendering hierarchy was already
@@ -182,6 +184,7 @@ export class RenderGraphInfo {
this.hasSubhierarchy = {};
this.root = new RenderGroupNodeInfo(hierarchy.root);
this.index[hierarchy.root.name] = this.root;
+ this.renderedOpNames.push(hierarchy.root.name);
this.buildSubhierarchy(hierarchy.root.name);
this.root.expanded = true;
this.traceInputs = false;
@@ -266,6 +269,7 @@ export class RenderGraphInfo {
new RenderGroupNodeInfo(<GroupNode>node) :
new RenderNodeInfo(node);
this.index[nodeName] = renderInfo;
+ this.renderedOpNames.push(nodeName);
if (node.stats) {
renderInfo.memoryColor = this.memoryUsageScale(node.stats.totalBytes);
@@ -345,6 +349,15 @@ export class RenderGraphInfo {
return !!found;
}
+ /**
+ * Returns a list of ops that have been rendered so far for this graph. More
+ * ops may later be rendered if the user expands nodes for instance. The list
+ * returned here can only stay the same size or grow on successive calls.
+ */
+ getNamesOfRenderedOps(): string[] {
+ return this.renderedOpNames;
+ }
+
buildSubhierarchy(nodeName: string): void {
// Terminate if the rendering hierarchy was already constructed
// for this node.
diff --git a/tensorflow/tensorboard/components/tf_graph_common/lib/scene/scene.ts b/tensorflow/tensorboard/components/tf_graph_common/lib/scene/scene.ts
index f8ad90a968..518d89e82a 100644
--- a/tensorflow/tensorboard/components/tf_graph_common/lib/scene/scene.ts
+++ b/tensorflow/tensorboard/components/tf_graph_common/lib/scene/scene.ts
@@ -13,102 +13,121 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
module tf.graph.scene {
+ const svgNamespace = 'http://www.w3.org/2000/svg';
-/** Enums element class of objects in the scene */
-export let Class = {
- Node: {
- // <g> element that contains nodes.
- CONTAINER: 'nodes',
- // <g> element that contains detail about a node.
- GROUP: 'node',
- // <g> element that contains visual elements (like rect, ellipse).
- SHAPE: 'nodeshape',
- // <*> element(s) under SHAPE that should receive color updates.
- COLOR_TARGET: 'nodecolortarget',
- // <text> element showing the node's label.
- LABEL: 'nodelabel',
- // <g> element that contains all visuals for the expand/collapse
- // button for expandable group nodes.
- BUTTON_CONTAINER: 'buttoncontainer',
- // <circle> element that surrounds expand/collapse buttons.
- BUTTON_CIRCLE: 'buttoncircle',
- // <path> element of the expand button.
- EXPAND_BUTTON: 'expandbutton',
- // <path> element of the collapse button.
- COLLAPSE_BUTTON: 'collapsebutton'
- },
- Edge: {
- CONTAINER: 'edges',
- GROUP: 'edge',
- LINE: 'edgeline',
- REF_LINE: 'refline',
- STRUCTURAL: 'structural'
- },
- Annotation: {
- OUTBOX: 'out-annotations',
- INBOX: 'in-annotations',
- GROUP: 'annotation',
- NODE: 'annotation-node',
- EDGE: 'annotation-edge',
- CONTROL_EDGE: 'annotation-control-edge',
- LABEL: 'annotation-label',
- ELLIPSIS: 'annotation-ellipsis'
- },
- Scene: {
- GROUP: 'scene',
- CORE: 'core',
- INEXTRACT: 'in-extract',
- OUTEXTRACT: 'out-extract'
- },
- Subscene: {GROUP: 'subscene'},
- OPNODE: 'op',
- METANODE: 'meta',
- SERIESNODE: 'series',
- BRIDGENODE: 'bridge',
- ELLIPSISNODE: 'ellipsis'
-};
+ /** Enums element class of objects in the scene */
+ export let Class = {
+ Node: {
+ // <g> element that contains nodes.
+ CONTAINER: 'nodes',
+ // <g> element that contains detail about a node.
+ GROUP: 'node',
+ // <g> element that contains visual elements (like rect, ellipse).
+ SHAPE: 'nodeshape',
+ // <*> element(s) under SHAPE that should receive color updates.
+ COLOR_TARGET: 'nodecolortarget',
+ // <text> element showing the node's label.
+ LABEL: 'nodelabel',
+ // <g> element that contains all visuals for the expand/collapse
+ // button for expandable group nodes.
+ BUTTON_CONTAINER: 'buttoncontainer',
+ // <circle> element that surrounds expand/collapse buttons.
+ BUTTON_CIRCLE: 'buttoncircle',
+ // <path> element of the expand button.
+ EXPAND_BUTTON: 'expandbutton',
+ // <path> element of the collapse button.
+ COLLAPSE_BUTTON: 'collapsebutton'
+ },
+ Edge: {
+ CONTAINER: 'edges',
+ GROUP: 'edge',
+ LINE: 'edgeline',
+ REF_LINE: 'refline',
+ STRUCTURAL: 'structural'
+ },
+ Annotation: {
+ OUTBOX: 'out-annotations',
+ INBOX: 'in-annotations',
+ GROUP: 'annotation',
+ NODE: 'annotation-node',
+ EDGE: 'annotation-edge',
+ CONTROL_EDGE: 'annotation-control-edge',
+ LABEL: 'annotation-label',
+ ELLIPSIS: 'annotation-ellipsis'
+ },
+ Scene: {
+ GROUP: 'scene',
+ CORE: 'core',
+ INEXTRACT: 'in-extract',
+ OUTEXTRACT: 'out-extract'
+ },
+ Subscene: {GROUP: 'subscene'},
+ OPNODE: 'op',
+ METANODE: 'meta',
+ SERIESNODE: 'series',
+ BRIDGENODE: 'bridge',
+ ELLIPSISNODE: 'ellipsis'
+ };
-/**
- * Helper method for fitting the graph in the svg view.
- *
- * @param svg The main svg.
- * @param zoomG The svg group used for panning and zooming.
- * @param d3zoom The zoom behavior.
- * @param callback Called when the fitting is done.
- */
-export function fit(svg, zoomG, d3zoom, callback) {
- let svgRect = svg.getBoundingClientRect();
- let sceneSize = null;
- try {
- sceneSize = zoomG.getBBox();
- if (sceneSize.width === 0) {
- // There is no scene anymore. We have been detached from the dom.
+ /**
+ * A health pill encapsulates an overview of tensor element values. The value
+ * field is a list of 12 numbers that shed light on the status of the tensor.
+ * Visualized in health pills are the 3rd through 8th (inclusive) numbers of
+ * health pill values. Those 6 numbers are counts of tensor elements that fall
+ * under -Inf, negative, 0, positive, +Inf, NaN (in that order).
+ *
+ * Please keep this interface consistent with HealthPillDatum within
+ * backend.ts.
+ */
+ export interface HealthPill {
+ node_name: string;
+ output_slot: number;
+ value: number[];
+ wall_time: number;
+ step: number;
+ }
+ ;
+
+ /**
+ * Helper method for fitting the graph in the svg view.
+ *
+ * @param svg The main svg.
+ * @param zoomG The svg group used for panning and zooming.
+ * @param d3zoom The zoom behavior.
+ * @param callback Called when the fitting is done.
+ */
+ export function fit(svg, zoomG, d3zoom, callback) {
+ let svgRect = svg.getBoundingClientRect();
+ let sceneSize = null;
+ try {
+ sceneSize = zoomG.getBBox();
+ if (sceneSize.width === 0) {
+ // There is no scene anymore. We have been detached from the dom.
+ return;
+ }
+ } catch (e) {
+ // Firefox produced NS_ERROR_FAILURE if we have been
+ // detached from the dom.
return;
}
- } catch (e) {
- // Firefox produced NS_ERROR_FAILURE if we have been
- // detached from the dom.
- return;
- }
- let scale = 0.9 * Math.min(
- svgRect.width / sceneSize.width,
- svgRect.height / sceneSize.height,
- 2
- );
- let params = layout.PARAMS.graph;
- let zoomEvent =
- d3zoom.scale(scale)
- .on('zoomend.fitted',
- () => {
- // Remove the listener for the zoomend event,
- // so we don't get called at the end of regular zoom events,
- // just those that fit the graph to screen.
- d3zoom.on('zoomend.fitted', null);
- callback();
- })
- .translate([params.padding.paddingLeft, params.padding.paddingTop])
- .event;
- d3.select(zoomG).transition().duration(500).call(zoomEvent);
+ let scale = 0.9 *
+ Math.min(
+ svgRect.width / sceneSize.width, svgRect.height / sceneSize.height,
+ 2);
+ let params = layout.PARAMS.graph;
+ let zoomEvent =
+ d3zoom.scale(scale)
+ .on('zoomend.fitted',
+ () => {
+ // Remove the listener for the zoomend event,
+ // so we don't get called at the end of regular zoom events,
+ // just those that fit the graph to screen.
+ d3zoom.on('zoomend.fitted', null);
+ callback();
+ })
+ .translate([params.padding.paddingLeft, params.padding.paddingTop])
+ .event;
+ d3.select(zoomG).transition().duration(500).call(zoomEvent);
};
/**
@@ -450,4 +469,81 @@ export function positionEllipse(ellipse, cx: number, cy: number,
});
};
+/**
+ * Renders a health pill for an op atop a node.
+ */
+function _addHealthPill(
+ nodeGroupElement: SVGElement, healthPills: HealthPill[],
+ nodeInfo: render.RenderGroupNodeInfo, colors: string[]) {
+ // Check if text already exists at location.
+ d3.select(nodeGroupElement.parentNode)
+ .selectAll('.health-pill-group')
+ .remove();
+
+ if (!nodeInfo || !healthPills || !healthPills.length) {
+ return;
+ }
+
+ let lastHealthPillData = healthPills[healthPills.length - 1].value;
+
+ // For now, we only visualize the 6 values that summarize counts of tensor
+ // elements of various categories: -Inf, negative, 0, positive, Inf, and NaN.
+ let lastHealthPillOverview = lastHealthPillData.slice(2, 8);
+
+ let healthPillWidth = 60;
+ let healthPillHeight = 10;
+ let healthPill = document.createElementNS(svgNamespace, 'svg');
+ healthPill.classList.add('health-pill-group');
+ healthPill.setAttribute('width', String(healthPillWidth));
+ healthPill.setAttribute('height', String(healthPillHeight));
+
+ let totalCount = lastHealthPillData[1];
+ // Create 1 rectangle for each category.
+ let totalCountSoFar = 0;
+ let totalWidthDividedByTotalCount = healthPillWidth / totalCount;
+ for (let i = 0; i < lastHealthPillOverview.length; i++) {
+ if (!lastHealthPillOverview[i]) {
+ // Do not render empty rectangles.
+ continue;
+ }
+ let rect = document.createElementNS(svgNamespace, 'rect');
+ rect.setAttribute('height', String(healthPillHeight));
+ rect.setAttribute(
+ 'width',
+ String(totalWidthDividedByTotalCount * lastHealthPillOverview[i]));
+ rect.setAttribute(
+ 'x', String(totalWidthDividedByTotalCount * totalCountSoFar));
+ rect.setAttribute('fill', colors[i]);
+ totalCountSoFar += lastHealthPillOverview[i];
+ Polymer.dom(healthPill).appendChild(rect);
+ }
+
+ // Center this health pill just right above the node for the op.
+ healthPill.setAttribute(
+ 'x', String(nodeInfo.x - healthPillWidth + nodeInfo.width / 2));
+ healthPill.setAttribute(
+ 'y',
+ String(nodeInfo.y - healthPillHeight - nodeInfo.coreBox.height / 2 - 2));
+ Polymer.dom(nodeGroupElement.parentNode).appendChild(healthPill);
+}
+
+/**
+ * Adds health pills (which visualize tensor summaries) to a graph group.
+ * @param svgRoot The root SVG element of the graph to add heath pills to.
+ * @param nodeNamesToHealthPills An object mapping node names to health pills.
+ * @param colors A list of colors to use.
+ */
+export function addHealthPills(
+ svgRoot: SVGElement, nodeNamesToHealthPills: {[key: string]: HealthPill[]},
+ colors: string[]) {
+ let svgRootSelection = d3.select(svgRoot);
+
+ svgRootSelection.selectAll('g.nodeshape')
+ .each(function(nodeInfo: render.RenderGroupNodeInfo) {
+ // The element is the first item of a d3 selection.
+ _addHealthPill(
+ this, nodeNamesToHealthPills[nodeInfo.node.name], nodeInfo, colors);
+ });
+};
+
} // close module
diff --git a/tensorflow/tensorboard/components/tf_graph_dashboard/tf-graph-dashboard.html b/tensorflow/tensorboard/components/tf_graph_dashboard/tf-graph-dashboard.html
index ae26f59762..5b3857e6f5 100644
--- a/tensorflow/tensorboard/components/tf_graph_dashboard/tf-graph-dashboard.html
+++ b/tensorflow/tensorboard/components/tf_graph_dashboard/tf-graph-dashboard.html
@@ -98,14 +98,29 @@ out-hierarchy-params="{{_hierarchyParams}}"
(function() {
Polymer({
is: 'tf-graph-dashboard',
+ behaviors: [
+ TF.Dashboard.ReloadBehavior("tf-graph-dashboard"),
+ TF.Backend.Behavior,
+ ],
properties: {
_datasets: Object,
_renderHierarchy: Object,
backend: {type: Object, observer: 'reload'},
+ debuggerDataEnabled: Boolean,
runs: Array
},
reload: function() {
- Promise.all([this.backend.graphRuns(), this.backend.runMetadataRuns()])
+ let requestPromises = [
+ this.backend.graphRuns(),
+ this.backend.runMetadataRuns()];
+ if (this.debuggerDataEnabled && this._renderHierarchy) {
+ // Request debugger data on graph reloads.
+ requestPromises.push(this._renderHierarchy.getNamesOfRenderedOps());
+ }
+ // TODO(chizeng): Prevent the graph layout itself from refreshing when the reload button is hit.
+ // We should only update the data atop the graph such as debugger data. The graph itself does
+ // not change on successive reloads.
+ Promise.all(requestPromises)
.then(function(result) {
var runsWithGraph = result[0].sort(VZ.Sorting.compareTagNames);
var runToMetadata = result[1];
diff --git a/tensorflow/tensorboard/components/tf_tensorboard/test/autoReloadTests.ts b/tensorflow/tensorboard/components/tf_tensorboard/test/autoReloadTests.ts
index dfb1a7af56..0d815cc882 100644
--- a/tensorflow/tensorboard/components/tf_tensorboard/test/autoReloadTests.ts
+++ b/tensorflow/tensorboard/components/tf_tensorboard/test/autoReloadTests.ts
@@ -13,8 +13,8 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
var assert = chai.assert;
-declare function fixture(id: string): void; window.HTMLImports.whenReady(() => {
-
+declare function fixture(id: string): void;
+window.HTMLImports.whenReady(() => {
Polymer({
is: 'autoreload-test-element',
behaviors: [TF.TensorBoard.AutoReloadBehavior],
diff --git a/tensorflow/tensorboard/components/tf_tensorboard/tf-tensorboard.html b/tensorflow/tensorboard/components/tf_tensorboard/tf-tensorboard.html
index f9ac4495c1..2df282c053 100644
--- a/tensorflow/tensorboard/components/tf_tensorboard/tf-tensorboard.html
+++ b/tensorflow/tensorboard/components/tf_tensorboard/tf-tensorboard.html
@@ -66,7 +66,7 @@ allows the user to toggle between various dashboards.
<paper-icon-button
icon="refresh"
on-tap="reload"
- disabled$="[[_modeIsGraphs(mode)]]"
+ disabled$="[[_isReloadDisabled(mode)]]"
id="reload-button"
></paper-icon-button>
<paper-icon-button
@@ -110,6 +110,7 @@ allows the user to toggle between various dashboards.
<tf-graph-dashboard
id="graphs"
backend="[[_backend]]"
+ debugger-data-enabled="[[_debuggerDataEnabled]]"
></tf-graph-dashboard>
</template>
@@ -215,6 +216,15 @@ allows the user to toggle between various dashboards.
type: Object,
computed: "_makeBackend(router, demoDir)",
},
+ _debuggerDataEnabled: {
+ type: Boolean,
+ value: function() {
+ // For now, Tensorboard only shows debugger data if the debugger_data GET param is set
+ // to enabled.
+ let match = window.location.href.match(/[&\?]debugger_data=enabled/);
+ return match && match.length == 1;
+ },
+ },
// Which tab is selected (scalars, graph, images etc).
mode: {
type: String,
@@ -260,6 +270,9 @@ allows the user to toggle between various dashboards.
}
return new TF.Backend.Backend(router);
},
+ _isReloadDisabled: function(mode) {
+ return !this._debuggerDataEnabled && this._modeIsGraphs(mode);
+ },
_modeIsScalars: function(mode) {
return mode === "scalars";
},
@@ -308,7 +321,10 @@ allows the user to toggle between various dashboards.
}
},
reload: function() {
- if (this.mode === "graphs" || this.mode === "embeddings") {
+ if (this._modeIsEmbeddings(this.mode)) {
+ return;
+ }
+ if (!this._debuggerDataEnabled && this._modeIsGraphs(this.mode)) {
return;
}
this.selectedDashboard().reload();
diff --git a/tensorflow/tensorboard/defs.bzl b/tensorflow/tensorboard/defs.bzl
index 3488978ab2..64f1960962 100644
--- a/tensorflow/tensorboard/defs.bzl
+++ b/tensorflow/tensorboard/defs.bzl
@@ -29,18 +29,25 @@ def tensorboard_typescript_genrule(name, srcs, typings=[], **kwargs):
src.endswith(".d.ts") or
not src.endswith(".ts")):
fail("srcs must be typescript sources in same package")
+ typings_out = [src[:-3] + ".d.ts" for src in srcs]
native.genrule(
name = name,
srcs = _DEFAULT_TYPINGS + typings + srcs,
- outs = [src[:-3] + ".js" for src in srcs],
+ outs = [src[:-3] + ".js" for src in srcs] + typings_out,
cmd = "$(location @com_microsoft_typescript//:tsc)" +
" --inlineSourceMap" +
" --inlineSources" +
+ " --declaration" +
" --outDir $(@D)" +
" $(SRCS)",
tools = ["@com_microsoft_typescript//:tsc"],
**kwargs
)
+ native.filegroup(
+ name = name + "_typings",
+ srcs = typings_out,
+ **kwargs
+ )
def tensorboard_ts_library(**kwargs):
"""Rules referencing this will be deleted from the codebase soon."""
diff --git a/tensorflow/tensorflow.bzl b/tensorflow/tensorflow.bzl
index a837a6012b..cc8afca511 100644
--- a/tensorflow/tensorflow.bzl
+++ b/tensorflow/tensorflow.bzl
@@ -21,7 +21,7 @@ load(
)
load(
- "//third_party/mkl:build_defs.bzl",
+ "//tensorflow/third_party/mkl:build_defs.bzl",
"if_mkl",
)
diff --git a/tensorflow/third_party/mkl/BUILD b/tensorflow/third_party/mkl/BUILD
new file mode 100644
index 0000000000..db6342ab72
--- /dev/null
+++ b/tensorflow/third_party/mkl/BUILD
@@ -0,0 +1,9 @@
+# This file is replaced on github with a real build rule.
+
+licenses(["notice"]) # Apache 2.0
+
+cc_library(
+ name = "intel_binary_blob",
+ srcs = [],
+ visibility = ["//visibility:public"],
+)
diff --git a/tensorflow/third_party/mkl/build_defs.bzl b/tensorflow/third_party/mkl/build_defs.bzl
new file mode 100644
index 0000000000..ca1308d311
--- /dev/null
+++ b/tensorflow/third_party/mkl/build_defs.bzl
@@ -0,0 +1,2 @@
+def if_mkl(if_true, if_false = []):
+ return if_false
diff --git a/tensorflow/tools/docs/parser.py b/tensorflow/tools/docs/parser.py
index cd4795568a..d5bb0da9e9 100644
--- a/tensorflow/tools/docs/parser.py
+++ b/tensorflow/tools/docs/parser.py
@@ -152,6 +152,27 @@ def replace_references(string, relative_path_to_root, duplicate_of):
string)
+# TODO(aselle): Collect these into a big list for all modules and functions
+# and make a rosetta stone page.
+def _handle_compatibility(doc):
+ """Parse and remove compatibility blocks from the main docstring.
+
+ Args:
+ doc: The docstring that contains compatibility notes"
+
+ Returns:
+ a tuple of the modified doc string and a hash that maps from compatibility
+ note type to the text of the note.
+ """
+ compatibility_notes = {}
+ match_compatibility = re.compile(r'[ \t]*@compatibility\((\w+)\)\s*\n'
+ r'((?:[^@\n]*\n)+)'
+ r'\s*@end_compatibility')
+ for f in match_compatibility.finditer(doc):
+ compatibility_notes[f.group(1)] = f.group(2)
+ return match_compatibility.subn(r'', doc)[0], compatibility_notes
+
+
def _md_docstring(py_object, relative_path_to_root, duplicate_of):
"""Get the docstring from an object and make it into nice Markdown.
@@ -177,6 +198,9 @@ def _md_docstring(py_object, relative_path_to_root, duplicate_of):
"""
# TODO(wicke): If this is a partial, use the .func docstring and add a note.
raw_docstring = _get_raw_docstring(py_object)
+ raw_docstring = replace_references(raw_docstring, relative_path_to_root,
+ duplicate_of)
+ raw_docstring, compatibility = _handle_compatibility(raw_docstring)
raw_lines = raw_docstring.split('\n')
# Define regular expressions used during parsing below.
@@ -189,10 +213,9 @@ def _md_docstring(py_object, relative_path_to_root, duplicate_of):
def is_section_start(i):
# Previous line is empty, line i is "Word:", and next line is indented.
- return (i > 0 and not raw_lines[i-1].strip() and
+ return (i > 0 and i < len(raw_lines) and not raw_lines[i-1].strip() and
re.match(section_re, raw_lines[i]) and
len(raw_lines) > i+1 and raw_lines[i+1].startswith(' '))
-
for i, line in enumerate(raw_lines):
if not in_special_section and is_section_start(i):
in_special_section = True
@@ -210,13 +233,14 @@ def _md_docstring(py_object, relative_path_to_root, duplicate_of):
lines.append(symbol_list_item_re.sub(r'* <b>`\1`</b>: ', line))
else:
lines.append(line)
-
docstring = '\n'.join(lines)
-
+ sorted_keys = compatibility.keys()
+ sorted_keys.sort()
+ for key in sorted_keys:
+ value = compatibility[key]
+ docstring += ('\n\n#### %s compatibility\n%s\n' % (key, value))
# TODO(deannarubin): Improve formatting for devsite
- # TODO(deannarubin): Interpret @compatibility and other formatting notes.
-
- return replace_references(docstring, relative_path_to_root, duplicate_of)
+ return docstring
def _get_arg_spec(func):
@@ -549,7 +573,7 @@ def _generate_markdown_for_module(full_name, duplicate_names, module,
_CODE_URL_PREFIX = (
- 'https://www.tensorflow.org/code/')
+ 'https://www.tensorflow.org/code/tensorflow/')
def generate_markdown(full_name, py_object,
@@ -631,7 +655,7 @@ def generate_markdown(full_name, py_object,
# Never include links outside this code base.
if not path.startswith('..'):
- markdown += '\n\nDefined in [`%s`](%s%s).\n\n' % (
+ markdown += '\n\nDefined in [`tensorflow/%s`](%s%s).\n\n' % (
path, _CODE_URL_PREFIX, path)
except TypeError: # getfile throws TypeError if py_object is a builtin.
markdown += '\n\nThis is an alias for a Python built-in.'
@@ -666,8 +690,8 @@ def generate_global_index(library_name, index, duplicate_of):
if parent_name in index and inspect.isclass(index[parent_name]):
# Skip methods (=functions with class parents).
continue
- symbol_links.append((index_name,
- _markdown_link(index_name, full_name,
+ symbol_links.append((full_name,
+ _markdown_link(full_name, full_name,
'.', duplicate_of)))
lines = ['# All symbols in %s' % library_name, '']
diff --git a/tensorflow/tools/docs/parser_test.py b/tensorflow/tools/docs/parser_test.py
index c92d7f968c..d77ed34453 100644
--- a/tensorflow/tools/docs/parser_test.py
+++ b/tensorflow/tools/docs/parser_test.py
@@ -51,6 +51,17 @@ def test_function_with_fancy_docstring(arg):
Returns:
arg: the input, and
arg: the input, again.
+
+ @compatibility(numpy)
+ NumPy has nothing as awesome as this function.
+ @end_compatibility
+
+ @compatibility(theano)
+ Theano has nothing as awesome as this function.
+
+ Check it out.
+ @end_compatibility
+
"""
return arg, arg
@@ -178,7 +189,6 @@ class ParserTest(googletest.TestCase):
# Make sure docstring shows up.
self.assertTrue(inspect.getdoc(test_function) in docs)
-
# Make sure the extracted signature is good.
self.assertTrue(
'test_function(unused_arg, unused_kwarg=\'default\')' in docs)
@@ -246,7 +256,6 @@ class ParserTest(googletest.TestCase):
py_object=test_function_with_fancy_docstring,
duplicate_of={}, duplicates={},
index=index, tree=tree, reverse_index={}, base_dir='/')
-
expected = '\n'.join([
'Function with a fancy docstring.',
'',
@@ -259,6 +268,22 @@ class ParserTest(googletest.TestCase):
'',
'* <b>`arg`</b>: the input, and',
'* <b>`arg`</b>: the input, again.',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '#### numpy compatibility',
+ 'NumPy has nothing as awesome as this function.',
+ '',
+ '',
+ '',
+ '#### theano compatibility',
+ 'Theano has nothing as awesome as this function.',
+ '',
+ 'Check it out.',
+ '',
+ '',
''])
self.assertTrue(expected in docs)
diff --git a/third_party/eigen3/BUILD b/third_party/eigen3/BUILD
index ff5323939d..08808115ad 100644
--- a/third_party/eigen3/BUILD
+++ b/third_party/eigen3/BUILD
@@ -14,6 +14,8 @@ exports_files(["LICENSE"])
load("//tensorflow:tensorflow.bzl", "if_mkl")
# INTEL_MKL end
+load("//tensorflow:tensorflow.bzl", "if_mkl")
+
cc_library(
name = "eigen3",
hdrs = glob(["unsupported/Eigen/CXX11/src/FixedPoint/*.h"]) + [
@@ -28,6 +30,7 @@ cc_library(
"unsupported/Eigen/CXX11/Tensor",
"unsupported/Eigen/CXX11/FixedPoint",
],
+ includes = if_mkl(["./mkl_include"]),
visibility = ["//visibility:public"],
# INTEL_MKL start
includes = if_mkl(["./mkl_include"]),
diff --git a/third_party/mkl/BUILD b/third_party/mkl/BUILD
index 7dd348975d..ddaf29a086 100644
--- a/third_party/mkl/BUILD
+++ b/third_party/mkl/BUILD
@@ -10,7 +10,10 @@ config_setting(
cc_library(
name = "intel_binary_blob",
+ srcs = [
+ "libiomp5.so",
+ "libmklml_intel.so",
+ ],
includes = ["."],
- srcs = ["libmklml_intel.so", "libiomp5.so"],
visibility = ["//visibility:public"],
)
diff --git a/third_party/mkl/build_defs.bzl b/third_party/mkl/build_defs.bzl
index da89330c5a..9a28b312c2 100644
--- a/third_party/mkl/build_defs.bzl
+++ b/third_party/mkl/build_defs.bzl
@@ -1,13 +1,13 @@
-# Macros for building MKL code.
-
-def if_mkl(if_true, if_false = []):
- """Shorthand for select()'ing on whether we're building with MKL.
-
- Returns a select statement which evaluates to if_true if we're building
- with MKL enabled. Otherwise, the select statement evaluates to if_false.
-
- """
- return select({
- "//third_party/mkl:using_mkl": if_true,
- "//conditions:default": if_false
- })
+# Macros for building MKL code.
+
+def if_mkl(if_true, if_false = []):
+ """Shorthand for select()'ing on whether we're building with MKL.
+
+ Returns a select statement which evaluates to if_true if we're building
+ with MKL enabled. Otherwise, the select statement evaluates to if_false.
+
+ """
+ return select({
+ "//third_party/mkl:using_mkl": if_true,
+ "//conditions:default": if_false
+ })