chore: import upstream snapshot with attribution
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:14:16 +08:00
commit 8a852e4b4e
36502 changed files with 9277225 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+58
View File
@@ -0,0 +1,58 @@
load("//tensorflow:tensorflow.bzl", "if_not_mobile")
load("//tensorflow/core/platform:rules_cc.bzl", "cc_library")
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:license"],
default_visibility = ["//tensorflow:internal"],
licenses = ["notice"],
)
filegroup(
name = "activity_watcher_headers",
srcs = [
"activity.h",
"activity_utils.h",
],
visibility = ["//visibility:public"],
)
cc_library(
name = "activity_watcher",
hdrs = ["activity.h"],
defines = if_not_mobile(["TF_ENABLE_ACTIVITY_WATCHER"]),
deps = [
"//tensorflow/core:lib",
"@com_google_absl//absl/container:flat_hash_map",
"@xla//xla/tsl/platform:types",
] + if_not_mobile([
":activity_watcher_impl",
]),
alwayslink = True,
)
cc_library(
name = "activity_watcher_impl",
srcs = [
"activity.cc",
],
hdrs = ["activity.h"],
deps = [
"//tensorflow/core:lib",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@xla//xla/tsl/platform:types",
],
alwayslink = True,
)
cc_library(
name = "activity_watcher_utils",
srcs = ["activity_utils.cc"],
hdrs = ["activity_utils.h"],
deps = [
":activity_watcher",
"//tensorflow/core:framework",
"@com_google_absl//absl/strings",
"@xla//xla/tsl/platform:types",
],
)
@@ -0,0 +1,39 @@
/* Copyright 2021 The TensorFlow Authors All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/core/activity_watcher/activity.h"
#include <atomic>
#include <memory>
#include "absl/base/attributes.h"
namespace tensorflow {
namespace activity_watcher {
ABSL_ATTRIBUTE_WEAK void MaybeEnableMultiWorkersWatching(
tsl::CoordinationServiceAgent* agent) {}
namespace tfw_internal {
ABSL_ATTRIBUTE_WEAK std::atomic<int> g_watcher_level(kWatcherDisabled);
ABSL_ATTRIBUTE_WEAK ActivityId RecordActivityStart(std::unique_ptr<Activity>) {
return kActivityNotRecorded;
}
ABSL_ATTRIBUTE_WEAK void RecordActivityEnd(ActivityId id) {}
} // namespace tfw_internal
} // namespace activity_watcher
} // namespace tensorflow
+187
View File
@@ -0,0 +1,187 @@
/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#ifndef TENSORFLOW_CORE_ACTIVITY_WATCHER_ACTIVITY_H_
#define TENSORFLOW_CORE_ACTIVITY_WATCHER_ACTIVITY_H_
#include <atomic>
#include <functional>
#include <memory>
#include <utility>
#include "absl/container/flat_hash_map.h"
#include "xla/tsl/platform/macros.h"
#include "xla/tsl/platform/types.h"
namespace tsl {
class CoordinationServiceAgent;
}
namespace tensorflow {
namespace activity_watcher {
using ActivityId = uint64_t;
constexpr ActivityId kActivityNotRecorded = 0;
constexpr int kWatcherDisabled = 0;
enum ActivityCategory {
kCollective = 0,
kRemoteFunction = 1,
kMisc = 2,
kDatasetOp = 3,
kTpuOp = 4,
kRendezvous = 5,
};
static std::string ToString(ActivityCategory category) {
switch (category) {
case ActivityCategory::kCollective:
return "Collective";
case ActivityCategory::kRemoteFunction:
return "Remote Function";
case ActivityCategory::kMisc:
return "Miscellaneous";
case ActivityCategory::kDatasetOp:
return "Dataset Op";
case ActivityCategory::kTpuOp:
return "TPU Op";
case ActivityCategory::kRendezvous:
return "Rendezvous";
}
return "Unknown";
}
// An activity to be recorded.
struct Activity {
using Attributes = absl::flat_hash_map<std::string, std::string>;
// A human readable title of the activity.
std::string title;
// The category of the activity.
ActivityCategory category = ActivityCategory::kMisc;
// Key/value pairs that are attached to the activity.
Attributes attributes;
Activity() = default;
Activity(std::string title, ActivityCategory category)
: title(std::move(title)), category(category) {}
Activity(std::string title, ActivityCategory category, Attributes attributes)
: title(std::move(title)),
category(category),
attributes(std::move(attributes)) {}
};
// Enable activity wathcer to send own workers activities to coordination
// service and also fetch all workers' activities.
void MaybeEnableMultiWorkersWatching(tsl::CoordinationServiceAgent* agent);
namespace tfw_internal {
#if defined(TF_ENABLE_ACTIVITY_WATCHER)
// Records an activity start without checking whether the watcher is enabled.
ActivityId RecordActivityStart(std::unique_ptr<Activity> activity);
// Records an activity end without checking whether the activity_id is valid.
void RecordActivityEnd(ActivityId activity_id);
TF_EXPORT extern std::atomic<int> g_watcher_level;
// Returns whether the activitity watcher is enabled.
inline bool WatcherEnabled(int level = 1) {
return g_watcher_level.load(std::memory_order_acquire) >= level;
}
#endif
// NOTE: Borrowed from boost C++ libraries because std::is_invocable_r is not
// available in Android NDK.
template <typename R, typename F, typename... Args>
struct is_invocable_r
: std::is_constructible<
std::function<R(Args...)>,
std::reference_wrapper<typename std::remove_reference<F>::type>> {};
} // namespace tfw_internal
template <typename F>
constexpr bool is_activity_generator =
tfw_internal::is_invocable_r<std::unique_ptr<Activity>, F>::value;
// Records an activity explicitly. Useful when the start and end of an activity
// happen in different threads. Generates the Activity only if activity
// watching is enabled, useful for avoiding expensive operations when activity
// watching is disabled.
// Example Usage:
// auto aid = ActivityStart([&]() {
// return std::make_unique<Activity>(
// op_name, category,
// Activity::Attributes{{"key1", value1}, {"key2", value2}});
// }, /*level=*/2);
// DoSomething();
// ActivityEnd(aid);
template <
typename ActivityGenerator,
std::enable_if_t<is_activity_generator<ActivityGenerator>, bool> = true>
inline ActivityId ActivityStart(ActivityGenerator&& gen, int level = 1) {
#if defined(TF_ENABLE_ACTIVITY_WATCHER)
if (TF_PREDICT_FALSE(tfw_internal::WatcherEnabled(level))) {
return tfw_internal::RecordActivityStart(
std::forward<ActivityGenerator>(gen)());
}
#endif
return kActivityNotRecorded;
}
inline void ActivityEnd(ActivityId id) {
#if defined(TF_ENABLE_ACTIVITY_WATCHER)
if (TF_PREDICT_FALSE(id != kActivityNotRecorded)) {
tfw_internal::RecordActivityEnd(id);
}
#endif
}
// ActivityScope marks a scope as an activity and record it with a global
// ActivityRecorder.
// Example Usage:
// {
// ActivityScope activity_scope([&]() {
// return std::make_unique<Activity>(
// op_name, ActivityCategory::kMisc,
// Activity::Attributes{{"key1", value1}, {"key2", value2}});
// }, /*level=*/2);
// DoSomething();
// }
class ActivityScope {
public:
template <
typename ActivityGenerator,
std::enable_if_t<is_activity_generator<ActivityGenerator>, bool> = true>
explicit ActivityScope(ActivityGenerator&& gen, int level = 1) {
activity_id_ = ActivityStart(std::forward<ActivityGenerator>(gen), level);
}
ActivityScope(ActivityScope&& activity) {
activity_id_ = activity.activity_id_;
activity.activity_id_ = kActivityNotRecorded;
}
~ActivityScope() { ActivityEnd(activity_id_); }
private:
ActivityId activity_id_;
ActivityScope(const ActivityScope&) = delete;
void operator=(const ActivityScope&) = delete;
};
} // namespace activity_watcher
} // namespace tensorflow
#endif // TENSORFLOW_CORE_ACTIVITY_WATCHER_ACTIVITY_H_
@@ -0,0 +1,60 @@
/* Copyright 2022 The TensorFlow Authors All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/core/activity_watcher/activity_utils.h"
#include <memory>
#include <string>
#include <utility>
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "xla/tsl/platform/types.h"
#include "tensorflow/core/activity_watcher/activity.h"
#include "tensorflow/core/framework/op_kernel.h"
namespace tensorflow {
namespace activity_watcher {
std::unique_ptr<Activity> ActivityFromContext(
OpKernelContext* context, std::string name, ActivityCategory category,
Activity::Attributes additional_attributes) {
Activity::Attributes attributes(std::move(additional_attributes));
if (context) {
attributes.merge(Activity::Attributes({
{"node_name", context->op_kernel().def().name()},
{"step_id", absl::StrCat(context->step_id())},
{"device", context->device()->name()},
{"op", context->op_kernel().def().op()},
{"iter_num", absl::StrCat(context->frame_iter().iter_id)},
{"inputs", absl::StrJoin(context->op_kernel().def().input(), "; ")},
{"original_node_names ", absl::StrJoin(context->op_kernel()
.def()
.experimental_debug_info()
.original_node_names(),
"; ")},
{"original_func_names", absl::StrJoin(context->op_kernel()
.def()
.experimental_debug_info()
.original_func_names(),
"; ")},
}));
}
return std::make_unique<Activity>(name, category, std::move(attributes));
}
} // namespace activity_watcher
} // namespace tensorflow
@@ -0,0 +1,38 @@
/* Copyright 2022 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#ifndef TENSORFLOW_CORE_ACTIVITY_WATCHER_ACTIVITY_UTILS_H_
#define TENSORFLOW_CORE_ACTIVITY_WATCHER_ACTIVITY_UTILS_H_
#include <memory>
#include "xla/tsl/platform/types.h"
#include "tensorflow/core/activity_watcher/activity.h"
namespace tensorflow {
class OpKernelContext;
namespace activity_watcher {
// A convenient way to create an activity. Writes OpKernelContext information
// and given attributes to a new activity and returns.
std::unique_ptr<Activity> ActivityFromContext(
OpKernelContext* context, std::string name, ActivityCategory category,
Activity::Attributes additional_attributes = Activity::Attributes());
} // namespace activity_watcher
} // namespace tensorflow
#endif // TENSORFLOW_CORE_ACTIVITY_WATCHER_ACTIVITY_UTILS_H_
+124
View File
@@ -0,0 +1,124 @@
# Description:
# Provides ApiDef access and ApiDef validation for TensorFlow.
#
# The following targets can be used to access ApiDefs:
# :base_api_def
# :python_api_def
# :java_api_def
load(
"@local_config_tensorrt//:build_defs.bzl",
"if_tensorrt",
)
load(
"@xla//xla/tsl/mkl:build_defs.bzl",
"if_mkl",
)
load(
"//tensorflow:tensorflow.bzl",
"tf_cc_binary",
"tf_cc_test",
)
load("//tensorflow/core/platform:rules_cc.bzl", "cc_library")
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:license"],
default_visibility = ["//visibility:private"],
licenses = ["notice"],
)
alias(
name = "base_api_def",
actual = "//tensorflow/core/api_def/base_api:base_api_def",
visibility = ["//tensorflow:internal"],
)
alias(
name = "python_api_def",
actual = "//tensorflow/core/api_def/python_api:python_api_def",
visibility = ["//tensorflow:internal"],
)
alias(
name = "java_api_def",
actual = "//tensorflow/core/api_def/java_api:java_api_def",
visibility = ["//tensorflow:internal"],
)
cc_library(
name = "excluded_ops_lib",
srcs = ["excluded_ops.cc"],
hdrs = ["excluded_ops.h"],
copts = if_mkl(["-DINTEL_MKL=1"]) + if_tensorrt(["-DGOOGLE_TENSORRT=1"]),
)
cc_library(
name = "update_api_def_lib",
srcs = ["update_api_def.cc"],
hdrs = ["update_api_def.h"],
deps = [
":excluded_ops_lib",
"//tensorflow/core:framework",
"//tensorflow/core:framework_internal",
"//tensorflow/core:lib",
"//tensorflow/core:lib_internal",
"//tensorflow/core:op_gen_lib",
"//tensorflow/core:ops",
"//tensorflow/core:protos_all_cc",
"@com_google_absl//absl/strings:str_format",
],
)
tf_cc_test(
name = "update_api_def_test",
srcs = ["update_api_def_test.cc"],
deps = [
":update_api_def_lib",
"//tensorflow/core:lib",
"//tensorflow/core:protos_all_cc",
"//tensorflow/core:test",
"//tensorflow/core:test_main",
],
)
tf_cc_binary(
name = "update_api_def",
srcs = [
"update_api_def_main.cc",
],
data = [
":base_api_def",
],
deps = [
":update_api_def_lib",
"//tensorflow/core:framework",
"//tensorflow/core:framework_internal",
"//tensorflow/core:lib",
],
)
tf_cc_test(
name = "api_test",
srcs = ["api_test.cc"],
data = [
":base_api_def",
":python_api_def",
],
deps = [
":excluded_ops_lib",
"//tensorflow/core:framework",
"//tensorflow/core:framework_internal",
"//tensorflow/core:lib",
"//tensorflow/core:lib_internal",
"//tensorflow/core:lib_test_internal",
"//tensorflow/core:op_gen_lib",
"//tensorflow/core:ops",
"//tensorflow/core:protos_all_cc",
"//tensorflow/core:test",
"//tensorflow/core:test_main",
"//tensorflow/core/platform:resource_loader",
"//tensorflow/core/tpu/ops:sparse_core_ops",
"//tensorflow/core/tpu/ops:sparse_core_preprocess_ops",
"//tensorflow/core/tpu/ops:tpu_copy_with_dynamic_shape_op",
],
)
+4
View File
@@ -0,0 +1,4 @@
This folder contains the ApiDef proto definitions of TensorFlow operations.
The canonical source of documentation for these operations can be found in
the base_api/ directory.
+353
View File
@@ -0,0 +1,353 @@
/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
// Test that validates tensorflow/core/api_def/base_api/api_def*.pbtxt files.
#include <ctype.h>
#include <algorithm>
#include <string>
#include <unordered_map>
#include <vector>
#include "tensorflow/core/api_def/excluded_ops.h"
#include "tensorflow/core/framework/api_def.pb.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/op_def.pb.h"
#include "tensorflow/core/framework/op_gen_lib.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/lib/core/status_test_util.h"
#include "tensorflow/core/lib/io/path.h"
#include "tensorflow/core/lib/strings/stringprintf.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/core/platform/protobuf.h"
#include "tensorflow/core/platform/resource_loader.h"
#include "tensorflow/core/platform/test.h"
#include "tensorflow/core/platform/types.h"
namespace tensorflow {
namespace {
constexpr char kApiDefFilePattern[] = "api_def_*.pbtxt";
std::string DefaultApiDefDir() {
return GetDataDependencyFilepath(
io::JoinPath("tensorflow", "core", "api_def", "base_api"));
}
std::string PythonApiDefDir() {
return GetDataDependencyFilepath(
io::JoinPath("tensorflow", "core", "api_def", "python_api"));
}
// Reads golden ApiDef files and returns a map from file name to ApiDef file
// contents.
void GetGoldenApiDefs(
Env* env, const std::string& api_files_dir,
std::unordered_map<std::string, ApiDef>* name_to_api_def) {
std::vector<std::string> matching_paths;
TF_CHECK_OK(env->GetMatchingPaths(
io::JoinPath(api_files_dir, kApiDefFilePattern), &matching_paths));
for (auto& file_path : matching_paths) {
std::string file_contents;
TF_CHECK_OK(ReadFileToString(env, file_path, &file_contents));
file_contents = PBTxtFromMultiline(file_contents);
ApiDefs api_defs;
QCHECK(tensorflow::protobuf::TextFormat::ParseFromString(file_contents,
&api_defs))
<< "Failed to load " << file_path;
CHECK_EQ(api_defs.op_size(), 1);
(*name_to_api_def)[api_defs.op(0).graph_op_name()] = api_defs.op(0);
}
}
void TestAllApiDefsHaveCorrespondingOp(
const OpList& ops,
const std::unordered_map<std::string, ApiDef>& api_defs_map) {
std::unordered_set<std::string> op_names;
for (const auto& op : ops.op()) {
op_names.insert(op.name());
}
for (const auto& name_and_api_def : api_defs_map) {
ASSERT_TRUE(op_names.find(name_and_api_def.first) != op_names.end())
<< name_and_api_def.first << " op has ApiDef but missing from ops. "
<< "Does api_def_" << name_and_api_def.first << " need to be deleted?";
}
}
void TestAllApiDefInputArgsAreValid(
const OpList& ops,
const std::unordered_map<std::string, ApiDef>& api_defs_map) {
for (const auto& op : ops.op()) {
const auto api_def_iter = api_defs_map.find(op.name());
if (api_def_iter == api_defs_map.end()) {
continue;
}
const auto& api_def = api_def_iter->second;
for (const auto& api_def_arg : api_def.in_arg()) {
bool found_arg = false;
for (const auto& op_arg : op.input_arg()) {
if (api_def_arg.name() == op_arg.name()) {
found_arg = true;
break;
}
}
ASSERT_TRUE(found_arg)
<< "Input argument " << api_def_arg.name()
<< " (overwritten in api_def_" << op.name()
<< ".pbtxt) is not defined in OpDef for " << op.name();
}
}
}
void TestAllApiDefOutputArgsAreValid(
const OpList& ops,
const std::unordered_map<std::string, ApiDef>& api_defs_map) {
for (const auto& op : ops.op()) {
const auto api_def_iter = api_defs_map.find(op.name());
if (api_def_iter == api_defs_map.end()) {
continue;
}
const auto& api_def = api_def_iter->second;
for (const auto& api_def_arg : api_def.out_arg()) {
bool found_arg = false;
for (const auto& op_arg : op.output_arg()) {
if (api_def_arg.name() == op_arg.name()) {
found_arg = true;
break;
}
}
ASSERT_TRUE(found_arg)
<< "Output argument " << api_def_arg.name()
<< " (overwritten in api_def_" << op.name()
<< ".pbtxt) is not defined in OpDef for " << op.name();
}
}
}
void TestAllApiDefAttributeNamesAreValid(
const OpList& ops,
const std::unordered_map<std::string, ApiDef>& api_defs_map) {
for (const auto& op : ops.op()) {
const auto api_def_iter = api_defs_map.find(op.name());
if (api_def_iter == api_defs_map.end()) {
continue;
}
const auto& api_def = api_def_iter->second;
for (const auto& api_def_attr : api_def.attr()) {
bool found_attr = false;
for (const auto& op_attr : op.attr()) {
if (api_def_attr.name() == op_attr.name()) {
found_attr = true;
}
}
ASSERT_TRUE(found_attr)
<< "Attribute " << api_def_attr.name() << " (overwritten in api_def_"
<< op.name() << ".pbtxt) is not defined in OpDef for " << op.name();
}
}
}
void TestDeprecatedAttributesSetCorrectly(
const std::unordered_map<std::string, ApiDef>& api_defs_map) {
for (const auto& name_and_api_def : api_defs_map) {
int num_deprecated_endpoints = 0;
const auto& api_def = name_and_api_def.second;
for (const auto& endpoint : api_def.endpoint()) {
if (endpoint.deprecated()) {
++num_deprecated_endpoints;
}
}
const auto& name = name_and_api_def.first;
ASSERT_TRUE(api_def.deprecation_message().empty() ||
num_deprecated_endpoints == 0)
<< "Endpoints are set to 'deprecated' for deprecated op " << name
<< ". If an op is deprecated (i.e. deprecation_message is set), "
<< "all the endpoints are deprecated implicitly and 'deprecated' "
<< "field should not be set.";
if (num_deprecated_endpoints > 0) {
ASSERT_NE(num_deprecated_endpoints, api_def.endpoint_size())
<< "All " << name << " endpoints are deprecated. Please, set "
<< "deprecation_message in api_def_" << name << ".pbtxt instead. "
<< "to indicate that the op is deprecated.";
}
}
}
void TestDeprecationVersionSetCorrectly(
const std::unordered_map<std::string, ApiDef>& api_defs_map) {
for (const auto& name_and_api_def : api_defs_map) {
const auto& name = name_and_api_def.first;
const auto& api_def = name_and_api_def.second;
if (api_def.deprecation_version() != 0) {
ASSERT_TRUE(api_def.deprecation_version() > 0)
<< "Found ApiDef with negative deprecation_version";
ASSERT_FALSE(api_def.deprecation_message().empty())
<< "ApiDef that includes deprecation_version > 0 must also specify "
<< "a deprecation_message. Op " << name
<< " has deprecation_version > 0 but deprecation_message is not set.";
}
}
}
class BaseApiTest : public ::testing::Test {
protected:
BaseApiTest() {
OpRegistry::Global()->Export(false, &ops_);
const std::vector<std::string> multi_line_fields = {"description"};
Env* env = Env::Default();
GetGoldenApiDefs(env, DefaultApiDefDir(), &api_defs_map_);
}
OpList ops_;
std::unordered_map<std::string, ApiDef> api_defs_map_;
};
// Check that all ops have an ApiDef.
TEST_F(BaseApiTest, AllOpsAreInApiDef) {
auto* excluded_ops = GetExcludedOps();
for (const auto& op : ops_.op()) {
if (excluded_ops->find(op.name()) != excluded_ops->end()) {
continue;
}
EXPECT_TRUE(api_defs_map_.find(op.name()) != api_defs_map_.end())
<< op.name() << " op does not have api_def_*.pbtxt file. "
<< "Please add api_def_" << op.name() << ".pbtxt file "
<< "under tensorflow/core/api_def/base_api/ directory.";
}
}
// Check that ApiDefs have a corresponding op.
TEST_F(BaseApiTest, AllApiDefsHaveCorrespondingOp) {
TestAllApiDefsHaveCorrespondingOp(ops_, api_defs_map_);
}
std::string GetOpDefHasDocStringError(const std::string& op_name) {
return absl::StrFormat(
"OpDef for %s has a doc string. "
"Doc strings must be defined in ApiDef instead of OpDef. "
"Please, add summary and descriptions in api_def_%s"
".pbtxt file instead",
op_name.c_str(), op_name.c_str());
}
// Check that OpDef's do not have descriptions and summaries.
// Descriptions and summaries must be in corresponding ApiDefs.
TEST_F(BaseApiTest, OpDefsShouldNotHaveDocs) {
auto* excluded_ops = GetExcludedOps();
for (const auto& op : ops_.op()) {
if (excluded_ops->find(op.name()) != excluded_ops->end()) {
continue;
}
ASSERT_TRUE(op.summary().empty()) << GetOpDefHasDocStringError(op.name());
ASSERT_TRUE(op.description().empty())
<< GetOpDefHasDocStringError(op.name());
for (const auto& arg : op.input_arg()) {
ASSERT_TRUE(arg.description().empty())
<< GetOpDefHasDocStringError(op.name());
}
for (const auto& arg : op.output_arg()) {
ASSERT_TRUE(arg.description().empty())
<< GetOpDefHasDocStringError(op.name());
}
for (const auto& attr : op.attr()) {
ASSERT_TRUE(attr.description().empty())
<< GetOpDefHasDocStringError(op.name());
}
}
}
// Checks that input arg names in an ApiDef match input
// arg names in corresponding OpDef.
TEST_F(BaseApiTest, AllApiDefInputArgsAreValid) {
TestAllApiDefInputArgsAreValid(ops_, api_defs_map_);
}
// Checks that output arg names in an ApiDef match output
// arg names in corresponding OpDef.
TEST_F(BaseApiTest, AllApiDefOutputArgsAreValid) {
TestAllApiDefOutputArgsAreValid(ops_, api_defs_map_);
}
// Checks that attribute names in an ApiDef match attribute
// names in corresponding OpDef.
TEST_F(BaseApiTest, AllApiDefAttributeNamesAreValid) {
TestAllApiDefAttributeNamesAreValid(ops_, api_defs_map_);
}
// Checks that deprecation is set correctly.
TEST_F(BaseApiTest, DeprecationSetCorrectly) {
TestDeprecatedAttributesSetCorrectly(api_defs_map_);
}
// Checks that deprecation_version is set for entire op only if
// deprecation_message is set.
TEST_F(BaseApiTest, DeprecationVersionSetCorrectly) {
TestDeprecationVersionSetCorrectly(api_defs_map_);
}
class PythonApiTest : public ::testing::Test {
protected:
PythonApiTest() {
OpRegistry::Global()->Export(false, &ops_);
const std::vector<std::string> multi_line_fields = {"description"};
Env* env = Env::Default();
GetGoldenApiDefs(env, PythonApiDefDir(), &api_defs_map_);
}
OpList ops_;
std::unordered_map<std::string, ApiDef> api_defs_map_;
};
// Check that ApiDefs have a corresponding op.
TEST_F(PythonApiTest, AllApiDefsHaveCorrespondingOp) {
TestAllApiDefsHaveCorrespondingOp(ops_, api_defs_map_);
}
// Checks that input arg names in an ApiDef match input
// arg names in corresponding OpDef.
TEST_F(PythonApiTest, AllApiDefInputArgsAreValid) {
TestAllApiDefInputArgsAreValid(ops_, api_defs_map_);
}
// Checks that output arg names in an ApiDef match output
// arg names in corresponding OpDef.
TEST_F(PythonApiTest, AllApiDefOutputArgsAreValid) {
TestAllApiDefOutputArgsAreValid(ops_, api_defs_map_);
}
// Checks that attribute names in an ApiDef match attribute
// names in corresponding OpDef.
TEST_F(PythonApiTest, AllApiDefAttributeNamesAreValid) {
TestAllApiDefAttributeNamesAreValid(ops_, api_defs_map_);
}
// Checks that deprecation is set correctly.
TEST_F(PythonApiTest, DeprecationSetCorrectly) {
TestDeprecatedAttributesSetCorrectly(api_defs_map_);
}
// Checks that deprecation_version is set for entire op only if
// deprecation_message is set.
TEST_F(PythonApiTest, DeprecationVersionSetCorrectly) {
TestDeprecationVersionSetCorrectly(api_defs_map_);
}
} // namespace
} // namespace tensorflow
+22
View File
@@ -0,0 +1,22 @@
# Description:
# Expose TensorFlow base api.
load("//tensorflow:tensorflow.default.bzl", "filegroup")
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:license"],
licenses = ["notice"],
)
filegroup(
name = "base_api_def",
srcs = glob(
[
"*",
],
exclude = [
"BUILD",
],
),
visibility = ["//tensorflow:internal"],
)
@@ -0,0 +1,16 @@
op {
graph_op_name: "Abort"
attr {
name: "error_msg"
description: <<END
A string which is the message associated with the exception.
END
}
summary: "Raise a exception to abort the process when called."
description: <<END
If exit_without_error is true, the process will exit normally,
otherwise it will exit with a SIGABORT signal.
Returns nothing but an exception.
END
}
@@ -0,0 +1,9 @@
op {
graph_op_name: "Abs"
summary: "Computes the absolute value of a tensor."
description: <<END
Given a tensor `x`, this operation returns a tensor containing the absolute
value of each element in `x`. For example, if x is an input element and y is
an output element, this operation computes \\(y = |x|\\).
END
}
@@ -0,0 +1,26 @@
op {
graph_op_name: "AccumulateNV2"
in_arg {
name: "inputs"
description: <<END
A list of `Tensor` objects, each with same shape and type.
END
}
attr {
name: "shape"
description: <<END
Shape of elements of `inputs`.
END
}
summary: "Returns the element-wise sum of a list of tensors."
description: <<END
`tf.accumulate_n_v2` performs the same operation as `tf.add_n`, but does not
wait for all of its inputs to be ready before beginning to sum. This can
save memory if inputs are ready at different times, since minimum temporary
storage is proportional to the output size rather than the inputs size.
Unlike the original `accumulate_n`, `accumulate_n_v2` is differentiable.
Returns a `Tensor` of same shape and type as the elements of `inputs`.
END
}
@@ -0,0 +1,32 @@
op {
graph_op_name: "AccumulatorApplyGradient"
in_arg {
name: "handle"
description: <<END
The handle to a accumulator.
END
}
in_arg {
name: "local_step"
description: <<END
The local_step value at which the gradient was computed.
END
}
in_arg {
name: "gradient"
description: <<END
A tensor of the gradient to be accumulated.
END
}
attr {
name: "dtype"
description: <<END
The data type of accumulated gradients. Needs to correspond to the type
of the accumulator.
END
}
summary: "Applies a gradient to a given accumulator."
description: <<END
Does not add if local_step is lesser than the accumulator's global_step.
END
}
@@ -0,0 +1,16 @@
op {
graph_op_name: "AccumulatorNumAccumulated"
in_arg {
name: "handle"
description: <<END
The handle to an accumulator.
END
}
out_arg {
name: "num_accumulated"
description: <<END
The number of gradients aggregated in the given accumulator.
END
}
summary: "Returns the number of gradients aggregated in the given accumulators."
}
@@ -0,0 +1,20 @@
op {
graph_op_name: "AccumulatorSetGlobalStep"
in_arg {
name: "handle"
description: <<END
The handle to an accumulator.
END
}
in_arg {
name: "new_global_step"
description: <<END
The new global_step value to set.
END
}
summary: "Updates the accumulator with a new value for global_step."
description: <<END
Logs warning if the accumulator's value is already higher than
new_global_step.
END
}
@@ -0,0 +1,36 @@
op {
graph_op_name: "AccumulatorTakeGradient"
in_arg {
name: "handle"
description: <<END
The handle to an accumulator.
END
}
in_arg {
name: "num_required"
description: <<END
Number of gradients required before we return an aggregate.
END
}
out_arg {
name: "average"
description: <<END
The average of the accumulated gradients.
END
}
attr {
name: "dtype"
description: <<END
The data type of accumulated gradients. Needs to correspond to the type
of the accumulator.
END
}
summary: "Extracts the average gradient in the given ConditionalAccumulator."
description: <<END
The op blocks until sufficient (i.e., more than num_required)
gradients have been accumulated. If the accumulator has already
aggregated more than num_required gradients, it returns the average of
the accumulated gradients. Also automatically increments the recorded
global_step in the accumulator by 1, and resets the aggregate to 0.
END
}
@@ -0,0 +1,11 @@
op {
graph_op_name: "Acos"
summary: "Computes acos of x element-wise."
description: <<END
Provided an input tensor, the `tf.math.acos` operation returns the inverse cosine of each element of the tensor. If `y = tf.math.cos(x)` then, `x = tf.math.acos(y)`.
Input range is `[-1, 1]` and the output has a range of `[0, pi]`.
END
}
@@ -0,0 +1,13 @@
op {
graph_op_name: "Acosh"
summary: "Computes inverse hyperbolic cosine of x element-wise."
description: <<END
Given an input tensor, the function computes inverse hyperbolic cosine of every element.
Input range is `[1, inf]`. It returns `nan` if the input lies outside the range.
```python
x = tf.constant([-2, -0.5, 1, 1.2, 200, 10000, float("inf")])
tf.math.acosh(x) ==> [nan nan 0. 0.62236255 5.9914584 9.903487 inf]
```
END
}
@@ -0,0 +1,13 @@
op {
graph_op_name: "Add"
summary: "Returns x + y element-wise."
description: <<END
*NOTE*: `Add` supports broadcasting. `AddN` does not. More about broadcasting
[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
Given two input tensors, the `tf.add` operation computes the sum for every element in the tensor.
Both input and output have a range `(-inf, inf)`.
END
}
@@ -0,0 +1,68 @@
op {
graph_op_name: "AddManySparseToTensorsMap"
in_arg {
name: "sparse_indices"
description: <<END
2-D. The `indices` of the minibatch `SparseTensor`.
`sparse_indices[:, 0]` must be ordered values in `[0, N)`.
END
}
in_arg {
name: "sparse_values"
description: <<END
1-D. The `values` of the minibatch `SparseTensor`.
END
}
in_arg {
name: "sparse_shape"
description: <<END
1-D. The `shape` of the minibatch `SparseTensor`.
The minibatch size `N == sparse_shape[0]`.
END
}
out_arg {
name: "sparse_handles"
description: <<END
1-D. The handles of the `SparseTensor` now stored in the
`SparseTensorsMap`. Shape: `[N]`.
END
}
attr {
name: "container"
description: <<END
The container name for the `SparseTensorsMap` created by this op.
END
}
attr {
name: "shared_name"
description: <<END
The shared name for the `SparseTensorsMap` created by this op.
If blank, the new Operation's unique name is used.
END
}
summary: "Add an `N`-minibatch `SparseTensor` to a `SparseTensorsMap`, return `N` handles."
description: <<END
A `SparseTensor` of rank `R` is represented by three tensors: `sparse_indices`,
`sparse_values`, and `sparse_shape`, where
```sparse_indices.shape[1] == sparse_shape.shape[0] == R```
An `N`-minibatch of `SparseTensor` objects is represented as a `SparseTensor`
having a first `sparse_indices` column taking values between `[0, N)`, where
the minibatch size `N == sparse_shape[0]`.
The input `SparseTensor` must have rank `R` greater than 1, and the first
dimension is treated as the minibatch dimension. Elements of the `SparseTensor`
must be sorted in increasing order of this first dimension. The stored
`SparseTensor` objects pointed to by each row of the output `sparse_handles`
will have rank `R-1`.
The `SparseTensor` values can then be read out as part of a minibatch by passing
the given keys as vector elements to `TakeManySparseFromTensorsMap`. To ensure
the correct `SparseTensorsMap` is accessed, ensure that the same
`container` and `shared_name` are passed to that Op. If no `shared_name`
is provided here, instead use the *name* of the Operation created by calling
`AddManySparseToTensorsMap` as the `shared_name` passed to
`TakeManySparseFromTensorsMap`. Ensure the Operations are colocated.
END
}
@@ -0,0 +1,12 @@
op {
graph_op_name: "AddN"
summary: "Add all input tensors element wise."
description: <<END
Inputs must be of same size and shape.
```python
x = [9, 7, 10]
tf.math.add_n(x) ==> 26
```
END
}
@@ -0,0 +1,58 @@
op {
graph_op_name: "AddSparseToTensorsMap"
in_arg {
name: "sparse_indices"
description: <<END
2-D. The `indices` of the `SparseTensor`.
END
}
in_arg {
name: "sparse_values"
description: <<END
1-D. The `values` of the `SparseTensor`.
END
}
in_arg {
name: "sparse_shape"
description: <<END
1-D. The `shape` of the `SparseTensor`.
END
}
out_arg {
name: "sparse_handle"
description: <<END
0-D. The handle of the `SparseTensor` now stored in the
`SparseTensorsMap`.
END
}
attr {
name: "container"
description: <<END
The container name for the `SparseTensorsMap` created by this op.
END
}
attr {
name: "shared_name"
description: <<END
The shared name for the `SparseTensorsMap` created by this op.
If blank, the new Operation's unique name is used.
END
}
summary: "Add a `SparseTensor` to a `SparseTensorsMap` return its handle."
description: <<END
A `SparseTensor` is represented by three tensors: `sparse_indices`,
`sparse_values`, and `sparse_shape`.
This operator takes the given `SparseTensor` and adds it to a container
object (a `SparseTensorsMap`). A unique key within this container is generated
in the form of an `int64`, and this is the value that is returned.
The `SparseTensor` can then be read out as part of a minibatch by passing
the key as a vector element to `TakeManySparseFromTensorsMap`. To ensure
the correct `SparseTensorsMap` is accessed, ensure that the same
`container` and `shared_name` are passed to that Op. If no `shared_name`
is provided here, instead use the *name* of the Operation created by calling
`AddSparseToTensorsMap` as the `shared_name` passed to
`TakeManySparseFromTensorsMap`. Ensure the Operations are colocated.
END
}
@@ -0,0 +1,8 @@
op {
graph_op_name: "AddV2"
summary: "Returns x + y element-wise."
description: <<END
*NOTE*: `Add` supports broadcasting. `AddN` does not. More about broadcasting
[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
END
}
@@ -0,0 +1,4 @@
op {
graph_op_name: "AdjustContrast"
summary: "Deprecated. Disallowed in GraphDef version >= 2."
}
@@ -0,0 +1,36 @@
op {
graph_op_name: "AdjustContrastv2"
endpoint {
name: "AdjustContrast"
}
in_arg {
name: "images"
description: <<END
Images to adjust. At least 3-D.
END
}
in_arg {
name: "contrast_factor"
description: <<END
A float multiplier for adjusting contrast.
END
}
out_arg {
name: "output"
description: <<END
The contrast-adjusted image or images.
END
}
summary: "Adjust the contrast of one or more images."
description: <<END
`images` is a tensor of at least 3 dimensions. The last 3 dimensions are
interpreted as `[height, width, channels]`. The other dimensions only
represent a collection of images, such as `[batch, height, width, channels].`
Contrast is adjusted independently for each channel of each image.
For each channel, the Op first computes the mean of the image pixels in the
channel and then adjusts each component of each pixel to
`(x - mean) * contrast_factor + mean`.
END
}
@@ -0,0 +1,30 @@
op {
graph_op_name: "AdjustHue"
in_arg {
name: "images"
description: <<END
Images to adjust. At least 3-D.
END
}
in_arg {
name: "delta"
description: <<END
A float delta to add to the hue.
END
}
out_arg {
name: "output"
description: <<END
The hue-adjusted image or images.
END
}
summary: "Adjust the hue of one or more images."
description: <<END
`images` is a tensor of at least 3 dimensions. The last dimension is
interpreted as channels, and must be three.
The input image is considered in the RGB colorspace. Conceptually, the RGB
colors are first mapped into HSV. A delta is then applied all the hue values,
and then remapped back to RGB colorspace.
END
}
@@ -0,0 +1,30 @@
op {
graph_op_name: "AdjustSaturation"
in_arg {
name: "images"
description: <<END
Images to adjust. At least 3-D.
END
}
in_arg {
name: "scale"
description: <<END
A float scale to add to the saturation.
END
}
out_arg {
name: "output"
description: <<END
The hue-adjusted image or images.
END
}
summary: "Adjust the saturation of one or more images."
description: <<END
`images` is a tensor of at least 3 dimensions. The last dimension is
interpreted as channels, and must be three.
The input image is considered in the RGB colorspace. Conceptually, the RGB
colors are first mapped into HSV. A scale is then applied all the saturation
values, and then remapped back to RGB colorspace.
END
}
@@ -0,0 +1,42 @@
op {
graph_op_name: "All"
endpoint {
name: "All"
}
endpoint {
name: "ReduceAll"
}
in_arg {
name: "input"
description: <<END
The tensor to reduce.
END
}
in_arg {
name: "reduction_indices"
rename_to: "axis"
description: <<END
The dimensions to reduce. Must be in the range
`[-rank(input), rank(input))`.
END
}
out_arg {
name: "output"
description: <<END
The reduced tensor.
END
}
attr {
name: "keep_dims"
description: <<END
If true, retain reduced dimensions with length 1.
END
}
summary: "Computes the \"logical and\" of elements across dimensions of a tensor."
description: <<END
Reduces `input` along the dimensions given in `reduction_indices`. Unless
`keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
`reduction_indices`. If `keep_dims` is true, the reduced dimensions are
retained with length 1.
END
}
@@ -0,0 +1,80 @@
op {
graph_op_name: "AllCandidateSampler"
in_arg {
name: "true_classes"
description: <<END
A batch_size * num_true matrix, in which each row contains the
IDs of the num_true target_classes in the corresponding original label.
END
}
out_arg {
name: "sampled_candidates"
description: <<END
A vector of length num_sampled, in which each element is
the ID of a sampled candidate.
END
}
out_arg {
name: "true_expected_count"
description: <<END
A batch_size * num_true matrix, representing
the number of times each candidate is expected to occur in a batch
of sampled candidates. If unique=true, then this is a probability.
END
}
out_arg {
name: "sampled_expected_count"
description: <<END
A vector of length num_sampled, for each sampled
candidate representing the number of times the candidate is expected
to occur in a batch of sampled candidates. If unique=true, then this is a
probability.
END
}
attr {
name: "num_true"
description: <<END
Number of true labels per context.
END
}
attr {
name: "num_sampled"
description: <<END
Number of candidates to produce.
END
}
attr {
name: "unique"
description: <<END
If unique is true, we sample with rejection, so that all sampled
candidates in a batch are unique. This requires some approximation to
estimate the post-rejection sampling probabilities.
END
}
attr {
name: "seed"
description: <<END
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.
END
}
attr {
name: "seed2"
description: <<END
An second seed to avoid seed collision.
END
}
summary: "Generates labels for candidate sampling with a learned unigram distribution."
description: <<END
See explanations of candidate sampling and the data formats at
go/candidate-sampling.
For each batch, this op picks a single set of sampled candidate labels.
The advantages of sampling candidates per-batch are simplicity and the
possibility of efficient dense matrix multiplication. The disadvantage is that
the sampled candidates must be chosen independently of the context and of the
true labels.
END
}
@@ -0,0 +1,68 @@
op {
graph_op_name: "AllToAll"
visibility: HIDDEN
in_arg {
name: "input"
description: <<END
The local input to the sum.
END
}
in_arg {
name: "group_assignment"
description: <<END
An int32 tensor with shape
[num_groups, num_replicas_per_group]. `group_assignment[i]` represents the
replica ids in the ith subgroup.
END
}
out_arg {
name: "output"
description: <<END
The exchanged result.
END
}
attr {
name: "T"
description: <<END
The type of elements to be exchanged.
END
}
attr {
name: "concat_dimension"
description: <<END
The dimension number to concatenate.
END
}
attr {
name: "split_dimension"
description: <<END
The dimension number to split.
END
}
attr {
name: "split_count"
description: <<END
The number of splits, this number must equal to the sub-group
size(group_assignment.get_shape()[1])
END
}
summary: "An Op to exchange data across TPU replicas."
description: <<END
On each replica, the input is split into `split_count` blocks along
`split_dimension` and send to the other replicas given group_assignment. After
receiving `split_count` - 1 blocks from other replicas, we concatenate the
blocks along `concat_dimension` as the output.
For example, suppose there are 2 TPU replicas:
replica 0 receives input: `[[A, B]]`
replica 1 receives input: `[[C, D]]`
group_assignment=`[[0, 1]]`
concat_dimension=0
split_dimension=1
split_count=2
replica 0's output: `[[A], [C]]`
replica 1's output: `[[B], [D]]`
END
}
@@ -0,0 +1,23 @@
op {
graph_op_name: "Angle"
summary: "Returns the argument of a complex number."
description: <<END
Given a tensor `input` of complex numbers, this operation returns a tensor of
type `float` that is the argument of each element in `input`. All elements in
`input` must be complex numbers of the form \\(a + bj\\), where *a*
is the real part and *b* is the imaginary part.
The argument returned by this operation is of the form \\(atan2(b, a)\\).
For example:
```
# tensor 'input' is [-2.25 + 4.75j, 3.25 + 5.75j]
tf.math.angle(input) ==> [2.0132, 1.056]
```
@compatibility(numpy)
Equivalent to np.angle.
@end_compatibility
END
}
@@ -0,0 +1,33 @@
op {
graph_op_name: "AnonymousHashTable"
visibility: HIDDEN
out_arg {
name: "table_handle"
description: <<END
The resource handle to the newly created hash-table resource.
END
}
attr {
name: "key_dtype"
description: <<END
Type of the table keys.
END
}
attr {
name: "value_dtype"
description: <<END
Type of the table values.
END
}
summary: "Creates a uninitialized anonymous hash table."
description: <<END
This op creates a new anonymous hash table (as a resource) everytime
it is executed, with the specified dtype of its keys and values,
returning the resource handle. Before using the table you will have
to initialize it. After initialization the table will be
immutable. The table is anonymous in the sense that it can only be
accessed by the returned resource handle (e.g. it cannot be looked up
by a name in a resource manager). The table will be automatically
deleted when all resource handles pointing to it are gone.
END
}
@@ -0,0 +1,13 @@
op {
graph_op_name: "AnonymousIterator"
out_arg {
name: "handle"
description: <<END
A handle to the iterator that can be passed to a "MakeIterator" or
"IteratorGetNext" op. In contrast to Iterator, AnonymousIterator prevents
resource sharing by name, and does not keep a reference to the resource
container.
END
}
summary: "A container for an iterator resource."
}
@@ -0,0 +1,20 @@
op {
graph_op_name: "AnonymousIteratorV2"
visibility: HIDDEN
out_arg {
name: "handle"
description: <<END
A handle to the iterator that can be passed to a "MakeIterator" or
"IteratorGetNext" op. In contrast to Iterator, AnonymousIterator prevents
resource sharing by name, and does not keep a reference to the resource
container.
END
}
out_arg {
name: "deleter"
description: <<END
A variant deleter that should be passed into the op that deletes the iterator.
END
}
summary: "A container for an iterator resource."
}
@@ -0,0 +1,14 @@
op {
graph_op_name: "AnonymousIteratorV3"
visibility: HIDDEN
out_arg {
name: "handle"
description: <<END
A handle to the iterator that can be passed to a "MakeIterator" or
"IteratorGetNext" op. In contrast to Iterator, AnonymousIterator prevents
resource sharing by name, and does not keep a reference to the resource
container.
END
}
summary: "A container for an iterator resource."
}
@@ -0,0 +1,4 @@
op {
graph_op_name: "AnonymousMemoryCache"
visibility: HIDDEN
}
@@ -0,0 +1,20 @@
op {
graph_op_name: "AnonymousMultiDeviceIterator"
visibility: HIDDEN
out_arg {
name: "handle"
description: <<END
A handle to a multi device iterator that can be passed to a
"MultiDeviceIteratorGetNextFromShard" op. In contrast to MultiDeviceIterator,
AnonymousIterator prevents resource sharing by name, and does not keep a
reference to the resource container.
END
}
out_arg {
name: "deleter"
description: <<END
A variant deleter that should be passed into the op that deletes the iterator.
END
}
summary: "A container for a multi device iterator resource."
}
@@ -0,0 +1,14 @@
op {
graph_op_name: "AnonymousMultiDeviceIteratorV3"
visibility: HIDDEN
out_arg {
name: "handle"
description: <<END
A handle to a multi device iterator that can be passed to a
"MultiDeviceIteratorGetNextFromShard" op. In contrast to MultiDeviceIterator,
AnonymousIterator prevents resource sharing by name, and does not keep a
reference to the resource container.
END
}
summary: "A container for a multi device iterator resource."
}
@@ -0,0 +1,65 @@
op {
graph_op_name: "AnonymousMutableDenseHashTable"
visibility: HIDDEN
in_arg {
name: "empty_key"
description: <<END
The key used to represent empty key buckets internally. Must not
be used in insert or lookup operations.
END
}
out_arg {
name: "table_handle"
description: <<END
The resource handle to the newly created hash-table resource.
END
}
attr {
name: "key_dtype"
description: <<END
Type of the table keys.
END
}
attr {
name: "value_dtype"
description: <<END
Type of the table values.
END
}
attr {
name: "value_shape"
description: <<END
The shape of each value.
END
}
attr {
name: "initial_num_buckets"
description: <<END
The initial number of hash table buckets. Must be a power
to 2.
END
}
attr {
name: "max_load_factor"
description: <<END
The maximum ratio between number of entries and number of
buckets before growing the table. Must be between 0 and 1.
END
}
summary: "Creates an empty anonymous mutable hash table that uses tensors as the backing store."
description: <<END
This op creates a new anonymous mutable hash table (as a resource) everytime
it is executed, with the specified dtype of its keys and values,
returning the resource handle. Each value must be a scalar.
Data can be inserted into the table using
the insert operations. It does not support the initialization operation.
It uses "open addressing" with quadratic reprobing to resolve
collisions.
The table is anonymous in the sense that it can only be
accessed by the returned resource handle (e.g. it cannot be looked up
by a name in a resource manager). The table will be automatically
deleted when all resource handles pointing to it are gone.
END
}
@@ -0,0 +1,34 @@
op {
graph_op_name: "AnonymousMutableHashTable"
visibility: HIDDEN
out_arg {
name: "table_handle"
description: <<END
The resource handle to the newly created hash-table resource.
END
}
attr {
name: "key_dtype"
description: <<END
Type of the table keys.
END
}
attr {
name: "value_dtype"
description: <<END
Type of the table values.
END
}
summary: "Creates an empty anonymous mutable hash table."
description: <<END
This op creates a new anonymous mutable hash table (as a resource) everytime
it is executed, with the specified dtype of its keys and values,
returning the resource handle. Each value must be a scalar.
Data can be inserted into the table using
the insert operations. It does not support the initialization operation.
The table is anonymous in the sense that it can only be
accessed by the returned resource handle (e.g. it cannot be looked up
by a name in a resource manager). The table will be automatically
deleted when all resource handles pointing to it are gone.
END
}
@@ -0,0 +1,34 @@
op {
graph_op_name: "AnonymousMutableHashTableOfTensors"
visibility: HIDDEN
out_arg {
name: "table_handle"
description: <<END
The resource handle to the newly created hash-table resource.
END
}
attr {
name: "key_dtype"
description: <<END
Type of the table keys.
END
}
attr {
name: "value_dtype"
description: <<END
Type of the table values.
END
}
summary: "Creates an empty anonymous mutable hash table of vector values."
description: <<END
This op creates a new anonymous mutable hash table (as a resource) everytime
it is executed, with the specified dtype of its keys and values,
returning the resource handle. Each value must be a vector.
Data can be inserted into the table using
the insert operations. It does not support the initialization operation.
The table is anonymous in the sense that it can only be
accessed by the returned resource handle (e.g. it cannot be looked up
by a name in a resource manager). The table will be automatically
deleted when all resource handles pointing to it are gone.
END
}
@@ -0,0 +1,4 @@
op {
graph_op_name: "AnonymousRandomSeedGenerator"
visibility: HIDDEN
}
@@ -0,0 +1,4 @@
op {
graph_op_name: "AnonymousSeedGenerator"
visibility: HIDDEN
}
@@ -0,0 +1,42 @@
op {
graph_op_name: "Any"
endpoint {
name: "Any"
}
endpoint {
name: "ReduceAny"
}
in_arg {
name: "input"
description: <<END
The tensor to reduce.
END
}
in_arg {
name: "reduction_indices"
rename_to: "axis"
description: <<END
The dimensions to reduce. Must be in the range
`[-rank(input), rank(input))`.
END
}
out_arg {
name: "output"
description: <<END
The reduced tensor.
END
}
attr {
name: "keep_dims"
description: <<END
If true, retain reduced dimensions with length 1.
END
}
summary: "Computes the \"logical or\" of elements across dimensions of a tensor."
description: <<END
Reduces `input` along the dimensions given in `reduction_indices`. Unless
`keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in
`reduction_indices`. If `keep_dims` is true, the reduced dimensions are
retained with length 1.
END
}
@@ -0,0 +1,78 @@
op {
graph_op_name: "ApplyAdaMax"
visibility: HIDDEN
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "m"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "v"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "beta1_power"
description: <<END
Must be a scalar.
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "beta1"
description: <<END
Momentum factor. Must be a scalar.
END
}
in_arg {
name: "beta2"
description: <<END
Momentum factor. Must be a scalar.
END
}
in_arg {
name: "epsilon"
description: <<END
Ridge term. Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var, m, and v tensors will be protected
by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
summary: "Update \'*var\' according to the AdaMax algorithm."
description: <<END
m_t <- beta1 * m_{t-1} + (1 - beta1) * g
v_t <- max(beta2 * v_{t-1}, abs(g))
variable <- variable - learning_rate / (1 - beta1^t) * m_t / (v_t + epsilon)
END
}
@@ -0,0 +1,65 @@
op {
graph_op_name: "ApplyAdadelta"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "accum"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "accum_update"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "rho"
description: <<END
Decay factor. Must be a scalar.
END
}
in_arg {
name: "epsilon"
description: <<END
Constant factor. Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
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.
END
}
summary: "Update \'*var\' according to the adadelta scheme."
description: <<END
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;
END
}
@@ -0,0 +1,46 @@
op {
graph_op_name: "ApplyAdagrad"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "accum"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var and accum tensors will be protected
by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
summary: "Update \'*var\' according to the adagrad scheme."
description: <<END
accum += grad * grad
var -= lr * grad * (1 / sqrt(accum))
END
}
@@ -0,0 +1,65 @@
op {
graph_op_name: "ApplyAdagradDA"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "gradient_accumulator"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "gradient_squared_accumulator"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "l1"
description: <<END
L1 regularization. Must be a scalar.
END
}
in_arg {
name: "l2"
description: <<END
L2 regularization. Must be a scalar.
END
}
in_arg {
name: "global_step"
description: <<END
Training step number. Must be a scalar.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If True, updating of the var and accum tensors will be protected by
a lock; otherwise the behavior is undefined, but may exhibit less contention.
END
}
summary: "Update \'*var\' according to the proximal adagrad scheme."
}
@@ -0,0 +1,53 @@
op {
graph_op_name: "ApplyAdagradV2"
visibility: HIDDEN
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "accum"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "epsilon"
description: <<END
Constant factor. Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var and accum tensors will be protected
by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
summary: "Update \'*var\' according to the adagrad scheme."
description: <<END
accum += grad * grad
var -= lr * grad * (1 / sqrt(accum))
END
}
@@ -0,0 +1,90 @@
op {
graph_op_name: "ApplyAdam"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "m"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "v"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "beta1_power"
description: <<END
Must be a scalar.
END
}
in_arg {
name: "beta2_power"
description: <<END
Must be a scalar.
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "beta1"
description: <<END
Momentum factor. Must be a scalar.
END
}
in_arg {
name: "beta2"
description: <<END
Momentum factor. Must be a scalar.
END
}
in_arg {
name: "epsilon"
description: <<END
Ridge term. Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var, m, and v tensors will be protected
by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
attr {
name: "use_nesterov"
description: <<END
If `True`, uses the nesterov update.
END
}
summary: "Update \'*var\' according to the Adam algorithm."
description: <<END
$$\text{lr}_t := \mathrm{lr} \cdot \frac{\sqrt{1 - \beta_2^t}}{1 - \beta_1^t}$$
$$m_t := \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g$$
$$v_t := \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g^2$$
$$\text{var} := \begin{cases} \text{var} - (m_t \beta_1 + g \cdot (1 - \beta_1))\cdot\text{lr}_t/(\sqrt{v_t} + \epsilon), &\text{if use_nesterov}\\\\ \text{var} - m_t \cdot \text{lr}_t /(\sqrt{v_t} + \epsilon), &\text{otherwise} \end{cases}$$
END
}
@@ -0,0 +1,65 @@
op {
graph_op_name: "ApplyAddSign"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "m"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "alpha"
description: <<END
Must be a scalar.
END
}
in_arg {
name: "sign_decay"
description: <<END
Must be a scalar.
END
}
in_arg {
name: "beta"
description: <<END
Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var and m tensors is
protected by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
summary: "Update \'*var\' according to the AddSign update."
description: <<END
m_t <- beta1 * m_{t-1} + (1 - beta1) * g
update <- (alpha + sign_decay * sign(g) *sign(m)) * g
variable <- variable - lr_t * update
END
}
@@ -0,0 +1,92 @@
op {
graph_op_name: "ApplyCenteredRMSProp"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "mg"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "ms"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "mom"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "rho"
description: <<END
Decay rate. Must be a scalar.
END
}
in_arg {
name: "momentum"
description: <<END
Momentum Scale. Must be a scalar.
END
}
in_arg {
name: "epsilon"
description: <<END
Ridge term. Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var, mg, ms, and mom tensors is
protected by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
summary: "Update \'*var\' according to the centered RMSProp algorithm."
description: <<END
The centered RMSProp algorithm uses an estimate of the centered second moment
(i.e., the variance) for normalization, as opposed to regular RMSProp, which
uses the (uncentered) second moment. This often helps with training, but is
slightly more expensive in terms of computation and memory.
Note that in dense implementation of this algorithm, mg, ms, and mom will
update even if the grad is zero, but in this sparse implementation, mg, ms,
and mom will not update in iterations during which the grad is zero.
mean_square = decay * mean_square + (1-decay) * gradient ** 2
mean_grad = decay * mean_grad + (1-decay) * gradient
Delta = learning_rate * gradient / sqrt(mean_square + epsilon - mean_grad ** 2)
mg <- rho * mg_{t-1} + (1-rho) * grad
ms <- rho * ms_{t-1} + (1-rho) * grad * grad
mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms - mg * mg + epsilon)
var <- var - mom
END
}
@@ -0,0 +1,73 @@
op {
graph_op_name: "ApplyFtrl"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "accum"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "linear"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "l1"
description: <<END
L1 regularization. Must be a scalar.
END
}
in_arg {
name: "l2"
description: <<END
L2 regularization. Must be a scalar.
END
}
in_arg {
name: "lr_power"
description: <<END
Scaling factor. Must be a scalar.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var and accum tensors will be protected
by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
summary: "Update \'*var\' according to the Ftrl-proximal scheme."
description: <<END
accum_new = accum + grad * grad
linear += grad - (accum_new^(-lr_power) - accum^(-lr_power)) / lr * var
quadratic = 1.0 / (accum_new^(lr_power) * lr) + 2 * l2
var = (sign(linear) * l1 - linear) / quadratic if |linear| > l1 else 0.0
accum = accum_new
END
}
@@ -0,0 +1,75 @@
op {
graph_op_name: "ApplyFtrlV2"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "accum"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "linear"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "l1"
description: <<END
L1 regularization. Must be a scalar.
END
}
in_arg {
name: "l2"
description: <<END
L2 shrinkage regularization. Must be a scalar.
END
}
in_arg {
name: "lr_power"
description: <<END
Scaling factor. Must be a scalar.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var and accum tensors will be protected
by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
summary: "Update \'*var\' according to the Ftrl-proximal scheme."
description: <<END
grad_with_shrinkage = grad + 2 * l2_shrinkage * var
accum_new = accum + grad * grad
linear += grad_with_shrinkage -
(accum_new^(-lr_power) - accum^(-lr_power)) / lr * var
quadratic = 1.0 / (accum_new^(lr_power) * lr) + 2 * l2
var = (sign(linear) * l1 - linear) / quadratic if |linear| > l1 else 0.0
accum = accum_new
END
}
@@ -0,0 +1,35 @@
op {
graph_op_name: "ApplyGradientDescent"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "alpha"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "delta"
description: <<END
The change.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, the subtraction will be protected by a lock;
otherwise the behavior is undefined, but may exhibit less contention.
END
}
summary: "Update \'*var\' by subtracting \'alpha\' * \'delta\' from it."
}
@@ -0,0 +1,62 @@
op {
graph_op_name: "ApplyMomentum"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "accum"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
in_arg {
name: "momentum"
description: <<END
Momentum. Must be a scalar.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var and accum tensors will be protected
by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
attr {
name: "use_nesterov"
description: <<END
If `True`, the tensor passed to compute grad will be
var - lr * momentum * accum, so in the end, the var you get is actually
var - lr * momentum * accum.
END
}
summary: "Update \'*var\' according to the momentum scheme."
description: <<END
Set use_nesterov = True if you want to use Nesterov momentum.
accum = accum * momentum + grad
var -= lr * accum
END
}
@@ -0,0 +1,65 @@
op {
graph_op_name: "ApplyPowerSign"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "m"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "logbase"
description: <<END
Must be a scalar.
END
}
in_arg {
name: "sign_decay"
description: <<END
Must be a scalar.
END
}
in_arg {
name: "beta"
description: <<END
Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var and m tensors is
protected by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
summary: "Update \'*var\' according to the AddSign update."
description: <<END
m_t <- beta1 * m_{t-1} + (1 - beta1) * g
update <- exp(logbase * sign_decay * sign(g) * sign(m_t)) * g
variable <- variable - lr_t * update
END
}
@@ -0,0 +1,58 @@
op {
graph_op_name: "ApplyProximalAdagrad"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "accum"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "l1"
description: <<END
L1 regularization. Must be a scalar.
END
}
in_arg {
name: "l2"
description: <<END
L2 regularization. Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If True, updating of the var and accum tensors will be protected by
a lock; otherwise the behavior is undefined, but may exhibit less contention.
END
}
summary: "Update \'*var\' and \'*accum\' according to FOBOS with Adagrad learning rate."
description: <<END
accum += grad * grad
prox_v = var - lr * grad * (1 / sqrt(accum))
var = sign(prox_v)/(1+lr*l2) * max{|prox_v|-lr*l1,0}
END
}
@@ -0,0 +1,51 @@
op {
graph_op_name: "ApplyProximalGradientDescent"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "alpha"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "l1"
description: <<END
L1 regularization. Must be a scalar.
END
}
in_arg {
name: "l2"
description: <<END
L2 regularization. Must be a scalar.
END
}
in_arg {
name: "delta"
description: <<END
The change.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If True, the subtraction will be protected by a lock;
otherwise the behavior is undefined, but may exhibit less contention.
END
}
summary: "Update \'*var\' as FOBOS algorithm with fixed learning rate."
description: <<END
prox_v = var - alpha * delta
var = sign(prox_v)/(1+alpha*l2) * max{|prox_v|-alpha*l1,0}
END
}
@@ -0,0 +1,72 @@
op {
graph_op_name: "ApplyRMSProp"
in_arg {
name: "var"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "ms"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "mom"
description: <<END
Should be from a Variable().
END
}
in_arg {
name: "lr"
description: <<END
Scaling factor. Must be a scalar.
END
}
in_arg {
name: "rho"
description: <<END
Decay rate. Must be a scalar.
END
}
in_arg {
name: "epsilon"
description: <<END
Ridge term. Must be a scalar.
END
}
in_arg {
name: "grad"
description: <<END
The gradient.
END
}
out_arg {
name: "out"
description: <<END
Same as "var".
END
}
attr {
name: "use_locking"
description: <<END
If `True`, updating of the var, ms, and mom tensors is protected
by a lock; otherwise the behavior is undefined, but may exhibit less
contention.
END
}
summary: "Update \'*var\' according to the RMSProp algorithm."
description: <<END
Note that in dense implementation of this algorithm, ms and mom will
update even if the grad is zero, but in this sparse implementation, ms
and mom will not update in iterations during which the grad is zero.
mean_square = decay * mean_square + (1-decay) * gradient ** 2
Delta = learning_rate * gradient / sqrt(mean_square + epsilon)
ms <- rho * ms_{t-1} + (1-rho) * grad * grad
mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms + epsilon)
var <- var - mom
END
}
@@ -0,0 +1,65 @@
op {
graph_op_name: "ApproxTopK"
endpoint {
name: "ApproxTopK"
}
in_arg {
name: "input"
description: "Array to search. Must be at least 1-D of the floating type"
}
out_arg {
name: "values"
description: <<END
The min/max k values along the `reduction_dimension` of the `input` operand.
The dimension are the same as the `input` operand except for the
`reduction_dimension`: when `aggregate_to_topk` is true, the reduction
dimension is `k`; otherwise, it is greater equals to `k` where the size is
implementation-defined.
END
}
out_arg {
name: "indices"
description: <<END
The indices of `values` along the `reduction_dimension` of the `input` operand.
END
}
attr {
name: "k"
description: "Specifies the number of min/max-k."
}
attr {
name: "reduction_dimension"
description: "Integer dimension along which to search. Default: -1."
}
attr {
name: "recall_target"
description: "Recall target for the approximation. Range in (0,1]"
}
attr {
name: "is_max_k"
description: "When true, computes max-k; otherwise computes min-k."
}
attr {
name: "reduction_input_size_override"
description: <<END
When set to a positive value, it overrides the size determined by
`input[reduction_dim]` for evaluating the recall. This option is useful when
the given `input` is only a subset of the overall computation in SPMD or
distributed pipelines, where the true input size cannot be deferred by the
`input` shape.
END
}
attr {
name: "aggregate_to_topk"
description: <<END
When true, aggregates approximate results to top-k. When false, returns the
approximate results. The number of the approximate results is implementation
defined and is greater equals to the specified `k`.
END
}
summary: "Returns min/max k values and their indices of the input operand in an approximate manner."
description: <<END
See https://arxiv.org/abs/2206.14286 for the algorithm details.
This op is only optimized on TPU currently.
END
}
@@ -0,0 +1,4 @@
op {
graph_op_name: "ApproximateEqual"
summary: "Returns the truth value of abs(x-y) < tolerance element-wise."
}
@@ -0,0 +1,25 @@
op {
graph_op_name: "ArgMax"
in_arg {
name: "dimension"
description: <<END
int16, int32 or int64, must be in the range `[-rank(input), rank(input))`.
Describes which dimension of the input Tensor to reduce across. For vectors,
use dimension = 0.
END
}
summary: "Returns the index with the largest value across dimensions of a tensor."
description: <<END
Note that in case of ties the identity of the return value is not guaranteed.
Usage:
```python
import tensorflow as tf
a = [1, 10, 26.9, 2.8, 166.32, 62.3]
b = tf.math.argmax(input = a)
c = tf.keras.backend.eval(b)
# c = 4
# here a[4] = 166.32 which is the largest element of a across axis 0
```
END
}
@@ -0,0 +1,25 @@
op {
graph_op_name: "ArgMin"
in_arg {
name: "dimension"
description: <<END
int32 or int64, must be in the range `[-rank(input), rank(input))`.
Describes which dimension of the input Tensor to reduce across. For vectors,
use dimension = 0.
END
}
summary: "Returns the index with the smallest value across dimensions of a tensor."
description: <<END
Note that in case of ties the identity of the return value is not guaranteed.
Usage:
```python
import tensorflow as tf
a = [1, 10, 26.9, 2.8, 166.32, 62.3]
b = tf.math.argmin(input = a)
c = tf.keras.backend.eval(b)
# c = 0
# here a[0] = 1 which is the smallest element of a across axis 0
```
END
}
@@ -0,0 +1,55 @@
op {
graph_op_name: "AsString"
attr {
name: "precision"
description: <<END
The post-decimal precision to use for floating point numbers.
Only used if precision > -1.
END
}
attr {
name: "scientific"
description: <<END
Use scientific notation for floating point numbers.
Can't be specified to `True` when `shortest` is set to `True`.
END
}
attr {
name: "shortest"
description: <<END
Use shortest representation (either scientific or standard) for
floating point numbers.
Can't be specified to `True` when `scientific` is set to `True`.
END
}
attr {
name: "width"
description: <<END
Pad pre-decimal numbers to this width.
Applies to both floating point and integer numbers.
Only used if width > -1.
END
}
attr {
name: "fill"
description: <<END
The value to pad if width > -1. If empty, pads with spaces.
Another typical value is '0'. String cannot be longer than 1 character.
END
}
summary: "Converts each entry in the given tensor to strings."
description: <<END
Supports many numeric types and boolean.
For Unicode, see the
[https://www.tensorflow.org/text/guide/unicode](Working with Unicode text)
tutorial.
Examples:
>>> tf.strings.as_string([3, 2])
<tf.Tensor: shape=(2,), dtype=string, numpy=array([b'3', b'2'], dtype=object)>
>>> tf.strings.as_string([3.1415926, 2.71828], precision=2).numpy()
array([b'3.14', b'2.72'], dtype=object)
END
}
@@ -0,0 +1,22 @@
op {
graph_op_name: "Asin"
summary: "Computes the trignometric inverse sine of x element-wise."
description: <<END
The `tf.math.asin` operation returns the inverse of `tf.math.sin`, such that
if `y = tf.math.sin(x)` then, `x = tf.math.asin(y)`.
**Note**: The output of `tf.math.asin` will lie within the invertible range
of sine, i.e [-pi/2, pi/2].
For example:
```python
# Note: [1.047, 0.785] ~= [(pi/3), (pi/4)]
x = tf.constant([1.047, 0.785])
y = tf.math.sin(x) # [0.8659266, 0.7068252]
tf.math.asin(y) # [1.047, 0.785] = x
```
END
}
@@ -0,0 +1,14 @@
op {
graph_op_name: "Asinh"
summary: "Computes inverse hyperbolic sine of x element-wise."
description: <<END
Given an input tensor, this function computes inverse hyperbolic sine
for every element in the tensor. Both input and output has a range of
`[-inf, inf]`.
```python
x = tf.constant([-float("inf"), -2, -0.5, 1, 1.2, 200, 10000, float("inf")])
tf.math.asinh(x) ==> [-inf -1.4436355 -0.4812118 0.8813736 1.0159732 5.991471 9.903487 inf]
```
END
}
@@ -0,0 +1,26 @@
op {
graph_op_name: "Assert"
in_arg {
name: "condition"
description: <<END
The condition to evaluate.
END
}
in_arg {
name: "data"
description: <<END
The tensors to print out when condition is false.
END
}
attr {
name: "summarize"
description: <<END
Print this many entries of each tensor.
END
}
summary: "Asserts that the given condition is true."
description: <<END
If `condition` evaluates to false, print the list of tensors in `data`.
`summarize` determines how many entries of the tensors to print.
END
}
@@ -0,0 +1,4 @@
op {
graph_op_name: "AssertCardinalityDataset"
visibility: HIDDEN
}
@@ -0,0 +1,29 @@
op {
graph_op_name: "AssertNextDataset"
visibility: HIDDEN
in_arg {
name: "input_dataset"
description: <<END
A variant tensor representing the input dataset.
`AssertNextDataset` passes through the outputs of its input dataset.
END
}
in_arg {
name: "transformations"
description: <<END
A `tf.string` vector `tf.Tensor` identifying the transformations that are
expected to happen next.
END
}
summary: "A transformation that asserts which transformations happen next."
description: <<END
This transformation checks whether the camel-case names (i.e. "FlatMap", not
"flat_map") of the transformations following this transformation match the list
of names in the `transformations` argument. If there is a mismatch, the
transformation raises an exception.
The check occurs when iterating over the contents of the dataset, which
means that the check happens *after* any static optimizations are applied
to the dataset graph.
END
}
@@ -0,0 +1,29 @@
op {
graph_op_name: "AssertPrevDataset"
visibility: HIDDEN
in_arg {
name: "input_dataset"
description: <<END
A variant tensor representing the input dataset.
`AssertPrevDataset` passes through the outputs of its input dataset.
END
}
in_arg {
name: "transformations"
description: <<END
A `tf.string` vector `tf.Tensor` identifying the transformations, with optional
attribute name-value pairs, that are expected to have happened previously.
END
}
summary: "A transformation that asserts which transformations happened previously."
description: <<END
This transformation checks the names and, optionally, the attribute name-value
pairs in the `transformations` argument against those of the transformations
that preceded this transformation. If there is a mismatch, the transformation
raises an exception.
The check occurs when iterating over the contents of the dataset, which
means that the check happens *after* any static optimizations are applied
to the dataset graph.
END
}
@@ -0,0 +1,42 @@
op {
graph_op_name: "Assign"
in_arg {
name: "ref"
description: <<END
Should be from a `Variable` node. May be uninitialized.
END
}
in_arg {
name: "value"
description: <<END
The value to be assigned to the variable.
END
}
out_arg {
name: "output_ref"
description: <<END
= Same as "ref". Returned as a convenience for operations that want
to use the new value after the variable has been reset.
END
}
attr {
name: "validate_shape"
description: <<END
If true, the operation will validate that the shape
of 'value' matches the shape of the Tensor being assigned to. If false,
'ref' will take on the shape of 'value'.
END
}
attr {
name: "use_locking"
description: <<END
If True, the assignment will be protected by a lock;
otherwise the behavior is undefined, but may exhibit less contention.
END
}
summary: "Update \'ref\' by assigning \'value\' to it."
description: <<END
This operation outputs "ref" after the assignment is done.
This makes it easier to chain operations that need to use the reset value.
END
}
@@ -0,0 +1,34 @@
op {
graph_op_name: "AssignAdd"
in_arg {
name: "ref"
description: <<END
Should be from a `Variable` node.
END
}
in_arg {
name: "value"
description: <<END
The value to be added to the variable.
END
}
out_arg {
name: "output_ref"
description: <<END
= Same as "ref". Returned as a convenience for operations that want
to use the new value after the variable has been updated.
END
}
attr {
name: "use_locking"
description: <<END
If True, the addition will be protected by a lock;
otherwise the behavior is undefined, but may exhibit less contention.
END
}
summary: "Update \'ref\' by adding \'value\' to it."
description: <<END
This operation outputs "ref" after the update is done.
This makes it easier to chain operations that need to use the reset value.
END
}
@@ -0,0 +1,26 @@
op {
graph_op_name: "AssignAddVariableOp"
in_arg {
name: "resource"
description: <<END
handle to the resource in which to store the variable.
END
}
in_arg {
name: "value"
description: <<END
the value by which the variable will be incremented.
END
}
attr {
name: "dtype"
description: <<END
the dtype of the value.
END
}
summary: "Adds a value to the current value of a variable."
description: <<END
Any ReadVariableOp with a control dependency on this op is guaranteed to
see the incremented value or a subsequent newer one.
END
}
@@ -0,0 +1,34 @@
op {
graph_op_name: "AssignSub"
in_arg {
name: "ref"
description: <<END
Should be from a `Variable` node.
END
}
in_arg {
name: "value"
description: <<END
The value to be subtracted to the variable.
END
}
out_arg {
name: "output_ref"
description: <<END
= Same as "ref". Returned as a convenience for operations that want
to use the new value after the variable has been updated.
END
}
attr {
name: "use_locking"
description: <<END
If True, the subtraction will be protected by a lock;
otherwise the behavior is undefined, but may exhibit less contention.
END
}
summary: "Update \'ref\' by subtracting \'value\' from it."
description: <<END
This operation outputs "ref" after the update is done.
This makes it easier to chain operations that need to use the reset value.
END
}
@@ -0,0 +1,26 @@
op {
graph_op_name: "AssignSubVariableOp"
in_arg {
name: "resource"
description: <<END
handle to the resource in which to store the variable.
END
}
in_arg {
name: "value"
description: <<END
the value by which the variable will be incremented.
END
}
attr {
name: "dtype"
description: <<END
the dtype of the value.
END
}
summary: "Subtracts a value from the current value of a variable."
description: <<END
Any ReadVariableOp with a control dependency on this op is guaranteed to
see the decremented value or a subsequent newer one.
END
}
@@ -0,0 +1,26 @@
op {
graph_op_name: "AssignVariableOp"
in_arg {
name: "resource"
description: <<END
handle to the resource in which to store the variable.
END
}
in_arg {
name: "value"
description: <<END
the value to set the new tensor to use.
END
}
attr {
name: "dtype"
description: <<END
the dtype of the value.
END
}
summary: "Assigns a new value to a variable."
description: <<END
Any ReadVariableOp with a control dependency on this op is guaranteed to return
this value or a subsequent newer value of the variable.
END
}
@@ -0,0 +1,65 @@
op {
graph_op_name: "AssignVariableXlaConcatND"
visibility: HIDDEN
in_arg {
name: "resource"
description: <<END
Resource variable for concatenated input tensors across all dimensions.
END
}
in_arg {
name: "inputs"
description: <<END
Input tensor slices in row-major order to merge across all dimensions. All
inputs must have the same shape.
END
}
attr {
name: "num_concats"
description: <<END
Number of ways to merge per dimension.
END
}
attr {
name: "paddings"
description: <<END
Optional list of right paddings per dimension to strip from the final merged
tensor. These paddings must not exceed the dimension size of the merged result
prior to stripping paddings.
END
}
summary: "Concats input tensor across all dimensions."
description: <<END
An op which merges slices the input tensor based on the given num_splits
attribute, strips paddings optionally, and writes the merged tensor without
paddings to the resource variable.
This op may be generated via the TPU bridge.
For example, with `input` tensor:
```
[[0, 1],
[4, 5]]
[[2, 3],
[6, 7]]
[[8, 9],
[12, 13]]
[[10, 11],
[14, 15]]
```
`num_splits`:
```
[2, 2]
```
and `paddings`:
```
[1, 1]
```
the expected `outputs` is:
```
[[0, 1, 2],
[4, 5, 6],
[8, 9, 10]]
```
END
}
@@ -0,0 +1,22 @@
op {
graph_op_name: "Atan"
summary: "Computes the trignometric inverse tangent of x element-wise."
description: <<END
The `tf.math.atan` operation returns the inverse of `tf.math.tan`, such that
if `y = tf.math.tan(x)` then, `x = tf.math.atan(y)`.
**Note**: The output of `tf.math.atan` will lie within the invertible range
of tan, i.e (-pi/2, pi/2).
For example:
```python
# Note: [1.047, 0.785] ~= [(pi/3), (pi/4)]
x = tf.constant([1.047, 0.785])
y = tf.math.tan(x) # [1.731261, 0.99920404]
tf.math.atan(y) # [1.047, 0.785] = x
```
END
}
@@ -0,0 +1,20 @@
op {
graph_op_name: "Atan2"
summary: "Computes arctangent of `y/x` element-wise, respecting signs of the arguments."
description: <<END
This is the angle \\( \theta \in [-\pi, \pi] \\) such that
\\[ x = r \cos(\theta) \\]
and
\\[ y = r \sin(\theta) \\]
where \\(r = \sqrt{x^2 + y^2} \\).
For example:
>>> x = [1., 1.]
>>> y = [1., -1.]
>>> print((tf.math.atan2(y,x) * (180 / np.pi)).numpy())
[ 45. -45.]
END
}
@@ -0,0 +1,16 @@
op {
graph_op_name: "Atanh"
summary: "Computes inverse hyperbolic tangent of x element-wise."
description: <<END
Given an input tensor, this function computes inverse hyperbolic tangent
for every element in the tensor. Input range is `[-1,1]` and output range is
`[-inf, inf]`. If input is `-1`, output will be `-inf` and if the
input is `1`, output will be `inf`. Values outside the range will have
`nan` as output.
```python
x = tf.constant([-float("inf"), -1, -0.5, 1, 0, 0.5, 10, float("inf")])
tf.math.atanh(x) ==> [nan -inf -0.54930615 inf 0. 0.54930615 nan nan]
```
END
}
@@ -0,0 +1,63 @@
op {
graph_op_name: "AudioSpectrogram"
in_arg {
name: "input"
description: <<END
Float representation of audio data.
END
}
out_arg {
name: "spectrogram"
description: <<END
3D representation of the audio frequencies as an image.
END
}
attr {
name: "window_size"
description: <<END
How wide the input window is in samples. For the highest efficiency
this should be a power of two, but other values are accepted.
END
}
attr {
name: "stride"
description: <<END
How widely apart the center of adjacent sample windows should be.
END
}
attr {
name: "magnitude_squared"
description: <<END
Whether to return the squared magnitude or just the
magnitude. Using squared magnitude can avoid extra calculations.
END
}
summary: "Produces a visualization of audio data over time."
description: <<END
Spectrograms are a standard way of representing audio information as a series of
slices of frequency information, one slice for each window of time. By joining
these together into a sequence, they form a distinctive fingerprint of the sound
over time.
This op expects to receive audio data as an input, stored as floats in the range
-1 to 1, together with a window width in samples, and a stride specifying how
far to move the window between slices. From this it generates a three
dimensional output. The first dimension is for the channels in the input, so a
stereo audio input would have two here for example. The second dimension is time,
with successive frequency slices. The third dimension has an amplitude value for
each frequency during that time slice.
This means the layout when converted and saved as an image is rotated 90 degrees
clockwise from a typical spectrogram. Time is descending down the Y axis, and
the frequency decreases from left to right.
Each value in the result represents the square root of the sum of the real and
imaginary parts of an FFT on the current window of samples. In this way, the
lowest dimension represents the power of each frequency in the current window,
and adjacent windows are concatenated in the next dimension.
To get a more intuitive and visual look at what this operation does, you can run
tensorflow/examples/wav_to_spectrogram to read in an audio file and save out the
resulting spectrogram as a PNG image.
END
}
@@ -0,0 +1,47 @@
op {
graph_op_name: "AudioSummary"
in_arg {
name: "tag"
description: <<END
Scalar. Used to build the `tag` attribute of the summary values.
END
}
in_arg {
name: "tensor"
description: <<END
2-D of shape `[batch_size, frames]`.
END
}
out_arg {
name: "summary"
description: <<END
Scalar. Serialized `Summary` protocol buffer.
END
}
attr {
name: "sample_rate"
description: <<END
The sample rate of the signal in hertz.
END
}
attr {
name: "max_outputs"
description: <<END
Max number of batch elements to generate audio for.
END
}
summary: "Outputs a `Summary` protocol buffer with audio."
description: <<END
The summary has up to `max_outputs` summary values containing audio. The
audio is built from `tensor` which must be 3-D with shape `[batch_size,
frames, channels]` or 2-D with shape `[batch_size, frames]`. The values are
assumed to be in the range of `[-1.0, 1.0]` with a sample rate of `sample_rate`.
The `tag` argument is a scalar `Tensor` of type `string`. It is used to
build the `tag` of the summary values:
* If `max_outputs` is 1, the summary value tag is '*tag*/audio'.
* If `max_outputs` is greater than 1, the summary value tags are
generated sequentially as '*tag*/audio/0', '*tag*/audio/1', etc.
END
}
@@ -0,0 +1,50 @@
op {
graph_op_name: "AudioSummaryV2"
endpoint {
name: "AudioSummary"
}
in_arg {
name: "tag"
description: <<END
Scalar. Used to build the `tag` attribute of the summary values.
END
}
in_arg {
name: "tensor"
description: <<END
2-D of shape `[batch_size, frames]`.
END
}
in_arg {
name: "sample_rate"
description: <<END
The sample rate of the signal in hertz.
END
}
out_arg {
name: "summary"
description: <<END
Scalar. Serialized `Summary` protocol buffer.
END
}
attr {
name: "max_outputs"
description: <<END
Max number of batch elements to generate audio for.
END
}
summary: "Outputs a `Summary` protocol buffer with audio."
description: <<END
The summary has up to `max_outputs` summary values containing audio. The
audio is built from `tensor` which must be 3-D with shape `[batch_size,
frames, channels]` or 2-D with shape `[batch_size, frames]`. The values are
assumed to be in the range of `[-1.0, 1.0]` with a sample rate of `sample_rate`.
The `tag` argument is a scalar `Tensor` of type `string`. It is used to
build the `tag` of the summary values:
* If `max_outputs` is 1, the summary value tag is '*tag*/audio'.
* If `max_outputs` is greater than 1, the summary value tags are
generated sequentially as '*tag*/audio/0', '*tag*/audio/1', etc.
END
}
@@ -0,0 +1,32 @@
op {
graph_op_name: "AutoShardDataset"
visibility: HIDDEN
in_arg {
name: "input_dataset"
description: <<END
A variant tensor representing the input dataset.
END
}
in_arg {
name: "num_workers"
description: <<END
A scalar representing the number of workers to distribute this dataset across.
END
}
in_arg {
name: "index"
description: <<END
A scalar representing the index of the current worker out of num_workers.
END
}
summary: "Creates a dataset that shards the input dataset."
description: <<END
Creates a dataset that shards the input dataset by num_workers, returning a
sharded dataset for the index-th worker. This attempts to automatically shard
a dataset by examining the Dataset graph and inserting a shard op before the
inputs to a reader Dataset (e.g. CSVDataset, TFRecordDataset).
This dataset will throw a NotFound error if we cannot shard the dataset
automatically.
END
}
@@ -0,0 +1,48 @@
op {
graph_op_name: "AvgPool"
in_arg {
name: "value"
description: <<END
4-D with shape `[batch, height, width, channels]`.
END
}
out_arg {
name: "output"
description: <<END
The average pooled output tensor.
END
}
attr {
name: "ksize"
description: <<END
The size of the sliding window for each dimension of `value`.
END
}
attr {
name: "strides"
description: <<END
The stride of the sliding window for each dimension of `value`.
END
}
attr {
name: "padding"
description: <<END
The type of padding algorithm to use.
END
}
attr {
name: "data_format"
description: <<END
Specify the data format of the input and output data. With the
default format "NHWC", the data is stored in the order of:
[batch, in_height, in_width, in_channels].
Alternatively, the format could be "NCHW", the data storage order of:
[batch, in_channels, in_height, in_width].
END
}
summary: "Performs average pooling on the input."
description: <<END
Each entry in `output` is the mean of the corresponding size `ksize`
window in `value`.
END
}
@@ -0,0 +1,50 @@
op {
graph_op_name: "AvgPool3D"
in_arg {
name: "input"
description: <<END
Shape `[batch, depth, rows, cols, channels]` tensor to pool over.
END
}
out_arg {
name: "output"
description: <<END
The average pooled output tensor.
END
}
attr {
name: "ksize"
description: <<END
1-D tensor of length 5. The size of the window for each dimension of
the input tensor. Must have `ksize[0] = ksize[4] = 1`.
END
}
attr {
name: "strides"
description: <<END
1-D tensor of length 5. The stride of the sliding window for each
dimension of `input`. Must have `strides[0] = strides[4] = 1`.
END
}
attr {
name: "padding"
description: <<END
The type of padding algorithm to use.
END
}
attr {
name: "data_format"
description: <<END
The data format of the input and output data. With the
default format "NDHWC", the data is stored in the order of:
[batch, in_depth, in_height, in_width, in_channels].
Alternatively, the format could be "NCDHW", the data storage order is:
[batch, in_channels, in_depth, in_height, in_width].
END
}
summary: "Performs 3D average pooling on the input."
description: <<END
Each entry in `output` is the mean of the corresponding size `ksize` window in
`value`.
END
}
@@ -0,0 +1,52 @@
op {
graph_op_name: "AvgPool3DGrad"
in_arg {
name: "orig_input_shape"
description: <<END
The original input dimensions.
END
}
in_arg {
name: "grad"
description: <<END
Output backprop of shape `[batch, depth, rows, cols, channels]`.
END
}
out_arg {
name: "output"
description: <<END
The backprop for input.
END
}
attr {
name: "ksize"
description: <<END
1-D tensor of length 5. The size of the window for each dimension of
the input tensor. Must have `ksize[0] = ksize[4] = 1`.
END
}
attr {
name: "strides"
description: <<END
1-D tensor of length 5. The stride of the sliding window for each
dimension of `input`. Must have `strides[0] = strides[4] = 1`.
END
}
attr {
name: "padding"
description: <<END
The type of padding algorithm to use.
END
}
attr {
name: "data_format"
description: <<END
The data format of the input and output data. With the
default format "NDHWC", the data is stored in the order of:
[batch, in_depth, in_height, in_width, in_channels].
Alternatively, the format could be "NCDHW", the data storage order is:
[batch, in_channels, in_depth, in_height, in_width].
END
}
summary: "Computes gradients of average pooling function."
}
@@ -0,0 +1,52 @@
op {
graph_op_name: "AvgPoolGrad"
visibility: HIDDEN
in_arg {
name: "orig_input_shape"
description: <<END
1-D. Shape of the original input to `avg_pool`.
END
}
in_arg {
name: "grad"
description: <<END
4-D with shape `[batch, height, width, channels]`. Gradients w.r.t.
the output of `avg_pool`.
END
}
out_arg {
name: "output"
description: <<END
4-D. Gradients w.r.t. the input of `avg_pool`.
END
}
attr {
name: "ksize"
description: <<END
The size of the sliding window for each dimension of the input.
END
}
attr {
name: "strides"
description: <<END
The stride of the sliding window for each dimension of the input.
END
}
attr {
name: "padding"
description: <<END
The type of padding algorithm to use.
END
}
attr {
name: "data_format"
description: <<END
Specify the data format of the input and output data. With the
default format "NHWC", the data is stored in the order of:
[batch, in_height, in_width, in_channels].
Alternatively, the format could be "NCHW", the data storage order of:
[batch, in_channels, in_height, in_width].
END
}
summary: "Computes gradients of the average pooling function."
}
@@ -0,0 +1,4 @@
op {
graph_op_name: "BandedTriangularSolve"
visibility: HIDDEN
}
@@ -0,0 +1,55 @@
op {
graph_op_name: "Barrier"
out_arg {
name: "handle"
description: <<END
The handle to the barrier.
END
}
attr {
name: "component_types"
description: <<END
The type of each component in a value.
END
}
attr {
name: "shapes"
description: <<END
The shape of each component in a value. Each shape must be 1 in the
first dimension. The length of this attr must be the same as the length of
component_types.
END
}
attr {
name: "capacity"
description: <<END
The capacity of the barrier. The default capacity is MAX_INT32,
which is the largest capacity of the underlying queue.
END
}
attr {
name: "container"
description: <<END
If non-empty, this barrier is placed in the given container.
Otherwise, a default container is used.
END
}
attr {
name: "shared_name"
description: <<END
If non-empty, this barrier will be shared under the given name
across multiple sessions.
END
}
summary: "Defines a barrier that persists across different graph executions."
description: <<END
A barrier represents a key-value map, where each key is a string, and
each value is a tuple of tensors.
At runtime, the barrier contains 'complete' and 'incomplete'
elements. A complete element has defined tensors for all components of
its value tuple, and may be accessed using BarrierTakeMany. An
incomplete element has some undefined components in its value tuple,
and may be updated using BarrierInsertMany.
END
}
@@ -0,0 +1,26 @@
op {
graph_op_name: "BarrierClose"
in_arg {
name: "handle"
description: <<END
The handle to a barrier.
END
}
attr {
name: "cancel_pending_enqueues"
description: <<END
If true, all pending enqueue requests that are
blocked on the barrier's queue will be canceled. InsertMany will fail, even
if no new key is introduced.
END
}
summary: "Closes the given barrier."
description: <<END
This operation signals that no more new elements will be inserted in the
given barrier. Subsequent InsertMany that try to introduce a new key will fail.
Subsequent InsertMany operations that just add missing components to already
existing elements will continue to succeed. Subsequent TakeMany operations will
continue to succeed if sufficient completed elements remain in the barrier.
Subsequent TakeMany operations that would block will fail immediately.
END
}
@@ -0,0 +1,17 @@
op {
graph_op_name: "BarrierIncompleteSize"
in_arg {
name: "handle"
description: <<END
The handle to a barrier.
END
}
out_arg {
name: "size"
description: <<END
The number of incomplete elements (i.e. those with some of their value
components not set) in the barrier.
END
}
summary: "Computes the number of incomplete elements in the given barrier."
}
@@ -0,0 +1,35 @@
op {
graph_op_name: "BarrierInsertMany"
in_arg {
name: "handle"
description: <<END
The handle to a barrier.
END
}
in_arg {
name: "keys"
description: <<END
A one-dimensional tensor of keys, with length n.
END
}
in_arg {
name: "values"
description: <<END
An any-dimensional tensor of values, which are associated with the
respective keys. The 0th dimension must have length n.
END
}
attr {
name: "component_index"
description: <<END
The component of the barrier elements that is being assigned.
END
}
summary: "For each key, assigns the respective value to the specified component."
description: <<END
If a key is not found in the barrier, this operation will create a new
incomplete element. If a key is found in the barrier, and the element
already has a value at component_index, this operation will fail with
INVALID_ARGUMENT, and leave the barrier in an undefined state.
END
}
@@ -0,0 +1,17 @@
op {
graph_op_name: "BarrierReadySize"
in_arg {
name: "handle"
description: <<END
The handle to a barrier.
END
}
out_arg {
name: "size"
description: <<END
The number of complete elements (i.e. those with all of their value
components set) in the barrier.
END
}
summary: "Computes the number of complete elements in the given barrier."
}
@@ -0,0 +1,68 @@
op {
graph_op_name: "BarrierTakeMany"
in_arg {
name: "handle"
description: <<END
The handle to a barrier.
END
}
in_arg {
name: "num_elements"
description: <<END
A single-element tensor containing the number of elements to
take.
END
}
out_arg {
name: "indices"
description: <<END
A one-dimensional tensor of indices, with length num_elems.
These indices refer to the batch in which the values were placed into the
barrier (starting with MIN_LONG and increasing with each BarrierInsertMany).
END
}
out_arg {
name: "keys"
description: <<END
A one-dimensional tensor of keys, with length num_elements.
END
}
out_arg {
name: "values"
description: <<END
One any-dimensional tensor per component in a barrier element. All
values have length num_elements in the 0th dimension.
END
}
attr {
name: "component_types"
description: <<END
The type of each component in a value.
END
}
attr {
name: "allow_small_batch"
description: <<END
Allow to return less than num_elements items if barrier is
already closed.
END
}
attr {
name: "timeout_ms"
description: <<END
If the queue is empty, this operation will block for up to
timeout_ms milliseconds.
Note: This option is not supported yet.
END
}
summary: "Takes the given number of completed elements from a barrier."
description: <<END
This operation concatenates completed-element component tensors along
the 0th dimension to make a single component tensor.
Elements come out of the barrier when they are complete, and in the order
in which they were placed into the barrier. The indices output provides
information about the batch in which each element was originally inserted
into the barrier.
END
}
@@ -0,0 +1,42 @@
op {
graph_op_name: "Batch"
summary: "Batches all input tensors nondeterministically."
description: <<END
When many instances of this Op are being run concurrently with the same
container/shared_name in the same device, some will output zero-shaped Tensors
and others will output Tensors of size up to max_batch_size.
All Tensors in in_tensors are batched together (so, for example, labels and
features should be batched with a single instance of this operation.
Each invocation of batch emits an `id` scalar which will be used to identify
this particular invocation when doing unbatch or its gradient.
Each op which emits a non-empty batch will also emit a non-empty batch_index
Tensor, which, is a [K, 3] matrix where each row contains the invocation's id,
start, and length of elements of each set of Tensors present in batched_tensors.
Batched tensors are concatenated along the first dimension, and all tensors in
in_tensors must have the first dimension of the same size.
in_tensors: The tensors to be batched.
num_batch_threads: Number of scheduling threads for processing batches of work.
Determines the number of batches processed in parallel.
max_batch_size: Batch sizes will never be bigger than this.
batch_timeout_micros: Maximum number of microseconds to wait before outputting
an incomplete batch.
allowed_batch_sizes: Optional list of allowed batch sizes. If left empty, does
nothing. Otherwise, supplies a list of batch sizes, causing the op to pad
batches up to one of those sizes. The entries must increase monotonically, and
the final entry must equal max_batch_size.
grad_timeout_micros: The timeout to use for the gradient. See Unbatch.
batched_tensors: Either empty tensors or a batch of concatenated Tensors.
batch_index: If out_tensors is non-empty, has information to invert it.
container: Controls the scope of sharing of this batch.
id: always contains a scalar with a unique ID for this invocation of Batch.
shared_name: Concurrently running instances of batch in the same device with the
same container and shared_name will batch their elements together. If left
empty, the op name will be used as the shared name.
T: the types of tensors to be batched.
END
}
@@ -0,0 +1,3 @@
op {
graph_op_name: "BatchCholesky"
}
@@ -0,0 +1,3 @@
op {
graph_op_name: "BatchCholeskyGrad"
}

Some files were not shown because too many files have changed in this diff Show More