1/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14==============================================================================*/
15
16// Functions for getting information about kernels registered in the binary.
17#ifndef TENSORFLOW_PYTHON_UTIL_UTIL_H_
18#define TENSORFLOW_PYTHON_UTIL_UTIL_H_
19
20#include <Python.h>
21
22#include <string>
23
24namespace tensorflow {
25namespace swig {
26
27// Implements `tensorflow.util.nest.is_nested`.
28bool IsNested(PyObject* o);
29
30// Implements `tensorflow.util.nest.is_nested_or_composite`.
31bool IsNestedOrComposite(PyObject* o);
32
33// Returns a true if its input is a CompositeTensor or a TypeSpec.
34//
35// Args:
36// o: the object to check.
37//
38// Returns:
39// True if the object is a CompositeTensor.
40bool IsCompositeTensor(PyObject* o);
41
42// Returns a true if its input is a TypeSpec, but is not a TensorSpec.
43//
44// Args:
45// o: the object to check.
46//
47// Returns:
48// True if the object is a TypeSpec, but is not a TensorSpec.
49bool IsTypeSpec(PyObject* o);
50
51// Implements the same interface as tensorflow.util.nest.is_namedtuple
52// Returns Py_True iff `instance` should be considered a `namedtuple`.
53//
54// Args:
55// instance: An instance of a Python object.
56// strict: If True, `instance` is considered to be a `namedtuple` only if
57// it is a "plain" namedtuple. For instance, a class inheriting
58// from a `namedtuple` will be considered to be a `namedtuple`
59// iff `strict=False`.
60//
61// Returns:
62// True if `instance` is a `namedtuple`.
63PyObject* IsNamedtuple(PyObject* o, bool strict);
64
65// Returns a true if its input is a collections.Mapping.
66//
67// Args:
68// o: the object to be checked.
69//
70// Returns:
71// True if the object subclasses mapping.
72bool IsMapping(PyObject* o);
73
74// Returns a true if its input is a collections.MutableMapping.
75//
76// Args:
77// o: the object to be checked.
78//
79// Returns:
80// True if the object subclasses mapping.
81bool IsMutableMapping(PyObject* o);
82
83// Returns a true if its input is a (possibly wrapped) tuple.
84//
85// Args:
86// o: the object to be checked.
87//
88// Returns:
89// True if the object is a tuple.
90bool IsTuple(PyObject* o);
91
92// Returns a true if its input is a collections.MappingView.
93//
94// Args:
95// o: the object to be checked.
96//
97// Returns:
98// True if the object subclasses mapping.
99bool IsMappingView(PyObject* o);
100
101// Returns a true if its input has a `__tf_dispatch__` attribute.
102//
103// Args:
104// o: the input to be checked.
105//
106// Returns:
107// True if `o` has a `__tf_dispatch__` attribute.
108bool IsDispatchable(PyObject* o);
109
110// A version of PyMapping_Keys that works in C++11
111//
112// Args:
113// o: The input to extract keys from
114//
115// Returns:
116// A new reference to a list of keys in the mapping.
117PyObject* MappingKeys(PyObject* o);
118
119// Returns a true if its input is an instance of an attr.s decorated class.
120//
121// Args:
122// o: the input to be checked.
123//
124// Returns:
125// True if the object is an instance of an attr.s decorated class.
126bool IsAttrs(PyObject* o);
127
128// Returns a true if its input is an ops.Tensor.
129//
130// Args:
131// o: the input to be checked.
132//
133// Returns:
134// True if the object is a tensor.
135bool IsTensor(PyObject* o);
136
137// Returns true if its input is a tf.TensorSpec.
138//
139// Args:
140// o: the input to be checked.
141//
142// Returns:
143// True if the object is a TensorSpec.
144bool IsTensorSpec(PyObject* o);
145
146// Returns a true if its input is an eager.EagerTensor.
147//
148// Args:
149// o: the input to be checked.
150//
151// Returns:
152// True if the object is an eager tensor (or mimicking as one).
153bool IsEagerTensorSlow(PyObject* o);
154
155// Returns a true if its input is a ResourceVariable.
156//
157// Args:
158// o: the input to be checked.
159//
160// Returns:
161// True if the object is a ResourceVariable.
162bool IsResourceVariable(PyObject* o);
163
164// Returns a true if its input is an OwnedIterator.
165//
166// Args:
167// o: the input to be checked.
168//
169// Returns:
170// True if the object is an OwnedIterator.
171bool IsOwnedIterator(PyObject* o);
172
173// Returns a true if its input is a Variable.
174//
175// Args:
176// o: the input to be checked.
177//
178// Returns:
179// True if the object is a Variable.
180bool IsVariable(PyObject* o);
181
182// Returns a true if its input is an ops.IndexesSlices.
183//
184// Args:
185// o: the input to be checked.
186//
187// Returns:
188// True if the object is an ops.IndexedSlices.
189bool IsIndexedSlices(PyObject* o);
190
191// Implements the same interface as tensorflow.util.nest.same_namedtuples
192// Returns Py_True iff the two namedtuples have the same name and fields.
193// Raises RuntimeError if `o1` or `o2` don't look like namedtuples (don't have
194// '_fields' attribute).
195PyObject* SameNamedtuples(PyObject* o1, PyObject* o2);
196
197// Implements `tensorflow.util.nest.assert_same_structrure`.
198PyObject* AssertSameStructure(PyObject* o1, PyObject* o2, bool check_types,
199 bool expand_composites);
200
201// Implements `tensorflow.util.nest.flatten`.
202PyObject* Flatten(PyObject* nested, bool expand_composites = false);
203
204// The tensorflow.python.data package has its own nest utility that follows very
205// slightly different semantics for its functions than the tensorflow.python
206// nest utility. Returns True if its input is a nested structure for tf.data.
207//
208// Main differences are (this is copied from nest.py in the
209// tensorflow.data.util):
210//
211// 1. It removes support for lists as a level of nesting in nested structures.
212// 2. It adds support for `SparseTensorValue` as an atomic element.
213bool IsNestedForData(PyObject* o);
214
215// Flatten specialized for `tf.data`. Additional comments about
216// difference in functionality can be found in nest.py in
217// `tensorflow.python.data.util` and in the comments for Flatten above.
218PyObject* FlattenForData(PyObject* nested);
219
220// AssertSameStructure specialized for `tf.data`.
221PyObject* AssertSameStructureForData(PyObject* o1, PyObject* o2,
222 bool check_types);
223
224// Registers a Python object so it can be looked up from c++. The set of
225// valid names, and the expected values for those names, are listed in
226// the documentation for `RegisteredPyObjects`. Returns PyNone.
227PyObject* RegisterPyObject(PyObject* name, PyObject* value);
228
229// Variant of RegisterPyObject that requires the object's value to be a type.
230PyObject* RegisterType(PyObject* type_name, PyObject* type);
231
232// Returns a borrowed reference to an object that was registered with
233// RegisterPyObject. (Do not call Py_DECREF on the result).
234PyObject* GetRegisteredPyObject(const std::string& name);
235
236} // namespace swig
237} // namespace tensorflow
238
239#endif // TENSORFLOW_PYTHON_UTIL_UTIL_H_
240