Import tensorflow

This commit is contained in:
2026-02-15 21:45:42 -08:00
parent f3e8b90764
commit c530630153
20524 changed files with 9017694 additions and 25 deletions
@@ -0,0 +1,147 @@
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Visitor restricting traversal to only the public tensorflow API."""
import re
from tensorflow.python.util import tf_inspect
class PublicAPIVisitor:
"""Visitor to use with `traverse` to visit exactly the public TF API."""
def __init__(self, visitor):
"""Constructor.
`visitor` should be a callable suitable as a visitor for `traverse`. It will
be called only for members of the public TensorFlow API.
Args:
visitor: A visitor to call for the public API.
"""
self._visitor = visitor
self._root_name = 'tf'
# Modules/classes we want to suppress entirely.
self._private_map = {
'tf': [
'compiler',
'core',
# TODO(scottzhu): See b/227410870 for more details. Currently
# dtensor API is exposed under tf.experimental.dtensor, but in the
# meantime, we have tensorflow/dtensor directory which will be treat
# as a python package. We want to avoid step into the
# tensorflow/dtensor directory when visit the API.
# When the tf.dtensor becomes the public API, it will actually pick
# up from tf.compat.v2.dtensor as priority and hide the
# tensorflow/dtensor package.
'security',
'dtensor',
'python',
'tsl', # TODO(tlongeri): Remove after TSL is moved out of TF.
],
# Some implementations have this internal module that we shouldn't
# expose.
'tf.flags': ['cpp_flags'],
}
# Modules/classes we do not want to descend into if we hit them. Usually,
# system modules exposed through platforms for compatibility reasons.
# Each entry maps a module path to a name to ignore in traversal.
self._do_not_descend_map = {
'tf': [
'examples',
'flags', # Don't add flags
# TODO(drpng): This can be removed once sealed off.
'platform',
# TODO(drpng): This can be removed once sealed.
'pywrap_tensorflow',
# TODO(drpng): This can be removed once sealed.
'user_ops',
'tools',
'tensorboard',
],
## Everything below here is legitimate.
# It'll stay, but it's not officially part of the API.
'tf.app': ['flags'],
# Imported for compatibility between py2/3.
'tf.test': ['mock'],
}
@property
def private_map(self):
"""A map from parents to symbols that should not be included at all.
This map can be edited, but it should not be edited once traversal has
begun.
Returns:
The map marking symbols to not include.
"""
return self._private_map
@property
def do_not_descend_map(self):
"""A map from parents to symbols that should not be descended into.
This map can be edited, but it should not be edited once traversal has
begun.
Returns:
The map marking symbols to not explore.
"""
return self._do_not_descend_map
def set_root_name(self, root_name):
"""Override the default root name of 'tf'."""
self._root_name = root_name
def _is_private(self, path, name, obj=None):
"""Return whether a name is private."""
# TODO(wicke): Find out what names to exclude.
del obj # Unused.
return ((path in self._private_map and name in self._private_map[path]) or
(name.startswith('_') and not re.match('__.*__$', name) or
name in ['__base__', '__class__', '__next_in_mro__']))
def _do_not_descend(self, path, name):
"""Safely queries if a specific fully qualified name should be excluded."""
return (path in self._do_not_descend_map and
name in self._do_not_descend_map[path])
def __call__(self, path, parent, children):
"""Visitor interface, see `traverse` for details."""
# Avoid long waits in cases of pretty unambiguous failure.
if tf_inspect.ismodule(parent) and len(path.split('.')) > 10:
raise RuntimeError('Modules nested too deep:\n%s.%s\n\nThis is likely a '
'problem with an accidental public import.' %
(self._root_name, path))
# Includes self._root_name
full_path = '.'.join([self._root_name, path]) if path else self._root_name
# Remove things that are not visible.
for name, child in list(children):
if self._is_private(full_path, name, child):
children.remove((name, child))
self._visitor(path, parent, children)
# Remove things that are visible, but which should not be descended into.
for name, child in list(children):
if self._do_not_descend(full_path, name):
children.remove((name, child))
@@ -0,0 +1,27 @@
# Copyright 2018 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.
# ==============================================================================
"""A module target for TraverseTest.test_module."""
from tensorflow.tools.common import test_module2
class ModuleClass1(object):
def __init__(self):
self._m2 = test_module2.ModuleClass2()
def __model_class1_method__(self):
pass
@@ -0,0 +1,25 @@
# Copyright 2018 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.
# ==============================================================================
"""A module target for TraverseTest.test_module."""
class ModuleClass2(object):
def __init__(self):
pass
def __model_class1_method__(self):
pass
@@ -0,0 +1,103 @@
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Traversing Python modules and classes."""
import enum
import sys
from tensorflow.python.util import tf_inspect
__all__ = ['traverse']
def _traverse_internal(root, visit, stack, path):
"""Internal helper for traverse."""
# Only traverse modules and classes
if not tf_inspect.isclass(root) and not tf_inspect.ismodule(root):
return
try:
children = tf_inspect.getmembers(root)
# Add labels for duplicate values in Enum.
if tf_inspect.isclass(root) and issubclass(root, enum.Enum):
for enum_member in root.__members__.items():
if enum_member not in children:
children.append(enum_member)
children = sorted(children)
except ImportError:
# Children could be missing for one of two reasons:
# 1. On some Python installations, some modules do not support enumerating
# members, leading to import errors.
# 2. Children are lazy-loaded.
try:
children = []
for child_name in root.__all__:
children.append((child_name, getattr(root, child_name)))
except AttributeError:
children = []
new_stack = stack + [root]
visit(path, root, children)
for name, child in children:
# Do not descend into built-in modules
if tf_inspect.ismodule(
child) and child.__name__ in sys.builtin_module_names:
continue
# Break cycles
if any(child is item for item in new_stack): # `in`, but using `is`
continue
child_path = path + '.' + name if path else name
_traverse_internal(child, visit, new_stack, child_path)
def traverse(root, visit):
"""Recursively enumerate all members of `root`.
Similar to the Python library function `os.path.walk`.
Traverses the tree of Python objects starting with `root`, depth first.
Parent-child relationships in the tree are defined by membership in modules or
classes. The function `visit` is called with arguments
`(path, parent, children)` for each module or class `parent` found in the tree
of python objects starting with `root`. `path` is a string containing the name
with which `parent` is reachable from the current context. For example, if
`root` is a local class called `X` which contains a class `Y`, `visit` will be
called with `('Y', X.Y, children)`).
If `root` is not a module or class, `visit` is never called. `traverse`
never descends into built-in modules.
`children`, a list of `(name, object)` pairs are determined by
`tf_inspect.getmembers`. To avoid visiting parts of the tree, `children` can
be modified in place, using `del` or slice assignment.
Cycles (determined by reference equality, `is`) stop the traversal. A stack of
objects is kept to find cycles. Objects forming cycles may appear in
`children`, but `visit` will not be called with any object as `parent` which
is already in the stack.
Traversing system modules can take a long time, it is advisable to pass a
`visit` callable which denylists such modules.
Args:
root: A python object with which to start the traversal.
visit: A function taking arguments `(path, parent, children)`. Will be
called for each object found in the traversal.
"""
_traverse_internal(root, visit, [], '')
@@ -0,0 +1,517 @@
# Copyright 2019 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.
# ==============================================================================
"""Provides a list of renames between TensorFlow 1.* and 2.0."""
from tensorflow.tools.compatibility import renames_v2
# pylint: disable=line-too-long
# Add additional renames not in renames_v2.py here.
# IMPORTANT: For the renames in here, if you also need to add to
# function_reorders or function_keyword_renames in tf_upgrade_v2.py,
# use the OLD function name.
# These renames happen after the arguments have been processed.
# After modifying this dict, run the following to update reorders_v2.py:
# bazel run tensorflow/tools/compatibility/update:generate_v2_reorders_map
manual_symbol_renames = {
"tf.batch_to_space_nd": "tf.batch_to_space",
"tf.batch_gather": "tf.compat.v1.batch_gather",
"tf.space_to_batch_nd": "tf.space_to_batch",
"tf.nn.space_to_batch": "tf.space_to_batch",
"tf.extract_image_patches": "tf.image.extract_patches",
"tf.image.extract_image_patches": "tf.image.extract_patches",
"tf.gfile.Copy": "tf.io.gfile.copy",
"tf.gfile.DeleteRecursively": "tf.io.gfile.rmtree",
"tf.gfile.Exists": "tf.io.gfile.exists",
"tf.gfile.Glob": "tf.io.gfile.glob",
"tf.gfile.GFile": "tf.io.gfile.GFile",
"tf.gfile.IsDirectory": "tf.io.gfile.isdir",
"tf.gfile.ListDirectory": "tf.io.gfile.listdir",
"tf.gfile.MakeDirs": "tf.io.gfile.makedirs",
"tf.gfile.MkDir": "tf.io.gfile.mkdir",
"tf.gfile.Open": "tf.io.gfile.GFile",
"tf.gfile.Remove": "tf.io.gfile.remove",
"tf.gfile.Rename": "tf.io.gfile.rename",
"tf.gfile.Stat": "tf.io.gfile.stat",
"tf.gfile.Walk": "tf.io.gfile.walk",
"tf.contrib.cluster_resolver.ClusterResolver": (
"tf.distribute.cluster_resolver.ClusterResolver"
),
"tf.contrib.cluster_resolver.GceClusterResolver": (
"tf.distribute.cluster_resolver.GCEClusterResolver"
),
"tf.contrib.cluster_resolver.KubernetesClusterResolver": (
"tf.distribute.cluster_resolver.KubernetesClusterResolver"
),
"tf.contrib.cluster_resolver.SimpleClusterResolver": (
"tf.distribute.cluster_resolver.SimpleClusterResolver"
),
"tf.contrib.cluster_resolver.SlurmClusterResolver": (
"tf.distribute.cluster_resolver.SlurmClusterResolver"
),
"tf.contrib.cluster_resolver.TFConfigClusterResolver": (
"tf.distribute.cluster_resolver.TFConfigClusterResolver"
),
"tf.contrib.cluster_resolver.TPUClusterResolver": (
"tf.distribute.cluster_resolver.TPUClusterResolver"
),
"tf.contrib.cluster_resolver.UnionClusterResolver": (
"tf.distribute.cluster_resolver.UnionClusterResolver"
),
"tf.contrib.data.AUTOTUNE": "tf.data.experimental.AUTOTUNE",
"tf.contrib.data.Counter": "tf.data.experimental.Counter",
"tf.contrib.data.CheckpointInputPipelineHook": (
"tf.data.experimental.CheckpointInputPipelineHook"
),
"tf.contrib.data.CsvDataset": "tf.data.experimental.CsvDataset",
"tf.contrib.data.Optional": "tf.data.experimental.Optional",
"tf.contrib.data.RandomDataset": "tf.data.experimental.RandomDataset",
"tf.contrib.data.Reducer": "tf.data.experimental.Reducer",
"tf.contrib.data.SqlDataset": "tf.data.experimental.SqlDataset",
"tf.contrib.data.StatsAggregator": "tf.data.experimental.StatsAggregator",
"tf.contrib.data.TFRecordWriter": "tf.data.experimental.TFRecordWriter",
"tf.contrib.data.assert_element_shape": (
"tf.data.experimental.assert_element_shape"
),
"tf.contrib.data.bucket_by_sequence_length": (
"tf.data.experimental.bucket_by_sequence_length"
),
"tf.contrib.data.choose_from_datasets": (
"tf.data.experimental.choose_from_datasets"
),
"tf.contrib.data.copy_to_device": "tf.data.experimental.copy_to_device",
"tf.contrib.data.dense_to_sparse_batch": (
"tf.data.experimental.dense_to_sparse_batch"
),
"tf.contrib.data.enumerate_dataset": (
"tf.data.experimental.enumerate_dataset"
),
"tf.contrib.data.get_next_as_optional": (
"tf.data.experimental.get_next_as_optional"
),
"tf.contrib.data.get_single_element": (
"tf.data.experimental.get_single_element"
),
"tf.contrib.data.group_by_reducer": "tf.data.experimental.group_by_reducer",
"tf.contrib.data.group_by_window": "tf.data.experimental.group_by_window",
"tf.contrib.data.ignore_errors": "tf.data.experimental.ignore_errors",
"tf.contrib.data.latency_stats": "tf.data.experimental.latency_stats",
"tf.contrib.data.make_batched_features_dataset": (
"tf.data.experimental.make_batched_features_dataset"
),
"tf.contrib.data.make_csv_dataset": "tf.data.experimental.make_csv_dataset",
"tf.contrib.data.make_saveable_from_iterator": (
"tf.data.experimental.make_saveable_from_iterator"
),
"tf.contrib.data.map_and_batch": "tf.data.experimental.map_and_batch",
"tf.contrib.data.parallel_interleave": (
"tf.data.experimental.parallel_interleave"
),
"tf.contrib.data.parse_example_dataset": (
"tf.data.experimental.parse_example_dataset"
),
"tf.contrib.data.prefetch_to_device": (
"tf.data.experimental.prefetch_to_device"
),
"tf.contrib.data.rejection_resample": (
"tf.data.experimental.rejection_resample"
),
"tf.contrib.data.sample_from_datasets": (
"tf.data.experimental.sample_from_datasets"
),
"tf.contrib.data.scan": "tf.data.experimental.scan",
"tf.contrib.data.set_stats_aggregator": (
"tf.data.experimental.set_stats_aggregator"
),
"tf.contrib.data.shuffle_and_repeat": (
"tf.data.experimental.shuffle_and_repeat"
),
"tf.contrib.data.unbatch": "tf.data.experimental.unbatch",
"tf.contrib.data.unique": "tf.data.experimental.unique",
"tf.contrib.distribute.CrossDeviceOps": "tf.distribute.CrossDeviceOps",
"tf.contrib.distribute.ReductionToOneDeviceCrossDeviceOps": (
"tf.distribute.ReductionToOneDevice"
),
"tf.contrib.framework.CriticalSection": "tf.CriticalSection",
"tf.contrib.framework.is_tensor": "tf.is_tensor",
"tf.contrib.framework.load_variable": "tf.train.load_variable",
"tf.contrib.framework.nest.assert_same_structure": (
"tf.nest.assert_same_structure"
),
"tf.contrib.framework.nest.flatten": "tf.nest.flatten",
"tf.contrib.framework.nest.is_nested": "tf.nest.is_nested",
"tf.contrib.framework.nest.map_structure": "tf.nest.map_structure",
"tf.contrib.framework.nest.pack_sequence_as": "tf.nest.pack_sequence_as",
"tf.contrib.batching.batch_function": "tf.nondifferentiable_batch_function",
"tf.contrib.util.constant_value": "tf.get_static_value",
"tf.contrib.saved_model.load_keras_model": (
"tf.compat.v1.keras.experimental.load_from_saved_model"
),
"tf.contrib.saved_model.save_keras_model": (
"tf.compat.v1.keras.experimental.export_saved_model"
),
"tf.contrib.rnn.RNNCell": "tf.compat.v1.nn.rnn_cell.RNNCell",
"tf.contrib.rnn.LSTMStateTuple": "tf.nn.rnn_cell.LSTMStateTuple",
"tf.contrib.rnn.BasicLSTMCell": "tf.compat.v1.nn.rnn_cell.BasicLSTMCell",
"tf.contrib.rnn.BasicRNNCell": "tf.compat.v1.nn.rnn_cell.BasicRNNCell",
"tf.contrib.rnn.GRUCell": "tf.compat.v1.nn.rnn_cell.GRUCell",
"tf.contrib.rnn.LSTMCell": "tf.compat.v1.nn.rnn_cell.LSTMCell",
"tf.contrib.rnn.MultiRNNCell": "tf.compat.v1.nn.rnn_cell.MultiRNNCell",
"tf.contrib.rnn.static_rnn": "tf.compat.v1.nn.static_rnn",
"tf.contrib.rnn.static_state_saving_rnn": (
"tf.compat.v1.nn.static_state_saving_rnn"
),
"tf.contrib.rnn.static_bidirectional_rnn": (
"tf.compat.v1.nn.static_bidirectional_rnn"
),
"tf.contrib.framework.sort": "tf.sort",
"tf.contrib.framework.argsort": "tf.argsort",
"tf.contrib.summary.all_summary_ops": (
"tf.compat.v1.summary.all_v2_summary_ops"
),
"tf.contrib.summary.always_record_summaries": (
"tf.compat.v2.summary.record_if"
),
"tf.contrib.summary.audio": "tf.compat.v2.summary.audio",
"tf.contrib.summary.create_file_writer": (
"tf.compat.v2.summary.create_file_writer"
),
"tf.contrib.summary.flush": "tf.compat.v2.summary.flush",
"tf.contrib.summary.generic": "tf.compat.v2.summary.write",
"tf.contrib.summary.histogram": "tf.compat.v2.summary.histogram",
"tf.contrib.summary.image": "tf.compat.v2.summary.image",
"tf.contrib.summary.initialize": "tf.compat.v1.summary.initialize",
"tf.contrib.summary.never_record_summaries": (
"tf.compat.v2.summary.record_if"
),
"tf.contrib.summary.scalar": "tf.compat.v2.summary.scalar",
"tf.contrib.tpu.CrossShardOptimizer": (
"tf.compat.v1.tpu.CrossShardOptimizer"
),
"tf.contrib.tpu.batch_parallel": "tf.compat.v1.tpu.batch_parallel",
"tf.contrib.tpu.bfloat16_scope": "tf.compat.v1.tpu.bfloat16_scope",
"tf.contrib.tpu.core": "tf.compat.v1.tpu.core",
"tf.contrib.tpu.cross_replica_sum": "tf.compat.v1.tpu.cross_replica_sum",
"tf.contrib.tpu.initialize_system": "tf.compat.v1.tpu.initialize_system",
"tf.contrib.tpu.outside_compilation": (
"tf.compat.v1.tpu.outside_compilation"
),
"tf.contrib.tpu.replicate": "tf.compat.v1.tpu.replicate",
"tf.contrib.tpu.rewrite": "tf.compat.v1.tpu.rewrite",
"tf.contrib.tpu.shard": "tf.compat.v1.tpu.shard",
"tf.contrib.tpu.shutdown_system": "tf.compat.v1.tpu.shutdown_system",
"tf.contrib.training.checkpoints_iterator": "tf.train.checkpoints_iterator",
"tf.contrib.layers.recompute_grad": "tf.recompute_grad",
"tf.count_nonzero": "tf.math.count_nonzero",
"tf.decode_raw": "tf.io.decode_raw",
"tf.manip.batch_to_space_nd": "tf.batch_to_space",
"tf.quantize_v2": "tf.quantization.quantize",
"tf.sparse_matmul": "tf.linalg.matmul",
"tf.random.stateless_multinomial": "tf.random.stateless_categorical",
"tf.substr": "tf.strings.substr",
# TODO(b/129398290)
"tf.string_split": "tf.compat.v1.string_split",
"tf.string_to_hash_bucket": "tf.strings.to_hash_bucket",
"tf.string_to_number": "tf.strings.to_number",
"tf.multinomial": "tf.random.categorical",
"tf.random.multinomial": "tf.random.categorical",
"tf.reduce_join": "tf.strings.reduce_join",
"tf.load_file_system_library": "tf.load_library",
"tf.bincount": "tf.math.bincount",
"tf.confusion_matrix": "tf.math.confusion_matrix",
"tf.train.confusion_matrix": "tf.math.confusion_matrix",
"tf.train.sdca_fprint": "tf.raw_ops.SdcaFprint",
"tf.train.sdca_optimizer": "tf.raw_ops.SdcaOptimizer",
"tf.train.sdca_shrink_l1": "tf.raw_ops.SdcaShrinkL1",
"tf.decode_csv": "tf.io.decode_csv",
"tf.data.Iterator": "tf.compat.v1.data.Iterator",
"tf.data.experimental.DatasetStructure": "tf.data.DatasetSpec",
"tf.data.experimental.OptionalStructure": "tf.OptionalSpec",
"tf.data.experimental.RaggedTensorStructure": "tf.RaggedTensorSpec",
"tf.data.experimental.SparseTensorStructure": "tf.SparseTensorSpec",
"tf.data.experimental.Structure": "tf.TypeSpec",
"tf.data.experimental.TensorArrayStructure": "tf.TensorArraySpec",
"tf.data.experimental.TensorStructure": "tf.TensorSpec",
"tf.parse_example": "tf.io.parse_example",
"tf.parse_single_example": "tf.io.parse_single_example",
"tf.nn.fused_batch_norm": "tf.compat.v1.nn.fused_batch_norm",
"tf.nn.softmax_cross_entropy_with_logits_v2": (
"tf.nn.softmax_cross_entropy_with_logits"
),
"tf.losses.Reduction.MEAN": "tf.compat.v1.losses.Reduction.MEAN",
"tf.losses.Reduction.SUM_BY_NONZERO_WEIGHTS": (
"tf.compat.v1.losses.Reduction.SUM_BY_NONZERO_WEIGHTS"
),
"tf.losses.Reduction.SUM_OVER_NONZERO_WEIGHTS": (
"tf.compat.v1.losses.Reduction.SUM_OVER_NONZERO_WEIGHTS"
),
"tf.lite.constants.FLOAT": "tf.float32",
"tf.lite.constants.FLOAT16": "tf.float16",
"tf.lite.constants.INT16": "tf.int16",
"tf.lite.constants.INT32": "tf.int32",
"tf.lite.constants.INT64": "tf.int64",
"tf.lite.constants.INT8": "tf.int8",
"tf.lite.constants.STRING": "tf.string",
"tf.lite.constants.QUANTIZED_UINT8": "tf.uint8",
"tf.arg_max": "tf.argmax",
"tf.arg_min": "tf.argmin",
# tf.nn.ctc_loss is still available in 2.0 but behavior
# changed significantly.
"tf.nn.ctc_loss": "tf.compat.v1.nn.ctc_loss",
# tf.saved_model.load in 1.x has no equivalent in 2.x, but there is a
# symbol with the same name.
"tf.saved_model.load": "tf.compat.v1.saved_model.load",
"tf.saved_model.loader.load": "tf.compat.v1.saved_model.load",
"tf.saved_model.load_v2": "tf.compat.v2.saved_model.load",
"tf.image.resize_images": "tf.image.resize",
"tf.assert_equal": "tf.compat.v1.assert_equal",
"tf.assert_greater": "tf.compat.v1.assert_greater",
"tf.assert_greater_equal": "tf.compat.v1.assert_greater_equal",
"tf.assert_integer": "tf.compat.v1.assert_integer",
"tf.assert_less": "tf.compat.v1.assert_less",
"tf.assert_less_equal": "tf.compat.v1.assert_less_equal",
"tf.assert_near": "tf.compat.v1.assert_near",
"tf.assert_negative": "tf.compat.v1.assert_negative",
"tf.assert_non_negative": "tf.compat.v1.assert_non_negative",
"tf.assert_non_positive": "tf.compat.v1.assert_non_positive",
"tf.assert_none_equal": "tf.compat.v1.assert_none_equal",
"tf.assert_positive": "tf.compat.v1.assert_positive",
"tf.assert_rank": "tf.compat.v1.assert_rank",
"tf.assert_rank_at_least": "tf.compat.v1.assert_rank_at_least",
"tf.assert_rank_in": "tf.compat.v1.assert_rank_in",
"tf.assert_scalar": "tf.compat.v1.assert_scalar",
"tf.assert_type": "tf.compat.v1.assert_type",
"tf.assert_variables_initialized": (
"tf.compat.v1.assert_variables_initialized"
),
"tf.debugging.assert_equal": "tf.compat.v1.debugging.assert_equal",
"tf.debugging.assert_greater": "tf.compat.v1.debugging.assert_greater",
"tf.debugging.assert_greater_equal": (
"tf.compat.v1.debugging.assert_greater_equal"
),
"tf.debugging.assert_integer": "tf.compat.v1.debugging.assert_integer",
"tf.debugging.assert_less": "tf.compat.v1.debugging.assert_less",
"tf.debugging.assert_less_equal": (
"tf.compat.v1.debugging.assert_less_equal"
),
"tf.debugging.assert_near": "tf.compat.v1.debugging.assert_near",
"tf.debugging.assert_negative": "tf.compat.v1.debugging.assert_negative",
"tf.debugging.assert_non_negative": (
"tf.compat.v1.debugging.assert_non_negative"
),
"tf.debugging.assert_non_positive": (
"tf.compat.v1.debugging.assert_non_positive"
),
"tf.debugging.assert_none_equal": (
"tf.compat.v1.debugging.assert_none_equal"
),
"tf.debugging.assert_positive": "tf.compat.v1.debugging.assert_positive",
"tf.debugging.assert_rank": "tf.compat.v1.debugging.assert_rank",
"tf.debugging.assert_rank_at_least": (
"tf.compat.v1.debugging.assert_rank_at_least"
),
"tf.debugging.assert_rank_in": "tf.compat.v1.debugging.assert_rank_in",
"tf.debugging.assert_scalar": "tf.compat.v1.debugging.assert_scalar",
"tf.debugging.assert_type": "tf.compat.v1.debugging.assert_type",
"tf.errors.exception_type_from_error_code": (
"tf.compat.v1.errors.exception_type_from_error_code"
),
"tf.errors.error_code_from_exception_type": (
"tf.compat.v1.errors.error_code_from_exception_type"
),
"tf.errors.raise_exception_on_not_ok_status": (
"tf.compat.v1.errors.raise_exception_on_not_ok_status"
),
"tf.nn.max_pool": "tf.nn.max_pool2d",
"tf.nn.avg_pool": "tf.nn.avg_pool2d",
"tf.keras.initializers.zeros": "tf.compat.v1.keras.initializers.zeros",
"tf.keras.initializers.Zeros": "tf.compat.v1.keras.initializers.Zeros",
"tf.keras.initializers.ones": "tf.compat.v1.keras.initializers.ones",
"tf.keras.initializers.Ones": "tf.compat.v1.keras.initializers.Ones",
"tf.keras.initializers.constant": (
"tf.compat.v1.keras.initializers.constant"
),
"tf.keras.initializers.Constant": (
"tf.compat.v1.keras.initializers.Constant"
),
"tf.keras.initializers.VarianceScaling": (
"tf.compat.v1.keras.initializers.VarianceScaling"
),
"tf.keras.initializers.Orthogonal": (
"tf.compat.v1.keras.initializers.Orthogonal"
),
"tf.keras.initializers.orthogonal": (
"tf.compat.v1.keras.initializers.orthogonal"
),
"tf.keras.initializers.Identity": (
"tf.compat.v1.keras.initializers.Identity"
),
"tf.keras.initializers.identity": (
"tf.compat.v1.keras.initializers.identity"
),
"tf.keras.initializers.glorot_uniform": (
"tf.compat.v1.keras.initializers.glorot_uniform"
),
"tf.keras.initializers.glorot_normal": (
"tf.compat.v1.keras.initializers.glorot_normal"
),
"tf.keras.initializers.lecun_normal": (
"tf.compat.v1.keras.initializers.lecun_normal"
),
"tf.keras.initializers.lecun_uniform": (
"tf.compat.v1.keras.initializers.lecun_uniform"
),
"tf.keras.initializers.he_normal": (
"tf.compat.v1.keras.initializers.he_normal"
),
"tf.keras.initializers.he_uniform": (
"tf.compat.v1.keras.initializers.he_uniform"
),
"tf.keras.initializers.TruncatedNormal": (
"tf.compat.v1.keras.initializers.TruncatedNormal"
),
"tf.keras.initializers.truncated_normal": (
"tf.compat.v1.keras.initializers.truncated_normal"
),
"tf.keras.initializers.RandomUniform": (
"tf.compat.v1.keras.initializers.RandomUniform"
),
"tf.keras.initializers.uniform": "tf.compat.v1.keras.initializers.uniform",
"tf.keras.initializers.random_uniform": (
"tf.compat.v1.keras.initializers.random_uniform"
),
"tf.keras.initializers.RandomNormal": (
"tf.compat.v1.keras.initializers.RandomNormal"
),
"tf.keras.initializers.normal": "tf.compat.v1.keras.initializers.normal",
"tf.keras.initializers.random_normal": (
"tf.compat.v1.keras.initializers.random_normal"
),
"tf.zeros_initializer": "tf.compat.v1.zeros_initializer",
"tf.initializers.zeros": "tf.compat.v1.initializers.zeros",
"tf.ones_initializer": "tf.compat.v1.ones_initializer",
"tf.initializers.ones": "tf.compat.v1.initializers.ones",
"tf.constant_initializer": "tf.compat.v1.constant_initializer",
"tf.initializers.constant": "tf.compat.v1.initializers.constant",
"tf.random_uniform_initializer": "tf.compat.v1.random_uniform_initializer",
"tf.initializers.random_uniform": (
"tf.compat.v1.initializers.random_uniform"
),
"tf.random_normal_initializer": "tf.compat.v1.random_normal_initializer",
"tf.initializers.random_normal": "tf.compat.v1.initializers.random_normal",
"tf.truncated_normal_initializer": (
"tf.compat.v1.truncated_normal_initializer"
),
"tf.initializers.truncated_normal": (
"tf.compat.v1.initializers.truncated_normal"
),
"tf.variance_scaling_initializer": (
"tf.compat.v1.variance_scaling_initializer"
),
"tf.initializers.variance_scaling": (
"tf.compat.v1.initializers.variance_scaling"
),
"tf.orthogonal_initializer": "tf.compat.v1.orthogonal_initializer",
"tf.initializers.orthogonal": "tf.compat.v1.initializers.orthogonal",
"tf.glorot_uniform_initializer": "tf.compat.v1.glorot_uniform_initializer",
"tf.initializers.glorot_uniform": (
"tf.compat.v1.initializers.glorot_uniform"
),
"tf.glorot_normal_initializer": "tf.compat.v1.glorot_normal_initializer",
"tf.initializers.glorot_normal": "tf.compat.v1.initializers.glorot_normal",
"tf.initializers.identity": "tf.compat.v1.initializers.identity",
"tf.initializers.lecun_normal": "tf.compat.v1.initializers.lecun_normal",
"tf.initializers.lecun_uniform": "tf.compat.v1.initializers.lecun_uniform",
"tf.initializers.he_normal": "tf.compat.v1.initializers.he_normal",
"tf.initializers.he_uniform": "tf.compat.v1.initializers.he_uniform",
"tf.data.experimental.map_and_batch_with_legacy_function": (
"tf.compat.v1.data.experimental.map_and_batch_with_legacy_function"
),
"tf.nn.conv2d_backprop_input": "tf.nn.conv2d_transpose",
"tf.test.compute_gradient": "tf.compat.v1.test.compute_gradient",
"tf.floor_div": "tf.math.floordiv",
"tf.where": "tf.compat.v1.where",
"tf.where_v2": "tf.compat.v2.where",
"tf.app.flags": "tf.compat.v1.app.flags",
}
# pylint: enable=line-too-long
def add_contrib_direct_import_support(symbol_dict):
"""Add support for `tf.contrib.*` alias `contrib_*.` Updates dict in place."""
for symbol_name in list(symbol_dict.keys()):
symbol_alias = symbol_name.replace("tf.contrib.", "contrib_")
symbol_dict[symbol_alias] = symbol_dict[symbol_name]
add_contrib_direct_import_support(manual_symbol_renames)
symbol_renames = renames_v2.renames
symbol_renames.update(manual_symbol_renames)
addons_symbol_mappings = {
"tf.contrib.layers.poincare_normalize":
"tfa.layers.PoincareNormalize",
"tf.contrib.layers.maxout":
"tfa.layers.Maxout",
"tf.contrib.layers.group_norm":
"tfa.layers.GroupNormalization",
"tf.contrib.layers.instance_norm":
"tfa.layers.InstanceNormalization",
"tf.contrib.sparsemax.sparsemax":
"tfa.activations.sparsemax",
"tf.contrib.losses.metric_learning.contrastive_loss":
"tfa.losses.ContrastiveLoss",
"tf.contrib.losses.metric_learning.lifted_struct_loss":
"tfa.losses.LiftedStructLoss",
"tf.contrib.sparsemax.sparsemax_loss":
"tfa.losses.SparsemaxLoss",
"tf.contrib.losses.metric_learning.triplet_semihard_loss":
"tfa.losses.TripletSemiHardLoss",
"tf.contrib.opt.LazyAdamOptimizer":
"tfa.optimizers.LazyAdam",
"tf.contrib.opt.MovingAverageOptimizer":
"tfa.optimizers.MovingAverage",
"tf.contrib.opt.MomentumWOptimizer":
"tfa.optimizers.SGDW",
"tf.contrib.opt.AdamWOptimizer":
"tfa.optimizers.AdamW",
"tf.contrib.opt.extend_with_decoupled_weight_decay":
"tfa.optimizers.extend_with_decoupled_weight_decay",
"tf.contrib.text.skip_gram_sample":
"tfa.text.skip_gram_sample",
"tf.contrib.text.skip_gram_sample_with_text_vocab":
"tfa.text.skip_gram_sample_with_text_vocab",
"tf.contrib.image.dense_image_warp":
"tfa.image.dense_image_warp",
"tf.contrib.image.adjust_hsv_in_yiq":
"tfa.image.adjust_hsv_in_yiq",
"tf.contrib.image.compose_transforms":
"tfa.image.compose_transforms",
"tf.contrib.image.random_hsv_in_yiq":
"tfa.image.random_hsv_in_yiq",
"tf.contrib.image.angles_to_projective_transforms":
"tfa.image.angles_to_projective_transforms",
"tf.contrib.image.matrices_to_flat_transforms":
"tfa.image.matrices_to_flat_transforms",
"tf.contrib.image.rotate":
"tfa.image.rotate",
"tf.contrib.image.transform":
"tfa.image.transform",
"tf.contrib.rnn.NASCell":
"tfa.rnn.NASCell",
"tf.contrib.rnn.LayerNormBasicLSTMCell":
"tfa.rnn.LayerNormLSTMCell"
}
add_contrib_direct_import_support(addons_symbol_mappings)
@@ -0,0 +1,170 @@
# Copyright 2019 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.
# =============================================================================
"""A module to support operations on ipynb files"""
import collections
import copy
import json
import re
import shutil
import tempfile
CodeLine = collections.namedtuple("CodeLine", ["cell_number", "code"])
def is_python(cell):
"""Checks if the cell consists of Python code."""
return (cell["cell_type"] == "code" # code cells only
and cell["source"] # non-empty cells
and not cell["source"][0].startswith("%%")) # multiline eg: %%bash
def process_file(in_filename, out_filename, upgrader):
"""The function where we inject the support for ipynb upgrade."""
print("Extracting code lines from original notebook")
raw_code, notebook = _get_code(in_filename)
raw_lines = [cl.code for cl in raw_code]
# The function follows the original flow from `upgrader.process_fil`
with tempfile.NamedTemporaryFile("w", delete=False) as temp_file:
processed_file, new_file_content, log, process_errors = (
upgrader.update_string_pasta("\n".join(raw_lines), in_filename))
if temp_file and processed_file:
new_notebook = _update_notebook(notebook, raw_code,
new_file_content.split("\n"))
json.dump(new_notebook, temp_file)
else:
raise SyntaxError(
"Was not able to process the file: \n%s\n" % "".join(log))
files_processed = processed_file
report_text = upgrader._format_log(log, in_filename, out_filename)
errors = process_errors
shutil.move(temp_file.name, out_filename)
return files_processed, report_text, errors
def skip_magic(code_line, magic_list):
"""Checks if the cell has magic, that is not Python-based.
Args:
code_line: A line of Python code
magic_list: A list of jupyter "magic" exceptions
Returns:
If the line jupyter "magic" line, not Python line
>>> skip_magic('!ls -laF', ['%', '!', '?'])
True
"""
for magic in magic_list:
if code_line.startswith(magic):
return True
return False
def check_line_split(code_line):
r"""Checks if a line was split with `\`.
Args:
code_line: A line of Python code
Returns:
If the line was split with `\`
>>> skip_magic("!gcloud ml-engine models create ${MODEL} \\\n")
True
"""
return re.search(r"\\\s*\n$", code_line)
def _get_code(input_file):
"""Loads the ipynb file and returns a list of CodeLines."""
raw_code = []
with open(input_file) as in_file:
notebook = json.load(in_file)
cell_index = 0
for cell in notebook["cells"]:
if is_python(cell):
cell_lines = cell["source"]
is_line_split = False
for line_idx, code_line in enumerate(cell_lines):
# Sometimes, jupyter has more than python code
# Idea is to comment these lines, for upgrade time
if skip_magic(code_line, ["%", "!", "?"]) or is_line_split:
# Found a special character, need to "encode"
code_line = "###!!!" + code_line
# if this cell ends with `\` -> skip the next line
is_line_split = check_line_split(code_line)
if is_line_split:
is_line_split = check_line_split(code_line)
# Sometimes, people leave \n at the end of cell
# in order to migrate only related things, and make the diff
# the smallest -> here is another hack
if (line_idx == len(cell_lines) - 1) and code_line.endswith("\n"):
code_line = code_line.replace("\n", "###===")
# sometimes a line would start with `\n` and content after
# that's the hack for this
raw_code.append(
CodeLine(cell_index,
code_line.rstrip().replace("\n", "###===")))
cell_index += 1
return raw_code, notebook
def _update_notebook(original_notebook, original_raw_lines, updated_code_lines):
"""Updates notebook, once migration is done."""
new_notebook = copy.deepcopy(original_notebook)
# validate that the number of lines is the same
assert len(original_raw_lines) == len(updated_code_lines), \
("The lengths of input and converted files are not the same: "
"{} vs {}".format(len(original_raw_lines), len(updated_code_lines)))
code_cell_idx = 0
for cell in new_notebook["cells"]:
if not is_python(cell):
continue
applicable_lines = [
idx for idx, code_line in enumerate(original_raw_lines)
if code_line.cell_number == code_cell_idx
]
new_code = [updated_code_lines[idx] for idx in applicable_lines]
cell["source"] = "\n".join(new_code).replace("###!!!", "").replace(
"###===", "\n")
code_cell_idx += 1
return new_notebook
@@ -0,0 +1,66 @@
# Copyright 2019 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.
# ==============================================================================
"""Module deprecation warnings for TensorFlow 2.0."""
from tensorflow.tools.compatibility import ast_edits
_CONTRIB_WARNING = (
ast_edits.ERROR,
"<function name> cannot be converted automatically. tf.contrib will not"
" be distributed with TensorFlow 2.0, please consider an alternative in"
" non-contrib TensorFlow, a community-maintained repository such as "
"tensorflow/addons, or fork the required code.")
_FLAGS_WARNING = (
ast_edits.ERROR,
"tf.flags and tf.app.flags have been removed, please use the argparse or "
"absl modules if you need command line parsing.")
_CONTRIB_CUDNN_RNN_WARNING = (
ast_edits.WARNING,
"(Manual edit required) tf.contrib.cudnn_rnn.* has been deprecated, "
"and the CuDNN kernel has been integrated with "
"tf.keras.layers.LSTM/GRU in TensorFlow 2.0. Please check the new API "
"and use that instead."
)
_CONTRIB_RNN_WARNING = (
ast_edits.WARNING,
"(Manual edit required) tf.contrib.rnn.* has been deprecated, and "
"widely used cells/functions will be moved to tensorflow/addons "
"repository. Please check it there and file Github issues if necessary."
)
_CONTRIB_DIST_STRAT_WARNING = (
ast_edits.WARNING,
"(Manual edit required) tf.contrib.distribute.* have been migrated to "
"tf.distribute.*. Please check out the new module for updated APIs.")
_CONTRIB_SEQ2SEQ_WARNING = (
ast_edits.WARNING,
"(Manual edit required) tf.contrib.seq2seq.* have been migrated to "
"`tfa.seq2seq.*` in TensorFlow Addons. Please see "
"https://github.com/tensorflow/addons for more info.")
MODULE_DEPRECATIONS = {
"tf.contrib": _CONTRIB_WARNING,
"tf.contrib.cudnn_rnn": _CONTRIB_CUDNN_RNN_WARNING,
"tf.contrib.rnn": _CONTRIB_RNN_WARNING,
"tf.flags": _FLAGS_WARNING,
"tf.app.flags": _FLAGS_WARNING,
"tf.contrib.distribute": _CONTRIB_DIST_STRAT_WARNING,
"tf.contrib.seq2seq": _CONTRIB_SEQ2SEQ_WARNING
}
@@ -0,0 +1,136 @@
# Copyright 2018 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.
# ==============================================================================
# pylint: disable=line-too-long
"""List of renames to apply when converting from TF 1.0 to TF 2.0.
THIS FILE IS AUTOGENERATED: To update, please run:
bazel run tensorflow/tools/compatibility/update:generate_v2_reorders_map
This file should be updated whenever a function is added to
self.reordered_function_names in tf_upgrade_v2.py.
"""
reorders = {
'tf.argmax': [None, None, 'name', 'dimension', 'output_type'],
'tf.argmin': [None, None, 'name', 'dimension', 'output_type'],
'tf.batch_to_space': [None, 'crops', 'block_size', 'name', 'block_shape'],
'tf.boolean_mask': [None, None, 'name', 'axis'],
'tf.cond': [None, None, None, 'strict', 'name', 'fn1', 'fn2'],
'tf.confusion_matrix': [None, None, None, 'dtype', 'name', 'weights'],
'tf.convert_to_tensor': [None, None, 'name', 'preferred_dtype', 'dtype_hint'],
'tf.data.experimental.RaggedTensorStructure': ['dtype', 'shape', 'ragged_rank'],
'tf.data.experimental.SparseTensorStructure': ['dtype', 'shape'],
'tf.data.experimental.TensorArrayStructure': ['dtype', 'element_shape', 'dynamic_size', 'infer_shape'],
'tf.data.experimental.TensorStructure': ['dtype', 'shape'],
'tf.debugging.assert_all_finite': ['t', 'msg', 'name', 'x', 'message'],
'tf.decode_csv': [None, None, None, None, 'name', 'na_value', 'select_cols'],
'tf.depth_to_space': [None, None, 'name', 'data_format'],
'tf.feature_column.categorical_column_with_vocabulary_file': [None, None, None, 'num_oov_buckets', 'default_value', 'dtype'],
'tf.gather_nd': [None, None, 'name', 'batch_dims'],
'tf.gradients': [None, None, None, None, 'colocate_gradients_with_ops', 'gate_gradients', 'aggregation_method', 'stop_gradients', 'unconnected_gradients'],
'tf.hessians': [None, None, 'name', 'colocate_gradients_with_ops', 'gate_gradients', 'aggregation_method'],
'tf.image.sample_distorted_bounding_box': [None, None, None, 'seed2', 'min_object_covered', 'aspect_ratio_range', 'area_range', 'max_attempts', 'use_image_if_no_bounding_boxes', 'name'],
'tf.initializers.uniform_unit_scaling': ['factor', 'seed', 'dtype'],
'tf.io.decode_csv': [None, None, None, None, 'name', 'na_value', 'select_cols'],
'tf.io.parse_example': [None, None, 'name', 'example_names'],
'tf.io.parse_single_example': [None, None, 'name', 'example_names'],
'tf.io.serialize_many_sparse': [None, 'name', 'out_type'],
'tf.io.serialize_sparse': [None, 'name', 'out_type'],
'tf.linalg.norm': [None, None, None, None, None, 'keep_dims'],
'tf.manip.gather_nd': [None, None, 'name', 'batch_dims'],
'tf.math.argmax': [None, None, 'name', 'dimension', 'output_type'],
'tf.math.argmin': [None, None, 'name', 'dimension', 'output_type'],
'tf.math.confusion_matrix': [None, None, None, 'dtype', 'name', 'weights'],
'tf.math.in_top_k': ['predictions', 'targets', 'k', 'name'],
'tf.math.reduce_all': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.math.reduce_any': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.math.reduce_logsumexp': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.math.reduce_max': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.math.reduce_mean': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.math.reduce_min': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.math.reduce_prod': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.math.reduce_sum': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.multinomial': [None, None, 'seed', 'name', 'output_dtype'],
'tf.nn.avg_pool': ['value', 'ksize', 'strides', 'padding', 'data_format', 'name', 'input'],
'tf.nn.avg_pool2d': ['value', 'ksize', 'strides', 'padding', 'data_format', 'name', 'input'],
'tf.nn.conv1d': ['value', 'filters', 'stride', 'padding', 'use_cudnn_on_gpu', 'data_format', 'name', 'input', 'dilations'],
'tf.nn.conv2d': [None, 'filter', 'strides', 'padding', 'use_cudnn_on_gpu', 'data_format', 'dilations', 'name', 'filters'],
'tf.nn.conv2d_backprop_input': ['input_sizes', 'filter', 'out_backprop', 'strides', 'padding', 'use_cudnn_on_gpu', 'data_format', 'dilations', 'name', 'filters'],
'tf.nn.convolution': [None, 'filter', 'padding', 'strides', 'dilation_rate', 'name', 'data_format', 'filters', 'dilations'],
'tf.nn.crelu': [None, 'name', 'axis'],
'tf.nn.ctc_beam_search_decoder': ['inputs', 'sequence_length', 'beam_width', 'top_paths', 'merge_repeated'],
'tf.nn.depth_to_space': [None, None, 'name', 'data_format'],
'tf.nn.depthwise_conv2d': [None, None, None, None, 'rate', 'name', 'data_format', 'dilations'],
'tf.nn.embedding_lookup': [None, None, 'partition_strategy', 'name', 'validate_indices', 'max_norm'],
'tf.nn.embedding_lookup_sparse': [None, None, None, 'partition_strategy', 'name', 'combiner', 'max_norm', 'allow_fast_lookup'],
'tf.nn.fractional_avg_pool': ['value', 'pooling_ratio', 'pseudo_random', 'overlapping', 'deterministic', 'seed', 'seed2', 'name'],
'tf.nn.fractional_max_pool': ['value', 'pooling_ratio', 'pseudo_random', 'overlapping', 'deterministic', 'seed', 'seed2', 'name'],
'tf.nn.in_top_k': ['predictions', 'targets', 'k', 'name'],
'tf.nn.max_pool': ['value', 'ksize', 'strides', 'padding', 'data_format', 'name', 'input'],
'tf.nn.moments': [None, None, None, 'name', 'keep_dims', 'keepdims'],
'tf.nn.pool': [None, None, None, 'padding', 'dilation_rate', 'strides', 'name', 'data_format', 'dilations'],
'tf.nn.separable_conv2d': [None, None, None, None, None, 'rate', 'name', 'data_format', 'dilations'],
'tf.nn.softmax_cross_entropy_with_logits': ['labels', 'logits', 'dim', 'name', 'axis'],
'tf.nn.space_to_batch': [None, 'paddings', 'block_size', 'name', 'block_shape'],
'tf.nn.space_to_depth': [None, None, 'name', 'data_format'],
'tf.nn.weighted_moments': [None, None, None, 'name', 'keep_dims', 'keepdims'],
'tf.norm': [None, None, None, None, None, 'keep_dims'],
'tf.pad': [None, None, None, 'name', 'constant_values'],
'tf.parse_example': [None, None, 'name', 'example_names'],
'tf.parse_single_example': [None, None, 'name', 'example_names'],
'tf.quantize_v2': [None, None, None, None, None, 'name', 'round_mode', 'narrow_range', 'axis', 'ensure_minimum_range'],
'tf.random.multinomial': [None, None, 'seed', 'name', 'output_dtype'],
'tf.random.poisson': ['lam', 'shape', 'dtype', 'seed', 'name'],
'tf.random_poisson': ['lam', 'shape', 'dtype', 'seed', 'name'],
'tf.reduce_all': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.reduce_any': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.reduce_join': [None, None, 'keep_dims', 'separator', 'name', 'reduction_indices', 'keepdims'],
'tf.reduce_logsumexp': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.reduce_max': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.reduce_mean': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.reduce_min': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.reduce_prod': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.reduce_sum': [None, None, None, None, 'reduction_indices', 'keep_dims'],
'tf.reverse_sequence': [None, None, None, None, None, 'seq_dim', 'batch_dim'],
'tf.serialize_many_sparse': [None, 'name', 'out_type'],
'tf.serialize_sparse': [None, 'name', 'out_type'],
'tf.shape': [None, 'name', 'out_type'],
'tf.size': [None, 'name', 'out_type'],
'tf.space_to_batch': [None, 'paddings', 'block_size', 'name', 'block_shape'],
'tf.space_to_depth': [None, None, 'name', 'data_format'],
'tf.sparse.add': [None, None, None, 'thresh'],
'tf.sparse.concat': [None, None, 'name', 'expand_nonconcat_dim', 'concat_dim', 'expand_nonconcat_dims'],
'tf.sparse.reduce_max': [None, None, None, 'reduction_axes', 'keep_dims'],
'tf.sparse.segment_mean': [None, None, None, 'name', 'num_segments', 'sparse_gradient'],
'tf.sparse.segment_sqrt_n': [None, None, None, 'name', 'num_segments', 'sparse_gradient'],
'tf.sparse.segment_sum': [None, None, None, 'name', 'num_segments', 'sparse_gradient'],
'tf.sparse.split': ['keyword_required', 'sp_input', 'num_split', 'axis', 'name', 'split_dim'],
'tf.sparse_add': [None, None, None, 'thresh'],
'tf.sparse_concat': [None, None, 'name', 'expand_nonconcat_dim', 'concat_dim', 'expand_nonconcat_dims'],
'tf.sparse_matmul': [None, None, None, None, 'a_is_sparse', 'b_is_sparse', 'name'],
'tf.sparse_reduce_max': [None, None, None, 'reduction_axes', 'keep_dims'],
'tf.sparse_segment_mean': [None, None, None, 'name', 'num_segments', 'sparse_gradient'],
'tf.sparse_segment_sqrt_n': [None, None, None, 'name', 'num_segments', 'sparse_gradient'],
'tf.sparse_segment_sum': [None, None, None, 'name', 'num_segments', 'sparse_gradient'],
'tf.sparse_split': ['keyword_required', 'sp_input', 'num_split', 'axis', 'name', 'split_dim'],
'tf.strings.length': [None, 'name', 'unit'],
'tf.strings.reduce_join': [None, None, 'keep_dims', 'separator', 'name', 'reduction_indices', 'keepdims'],
'tf.strings.substr': [None, None, None, 'name', 'unit'],
'tf.substr': [None, None, None, 'name', 'unit'],
'tf.test.assert_equal_graph_def': ['actual', 'expected', 'checkpoint_v2', 'hash_table_shared_name'],
'tf.transpose': [None, None, 'name', 'conjugate'],
'tf.tuple': [None, 'name', 'control_inputs'],
'tf.uniform_unit_scaling_initializer': ['factor', 'seed', 'dtype'],
'tf.verify_tensor_all_finite': ['t', 'msg', 'name', 'x', 'message'],
'tf.while_loop': ['cond', 'body', 'loop_vars', 'shape_invariants', 'parallel_iterations', 'back_prop', 'swap_memory', 'name', 'maximum_iterations', 'return_same_structure']
}
@@ -0,0 +1,206 @@
# Copyright 2018 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.
# ==============================================================================
"""Upgrader for Python scripts from 1.x TensorFlow to 2.0 TensorFlow."""
import argparse
from tensorflow.tools.compatibility import ast_edits
from tensorflow.tools.compatibility import ipynb
from tensorflow.tools.compatibility import tf_upgrade_v2
from tensorflow.tools.compatibility import tf_upgrade_v2_safety
# Make straightforward changes to convert to 2.0. In harder cases,
# use compat.v1.
_DEFAULT_MODE = "DEFAULT"
# Convert to use compat.v1.
_SAFETY_MODE = "SAFETY"
# Whether to rename to compat.v2
_IMPORT_RENAME_DEFAULT = False
def process_file(in_filename, out_filename, upgrader):
"""Process a file of type `.py` or `.ipynb`."""
if in_filename.endswith(".py"):
files_processed, report_text, errors = \
upgrader.process_file(in_filename, out_filename)
elif in_filename.endswith(".ipynb"):
files_processed, report_text, errors = \
ipynb.process_file(in_filename, out_filename, upgrader)
else:
raise NotImplementedError(
"Currently converter only supports python or ipynb")
return files_processed, report_text, errors
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""Convert a TensorFlow Python file from 1.x to 2.0
Simple usage:
tf_upgrade_v2.py --infile foo.py --outfile bar.py
tf_upgrade_v2.py --infile foo.ipynb --outfile bar.ipynb
tf_upgrade_v2.py --intree ~/code/old --outtree ~/code/new
""")
parser.add_argument(
"--infile",
dest="input_file",
help="If converting a single file, the name of the file "
"to convert")
parser.add_argument(
"--outfile",
dest="output_file",
help="If converting a single file, the output filename.")
parser.add_argument(
"--intree",
dest="input_tree",
help="If converting a whole tree of files, the directory "
"to read from (relative or absolute).")
parser.add_argument(
"--outtree",
dest="output_tree",
help="If converting a whole tree of files, the output "
"directory (relative or absolute).")
parser.add_argument(
"--copyotherfiles",
dest="copy_other_files",
help=("If converting a whole tree of files, whether to "
"copy the other files."),
type=bool,
default=True)
parser.add_argument(
"--inplace",
dest="in_place",
help=("If converting a set of files, whether to "
"allow the conversion to be performed on the "
"input files."),
action="store_true")
parser.add_argument(
"--no_import_rename",
dest="no_import_rename",
help=("Not to rename import to compat.v2 explicitly."),
action="store_true")
parser.add_argument(
"--no_upgrade_compat_v1_import",
dest="no_upgrade_compat_v1_import",
help=("If specified, don't upgrade explicit imports of "
"`tensorflow.compat.v1 as tf` to the v2 APIs. Otherwise, "
"explicit imports of the form `tensorflow.compat.v1 as tf` will "
"be upgraded."),
action="store_true")
parser.add_argument(
"--reportfile",
dest="report_filename",
help=("The name of the file where the report log is "
"stored."
"(default: %(default)s)"),
default="report.txt")
parser.add_argument(
"--mode",
dest="mode",
choices=[_DEFAULT_MODE, _SAFETY_MODE],
help=("Upgrade script mode. Supported modes:\n"
"%s: Perform only straightforward conversions to upgrade to "
"2.0. In more difficult cases, switch to use compat.v1.\n"
"%s: Keep 1.* code intact and import compat.v1 "
"module." %
(_DEFAULT_MODE, _SAFETY_MODE)),
default=_DEFAULT_MODE)
parser.add_argument(
"--print_all",
dest="print_all",
help="Print full log to stdout instead of just printing errors",
action="store_true")
args = parser.parse_args()
if args.mode == _SAFETY_MODE:
change_spec = tf_upgrade_v2_safety.TFAPIChangeSpec()
else:
if args.no_import_rename:
change_spec = tf_upgrade_v2.TFAPIChangeSpec(
import_rename=False,
upgrade_compat_v1_import=not args.no_upgrade_compat_v1_import)
else:
change_spec = tf_upgrade_v2.TFAPIChangeSpec(
import_rename=_IMPORT_RENAME_DEFAULT,
upgrade_compat_v1_import=not args.no_upgrade_compat_v1_import)
upgrade = ast_edits.ASTCodeUpgrader(change_spec)
report_text = None
report_filename = args.report_filename
files_processed = 0
if args.input_file:
if not args.in_place and not args.output_file:
raise ValueError(
"--outfile=<output file> argument is required when converting a "
"single file.")
if args.in_place and args.output_file:
raise ValueError("--outfile argument is invalid when converting in place")
output_file = args.input_file if args.in_place else args.output_file
files_processed, report_text, errors = process_file(
args.input_file, output_file, upgrade)
errors = {args.input_file: errors}
files_processed = 1
elif args.input_tree:
if not args.in_place and not args.output_tree:
raise ValueError(
"--outtree=<output directory> argument is required when converting a "
"file tree.")
if args.in_place and args.output_tree:
raise ValueError("--outtree argument is invalid when converting in place")
output_tree = args.input_tree if args.in_place else args.output_tree
files_processed, report_text, errors = upgrade.process_tree(
args.input_tree, output_tree, args.copy_other_files)
else:
parser.print_help()
if report_text:
num_errors = 0
report = []
for f in errors:
if errors[f]:
num_errors += len(errors[f])
report.append("-" * 80 + "\n")
report.append("File: %s\n" % f)
report.append("-" * 80 + "\n")
report.append("\n".join(errors[f]) + "\n")
report = ("TensorFlow 2.0 Upgrade Script\n"
"-----------------------------\n"
"Converted %d files\n" % files_processed +
"Detected %d issues that require attention" % num_errors + "\n" +
"-" * 80 + "\n") + "".join(report)
detailed_report_header = "=" * 80 + "\n"
detailed_report_header += "Detailed log follows:\n\n"
detailed_report_header += "=" * 80 + "\n"
with open(report_filename, "w") as report_file:
report_file.write(report)
report_file.write(detailed_report_header)
report_file.write(report_text)
if args.print_all:
print(report)
print(detailed_report_header)
print(report_text)
else:
print(report)
print("\nMake sure to read the detailed log %r\n" % report_filename)
if __name__ == "__main__":
main()
@@ -0,0 +1,58 @@
# Copyright 2019 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.
# ==============================================================================
"""Upgrader for Python scripts from 1.* to 2.0 TensorFlow using SAFETY mode."""
from tensorflow.tools.compatibility import all_renames_v2
from tensorflow.tools.compatibility import ast_edits
from tensorflow.tools.compatibility import module_deprecations_v2
class TFAPIChangeSpec(ast_edits.APIChangeSpec):
"""List of maps that describe what changed in the API."""
def __init__(self):
self.function_keyword_renames = {}
self.symbol_renames = {}
self.change_to_function = {}
self.function_reorders = {}
self.function_warnings = {}
self.function_transformers = {}
self.module_deprecations = module_deprecations_v2.MODULE_DEPRECATIONS
## Inform about the addons mappings
for symbol, replacement in all_renames_v2.addons_symbol_mappings.items():
warning = (
ast_edits.WARNING, (
"(Manual edit required) `{}` has been migrated to `{}` in "
"TensorFlow Addons. The API spec may have changed during the "
"migration. Please see https://github.com/tensorflow/addons "
"for more info.").format(symbol, replacement))
self.function_warnings[symbol] = warning
# List module renames. If changed, please update max_submodule_depth.
self.import_renames = {
"tensorflow":
ast_edits.ImportRename(
"tensorflow.compat.v1",
excluded_prefixes=[
"tensorflow.contrib", "tensorflow.flags",
"tensorflow.compat",
"tensorflow.compat.v1", "tensorflow.compat.v2",
"tensorflow.google"
],
)
}
# Needs to be updated if self.import_renames is changed.
self.max_submodule_depth = 2
@@ -0,0 +1,368 @@
# Copyright 2018 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.
# ==============================================================================
"""Documentation control decorators."""
from typing import Optional, TypeVar
T = TypeVar("T")
_DEPRECATED = "_tf_docs_deprecated"
def set_deprecated(obj: T) -> T:
"""Explicitly tag an object as deprecated for the doc generator."""
setattr(obj, _DEPRECATED, None)
return obj
_INHERITABLE_HEADER = "_tf_docs_inheritable_header"
def inheritable_header(text):
def _wrapped(cls):
setattr(cls, _INHERITABLE_HEADER, text)
return cls
return _wrapped
def get_inheritable_header(obj) -> Optional[str]:
return getattr(obj, _INHERITABLE_HEADER, None)
header = inheritable_header
get_header = get_inheritable_header
_DO_NOT_DOC = "_tf_docs_do_not_document"
def do_not_generate_docs(obj: T) -> T:
"""A decorator: Do not generate docs for this object.
For example the following classes:
```
class Parent(object):
def method1(self):
pass
def method2(self):
pass
class Child(Parent):
def method1(self):
pass
def method2(self):
pass
```
Produce the following api_docs:
```
/Parent.md
# method1
# method2
/Child.md
# method1
# method2
```
This decorator allows you to skip classes or methods:
```
@do_not_generate_docs
class Parent(object):
def method1(self):
pass
def method2(self):
pass
class Child(Parent):
@do_not_generate_docs
def method1(self):
pass
def method2(self):
pass
```
This will only produce the following docs:
```
/Child.md
# method2
```
Note: This is implemented by adding a hidden attribute on the object, so it
cannot be used on objects which do not allow new attributes to be added. So
this decorator must go *below* `@property`, `@classmethod`,
or `@staticmethod`:
```
class Example(object):
@property
@do_not_generate_docs
def x(self):
return self._x
```
Args:
obj: The object to hide from the generated docs.
Returns:
obj
"""
setattr(obj, _DO_NOT_DOC, None)
return obj
_DO_NOT_DOC_INHERITABLE = "_tf_docs_do_not_doc_inheritable"
def do_not_doc_inheritable(obj: T) -> T:
"""A decorator: Do not generate docs for this method.
This version of the decorator is "inherited" by subclasses. No docs will be
generated for the decorated method in any subclass. Even if the sub-class
overrides the method.
For example, to ensure that `method1` is **never documented** use this
decorator on the base-class:
```
class Parent(object):
@do_not_doc_inheritable
def method1(self):
pass
def method2(self):
pass
class Child(Parent):
def method1(self):
pass
def method2(self):
pass
```
This will produce the following docs:
```
/Parent.md
# method2
/Child.md
# method2
```
When generating docs for a class's arributes, the `__mro__` is searched and
the attribute will be skipped if this decorator is detected on the attribute
on any class in the `__mro__`.
Note: This is implemented by adding a hidden attribute on the object, so it
cannot be used on objects which do not allow new attributes to be added. So
this decorator must go *below* `@property`, `@classmethod`,
or `@staticmethod`:
```
class Example(object):
@property
@do_not_doc_inheritable
def x(self):
return self._x
```
Args:
obj: The class-attribute to hide from the generated docs.
Returns:
obj
"""
setattr(obj, _DO_NOT_DOC_INHERITABLE, None)
return obj
_FOR_SUBCLASS_IMPLEMENTERS = "_tf_docs_tools_for_subclass_implementers"
def for_subclass_implementers(obj: T) -> T:
"""A decorator: Only generate docs for this method in the defining class.
Also group this method's docs with and `@abstractmethod` in the class's docs.
No docs will generated for this class attribute in sub-classes.
The canonical use case for this is `tf.keras.layers.Layer.call`: It's a
public method, essential for anyone implementing a subclass, but it should
never be called directly.
Works on method, or other class-attributes.
When generating docs for a class's arributes, the `__mro__` is searched and
the attribute will be skipped if this decorator is detected on the attribute
on any **parent** class in the `__mro__`.
For example:
```
class Parent(object):
@for_subclass_implementers
def method1(self):
pass
def method2(self):
pass
class Child1(Parent):
def method1(self):
pass
def method2(self):
pass
class Child2(Parent):
def method1(self):
pass
def method2(self):
pass
```
This will produce the following docs:
```
/Parent.md
# method1
# method2
/Child1.md
# method2
/Child2.md
# method2
```
Note: This is implemented by adding a hidden attribute on the object, so it
cannot be used on objects which do not allow new attributes to be added. So
this decorator must go *below* `@property`, `@classmethod`,
or `@staticmethod`:
```
class Example(object):
@property
@for_subclass_implementers
def x(self):
return self._x
```
Args:
obj: The class-attribute to hide from the generated docs.
Returns:
obj
"""
setattr(obj, _FOR_SUBCLASS_IMPLEMENTERS, None)
return obj
do_not_doc_in_subclasses = for_subclass_implementers
_DOC_PRIVATE = "_tf_docs_doc_private"
def doc_private(obj: T) -> T:
"""A decorator: Generates docs for private methods/functions.
For example:
```
class Try:
@doc_controls.doc_private
def _private(self):
...
```
As a rule of thumb, private(beginning with `_`) methods/functions are
not documented.
This decorator allows to force document a private method/function.
Args:
obj: The class-attribute to hide from the generated docs.
Returns:
obj
"""
setattr(obj, _DOC_PRIVATE, None)
return obj
_DOC_IN_CURRENT_AND_SUBCLASSES = "_tf_docs_doc_in_current_and_subclasses"
def doc_in_current_and_subclasses(obj: T) -> T:
"""Overrides `do_not_doc_in_subclasses` decorator.
If this decorator is set on a child class's method whose parent's method
contains `do_not_doc_in_subclasses`, then that will be overriden and the
child method will get documented. All classes inherting from the child will
also document that method.
For example:
```
class Parent:
@do_not_doc_in_subclasses
def method1(self):
pass
def method2(self):
pass
class Child1(Parent):
@doc_in_current_and_subclasses
def method1(self):
pass
def method2(self):
pass
class Child2(Parent):
def method1(self):
pass
def method2(self):
pass
class Child11(Child1):
pass
```
This will produce the following docs:
```
/Parent.md
# method1
# method2
/Child1.md
# method1
# method2
/Child2.md
# method2
/Child11.md
# method1
# method2
```
Args:
obj: The class-attribute to hide from the generated docs.
Returns:
obj
"""
setattr(obj, _DOC_IN_CURRENT_AND_SUBCLASSES, None)
return obj
@@ -0,0 +1,224 @@
# Copyright 2019 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.
# ==============================================================================
"""Run doctests for tensorflow."""
import doctest
import re
import textwrap
import numpy as np
class _FloatExtractor(object):
"""Class for extracting floats from a string.
For example:
>>> text_parts, floats = _FloatExtractor()("Text 1.0 Text")
>>> text_parts
["Text ", " Text"]
>>> floats
np.array([1.0])
"""
# Note: non-capturing groups "(?" are not returned in matched groups, or by
# re.split.
_FLOAT_RE = re.compile(
r"""
( # Captures the float value.
(?:
[-+]| # Start with a sign is okay anywhere.
(?: # Otherwise:
^| # Start after the start of string
(?<=[^\w.]) # Not after a word char, or a .
)
)
(?: # Digits and exponent - something like:
{digits_dot_maybe_digits}{exponent}?| # "1.0" "1." "1.0e3", "1.e3"
{dot_digits}{exponent}?| # ".1" ".1e3"
{digits}{exponent}| # "1e3"
{digits}(?=j) # "300j"
)
)
j? # Optional j for cplx numbers, not captured.
(?= # Only accept the match if
$| # * At the end of the string, or
[^\w.] # * Next char is not a word char or "."
)
""".format(
# Digits, a "." and optional more digits: "1.1".
digits_dot_maybe_digits=r'(?:[0-9]+\.(?:[0-9]*))',
# A "." with trailing digits ".23"
dot_digits=r'(?:\.[0-9]+)',
# digits: "12"
digits=r'(?:[0-9]+)',
# The exponent: An "e" or "E", optional sign, and at least one digit.
# "e-123", "E+12", "e12"
exponent=r'(?:[eE][-+]?[0-9]+)'),
re.VERBOSE)
def __call__(self, string):
"""Extracts floats from a string.
>>> text_parts, floats = _FloatExtractor()("Text 1.0 Text")
>>> text_parts
["Text ", " Text"]
>>> floats
np.array([1.0])
Args:
string: the string to extract floats from.
Returns:
A (string, array) pair, where `string` has each float replaced by "..."
and `array` is a `float32` `numpy.array` containing the extracted floats.
"""
texts = []
floats = []
for i, part in enumerate(self._FLOAT_RE.split(string)):
if i % 2 == 0:
texts.append(part)
else:
floats.append(float(part))
return texts, np.array(floats)
class TfDoctestOutputChecker(doctest.OutputChecker, object):
"""Customizes how `want` and `got` are compared, see `check_output`."""
def __init__(self, *args, **kwargs):
super(TfDoctestOutputChecker, self).__init__(*args, **kwargs)
self.extract_floats = _FloatExtractor()
self.text_good = None
self.float_size_good = None
_ADDRESS_RE = re.compile(r'\bat 0x[0-9a-f]*?>')
# TODO(yashkatariya): Add other tensor's string substitutions too.
# tf.RaggedTensor doesn't need one.
_NUMPY_OUTPUT_RE = re.compile(r'<tf.Tensor.*?numpy=(.*?)>', re.DOTALL)
def _allclose(self, want, got, rtol=1e-3, atol=1e-3):
return np.allclose(want, got, rtol=rtol, atol=atol)
def _tf_tensor_numpy_output(self, string):
modified_string = self._NUMPY_OUTPUT_RE.sub(r'\1', string)
return modified_string, modified_string != string
MESSAGE = textwrap.dedent("""\n
#############################################################
Check the documentation (https://www.tensorflow.org/community/contribute/docs_ref) on how to
write testable docstrings.
#############################################################""")
def check_output(self, want, got, optionflags):
"""Compares the docstring output to the output gotten by running the code.
Python addresses in the output are replaced with wildcards.
Float values in the output compared as using `np.allclose`:
* Float values are extracted from the text and replaced with wildcards.
* The wildcard text is compared to the actual output.
* The float values are compared using `np.allclose`.
The method returns `True` if both the text comparison and the numeric
comparison are successful.
The numeric comparison will fail if either:
* The wrong number of floats are found.
* The float values are not within tolerence.
Args:
want: The output in the docstring.
got: The output generated after running the snippet.
optionflags: Flags passed to the doctest.
Returns:
A bool, indicating if the check was successful or not.
"""
# If the docstring's output is empty and there is some output generated
# after running the snippet, return True. This is because if the user
# doesn't want to display output, respect that over what the doctest wants.
if got and not want:
return True
if want is None:
want = ''
if want == got:
return True
# Replace python's addresses with ellipsis (`...`) since it can change on
# each execution.
want = self._ADDRESS_RE.sub('at ...>', want)
# Replace tf.Tensor strings with only their numpy field values.
want, want_changed = self._tf_tensor_numpy_output(want)
if want_changed:
got, _ = self._tf_tensor_numpy_output(got)
# Separate out the floats, and replace `want` with the wild-card version
# "result=7.0" => "result=..."
want_text_parts, self.want_floats = self.extract_floats(want)
# numpy sometimes pads floats in arrays with spaces
# got: [1.2345, 2.3456, 3.0 ] want: [1.2345, 2.3456, 3.0001]
# And "normalize whitespace" only works when there's at least one space,
# so strip them and let the wildcard handle it.
want_text_parts = [part.strip(' ') for part in want_text_parts]
want_text_wild = '...'.join(want_text_parts)
if '....' in want_text_wild:
# If a float comes just after a period you'll end up four dots and the
# first three count as the ellipsis. Replace it with three dots.
want_text_wild = re.sub(r'\.\.\.\.+', '...', want_text_wild)
# Find the floats in the string returned by the test
_, self.got_floats = self.extract_floats(got)
self.text_good = super(TfDoctestOutputChecker, self).check_output(
want=want_text_wild, got=got, optionflags=optionflags)
if not self.text_good:
return False
if self.want_floats.size == 0:
# If there are no floats in the "want" string, ignore all the floats in
# the result. "np.array([ ... ])" matches "np.array([ 1.0, 2.0 ])"
return True
self.float_size_good = (self.want_floats.size == self.got_floats.size)
if self.float_size_good:
return self._allclose(self.want_floats, self.got_floats)
else:
return False
def output_difference(self, example, got, optionflags):
got = [got]
# If the some of the float output is hidden with `...`, `float_size_good`
# will be False. This is because the floats extracted from the string is
# converted into a 1-D numpy array. Hence hidding floats is not allowed
# anymore.
if self.text_good:
if not self.float_size_good:
got.append("\n\nCAUTION: tf_doctest doesn't work if *some* of the "
"*float output* is hidden with a \"...\".")
got.append(self.MESSAGE)
got = '\n'.join(got)
return (super(TfDoctestOutputChecker,
self).output_difference(example, got, optionflags))
@@ -0,0 +1,423 @@
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License..
# ==============================================================================
"""TensorFlow is an open source machine learning framework for everyone.
[![Python](https://img.shields.io/pypi/pyversions/tensorflow.svg?style=plastic)](https://badge.fury.io/py/tensorflow)
[![PyPI](https://badge.fury.io/py/tensorflow.svg)](https://badge.fury.io/py/tensorflow)
TensorFlow is an open source software library for high performance numerical
computation. Its flexible architecture allows easy deployment of computation
across a variety of platforms (CPUs, GPUs, TPUs), and from desktops to clusters
of servers to mobile and edge devices.
Originally developed by researchers and engineers from the Google Brain team
within Google's AI organization, it comes with strong support for machine
learning and deep learning and the flexible numerical computation core is used
across many other scientific domains. TensorFlow is licensed under [Apache
2.0](https://github.com/tensorflow/tensorflow/blob/master/LICENSE).
"""
import datetime
import fnmatch
import os
import platform
import re
import sys
from setuptools import Command
from setuptools import find_namespace_packages
from setuptools import setup
from setuptools.command.install import install as InstallCommandBase
from setuptools.dist import Distribution
# A genrule //tensorflow/tools/pip_package:setup_py replaces dummy string by
# by the data provided in //tensorflow/tf_version.bzl.
# The version suffix can be set by passing the build parameters
# --repo_env=ML_WHEEL_BUILD_DATE=<date> and
# --repo_env=ML_WHEEL_VERSION_SUFFIX=<suffix>.
# To update the project version, update tf_version.bzl.
# This version string is semver compatible, but incompatible with pip.
# For pip, we will remove all '-' characters from this string, and use the
# result for pip.
_VERSION = '2.20.0'
# We use the same setup.py for all tensorflow_* packages and for the nightly
# equivalents (tf_nightly_*). The package is controlled from the argument line
# when building the pip package.
project_name = 'tensorflow'
if os.environ.get('project_name', None):
project_name = os.environ['project_name']
collaborator_build = os.environ.get('collaborator_build', False)
# Returns standard if a tensorflow-* package is being built, and nightly if a
# tf_nightly-* package is being built.
def standard_or_nightly(standard, nightly):
return nightly if 'tf_nightly' in project_name else standard
# All versions of TF need these packages. We indicate the widest possible range
# of package releases possible to be as up-to-date as possible as well as to
# accomodate as many pre-installed packages as possible.
# For packages that don't have yet a stable release, we pin using `~= 0.x` which
# means we accept any `0.y` version (y >= x) but not the first major release. We
# will need additional testing for that.
# NOTE: This assumes that all packages follow SemVer. If a package follows a
# different versioning scheme (e.g., PVP), we use different bound specifier and
# comment the versioning scheme.
REQUIRED_PACKAGES = [
'absl-py >= 1.0.0',
'astunparse >= 1.6.0',
'flatbuffers >= 24.3.25',
'gast >=0.2.1,!=0.5.0,!=0.5.1,!=0.5.2',
'google_pasta >= 0.1.1',
'libclang >= 13.0.0',
'opt_einsum >= 2.3.2',
'packaging',
'protobuf>=5.28.0',
'requests >= 2.21.0, < 3',
'setuptools',
'six >= 1.12.0',
'termcolor >= 1.1.0',
'typing_extensions >= 3.6.6',
'wrapt >= 1.11.0',
# grpcio does not build correctly on big-endian machines due to lack of
# BoringSSL support.
# See https://github.com/tensorflow/tensorflow/issues/17882.
'grpcio >= 1.24.3, < 2.0' if sys.byteorder == 'little' else None,
# TensorFlow exposes the TF API for certain TF ecosystem packages like
# keras. When TF depends on those packages, the package version needs to
# match the current TF version. For tf_nightly, we install the nightly
# variant of each package instead, which must be one version ahead of the
# current release version. These also usually have "alpha" or "dev" in their
# version name. During the TF release process the version of these
# dependencies on the release branch is updated to the stable releases (RC
# or final). For example, 'keras-nightly ~= 2.14.0.dev' will be replaced by
# 'keras >= 2.14.0rc0, < 2.15' on the release branch after the branch cut.
'tensorboard ~= 2.20.0',
'keras >= 3.10.0',
'numpy >= 1.26.0',
'h5py >= 3.11.0',
'ml_dtypes >= 0.5.1, < 1.0.0',
]
REQUIRED_PACKAGES = [p for p in REQUIRED_PACKAGES if p is not None]
FAKE_REQUIRED_PACKAGES = [
# The depedencies here below are not actually used but are needed for
# package managers like poetry to parse as they are confused by the
# different architectures having different requirements.
# The entries here should be a simple duplicate of those in the collaborator
# build section.
]
if platform.system() == 'Linux' and platform.machine() == 'x86_64':
REQUIRED_PACKAGES.append(FAKE_REQUIRED_PACKAGES)
if collaborator_build:
# If this is a collaborator build, then build an "installer" wheel and
# add the collaborator packages as the only dependencies.
REQUIRED_PACKAGES = [
# Install the TensorFlow package built by Intel if the user is on a
# Windows machine.
standard_or_nightly('tensorflow-intel', 'tf-nightly-intel')
+ '=='
+ _VERSION
+ ';platform_system=="Windows"',
]
# Set up extra packages, which are optional sets of other Python package deps.
# E.g. "pip install tensorflow[and-cuda]" below installs the normal TF deps,
# plus the CUDA libraries listed.
EXTRA_PACKAGES = {
'and-cuda': [
# TODO(nluehr): set nvidia-* versions based on build components.
'nvidia-cublas-cu12 >= 12.5.3.2, < 13.0',
'nvidia-cuda-cupti-cu12 >= 12.5.82, < 13.0',
'nvidia-cuda-nvcc-cu12 >= 12.5.82, < 13.0',
'nvidia-cuda-nvrtc-cu12 >= 12.5.82, < 13.0',
'nvidia-cuda-runtime-cu12 >= 12.5.82, < 13.0',
'nvidia-cudnn-cu12 >= 9.3.0.75, < 10.0',
'nvidia-cufft-cu12 >= 11.2.3.61, < 12.0',
'nvidia-curand-cu12 >= 10.3.6.82, < 11.0',
'nvidia-cusolver-cu12 >= 11.6.3.83, < 12.0',
'nvidia-cusparse-cu12 >= 12.5.1.3, < 13.0',
'nvidia-nccl-cu12 >= 2.25.1, < 3.0',
'nvidia-nvjitlink-cu12 >= 12.5.82, < 13.0',
],
'gcs-filesystem': [
('tensorflow-io-gcs-filesystem>=0.23.1; '
'sys_platform!="win32" and python_version<"3.13"'),
('tensorflow-io-gcs-filesystem>=0.23.1; '
'sys_platform=="win32" and python_version<"3.12"'),
]
}
DOCLINES = __doc__.split('\n')
# pylint: disable=line-too-long
CONSOLE_SCRIPTS = [
'tflite_convert = tensorflow.lite.python.tflite_convert:main',
'toco = tensorflow.lite.python.tflite_convert:main',
'saved_model_cli = tensorflow.python.tools.saved_model_cli:main',
(
'import_pb_to_tensorboard ='
' tensorflow.python.tools.import_pb_to_tensorboard:main'
),
# We need to keep the TensorBoard command, even though the console script
# is now declared by the tensorboard pip package. If we remove the
# TensorBoard command, pip will inappropriately remove it during install,
# even though the command is not removed, just moved to a different wheel.
# We exclude it anyway if building tf_nightly.
standard_or_nightly('tensorboard = tensorboard.main:run_main', None),
'tf_upgrade_v2 = tensorflow.tools.compatibility.tf_upgrade_v2_main:main',
]
CONSOLE_SCRIPTS = [s for s in CONSOLE_SCRIPTS if s is not None]
# pylint: enable=line-too-long
class BinaryDistribution(Distribution):
def has_ext_modules(self):
return True
class InstallCommand(InstallCommandBase):
"""Override the dir where the headers go."""
def finalize_options(self):
ret = InstallCommandBase.finalize_options(self) # pylint: disable=assignment-from-no-return
self.install_headers = os.path.join(self.install_platlib, 'tensorflow',
'include')
self.install_lib = self.install_platlib
return ret
class InstallHeaders(Command):
"""Override how headers are copied.
The install_headers that comes with setuptools copies all files to
the same directory. But we need the files to be in a specific directory
hierarchy for -I <include_dir> to work correctly.
"""
description = 'install C/C++ header files'
user_options = [
('install-dir=', 'd', 'directory to install header files to'),
('force', 'f', 'force installation (overwrite existing files)'),
]
boolean_options = ['force']
def initialize_options(self):
self.install_dir = None
self.force = 0
self.outfiles = []
def finalize_options(self):
self.set_undefined_options('install', ('install_headers', 'install_dir'),
('force', 'force'))
def mkdir_and_copy_file(self, header):
install_dir = os.path.join(self.install_dir, os.path.dirname(header))
# Windows platform uses "\" in path strings, the external header location
# expects "/" in paths. Hence, we replaced "\" with "/" for this reason
install_dir = install_dir.replace('\\', '/')
# Get rid of some extra intervening directories so we can have fewer
# directories for -I
install_dir = re.sub('/google/protobuf_archive/src', '', install_dir)
# Copy external code headers into tensorflow/include.
# A symlink would do, but the wheel file that gets created ignores
# symlink within the directory hierarchy.
# NOTE(keveman): Figure out how to customize bdist_wheel package so
# we can do the symlink.
# pylint: disable=line-too-long
external_header_locations = {
'/tensorflow/include/external/com_google_absl': '',
'/tensorflow/include/external/ducc': '/ducc',
'/tensorflow/include/external/eigen_archive': '',
'/tensorflow/include/external/ml_dtypes_py': '',
'/tensorflow/include/tensorflow/compiler/xla': (
'/tensorflow/include/xla'
),
'/tensorflow/include/tensorflow/tsl': '/tensorflow/include/tsl',
}
# pylint: enable=line-too-long
for location in external_header_locations:
if location in install_dir:
extra_dir = install_dir.replace(location,
external_header_locations[location])
if not os.path.exists(extra_dir):
self.mkpath(extra_dir)
self.copy_file(header, extra_dir)
if not os.path.exists(install_dir):
self.mkpath(install_dir)
return self.copy_file(header, install_dir)
def run(self):
hdrs = self.distribution.headers
if not hdrs:
return
self.mkpath(self.install_dir)
for header in hdrs:
(out, _) = self.mkdir_and_copy_file(header)
self.outfiles.append(out)
def get_inputs(self):
return self.distribution.headers or []
def get_outputs(self):
return self.outfiles
def find_files(pattern, root):
"""Return all the files matching pattern below root dir."""
for dirpath, _, files in os.walk(root):
for filename in fnmatch.filter(files, pattern):
yield os.path.join(dirpath, filename)
so_lib_paths = [
i for i in os.listdir('.')
if os.path.isdir(i) and fnmatch.fnmatch(i, '_solib_*')
]
matches = []
for path in so_lib_paths:
matches.extend(['../' + x for x in find_files('*', path) if '.py' not in x])
if '_tpu' in project_name:
REQUIRED_PACKAGES.append([f'libtpu~=0.0.14'])
CONSOLE_SCRIPTS.extend([
'start_grpc_tpu_worker = tensorflow.python.tools.grpc_tpu_worker:run',
('start_grpc_tpu_service = '
'tensorflow.python.tools.grpc_tpu_worker_service:run'),
])
if os.name == 'nt':
EXTENSION_NAME = 'python/_pywrap_tensorflow_internal.pyd'
else:
EXTENSION_NAME = 'python/_pywrap_tensorflow_internal.so'
headers = (
list(find_files('*.proto', 'tensorflow/compiler'))
+ list(find_files('*.proto', 'tensorflow/core'))
+ list(find_files('*.proto', 'tensorflow/python'))
+ list(find_files('*.proto', 'tensorflow/python/framework'))
+ list(find_files('*.proto', 'tensorflow/tsl'))
+ list(find_files('*.def', 'tensorflow/compiler'))
+ list(find_files('*.h', 'tensorflow/c'))
+ list(find_files('*.h', 'tensorflow/cc'))
+ list(find_files('*.h', 'tensorflow/compiler'))
+ list(find_files('*.h.inc', 'tensorflow/compiler'))
+ list(find_files('*.h', 'tensorflow/core'))
+ list(find_files('*.h', 'tensorflow/lite/kernels/shim'))
+ list(find_files('*.h', 'tensorflow/python'))
+ list(find_files('*.h', 'tensorflow/python/client'))
+ list(find_files('*.h', 'tensorflow/python/framework'))
+ list(find_files('*.h', 'tensorflow/stream_executor'))
+ list(find_files('*.h', 'tensorflow/compiler/xla/stream_executor'))
+ list(find_files('*.h', 'tensorflow/tsl'))
+ list(find_files('*.h', 'google/com_google_protobuf/src'))
+ list(find_files('*.inc', 'google/com_google_protobuf/src'))
+ list(find_files('*', 'third_party/gpus'))
+ list(find_files('*.h', 'tensorflow/include/external/com_google_absl'))
+ list(find_files('*.inc', 'tensorflow/include/external/com_google_absl'))
+ list(find_files('*.h', 'tensorflow/include/external/ducc/google'))
+ list(find_files('*', 'tensorflow/include/external/eigen_archive'))
+ list(find_files('*.h', 'tensorflow/include/external/ml_dtypes_py'))
)
# Quite a lot of setup() options are different if this is a collaborator package
# build. We explicitly list the differences here, then unpack the dict as
# options at the end of the call to setup() below. For what each keyword does,
# see https://setuptools.pypa.io/en/latest/references/keywords.html.
if collaborator_build:
collaborator_build_dependent_options = {
'cmdclass': {},
'distclass': None,
'entry_points': {},
'headers': [],
'include_package_data': None,
'packages': [],
'package_data': {},
}
else:
collaborator_build_dependent_options = {
'cmdclass': {
'install_headers': InstallHeaders,
'install': InstallCommand,
},
'distclass': BinaryDistribution,
'entry_points': {
'console_scripts': CONSOLE_SCRIPTS,
},
'headers': headers,
'include_package_data': True,
'packages': find_namespace_packages(),
'package_data': {
'tensorflow': [EXTENSION_NAME] + matches,
},
}
setup(
name=project_name,
version=_VERSION.replace('-', ''),
description=DOCLINES[0],
long_description='\n'.join(DOCLINES[2:]),
long_description_content_type='text/markdown',
url='https://www.tensorflow.org/',
download_url='https://github.com/tensorflow/tensorflow/tags',
author='Google Inc.',
author_email='packages@tensorflow.org',
install_requires=REQUIRED_PACKAGES,
extras_require=EXTRA_PACKAGES,
# Add in any packaged data.
zip_safe=False,
# Supported Python versions
python_requires='>=3.9',
# PyPI package information.
classifiers=sorted([
'Development Status :: 5 - Production/Stable',
# TODO(angerson) Add IFTTT when possible
'Environment :: GPU :: NVIDIA CUDA :: 12',
'Environment :: GPU :: NVIDIA CUDA :: 12 :: 12.2',
'Intended Audience :: Developers',
'Intended Audience :: Education',
'Intended Audience :: Science/Research',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: 3 :: Only',
'Topic :: Scientific/Engineering',
'Topic :: Scientific/Engineering :: Mathematics',
'Topic :: Scientific/Engineering :: Artificial Intelligence',
'Topic :: Software Development',
'Topic :: Software Development :: Libraries',
'Topic :: Software Development :: Libraries :: Python Modules',
]),
license='Apache 2.0',
keywords='tensorflow tensor machine learning',
**collaborator_build_dependent_options
)