Move TensorLike under types.internal and rename it NativeObject to distinguish from types which actually behave like tensors.

PiperOrigin-RevId: 307878924
Change-Id: Ia1ba2d5df2f57540fa8063a0feaf54ed1e256077
This commit is contained in:
Dan Moldovan 2020-04-22 12:58:15 -07:00 committed by TensorFlower Gardener
parent 43b8f6e710
commit bb126a32c8
19 changed files with 43 additions and 44 deletions

View File

@ -1550,7 +1550,6 @@ py_library(
":platform",
":registry",
":tensor_conversion_registry",
":tensor_like",
":tensor_shape",
":tf2",
":traceable_stack",
@ -1589,13 +1588,6 @@ cuda_py_test(
],
)
py_library(
name = "tensor_like",
srcs = ["framework/tensor_like.py"],
srcs_version = "PY2AND3",
deps = [],
)
py_library(
name = "indexed_slices",
srcs = ["framework/indexed_slices.py"],
@ -1608,6 +1600,7 @@ py_library(
":type_spec",
":util",
"//tensorflow/python/eager:context",
"//tensorflow/python/types",
],
)
@ -1768,9 +1761,9 @@ py_library(
":composite_tensor",
":dtypes",
":framework_ops",
":tensor_like",
":tensor_util",
":type_spec",
"//tensorflow/python/types",
],
)
@ -1878,7 +1871,6 @@ py_library(
srcs = ["framework/tensor_util.py"],
srcs_version = "PY2AND3",
deps = [
":tensor_like",
":tensor_shape",
":util",
"//tensorflow/core:protos_all_py",

View File

@ -32,9 +32,9 @@ from tensorflow.python.eager import context
from tensorflow.python.framework import combinations
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.framework import tensor_like
from tensorflow.python.platform import test
from tensorflow.python.platform import tf_logging as logging
from tensorflow.python.types import internal
# memory_profiler might not be available in the OSS version of TensorFlow.
@ -116,7 +116,7 @@ class MemoryCleanupTest(test_base.DatasetTestBase, parameterized.TestCase):
gc.collect()
tensors = [
o for o in gc.get_objects() if isinstance(o, tensor_like.TensorLike)
o for o in gc.get_objects() if isinstance(o, internal.NativeObject)
]
self.assertEmpty(tensors, "%d Tensors are still alive." % len(tensors))

View File

@ -29,9 +29,9 @@ from tensorflow.python.eager import context
from tensorflow.python.framework import composite_tensor
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import tensor_conversion_registry
from tensorflow.python.framework import tensor_like
from tensorflow.python.framework import tensor_shape
from tensorflow.python.framework import type_spec
from tensorflow.python.types import internal
from tensorflow.python.util.lazy_loader import LazyLoader
from tensorflow.python.util.tf_export import tf_export
@ -55,8 +55,9 @@ tensor_util = LazyLoader(
"tensorflow.python.framework.tensor_util")
# TODO(mdan): Should IndexedSlices be a "tensor"?
@tf_export("IndexedSlices")
class IndexedSlices(tensor_like.TensorLike, composite_tensor.CompositeTensor):
class IndexedSlices(internal.NativeObject, composite_tensor.CompositeTensor):
"""A sparse representation of a set of tensor slices at given indices.
This class is a simple wrapper for a pair of `Tensor` objects:
@ -305,7 +306,8 @@ def internal_convert_to_tensor_or_indexed_slices(value,
"""
if isinstance(value, ops.EagerTensor) and not context.executing_eagerly():
return ops.convert_to_tensor(value, dtype=dtype, name=name, as_ref=as_ref)
elif isinstance(value, tensor_like.TensorLike):
# TODO(mdan): Name says tensor_or_indexed_slices. So do explicitly just that?
elif isinstance(value, internal.NativeObject):
if dtype and not dtypes.as_dtype(dtype).is_compatible_with(value.dtype):
raise ValueError(
"Tensor conversion requested dtype %s for Tensor with dtype %s: %r" %

View File

@ -56,13 +56,13 @@ from tensorflow.python.framework import errors
from tensorflow.python.framework import indexed_slices
from tensorflow.python.framework import registry
from tensorflow.python.framework import tensor_conversion_registry
from tensorflow.python.framework import tensor_like
from tensorflow.python.framework import tensor_shape
from tensorflow.python.framework import traceable_stack
from tensorflow.python.framework import versions
from tensorflow.python.ops import control_flow_util
from tensorflow.python.platform import app
from tensorflow.python.platform import tf_logging as logging
from tensorflow.python.types import internal
from tensorflow.python.util import compat
from tensorflow.python.util import decorator_utils
from tensorflow.python.util import deprecation
@ -302,8 +302,9 @@ def disable_tensor_equality():
Tensor._USE_EQUALITY = False # pylint: disable=protected-access
# TODO(mdan): This object should subclass Symbol, not just Tensor.
@tf_export("Tensor")
class Tensor(tensor_like.TensorLike):
class Tensor(internal.NativeObject):
"""A tensor is a multidimensional array of elements represented by a
`tf.Tensor` object. All elements are of a single known data type.
@ -1007,6 +1008,7 @@ class Tensor(tensor_like.TensorLike):
# TODO(agarwal): consider getting rid of this.
# TODO(mdan): This object should not subclass ops.Tensor.
class _EagerTensorBase(Tensor):
"""Base class for EagerTensor."""
@ -6057,7 +6059,7 @@ def _get_graph_from_inputs(op_input_list, graph=None):
# TODO(josh11b): Note that we exclude subclasses of Tensor. Need to clean this
# up.
graph_element = None
if (isinstance(op_input, (Operation, tensor_like.TensorLike)) and
if (isinstance(op_input, (Operation, internal.NativeObject)) and
((not isinstance(op_input, Tensor)) or type(op_input) == Tensor)): # pylint: disable=unidiomatic-typecheck
graph_element = op_input
else:

View File

@ -29,12 +29,12 @@ from tensorflow.python.framework import composite_tensor
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.framework import tensor_like
from tensorflow.python.framework import tensor_shape
from tensorflow.python.framework import tensor_spec
from tensorflow.python.framework import tensor_util
from tensorflow.python.framework import type_spec
from tensorflow.python.ops import gen_sparse_ops
from tensorflow.python.types import internal
from tensorflow.python.util.tf_export import tf_export
# pylint: disable=protected-access
@ -44,7 +44,7 @@ _override_helper = ops._override_helper
@tf_export("sparse.SparseTensor", "SparseTensor")
class SparseTensor(tensor_like.TensorLike, composite_tensor.CompositeTensor):
class SparseTensor(internal.NativeObject, composite_tensor.CompositeTensor):
"""Represents a sparse tensor.
TensorFlow represents a sparse tensor as three separate dense tensors:

View File

@ -25,9 +25,8 @@ from tensorflow.core.framework import tensor_shape_pb2
from tensorflow.python.eager import context
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.framework import tensor_like
from tensorflow.python.framework import tensor_shape
from tensorflow.python.types import core
from tensorflow.python.types import internal
from tensorflow.python.util import compat
from tensorflow.python.util import nest
from tensorflow.python.util.tf_export import tf_export
@ -980,6 +979,7 @@ def constant_value_as_shape(tensor): # pylint: disable=invalid-name
return ret
# TODO(mdan): Deprecate in favor of more static-friendly types.
@tf_export("is_tensor")
def is_tensor(x): # pylint: disable=invalid-name
"""Checks whether `x` is a TF-native type that can be passed to many TF ops.
@ -1006,7 +1006,7 @@ def is_tensor(x): # pylint: disable=invalid-name
Returns:
`True` if `x` is a tensor or "tensor-like", `False` if not.
"""
return (isinstance(x, (tensor_like.TensorLike, core.Tensor)) or
return (isinstance(x, internal.NativeObject) or
ops.is_dense_tensor_like(x) or
getattr(x, "is_tensor_like", False))

View File

@ -30,7 +30,6 @@ from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.framework import sparse_tensor
from tensorflow.python.framework import tensor_like
from tensorflow.python.framework import tensor_shape
from tensorflow.python.framework import tensor_spec
from tensorflow.python.framework import tensor_util
@ -44,6 +43,7 @@ from tensorflow.python.ops.ragged import ragged_config
from tensorflow.python.ops.ragged import ragged_tensor_value
from tensorflow.python.ops.ragged import ragged_util
from tensorflow.python.ops.ragged.row_partition import RowPartition
from tensorflow.python.types import internal as internal_types
from tensorflow.python.util.tf_export import tf_export
# pylint: disable=protected-access
@ -56,7 +56,8 @@ _convert_row_partition = RowPartition._convert_row_partition
@tf_export("RaggedTensor")
class RaggedTensor(composite_tensor.CompositeTensor, tensor_like.TensorLike):
class RaggedTensor(composite_tensor.CompositeTensor,
internal_types.NativeObject):
"""Represents a ragged tensor.
A `RaggedTensor` is a tensor with one or more *ragged dimensions*, which are

View File

@ -23,9 +23,9 @@ py_strict_library(
srcs = [
"__init__.py",
"core.py",
"internal.py",
],
srcs_version = "PY2AND3",
visibility = ["//tensorflow:__subpackages__"],
deps = [
],
deps = [],
)

View File

@ -1,4 +1,4 @@
# Copyright 2019 The TensorFlow Authors. All Rights Reserved.
# Copyright 2020 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.
@ -12,17 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Base class for tensor-like objects."""
"""Types internal to TensorFlow.
These types should not be exported. External code should not rely on these.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
class TensorLike(object):
"""TF-specific types TF operations are expected to natively support.
# TODO(mdan): Is this strictly needed? Only ops.py really uses it.
class NativeObject(object):
"""Types natively supported by various TF operations.
Do not check this with isinstance directly; prefer instead using
`tf.is_tensor` to check whether converting to a tensor is necessary.
The most notable example of NativeObject is Tensor.
"""
pass

View File

@ -1,7 +1,7 @@
path: "tensorflow.IndexedSlices"
tf_class {
is_instance: "<class \'tensorflow.python.framework.indexed_slices.IndexedSlices\'>"
is_instance: "<class \'tensorflow.python.framework.tensor_like.TensorLike\'>"
is_instance: "<class \'tensorflow.python.types.internal.NativeObject\'>"
is_instance: "<class \'tensorflow.python.framework.composite_tensor.CompositeTensor\'>"
is_instance: "<type \'object\'>"
member {

View File

@ -2,7 +2,7 @@ path: "tensorflow.RaggedTensor"
tf_class {
is_instance: "<class \'tensorflow.python.ops.ragged.ragged_tensor.RaggedTensor\'>"
is_instance: "<class \'tensorflow.python.framework.composite_tensor.CompositeTensor\'>"
is_instance: "<class \'tensorflow.python.framework.tensor_like.TensorLike\'>"
is_instance: "<class \'tensorflow.python.types.internal.NativeObject\'>"
is_instance: "<type \'object\'>"
member {
name: "dtype"

View File

@ -1,7 +1,7 @@
path: "tensorflow.SparseTensor"
tf_class {
is_instance: "<class \'tensorflow.python.framework.sparse_tensor.SparseTensor\'>"
is_instance: "<class \'tensorflow.python.framework.tensor_like.TensorLike\'>"
is_instance: "<class \'tensorflow.python.types.internal.NativeObject\'>"
is_instance: "<class \'tensorflow.python.framework.composite_tensor.CompositeTensor\'>"
is_instance: "<type \'object\'>"
member {

View File

@ -1,7 +1,7 @@
path: "tensorflow.Tensor"
tf_class {
is_instance: "<class \'tensorflow.python.framework.ops.Tensor\'>"
is_instance: "<class \'tensorflow.python.framework.tensor_like.TensorLike\'>"
is_instance: "<class \'tensorflow.python.types.internal.NativeObject\'>"
is_instance: "<type \'object\'>"
member {
name: "OVERLOADABLE_OPERATORS"

View File

@ -1,7 +1,7 @@
path: "tensorflow.sparse.SparseTensor"
tf_class {
is_instance: "<class \'tensorflow.python.framework.sparse_tensor.SparseTensor\'>"
is_instance: "<class \'tensorflow.python.framework.tensor_like.TensorLike\'>"
is_instance: "<class \'tensorflow.python.types.internal.NativeObject\'>"
is_instance: "<class \'tensorflow.python.framework.composite_tensor.CompositeTensor\'>"
is_instance: "<type \'object\'>"
member {

View File

@ -1,7 +1,7 @@
path: "tensorflow.IndexedSlices"
tf_class {
is_instance: "<class \'tensorflow.python.framework.indexed_slices.IndexedSlices\'>"
is_instance: "<class \'tensorflow.python.framework.tensor_like.TensorLike\'>"
is_instance: "<class \'tensorflow.python.types.internal.NativeObject\'>"
is_instance: "<class \'tensorflow.python.framework.composite_tensor.CompositeTensor\'>"
is_instance: "<type \'object\'>"
member {

View File

@ -2,7 +2,7 @@ path: "tensorflow.RaggedTensor"
tf_class {
is_instance: "<class \'tensorflow.python.ops.ragged.ragged_tensor.RaggedTensor\'>"
is_instance: "<class \'tensorflow.python.framework.composite_tensor.CompositeTensor\'>"
is_instance: "<class \'tensorflow.python.framework.tensor_like.TensorLike\'>"
is_instance: "<class \'tensorflow.python.types.internal.NativeObject\'>"
is_instance: "<type \'object\'>"
member {
name: "dtype"

View File

@ -1,7 +1,7 @@
path: "tensorflow.SparseTensor"
tf_class {
is_instance: "<class \'tensorflow.python.framework.sparse_tensor.SparseTensor\'>"
is_instance: "<class \'tensorflow.python.framework.tensor_like.TensorLike\'>"
is_instance: "<class \'tensorflow.python.types.internal.NativeObject\'>"
is_instance: "<class \'tensorflow.python.framework.composite_tensor.CompositeTensor\'>"
is_instance: "<type \'object\'>"
member {

View File

@ -1,7 +1,7 @@
path: "tensorflow.Tensor"
tf_class {
is_instance: "<class \'tensorflow.python.framework.ops.Tensor\'>"
is_instance: "<class \'tensorflow.python.framework.tensor_like.TensorLike\'>"
is_instance: "<class \'tensorflow.python.types.internal.NativeObject\'>"
is_instance: "<type \'object\'>"
member {
name: "OVERLOADABLE_OPERATORS"

View File

@ -1,7 +1,7 @@
path: "tensorflow.sparse.SparseTensor"
tf_class {
is_instance: "<class \'tensorflow.python.framework.sparse_tensor.SparseTensor\'>"
is_instance: "<class \'tensorflow.python.framework.tensor_like.TensorLike\'>"
is_instance: "<class \'tensorflow.python.types.internal.NativeObject\'>"
is_instance: "<class \'tensorflow.python.framework.composite_tensor.CompositeTensor\'>"
is_instance: "<type \'object\'>"
member {