1 | /* Copyright 2017 The TensorFlow Authors. All Rights Reserved. |
2 | |
3 | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | you may not use this file except in compliance with the License. |
5 | You may obtain a copy of the License at |
6 | |
7 | http://www.apache.org/licenses/LICENSE-2.0 |
8 | |
9 | Unless required by applicable law or agreed to in writing, software |
10 | distributed under the License is distributed on an "AS IS" BASIS, |
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | See the License for the specific language governing permissions and |
13 | limitations 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 | |
24 | namespace tensorflow { |
25 | namespace swig { |
26 | |
27 | // Implements `tensorflow.util.nest.is_nested`. |
28 | bool IsNested(PyObject* o); |
29 | |
30 | // Implements `tensorflow.util.nest.is_nested_or_composite`. |
31 | bool 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. |
40 | bool 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. |
49 | bool 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`. |
63 | PyObject* 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. |
72 | bool 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. |
81 | bool 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. |
90 | bool 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. |
99 | bool 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. |
108 | bool 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. |
117 | PyObject* 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. |
126 | bool 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. |
135 | bool 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. |
144 | bool 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). |
153 | bool 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. |
162 | bool 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. |
171 | bool 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. |
180 | bool 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. |
189 | bool 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). |
195 | PyObject* SameNamedtuples(PyObject* o1, PyObject* o2); |
196 | |
197 | // Implements `tensorflow.util.nest.assert_same_structrure`. |
198 | PyObject* AssertSameStructure(PyObject* o1, PyObject* o2, bool check_types, |
199 | bool expand_composites); |
200 | |
201 | // Implements `tensorflow.util.nest.flatten`. |
202 | PyObject* 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. |
213 | bool 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. |
218 | PyObject* FlattenForData(PyObject* nested); |
219 | |
220 | // AssertSameStructure specialized for `tf.data`. |
221 | PyObject* 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. |
227 | PyObject* RegisterPyObject(PyObject* name, PyObject* value); |
228 | |
229 | // Variant of RegisterPyObject that requires the object's value to be a type. |
230 | PyObject* 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). |
234 | PyObject* GetRegisteredPyObject(const std::string& name); |
235 | |
236 | } // namespace swig |
237 | } // namespace tensorflow |
238 | |
239 | #endif // TENSORFLOW_PYTHON_UTIL_UTIL_H_ |
240 | |