xref: /aosp_15_r20/external/tensorflow/tensorflow/python/client/tf_session_helper.h (revision b6fb3261f9314811a0f4371741dbb8839866f948)
1  /* Copyright 2015 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  #ifndef TENSORFLOW_PYTHON_CLIENT_TF_SESSION_HELPER_H_
17  #define TENSORFLOW_PYTHON_CLIENT_TF_SESSION_HELPER_H_
18  
19  // Must be included first
20  #include "tensorflow/python/lib/core/numpy.h"
21  
22  #include "tensorflow/c/c_api.h"
23  #include "tensorflow/core/framework/graph.pb.h"
24  #include "tensorflow/core/lib/core/errors.h"
25  #include "tensorflow/core/lib/core/status.h"
26  #include "tensorflow/core/lib/gtl/inlined_vector.h"
27  
28  namespace tensorflow {
29  
30  // Container types for the various arguments and temporary values used
31  // in the wrapper.
32  
33  // A NameVector is a vector of tensor or operation names, as borrowed
34  // C strings.
35  typedef tensorflow::gtl::InlinedVector<const char*, 8> NameVector;
36  
37  // A PyObjectVector is a vector of borrowed pointers to PyObjects.
38  typedef tensorflow::gtl::InlinedVector<PyObject*, 8> PyObjectVector;
39  
40  // A TF_TensorVector is a vector of borrowed pointers to TF_Tensors.
41  typedef gtl::InlinedVector<TF_Tensor*, 8> TF_TensorVector;
42  
43  TF_Session* TF_NewSessionRef(TF_Graph* graph, const TF_SessionOptions* opts,
44                               TF_Status* status);
45  
46  // Run the graph associated with the session starting with the
47  // supplied inputs[].  Regardless of success or failure, inputs[] are
48  // stolen by the implementation (i.e. the implementation will
49  // eventually call Py_DECREF on each array input).
50  //
51  // The PyObject* feed_dict must be a dictionary mapping strings to
52  // NumPy arrays. This function does not modify its reference count.
53  //
54  // On success, the tensors corresponding to output_names[0,noutputs-1]
55  // are placed in out_values[], and these outputs[] become the property
56  // of the caller (the caller must eventually call Py_DECREF on them).
57  //
58  // On failure, out_status contains a tensorflow::Status with an error
59  // message.
60  void TF_Run_wrapper(TF_DeprecatedSession* session, const TF_Buffer* run_options,
61                      PyObject* feed_dict, const NameVector& output_names,
62                      const NameVector& target_nodes, TF_Status* out_status,
63                      PyObjectVector* out_values, TF_Buffer* run_outputs);
64  
65  // Python wrappers for the `Session::MakeCallable()` API.
66  void TF_DeprecatedSessionMakeCallable(TF_DeprecatedSession* session,
67                                        const TF_Buffer* callable_options,
68                                        int64_t* out_handle, TF_Status* status);
69  void TF_SessionMakeCallable(TF_Session* session,
70                              const TF_Buffer* callable_options,
71                              int64_t* out_handle, TF_Status* status);
72  
73  // Python wrappers for the `Session::RunCallable()` API.
74  void TF_DeprecatedSessionRunCallable(TF_DeprecatedSession* session,
75                                       int64_t handle, PyObject* feed_values,
76                                       PyObjectVector* out_values,
77                                       TF_Buffer* run_metadata,
78                                       TF_Status* status);
79  void TF_SessionRunCallable(TF_Session* session, int64_t handle,
80                             PyObject* feed_values, PyObjectVector* out_values,
81                             TF_Buffer* run_metadata, TF_Status* status);
82  
83  // Python wrappers for the `Session::ReleaseCallable()` API.
84  void TF_DeprecatedSessionReleaseCallable(TF_DeprecatedSession* session,
85                                           int64_t handle, TF_Status* status);
86  void TF_SessionReleaseCallable(TF_Session* session, int64_t handle,
87                                 TF_Status* status);
88  
89  // Set up the graph with the intended feeds and fetches for partial run.
90  // *out_handle is owned by the caller.
91  //
92  // On success, returns a handle that is used for subsequent PRun calls.
93  //
94  // On failure, out_status contains a tensorflow::Status with an error
95  // message.
96  void TF_PRunSetup_wrapper(TF_DeprecatedSession* session,
97                            const NameVector& input_names,
98                            const NameVector& output_names,
99                            const NameVector& target_nodes, TF_Status* out_status,
100                            const char** out_handle);
101  
102  // Continue to run the graph with additional feeds and fetches. The
103  // execution state is uniquely identified by the handle.
104  //
105  // The PyObject* feed_dict must be a dictionary mapping strings to
106  // NumPy arrays. This function does not modify its reference count.
107  //
108  // On success,  the tensors corresponding to output_names[0,noutputs-1]
109  // are placed in out_values[], and these outputs[] become the property
110  // of the caller (the caller must eventually call Py_DECREF on them).
111  //
112  // On failure,  out_status contains a tensorflow::Status with an error
113  // message.
114  void TF_PRun_wrapper(TF_DeprecatedSession* session, const char* handle,
115                       PyObject* feed_dict, const NameVector& output_names,
116                       TF_Status* out_status, PyObjectVector* out_values);
117  
118  // Wrapper for TF_Reset that converts the string vectors to character arrays.
119  void TF_Reset_wrapper(const TF_SessionOptions* opt,
120                        const NameVector& containers, TF_Status* status);
121  
122  // Convenience wrapper around EqualGraphDef to make it easier to wrap.
123  // Returns an explanation if a difference is found, or the empty string
124  // for no difference.
125  string EqualGraphDefWrapper(const string& actual, const string& expected);
126  
127  // Convenience wrapper around AreAttrValuesEqual to make it easier to wrap.
128  // The actual and expected strings must correspond to a serialized binary
129  // representation of two AttrValue proto instances.
130  // Returns an explanation if a difference is found, or the empty string
131  // for no difference.
132  string EqualAttrValueWrapper(const string& actual, const string& expected);
133  
134  // Gets shape from C API Graph object.
135  //
136  // If shape is known, returns shape vector where -1 means "unknown
137  // dimension".  Sets unknown_shape to false.
138  //
139  // If shape is unknown, sets unknown_shape to true.
140  tensorflow::gtl::InlinedVector<int64_t, 6> TF_GraphGetTensorShapeHelper(
141      TF_Graph* graph, TF_Output output, TF_Status* status, bool* unknown_shape);
142  
143  // Runs the graph associated with the session starting with the supplied inputs.
144  // On success, `py_outputs` is populated with a numpy ndarray for each output
145  // (the caller must decref these ndarrays, although this will likely be handled
146  // by the Python gc). `session`, `out_status`, and `py_outputs` must be
147  // non-null. `py_outputs` should be empty.
148  void TF_SessionRun_wrapper(TF_Session* session, const TF_Buffer* run_options,
149                             const std::vector<TF_Output>& inputs,
150                             const std::vector<PyObject*>& input_ndarrays,
151                             const std::vector<TF_Output>& outputs,
152                             const std::vector<TF_Operation*>& targets,
153                             TF_Buffer* run_metadata, TF_Status* status,
154                             std::vector<PyObject*>* py_outputs);
155  
156  // Set up the graph with the intended feeds (inputs) and fetches (output) for
157  // a sequence of partial run calls.
158  //
159  // On success, returns a handle that can be used for subsequent PRun calls. The
160  // handle is owned by the caller and should be deleted with TF_DeletePRunHandle
161  // when it is no longer needed.
162  //
163  // On failure, out_status contains a tensorflow::Status with an error
164  // message.
165  void TF_SessionPRunSetup_wrapper(TF_Session* session,
166                                   const std::vector<TF_Output>& inputs,
167                                   const std::vector<TF_Output>& outputs,
168                                   const std::vector<TF_Operation*>& targets,
169                                   const char** out_handle, TF_Status* status);
170  
171  // Continue to run the graph with additional feeds and fetches. The
172  // execution state is uniquely identified by the handle.
173  //
174  // On success, `py_outputs` is populated with a numpy ndarray for each output
175  // (the caller must decref these ndarrays, although this will likely be handled
176  // by the Python gc). `session`, `handle`, `out_status`, and `py_outputs` must
177  // be non-null. `py_outputs` should be empty.
178  //
179  // On failure, out_status contains a tensorflow::Status with an error
180  // message.
181  void TF_SessionPRun_wrapper(TF_Session* session, const char* handle,
182                              const std::vector<TF_Output>& inputs,
183                              const std::vector<PyObject*>& input_ndarrays,
184                              const std::vector<TF_Output>& outputs,
185                              TF_Status* status,
186                              std::vector<PyObject*>* py_outputs);
187  
188  // Retrieves the inputs of this operation.
189  std::vector<TF_Output> GetOperationInputs(TF_Operation* oper);
190  
191  // Retrieves the control inputs of this operation.
192  std::vector<TF_Operation*> TF_OperationGetControlInputs_wrapper(
193      TF_Operation* oper);
194  
195  // Retrieves the control outputs of this operation.
196  std::vector<TF_Operation*> TF_OperationGetControlOutputs_wrapper(
197      TF_Operation* oper);
198  
199  // Retrieves the op names of the consumers of `oper_out`. The returned strings
200  // have the lifetime of the underlying TF_Graph.
201  std::vector<const char*> TF_OperationOutputConsumers_wrapper(
202      TF_Output oper_out);
203  
204  // `opers` equaling NULL are converted to `nopers = -1`.
205  // `output_names` must be empty or have the same length as `outputs`.
206  TF_Function* TF_GraphToFunction_wrapper(
207      const TF_Graph* fn_body, const char* fn_name, bool append_hash_to_fn_name,
208      const std::vector<TF_Operation*>* opers,
209      const std::vector<TF_Output>& inputs, const std::vector<TF_Output>& outputs,
210      const NameVector& output_names,
211      const std::vector<TF_Operation*>* control_outputs,
212      const NameVector& control_output_names, const TF_FunctionOptions* opts,
213      const char* description, TF_Status* status);
214  
215  // Set the shapes and types for the output's handle.
216  //
217  // The sizes of 'shapes', 'ranks', and 'types' must be equal; `shapes[i]`
218  // contains the shape of the handle's i-th value, `ranks[i]` contains the i-th
219  // shape's rank, and `types[i]` contains the i-th value's dtype. If the i-th
220  // shape is unknown, then `ranks[i]` must be equal to -1.
221  //
222  // The space between the double angle brackets below looks extraneous, but
223  // our version of SWIG cannot parse ">>".
224  void TF_GraphSetOutputHandleShapesAndTypes_wrapper(
225      TF_Graph* graph, TF_Output output,
226      const std::vector<std::vector<int64_t> >& shapes,
227      const std::vector<int>& ranks, const std::vector<TF_DataType>& types,
228      TF_Status* status);
229  
230  // Creates Placeholders with specified types in the Graph.
231  //
232  // This is an internal API used to speed up creation of unused placeholders
233  // in while_v2 cond graph and is subject to change/removal.
234  std::vector<TF_Output> TF_CreatePlaceholders(TF_Graph* graph, PyObject* dtypes,
235                                               const char* prefix,
236                                               TF_Status* status);
237  
238  // Set the shape of output. If unknown is true, `num_dims` must be set to
239  // -1 and `dims` is set to nullptr.
240  void TF_GraphSetTensorShape_wrapper(TF_Graph* graph, TF_Output output,
241                                      const std::vector<int64_t>& dims,
242                                      bool unknown_shape, TF_Status* status);
243  
244  // Returns the string representations of the missing unused input mappings.
245  std::vector<string> TF_ImportGraphDefResultsMissingUnusedInputMappings_wrapper(
246      TF_ImportGraphDefResults* results);
247  
248  // If evaluation was possible, returns the numpy ndarray of the evaluated
249  // result. Otherwise returns None.
250  PyObject* TF_TryEvaluateConstant_wrapper(TF_Graph* graph, TF_Output output,
251                                           TF_Status* status);
252  
253  }  // namespace tensorflow
254  
255  #endif  // TENSORFLOW_PYTHON_CLIENT_TF_SESSION_HELPER_H_
256