• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_C_C_API_H_
17 #define TENSORFLOW_C_C_API_H_
18 
19 #include <stddef.h>
20 #include <stdint.h>
21 
22 #include "tensorflow/c/tf_attrtype.h"
23 #include "tensorflow/c/tf_buffer.h"
24 #include "tensorflow/c/tf_datatype.h"
25 #include "tensorflow/c/tf_status.h"
26 #include "tensorflow/c/tf_tensor.h"
27 #include "tensorflow/c/tf_tstring.h"
28 
29 // --------------------------------------------------------------------------
30 // C API for TensorFlow.
31 //
32 // The API leans towards simplicity and uniformity instead of convenience
33 // since most usage will be by language specific wrappers.
34 //
35 // Conventions:
36 // * We use the prefix TF_ for everything in the API.
37 // * Objects are always passed around as pointers to opaque structs
38 //   and these structs are allocated/deallocated via the API.
39 // * TF_Status holds error information.  It is an object type
40 //   and therefore is passed around as a pointer to an opaque
41 //   struct as mentioned above.
42 // * Every call that has a TF_Status* argument clears it on success
43 //   and fills it with error info on failure.
44 // * unsigned char is used for booleans (instead of the 'bool' type).
45 //   In C++ bool is a keyword while in C99 bool is a macro defined
46 //   in stdbool.h. It is possible for the two to be inconsistent.
47 //   For example, neither the C99 nor the C++11 standard force a byte
48 //   size on the bool type, so the macro defined in stdbool.h could
49 //   be inconsistent with the bool keyword in C++. Thus, the use
50 //   of stdbool.h is avoided and unsigned char is used instead.
51 // * size_t is used to represent byte sizes of objects that are
52 //   materialized in the address space of the calling process.
53 // * int is used as an index into arrays.
54 // * Deletion functions are safe to call on nullptr.
55 //
56 // Questions left to address:
57 // * Might at some point need a way for callers to provide their own Env.
58 // * Maybe add TF_TensorShape that encapsulates dimension info.
59 //
60 // Design decisions made:
61 // * Backing store for tensor memory has an associated deallocation
62 //   function.  This deallocation function will point to client code
63 //   for tensors populated by the client.  So the client can do things
64 //   like shadowing a numpy array.
65 // * We do not provide TF_OK since it is not strictly necessary and we
66 //   are not optimizing for convenience.
67 // * We make assumption that one session has one graph.  This should be
68 //   fine since we have the ability to run sub-graphs.
69 // * We could allow NULL for some arguments (e.g., NULL options arg).
70 //   However since convenience is not a primary goal, we don't do this.
71 // * Devices are not in this API.  Instead, they are created/used internally
72 //   and the API just provides high level controls over the number of
73 //   devices of each type.
74 
75 // Macro to control visibility of exported symbols in the shared library (.so,
76 // .dylib, .dll).
77 // This duplicates the TF_EXPORT macro definition in
78 // tensorflow/core/platform/macros.h in order to keep this .h file independent
79 // of any other includes.
80 #ifdef SWIG
81 #define TF_CAPI_EXPORT
82 #else
83 #if defined(_WIN32)
84 #ifdef TF_COMPILE_LIBRARY
85 #define TF_CAPI_EXPORT __declspec(dllexport)
86 #else
87 #define TF_CAPI_EXPORT __declspec(dllimport)
88 #endif  // TF_COMPILE_LIBRARY
89 #else
90 #define TF_CAPI_EXPORT __attribute__((visibility("default")))
91 #endif  // _WIN32
92 #endif  // SWIG
93 
94 #ifdef __cplusplus
95 extern "C" {
96 #endif
97 
98 // --------------------------------------------------------------------------
99 // TF_Version returns a string describing version information of the
100 // TensorFlow library. TensorFlow uses semantic versioning.
101 TF_CAPI_EXPORT extern const char* TF_Version(void);
102 
103 // Parsing a serialized TensorProto into a TF_Tensor.
104 TF_CAPI_EXPORT extern void TF_TensorFromProto(const TF_Buffer* from,
105                                               TF_Tensor* to, TF_Status* status);
106 
107 // Parsing a serialized TensorProto into a TF_Tensor.
108 TF_CAPI_EXPORT extern void TF_TensorFromProto(const TF_Buffer* from,
109                                               TF_Tensor* to, TF_Status* status);
110 
111 // --------------------------------------------------------------------------
112 // Used to return strings across the C API. The caller does not take ownership
113 // of the underlying data pointer and is not responsible for freeing it.
114 typedef struct TF_StringView {
115   const char* data;
116   size_t len;
117 } TF_StringView;
118 
119 // --------------------------------------------------------------------------
120 // TF_SessionOptions holds options that can be passed during session creation.
121 typedef struct TF_SessionOptions TF_SessionOptions;
122 
123 // Return a new options object.
124 TF_CAPI_EXPORT extern TF_SessionOptions* TF_NewSessionOptions(void);
125 
126 // Set the target in TF_SessionOptions.options.
127 // target can be empty, a single entry, or a comma separated list of entries.
128 // Each entry is in one of the following formats :
129 // "local"
130 // ip:port
131 // host:port
132 TF_CAPI_EXPORT extern void TF_SetTarget(TF_SessionOptions* options,
133                                         const char* target);
134 
135 // Set the config in TF_SessionOptions.options.
136 // config should be a serialized tensorflow.ConfigProto proto.
137 // If config was not parsed successfully as a ConfigProto, record the
138 // error information in *status.
139 TF_CAPI_EXPORT extern void TF_SetConfig(TF_SessionOptions* options,
140                                         const void* proto, size_t proto_len,
141                                         TF_Status* status);
142 
143 // Destroy an options object.
144 TF_CAPI_EXPORT extern void TF_DeleteSessionOptions(TF_SessionOptions*);
145 
146 // TODO(jeff,sanjay):
147 // - export functions to set Config fields
148 
149 // --------------------------------------------------------------------------
150 // The new graph construction API, still under development.
151 
152 // Represents a computation graph.  Graphs may be shared between sessions.
153 // Graphs are thread-safe when used as directed below.
154 typedef struct TF_Graph TF_Graph;
155 
156 // Return a new graph object.
157 TF_CAPI_EXPORT extern TF_Graph* TF_NewGraph(void);
158 
159 // Destroy an options object. Graph will be deleted once no more
160 // TFSession's are referencing it.
161 TF_CAPI_EXPORT extern void TF_DeleteGraph(TF_Graph*);
162 
163 // Operation being built. The underlying graph must outlive this.
164 typedef struct TF_OperationDescription TF_OperationDescription;
165 
166 // Operation that has been added to the graph. Valid until the graph is
167 // deleted -- in particular adding a new operation to the graph does not
168 // invalidate old TF_Operation* pointers.
169 typedef struct TF_Operation TF_Operation;
170 
171 // Represents a specific input of an operation.
172 typedef struct TF_Input {
173   TF_Operation* oper;
174   int index;  // The index of the input within oper.
175 } TF_Input;
176 
177 // Represents a specific output of an operation.
178 typedef struct TF_Output {
179   TF_Operation* oper;
180   int index;  // The index of the output within oper.
181 } TF_Output;
182 
183 // TF_Function is a grouping of operations with defined inputs and outputs.
184 // Once created and added to graphs, functions can be invoked by creating an
185 // operation whose operation type matches the function name.
186 typedef struct TF_Function TF_Function;
187 
188 // Function definition options. TODO(iga): Define and implement
189 typedef struct TF_FunctionOptions TF_FunctionOptions;
190 
191 // Sets the shape of the Tensor referenced by `output` in `graph` to
192 // the shape described by `dims` and `num_dims`.
193 //
194 // If the number of dimensions is unknown, `num_dims` must be set to
195 // -1 and `dims` can be null. If a dimension is unknown, the
196 // corresponding entry in the `dims` array must be -1.
197 //
198 // This does not overwrite the existing shape associated with `output`,
199 // but merges the input shape with the existing shape.  For example,
200 // setting a shape of [-1, 2] with an existing shape [2, -1] would set
201 // a final shape of [2, 2] based on shape merging semantics.
202 //
203 // Returns an error into `status` if:
204 //   * `output` is not in `graph`.
205 //   * An invalid shape is being set (e.g., the shape being set
206 //     is incompatible with the existing shape).
207 TF_CAPI_EXPORT extern void TF_GraphSetTensorShape(TF_Graph* graph,
208                                                   TF_Output output,
209                                                   const int64_t* dims,
210                                                   const int num_dims,
211                                                   TF_Status* status);
212 
213 // Returns the number of dimensions of the Tensor referenced by `output`
214 // in `graph`.
215 //
216 // If the number of dimensions in the shape is unknown, returns -1.
217 //
218 // Returns an error into `status` if:
219 //   * `output` is not in `graph`.
220 TF_CAPI_EXPORT extern int TF_GraphGetTensorNumDims(TF_Graph* graph,
221                                                    TF_Output output,
222                                                    TF_Status* status);
223 
224 // Returns the shape of the Tensor referenced by `output` in `graph`
225 // into `dims`. `dims` must be an array large enough to hold `num_dims`
226 // entries (e.g., the return value of TF_GraphGetTensorNumDims).
227 //
228 // If the number of dimensions in the shape is unknown or the shape is
229 // a scalar, `dims` will remain untouched. Otherwise, each element of
230 // `dims` will be set corresponding to the size of the dimension. An
231 // unknown dimension is represented by `-1`.
232 //
233 // Returns an error into `status` if:
234 //   * `output` is not in `graph`.
235 //   * `num_dims` does not match the actual number of dimensions.
236 TF_CAPI_EXPORT extern void TF_GraphGetTensorShape(TF_Graph* graph,
237                                                   TF_Output output,
238                                                   int64_t* dims, int num_dims,
239                                                   TF_Status* status);
240 
241 // Creates a new operation - see `TF_NewOperation` for more details.
242 //
243 // The lock for `graph` must be held when calling this function.
244 //
245 // Unless implementing advanced behavior, like custom gradient functions, you
246 // most likely need to call `TF_NewOperation` instead.
247 TF_CAPI_EXPORT extern TF_OperationDescription* TF_NewOperationLocked(
248     TF_Graph* graph, const char* op_type, const char* oper_name);
249 
250 // Operation will only be added to *graph when TF_FinishOperation() is
251 // called (assuming TF_FinishOperation() does not return an error).
252 // *graph must not be deleted until after TF_FinishOperation() is
253 // called.
254 TF_CAPI_EXPORT extern TF_OperationDescription* TF_NewOperation(
255     TF_Graph* graph, const char* op_type, const char* oper_name);
256 
257 // Specify the device for `desc`.  Defaults to empty, meaning unconstrained.
258 TF_CAPI_EXPORT extern void TF_SetDevice(TF_OperationDescription* desc,
259                                         const char* device);
260 
261 // The calls to TF_AddInput and TF_AddInputList must match (in number,
262 // order, and type) the op declaration.  For example, the "Concat" op
263 // has registration:
264 //   REGISTER_OP("Concat")
265 //       .Input("concat_dim: int32")
266 //       .Input("values: N * T")
267 //       .Output("output: T")
268 //       .Attr("N: int >= 2")
269 //       .Attr("T: type");
270 // that defines two inputs, "concat_dim" and "values" (in that order).
271 // You must use TF_AddInput() for the first input (since it takes a
272 // single tensor), and TF_AddInputList() for the second input (since
273 // it takes a list, even if you were to pass a list with a single
274 // tensor), as in:
275 //   TF_OperationDescription* desc = TF_NewOperation(graph, "Concat", "c");
276 //   TF_Output concat_dim_input = {...};
277 //   TF_AddInput(desc, concat_dim_input);
278 //   TF_Output values_inputs[5] = {{...}, ..., {...}};
279 //   TF_AddInputList(desc, values_inputs, 5);
280 
281 // For inputs that take a single tensor.
282 TF_CAPI_EXPORT extern void TF_AddInput(TF_OperationDescription* desc,
283                                        TF_Output input);
284 
285 // For inputs that take a list of tensors.
286 // inputs must point to TF_Output[num_inputs].
287 TF_CAPI_EXPORT extern void TF_AddInputList(TF_OperationDescription* desc,
288                                            const TF_Output* inputs,
289                                            int num_inputs);
290 
291 // Call once per control input to `desc`.
292 TF_CAPI_EXPORT extern void TF_AddControlInput(TF_OperationDescription* desc,
293                                               TF_Operation* input);
294 
295 // Request that `desc` be co-located on the device where `op`
296 // is placed.
297 //
298 // Use of this is discouraged since the implementation of device placement is
299 // subject to change. Primarily intended for internal libraries
300 TF_CAPI_EXPORT extern void TF_ColocateWith(TF_OperationDescription* desc,
301                                            TF_Operation* op);
302 
303 // Call some TF_SetAttr*() function for every attr that is not
304 // inferred from an input and doesn't have a default value you wish to
305 // keep.
306 
307 // `value` must point to a string of length `length` bytes.
308 TF_CAPI_EXPORT extern void TF_SetAttrString(TF_OperationDescription* desc,
309                                             const char* attr_name,
310                                             const void* value, size_t length);
311 // `values` and `lengths` each must have lengths `num_values`.
312 // `values[i]` must point to a string of length `lengths[i]` bytes.
313 TF_CAPI_EXPORT extern void TF_SetAttrStringList(TF_OperationDescription* desc,
314                                                 const char* attr_name,
315                                                 const void* const* values,
316                                                 const size_t* lengths,
317                                                 int num_values);
318 TF_CAPI_EXPORT extern void TF_SetAttrInt(TF_OperationDescription* desc,
319                                          const char* attr_name, int64_t value);
320 TF_CAPI_EXPORT extern void TF_SetAttrIntList(TF_OperationDescription* desc,
321                                              const char* attr_name,
322                                              const int64_t* values,
323                                              int num_values);
324 TF_CAPI_EXPORT extern void TF_SetAttrFloat(TF_OperationDescription* desc,
325                                            const char* attr_name, float value);
326 TF_CAPI_EXPORT extern void TF_SetAttrFloatList(TF_OperationDescription* desc,
327                                                const char* attr_name,
328                                                const float* values,
329                                                int num_values);
330 TF_CAPI_EXPORT extern void TF_SetAttrBool(TF_OperationDescription* desc,
331                                           const char* attr_name,
332                                           unsigned char value);
333 TF_CAPI_EXPORT extern void TF_SetAttrBoolList(TF_OperationDescription* desc,
334                                               const char* attr_name,
335                                               const unsigned char* values,
336                                               int num_values);
337 TF_CAPI_EXPORT extern void TF_SetAttrType(TF_OperationDescription* desc,
338                                           const char* attr_name,
339                                           TF_DataType value);
340 TF_CAPI_EXPORT extern void TF_SetAttrTypeList(TF_OperationDescription* desc,
341                                               const char* attr_name,
342                                               const TF_DataType* values,
343                                               int num_values);
344 TF_CAPI_EXPORT extern void TF_SetAttrPlaceholder(TF_OperationDescription* desc,
345                                                  const char* attr_name,
346                                                  const char* placeholder);
347 
348 // Set a 'func' attribute to the specified name.
349 // `value` must point to a string of length `length` bytes.
350 TF_CAPI_EXPORT extern void TF_SetAttrFuncName(TF_OperationDescription* desc,
351                                               const char* attr_name,
352                                               const char* value, size_t length);
353 
354 // Set `num_dims` to -1 to represent "unknown rank".  Otherwise,
355 // `dims` points to an array of length `num_dims`.  `dims[i]` must be
356 // >= -1, with -1 meaning "unknown dimension".
357 TF_CAPI_EXPORT extern void TF_SetAttrShape(TF_OperationDescription* desc,
358                                            const char* attr_name,
359                                            const int64_t* dims, int num_dims);
360 // `dims` and `num_dims` must point to arrays of length `num_shapes`.
361 // Set `num_dims[i]` to -1 to represent "unknown rank".  Otherwise,
362 // `dims[i]` points to an array of length `num_dims[i]`.  `dims[i][j]`
363 // must be >= -1, with -1 meaning "unknown dimension".
364 TF_CAPI_EXPORT extern void TF_SetAttrShapeList(TF_OperationDescription* desc,
365                                                const char* attr_name,
366                                                const int64_t* const* dims,
367                                                const int* num_dims,
368                                                int num_shapes);
369 // `proto` must point to an array of `proto_len` bytes representing a
370 // binary-serialized TensorShapeProto.
371 TF_CAPI_EXPORT extern void TF_SetAttrTensorShapeProto(
372     TF_OperationDescription* desc, const char* attr_name, const void* proto,
373     size_t proto_len, TF_Status* status);
374 // `protos` and `proto_lens` must point to arrays of length `num_shapes`.
375 // `protos[i]` must point to an array of `proto_lens[i]` bytes
376 // representing a binary-serialized TensorShapeProto.
377 TF_CAPI_EXPORT extern void TF_SetAttrTensorShapeProtoList(
378     TF_OperationDescription* desc, const char* attr_name,
379     const void* const* protos, const size_t* proto_lens, int num_shapes,
380     TF_Status* status);
381 
382 TF_CAPI_EXPORT extern void TF_SetAttrTensor(TF_OperationDescription* desc,
383                                             const char* attr_name,
384                                             TF_Tensor* value,
385                                             TF_Status* status);
386 TF_CAPI_EXPORT extern void TF_SetAttrTensorList(TF_OperationDescription* desc,
387                                                 const char* attr_name,
388                                                 TF_Tensor* const* values,
389                                                 int num_values,
390                                                 TF_Status* status);
391 
392 // `proto` should point to a sequence of bytes of length `proto_len`
393 // representing a binary serialization of an AttrValue protocol
394 // buffer.
395 TF_CAPI_EXPORT extern void TF_SetAttrValueProto(TF_OperationDescription* desc,
396                                                 const char* attr_name,
397                                                 const void* proto,
398                                                 size_t proto_len,
399                                                 TF_Status* status);
400 
401 // Adds this operation to the graph - see `TF_FinishOperation` for more details.
402 //
403 // The lock for `graph` must be held when calling this function.
404 //
405 // Unless implementing advanced behavior, like custom gradient functions, you
406 // most likely need to call `TF_FinishOperation` instead.
407 TF_CAPI_EXPORT extern TF_Operation* TF_FinishOperationLocked(
408     TF_OperationDescription* desc, TF_Status* status);
409 
410 // If this function succeeds:
411 //   * *status is set to an OK value,
412 //   * a TF_Operation is added to the graph,
413 //   * a non-null value pointing to the added operation is returned --
414 //     this value is valid until the underlying graph is deleted.
415 // Otherwise:
416 //   * *status is set to a non-OK value,
417 //   * the graph is not modified,
418 //   * a null value is returned.
419 // In either case, it deletes `desc`.
420 TF_CAPI_EXPORT extern TF_Operation* TF_FinishOperation(
421     TF_OperationDescription* desc, TF_Status* status);
422 
423 // TF_Operation functions.  Operations are immutable once created, so
424 // these are all query functions.
425 
426 TF_CAPI_EXPORT extern const char* TF_OperationName(TF_Operation* oper);
427 TF_CAPI_EXPORT extern const char* TF_OperationOpType(TF_Operation* oper);
428 TF_CAPI_EXPORT extern const char* TF_OperationDevice(TF_Operation* oper);
429 
430 TF_CAPI_EXPORT extern int TF_OperationNumOutputs(TF_Operation* oper);
431 TF_CAPI_EXPORT extern TF_DataType TF_OperationOutputType(TF_Output oper_out);
432 TF_CAPI_EXPORT extern int TF_OperationOutputListLength(TF_Operation* oper,
433                                                        const char* arg_name,
434                                                        TF_Status* status);
435 
436 TF_CAPI_EXPORT extern int TF_OperationNumInputs(TF_Operation* oper);
437 TF_CAPI_EXPORT extern TF_DataType TF_OperationInputType(TF_Input oper_in);
438 TF_CAPI_EXPORT extern int TF_OperationInputListLength(TF_Operation* oper,
439                                                       const char* arg_name,
440                                                       TF_Status* status);
441 
442 // In this code:
443 //   TF_Output producer = TF_OperationInput(consumer);
444 // There is an edge from producer.oper's output (given by
445 // producer.index) to consumer.oper's input (given by consumer.index).
446 TF_CAPI_EXPORT extern TF_Output TF_OperationInput(TF_Input oper_in);
447 
448 // Get list of all inputs of a specific operation.  `inputs` must point to
449 // an array of length at least `max_inputs` (ideally set to
450 // TF_OperationNumInputs(oper)).  Beware that a concurrent
451 // modification of the graph can increase the number of inputs of
452 // an operation.
453 TF_CAPI_EXPORT extern void TF_OperationAllInputs(TF_Operation* oper,
454                                                  TF_Output* inputs,
455                                                  int max_inputs);
456 
457 // Get the number of current consumers of a specific output of an
458 // operation.  Note that this number can change when new operations
459 // are added to the graph.
460 TF_CAPI_EXPORT extern int TF_OperationOutputNumConsumers(TF_Output oper_out);
461 
462 // Get list of all current consumers of a specific output of an
463 // operation.  `consumers` must point to an array of length at least
464 // `max_consumers` (ideally set to
465 // TF_OperationOutputNumConsumers(oper_out)).  Beware that a concurrent
466 // modification of the graph can increase the number of consumers of
467 // an operation.  Returns the number of output consumers (should match
468 // TF_OperationOutputNumConsumers(oper_out)).
469 TF_CAPI_EXPORT extern int TF_OperationOutputConsumers(TF_Output oper_out,
470                                                       TF_Input* consumers,
471                                                       int max_consumers);
472 
473 // Get the number of control inputs to an operation.
474 TF_CAPI_EXPORT extern int TF_OperationNumControlInputs(TF_Operation* oper);
475 
476 // Get list of all control inputs to an operation.  `control_inputs` must
477 // point to an array of length `max_control_inputs` (ideally set to
478 // TF_OperationNumControlInputs(oper)).  Returns the number of control
479 // inputs (should match TF_OperationNumControlInputs(oper)).
480 TF_CAPI_EXPORT extern int TF_OperationGetControlInputs(
481     TF_Operation* oper, TF_Operation** control_inputs, int max_control_inputs);
482 
483 // Get the number of operations that have `*oper` as a control input.
484 // Note that this number can change when new operations are added to
485 // the graph.
486 TF_CAPI_EXPORT extern int TF_OperationNumControlOutputs(TF_Operation* oper);
487 
488 // Get the list of operations that have `*oper` as a control input.
489 // `control_outputs` must point to an array of length at least
490 // `max_control_outputs` (ideally set to
491 // TF_OperationNumControlOutputs(oper)). Beware that a concurrent
492 // modification of the graph can increase the number of control
493 // outputs.  Returns the number of control outputs (should match
494 // TF_OperationNumControlOutputs(oper)).
495 TF_CAPI_EXPORT extern int TF_OperationGetControlOutputs(
496     TF_Operation* oper, TF_Operation** control_outputs,
497     int max_control_outputs);
498 
499 // TF_AttrMetadata describes the value of an attribute on an operation.
500 typedef struct TF_AttrMetadata {
501   // A boolean: 1 if the attribute value is a list, 0 otherwise.
502   unsigned char is_list;
503 
504   // Length of the list if is_list is true. Undefined otherwise.
505   int64_t list_size;
506 
507   // Type of elements of the list if is_list != 0.
508   // Type of the single value stored in the attribute if is_list == 0.
509   TF_AttrType type;
510 
511   // Total size the attribute value.
512   // The units of total_size depend on is_list and type.
513   // (1) If type == TF_ATTR_STRING and is_list == 0
514   //     then total_size is the byte size of the string
515   //     valued attribute.
516   // (2) If type == TF_ATTR_STRING and is_list == 1
517   //     then total_size is the cumulative byte size
518   //     of all the strings in the list.
519   // (3) If type == TF_ATTR_SHAPE and is_list == 0
520   //     then total_size is the number of dimensions
521   //     of the shape valued attribute, or -1
522   //     if its rank is unknown.
523   // (4) If type == TF_ATTR_SHAPE and is_list == 1
524   //     then total_size is the cumulative number
525   //     of dimensions of all shapes in the list.
526   // (5) Otherwise, total_size is undefined.
527   int64_t total_size;
528 } TF_AttrMetadata;
529 
530 // Returns metadata about the value of the attribute `attr_name` of `oper`.
531 TF_CAPI_EXPORT extern TF_AttrMetadata TF_OperationGetAttrMetadata(
532     TF_Operation* oper, const char* attr_name, TF_Status* status);
533 
534 // Fills in `value` with the value of the attribute `attr_name`.  `value` must
535 // point to an array of length at least `max_length` (ideally set to
536 // TF_AttrMetadata.total_size from TF_OperationGetAttrMetadata(oper,
537 // attr_name)).
538 TF_CAPI_EXPORT extern void TF_OperationGetAttrString(TF_Operation* oper,
539                                                      const char* attr_name,
540                                                      void* value,
541                                                      size_t max_length,
542                                                      TF_Status* status);
543 
544 // Get the list of strings in the value of the attribute `attr_name`.  Fills in
545 // `values` and `lengths`, each of which must point to an array of length at
546 // least `max_values`.
547 //
548 // The elements of values will point to addresses in `storage` which must be at
549 // least `storage_size` bytes in length.  Ideally, max_values would be set to
550 // TF_AttrMetadata.list_size and `storage` would be at least
551 // TF_AttrMetadata.total_size, obtained from TF_OperationGetAttrMetadata(oper,
552 // attr_name).
553 //
554 // Fails if storage_size is too small to hold the requested number of strings.
555 TF_CAPI_EXPORT extern void TF_OperationGetAttrStringList(
556     TF_Operation* oper, const char* attr_name, void** values, size_t* lengths,
557     int max_values, void* storage, size_t storage_size, TF_Status* status);
558 
559 TF_CAPI_EXPORT extern void TF_OperationGetAttrInt(TF_Operation* oper,
560                                                   const char* attr_name,
561                                                   int64_t* value,
562                                                   TF_Status* status);
563 
564 // Fills in `values` with the value of the attribute `attr_name` of `oper`.
565 // `values` must point to an array of length at least `max_values` (ideally set
566 // TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,
567 // attr_name)).
568 TF_CAPI_EXPORT extern void TF_OperationGetAttrIntList(TF_Operation* oper,
569                                                       const char* attr_name,
570                                                       int64_t* values,
571                                                       int max_values,
572                                                       TF_Status* status);
573 
574 TF_CAPI_EXPORT extern void TF_OperationGetAttrFloat(TF_Operation* oper,
575                                                     const char* attr_name,
576                                                     float* value,
577                                                     TF_Status* status);
578 
579 // Fills in `values` with the value of the attribute `attr_name` of `oper`.
580 // `values` must point to an array of length at least `max_values` (ideally set
581 // to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,
582 // attr_name)).
583 TF_CAPI_EXPORT extern void TF_OperationGetAttrFloatList(TF_Operation* oper,
584                                                         const char* attr_name,
585                                                         float* values,
586                                                         int max_values,
587                                                         TF_Status* status);
588 
589 TF_CAPI_EXPORT extern void TF_OperationGetAttrBool(TF_Operation* oper,
590                                                    const char* attr_name,
591                                                    unsigned char* value,
592                                                    TF_Status* status);
593 
594 // Fills in `values` with the value of the attribute `attr_name` of `oper`.
595 // `values` must point to an array of length at least `max_values` (ideally set
596 // to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,
597 // attr_name)).
598 TF_CAPI_EXPORT extern void TF_OperationGetAttrBoolList(TF_Operation* oper,
599                                                        const char* attr_name,
600                                                        unsigned char* values,
601                                                        int max_values,
602                                                        TF_Status* status);
603 
604 TF_CAPI_EXPORT extern void TF_OperationGetAttrType(TF_Operation* oper,
605                                                    const char* attr_name,
606                                                    TF_DataType* value,
607                                                    TF_Status* status);
608 
609 // Fills in `values` with the value of the attribute `attr_name` of `oper`.
610 // `values` must point to an array of length at least `max_values` (ideally set
611 // to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,
612 // attr_name)).
613 TF_CAPI_EXPORT extern void TF_OperationGetAttrTypeList(TF_Operation* oper,
614                                                        const char* attr_name,
615                                                        TF_DataType* values,
616                                                        int max_values,
617                                                        TF_Status* status);
618 
619 // Fills in `value` with the value of the attribute `attr_name` of `oper`.
620 // `values` must point to an array of length at least `num_dims` (ideally set to
621 // TF_Attr_Meta.size from TF_OperationGetAttrMetadata(oper, attr_name)).
622 TF_CAPI_EXPORT extern void TF_OperationGetAttrShape(TF_Operation* oper,
623                                                     const char* attr_name,
624                                                     int64_t* value,
625                                                     int num_dims,
626                                                     TF_Status* status);
627 
628 // Fills in `dims` with the list of shapes in the attribute `attr_name` of
629 // `oper` and `num_dims` with the corresponding number of dimensions. On return,
630 // for every i where `num_dims[i]` > 0, `dims[i]` will be an array of
631 // `num_dims[i]` elements. A value of -1 for `num_dims[i]` indicates that the
632 // i-th shape in the list is unknown.
633 //
634 // The elements of `dims` will point to addresses in `storage` which must be
635 // large enough to hold at least `storage_size` int64_ts.  Ideally, `num_shapes`
636 // would be set to TF_AttrMetadata.list_size and `storage_size` would be set to
637 // TF_AttrMetadata.total_size from TF_OperationGetAttrMetadata(oper,
638 // attr_name).
639 //
640 // Fails if storage_size is insufficient to hold the requested shapes.
641 TF_CAPI_EXPORT extern void TF_OperationGetAttrShapeList(
642     TF_Operation* oper, const char* attr_name, int64_t** dims, int* num_dims,
643     int num_shapes, int64_t* storage, int storage_size, TF_Status* status);
644 
645 // Sets `value` to the binary-serialized TensorShapeProto of the value of
646 // `attr_name` attribute of `oper`.
647 TF_CAPI_EXPORT extern void TF_OperationGetAttrTensorShapeProto(
648     TF_Operation* oper, const char* attr_name, TF_Buffer* value,
649     TF_Status* status);
650 
651 // Fills in `values` with binary-serialized TensorShapeProto values of the
652 // attribute `attr_name` of `oper`. `values` must point to an array of length at
653 // least `num_values` (ideally set to TF_AttrMetadata.list_size from
654 // TF_OperationGetAttrMetadata(oper, attr_name)).
655 TF_CAPI_EXPORT extern void TF_OperationGetAttrTensorShapeProtoList(
656     TF_Operation* oper, const char* attr_name, TF_Buffer** values,
657     int max_values, TF_Status* status);
658 
659 // Gets the TF_Tensor valued attribute of `attr_name` of `oper`.
660 //
661 // Allocates a new TF_Tensor which the caller is expected to take
662 // ownership of (and can deallocate using TF_DeleteTensor).
663 TF_CAPI_EXPORT extern void TF_OperationGetAttrTensor(TF_Operation* oper,
664                                                      const char* attr_name,
665                                                      TF_Tensor** value,
666                                                      TF_Status* status);
667 
668 // Fills in `values` with the TF_Tensor values of the attribute `attr_name` of
669 // `oper`. `values` must point to an array of TF_Tensor* of length at least
670 // `max_values` (ideally set to TF_AttrMetadata.list_size from
671 // TF_OperationGetAttrMetadata(oper, attr_name)).
672 //
673 // The caller takes ownership of all the non-null TF_Tensor* entries in `values`
674 // (which can be deleted using TF_DeleteTensor(values[i])).
675 TF_CAPI_EXPORT extern void TF_OperationGetAttrTensorList(TF_Operation* oper,
676                                                          const char* attr_name,
677                                                          TF_Tensor** values,
678                                                          int max_values,
679                                                          TF_Status* status);
680 
681 // Sets `output_attr_value` to the binary-serialized AttrValue proto
682 // representation of the value of the `attr_name` attr of `oper`.
683 TF_CAPI_EXPORT extern void TF_OperationGetAttrValueProto(
684     TF_Operation* oper, const char* attr_name, TF_Buffer* output_attr_value,
685     TF_Status* status);
686 
687 // Get the number of attributes the operation has.
688 TF_CAPI_EXPORT extern int TF_OperationGetNumAttrs(TF_Operation* oper);
689 
690 // Get the length of the name of the ith attribute, or -1 if there is not an
691 // ith attribute.
692 TF_CAPI_EXPORT extern int TF_OperationGetAttrNameLength(TF_Operation* oper,
693                                                         int i);
694 
695 // Get the name of the ith attribute.  output should have the size of
696 // TF_OperationGetAttrNameLength(oper, i).
697 TF_CAPI_EXPORT extern void TF_OperationGetAttrName(TF_Operation* oper, int i,
698                                                    char* output,
699                                                    TF_Status* status);
700 
701 // Returns the operation in the graph with `oper_name`. Returns nullptr if
702 // no operation found.
703 TF_CAPI_EXPORT extern TF_Operation* TF_GraphOperationByName(
704     TF_Graph* graph, const char* oper_name);
705 
706 // Iterate through the operations of a graph.  To use:
707 // size_t pos = 0;
708 // TF_Operation* oper;
709 // while ((oper = TF_GraphNextOperation(graph, &pos)) != nullptr) {
710 //   DoSomethingWithOperation(oper);
711 // }
712 TF_CAPI_EXPORT extern TF_Operation* TF_GraphNextOperation(TF_Graph* graph,
713                                                           size_t* pos);
714 
715 // Write out a serialized representation of `graph` (as a GraphDef protocol
716 // message) to `output_graph_def` (allocated by TF_NewBuffer()).
717 // `output_graph_def`'s underlying buffer will be freed when TF_DeleteBuffer()
718 // is called.
719 //
720 // May fail on very large graphs in the future.
721 TF_CAPI_EXPORT extern void TF_GraphToGraphDef(TF_Graph* graph,
722                                               TF_Buffer* output_graph_def,
723                                               TF_Status* status);
724 
725 // Returns the serialized OpDef proto with name `op_name`, or a bad status if no
726 // such op exists. This can return OpDefs of functions copied into the graph.
727 TF_CAPI_EXPORT extern void TF_GraphGetOpDef(TF_Graph* graph,
728                                             const char* op_name,
729                                             TF_Buffer* output_op_def,
730                                             TF_Status* status);
731 
732 // Returns the serialized VersionDef proto for this graph.
733 TF_CAPI_EXPORT extern void TF_GraphVersions(TF_Graph* graph,
734                                             TF_Buffer* output_version_def,
735                                             TF_Status* status);
736 
737 // TF_ImportGraphDefOptions holds options that can be passed to
738 // TF_GraphImportGraphDef.
739 typedef struct TF_ImportGraphDefOptions TF_ImportGraphDefOptions;
740 
741 TF_CAPI_EXPORT extern TF_ImportGraphDefOptions* TF_NewImportGraphDefOptions(
742     void);
743 TF_CAPI_EXPORT extern void TF_DeleteImportGraphDefOptions(
744     TF_ImportGraphDefOptions* opts);
745 
746 // Set the prefix to be prepended to the names of nodes in `graph_def` that will
747 // be imported into `graph`. `prefix` is copied and has no lifetime
748 // requirements.
749 TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsSetPrefix(
750     TF_ImportGraphDefOptions* opts, const char* prefix);
751 
752 // Set the execution device for nodes in `graph_def`.
753 // Only applies to nodes where a device was not already explicitly specified.
754 // `device` is copied and has no lifetime requirements.
755 TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsSetDefaultDevice(
756     TF_ImportGraphDefOptions* opts, const char* device);
757 
758 // Set whether to uniquify imported operation names. If true, imported operation
759 // names will be modified if their name already exists in the graph. If false,
760 // conflicting names will be treated as an error. Note that this option has no
761 // effect if a prefix is set, since the prefix will guarantee all names are
762 // unique. Defaults to false.
763 TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsSetUniquifyNames(
764     TF_ImportGraphDefOptions* opts, unsigned char uniquify_names);
765 
766 // If true, the specified prefix will be modified if it already exists as an
767 // operation name or prefix in the graph. If false, a conflicting prefix will be
768 // treated as an error. This option has no effect if no prefix is specified.
769 TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsSetUniquifyPrefix(
770     TF_ImportGraphDefOptions* opts, unsigned char uniquify_prefix);
771 
772 // Set any imported nodes with input `src_name:src_index` to have that input
773 // replaced with `dst`. `src_name` refers to a node in the graph to be imported,
774 // `dst` references a node already existing in the graph being imported into.
775 // `src_name` is copied and has no lifetime requirements.
776 TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsAddInputMapping(
777     TF_ImportGraphDefOptions* opts, const char* src_name, int src_index,
778     TF_Output dst);
779 
780 // Set any imported nodes with control input `src_name` to have that input
781 // replaced with `dst`. `src_name` refers to a node in the graph to be imported,
782 // `dst` references an operation already existing in the graph being imported
783 // into. `src_name` is copied and has no lifetime requirements.
784 TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsRemapControlDependency(
785     TF_ImportGraphDefOptions* opts, const char* src_name, TF_Operation* dst);
786 
787 // Cause the imported graph to have a control dependency on `oper`. `oper`
788 // should exist in the graph being imported into.
789 TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsAddControlDependency(
790     TF_ImportGraphDefOptions* opts, TF_Operation* oper);
791 
792 // Add an output in `graph_def` to be returned via the `return_outputs` output
793 // parameter of TF_GraphImportGraphDef(). If the output is remapped via an input
794 // mapping, the corresponding existing tensor in `graph` will be returned.
795 // `oper_name` is copied and has no lifetime requirements.
796 TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsAddReturnOutput(
797     TF_ImportGraphDefOptions* opts, const char* oper_name, int index);
798 
799 // Returns the number of return outputs added via
800 // TF_ImportGraphDefOptionsAddReturnOutput().
801 TF_CAPI_EXPORT extern int TF_ImportGraphDefOptionsNumReturnOutputs(
802     const TF_ImportGraphDefOptions* opts);
803 
804 // Add an operation in `graph_def` to be returned via the `return_opers` output
805 // parameter of TF_GraphImportGraphDef(). `oper_name` is copied and has no
806 // lifetime requirements.
807 TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsAddReturnOperation(
808     TF_ImportGraphDefOptions* opts, const char* oper_name);
809 
810 // Returns the number of return operations added via
811 // TF_ImportGraphDefOptionsAddReturnOperation().
812 TF_CAPI_EXPORT extern int TF_ImportGraphDefOptionsNumReturnOperations(
813     const TF_ImportGraphDefOptions* opts);
814 
815 // TF_ImportGraphDefResults holds results that are generated by
816 // TF_GraphImportGraphDefWithResults().
817 typedef struct TF_ImportGraphDefResults TF_ImportGraphDefResults;
818 
819 // Fetches the return outputs requested via
820 // TF_ImportGraphDefOptionsAddReturnOutput(). The number of fetched outputs is
821 // returned in `num_outputs`. The array of return outputs is returned in
822 // `outputs`. `*outputs` is owned by and has the lifetime of `results`.
823 TF_CAPI_EXPORT extern void TF_ImportGraphDefResultsReturnOutputs(
824     TF_ImportGraphDefResults* results, int* num_outputs, TF_Output** outputs);
825 
826 // Fetches the return operations requested via
827 // TF_ImportGraphDefOptionsAddReturnOperation(). The number of fetched
828 // operations is returned in `num_opers`. The array of return operations is
829 // returned in `opers`. `*opers` is owned by and has the lifetime of `results`.
830 TF_CAPI_EXPORT extern void TF_ImportGraphDefResultsReturnOperations(
831     TF_ImportGraphDefResults* results, int* num_opers, TF_Operation*** opers);
832 
833 // Fetches any input mappings requested via
834 // TF_ImportGraphDefOptionsAddInputMapping() that didn't appear in the GraphDef
835 // and weren't used as input to any node in the imported graph def. The number
836 // of fetched mappings is returned in `num_missing_unused_input_mappings`. The
837 // array of each mapping's source node name is returned in `src_names`, and the
838 // array of each mapping's source index is returned in `src_indexes`.
839 //
840 // `*src_names`, `*src_indexes`, and the memory backing each string in
841 // `src_names` are owned by and have the lifetime of `results`.
842 TF_CAPI_EXPORT extern void TF_ImportGraphDefResultsMissingUnusedInputMappings(
843     TF_ImportGraphDefResults* results, int* num_missing_unused_input_mappings,
844     const char*** src_names, int** src_indexes);
845 
846 // Deletes a results object returned by TF_GraphImportGraphDefWithResults().
847 TF_CAPI_EXPORT extern void TF_DeleteImportGraphDefResults(
848     TF_ImportGraphDefResults* results);
849 
850 // Import the graph serialized in `graph_def` into `graph`.  Returns nullptr and
851 // a bad status on error. Otherwise, returns a populated
852 // TF_ImportGraphDefResults instance. The returned instance must be deleted via
853 // TF_DeleteImportGraphDefResults().
854 TF_CAPI_EXPORT extern TF_ImportGraphDefResults*
855 TF_GraphImportGraphDefWithResults(TF_Graph* graph, const TF_Buffer* graph_def,
856                                   const TF_ImportGraphDefOptions* options,
857                                   TF_Status* status);
858 
859 // Import the graph serialized in `graph_def` into `graph`.
860 // Convenience function for when only return outputs are needed.
861 //
862 // `num_return_outputs` must be the number of return outputs added (i.e. the
863 // result of TF_ImportGraphDefOptionsNumReturnOutputs()).  If
864 // `num_return_outputs` is non-zero, `return_outputs` must be of length
865 // `num_return_outputs`. Otherwise it can be null.
866 TF_CAPI_EXPORT extern void TF_GraphImportGraphDefWithReturnOutputs(
867     TF_Graph* graph, const TF_Buffer* graph_def,
868     const TF_ImportGraphDefOptions* options, TF_Output* return_outputs,
869     int num_return_outputs, TF_Status* status);
870 
871 // Import the graph serialized in `graph_def` into `graph`.
872 // Convenience function for when no results are needed.
873 TF_CAPI_EXPORT extern void TF_GraphImportGraphDef(
874     TF_Graph* graph, const TF_Buffer* graph_def,
875     const TF_ImportGraphDefOptions* options, TF_Status* status);
876 
877 // Adds a copy of function `func` and optionally its gradient function `grad`
878 // to `g`. Once `func`/`grad` is added to `g`, it can be called by creating
879 // an operation using the function's name.
880 // Any changes to `func`/`grad` (including deleting it) done after this method
881 // returns, won't affect the copy of `func`/`grad` in `g`.
882 // If `func` or `grad` are already in `g`, TF_GraphCopyFunction has no
883 // effect on them, but can establish the function->gradient relationship
884 // between them if `func` does not already have a gradient. If `func` already
885 // has a gradient different from `grad`, an error is returned.
886 //
887 // `func` must not be null.
888 // If `grad` is null and `func` is not in `g`, `func` is added without a
889 // gradient.
890 // If `grad` is null and `func` is in `g`, TF_GraphCopyFunction is a noop.
891 // `grad` must have appropriate signature as described in the doc of
892 // GradientDef in tensorflow/core/framework/function.proto.
893 //
894 // If successful, status is set to OK and `func` and `grad` are added to `g`.
895 // Otherwise, status is set to the encountered error and `g` is unmodified.
896 TF_CAPI_EXPORT extern void TF_GraphCopyFunction(TF_Graph* g,
897                                                 const TF_Function* func,
898                                                 const TF_Function* grad,
899                                                 TF_Status* status);
900 
901 // Returns the number of TF_Functions registered in `g`.
902 TF_CAPI_EXPORT extern int TF_GraphNumFunctions(TF_Graph* g);
903 
904 // Fills in `funcs` with the TF_Function* registered in `g`.
905 // `funcs` must point to an array of TF_Function* of length at least
906 // `max_func`. In usual usage, max_func should be set to the result of
907 // TF_GraphNumFunctions(g). In this case, all the functions registered in
908 // `g` will be returned. Else, an unspecified subset.
909 //
910 // If successful, returns the number of TF_Function* successfully set in
911 // `funcs` and sets status to OK. The caller takes ownership of
912 // all the returned TF_Functions. They must be deleted with TF_DeleteFunction.
913 // On error, returns 0, sets status to the encountered error, and the contents
914 // of funcs will be undefined.
915 TF_CAPI_EXPORT extern int TF_GraphGetFunctions(TF_Graph* g, TF_Function** funcs,
916                                                int max_func, TF_Status* status);
917 
918 // Note: The following function may fail on very large protos in the future.
919 
920 TF_CAPI_EXPORT extern void TF_OperationToNodeDef(TF_Operation* oper,
921                                                  TF_Buffer* output_node_def,
922                                                  TF_Status* status);
923 
924 typedef struct TF_WhileParams {
925   // The number of inputs to the while loop, i.e. the number of loop variables.
926   // This is the size of cond_inputs, body_inputs, and body_outputs.
927   const int ninputs;
928 
929   // The while condition graph. The inputs are the current values of the loop
930   // variables. The output should be a scalar boolean.
931   TF_Graph* const cond_graph;
932   const TF_Output* const cond_inputs;
933   TF_Output cond_output;
934 
935   // The loop body graph. The inputs are the current values of the loop
936   // variables. The outputs are the updated values of the loop variables.
937   TF_Graph* const body_graph;
938   const TF_Output* const body_inputs;
939   TF_Output* const body_outputs;
940 
941   // Unique null-terminated name for this while loop. This is used as a prefix
942   // for created operations.
943   const char* name;
944 } TF_WhileParams;
945 
946 // Creates a TF_WhileParams for creating a while loop in `g`. `inputs` are
947 // outputs that already exist in `g` used as initial values for the loop
948 // variables.
949 //
950 // The returned TF_WhileParams will have all fields initialized except
951 // `cond_output`, `body_outputs`, and `name`. The `body_outputs` buffer will be
952 // allocated to size `ninputs`. The caller should build `cond_graph` and
953 // `body_graph` starting from the inputs, and store the final outputs in
954 // `cond_output` and `body_outputs`.
955 //
956 // If `status` is OK, the caller must call either TF_FinishWhile or
957 // TF_AbortWhile on the returned TF_WhileParams. If `status` isn't OK, the
958 // returned TF_WhileParams is not valid, and the caller should not call
959 // TF_FinishWhile() or TF_AbortWhile().
960 //
961 // Missing functionality (TODO):
962 // - Gradients
963 // - Reference-type inputs
964 // - Directly referencing external tensors from the cond/body graphs (this is
965 //   possible in the Python API)
966 TF_CAPI_EXPORT extern TF_WhileParams TF_NewWhile(TF_Graph* g, TF_Output* inputs,
967                                                  int ninputs,
968                                                  TF_Status* status);
969 
970 // Builds the while loop specified by `params` and returns the output tensors of
971 // the while loop in `outputs`. `outputs` should be allocated to size
972 // `params.ninputs`.
973 //
974 // `params` is no longer valid once this returns.
975 //
976 // Either this or TF_AbortWhile() must be called after a successful
977 // TF_NewWhile() call.
978 TF_CAPI_EXPORT extern void TF_FinishWhile(const TF_WhileParams* params,
979                                           TF_Status* status,
980                                           TF_Output* outputs);
981 
982 // Frees `params`s resources without building a while loop. `params` is no
983 // longer valid after this returns. Either this or TF_FinishWhile() must be
984 // called after a successful TF_NewWhile() call.
985 TF_CAPI_EXPORT extern void TF_AbortWhile(const TF_WhileParams* params);
986 
987 // Adds operations to compute the partial derivatives of sum of `y`s w.r.t `x`s,
988 // i.e., d(y_1 + y_2 + ...)/dx_1, d(y_1 + y_2 + ...)/dx_2...
989 //
990 // `dx` are used as initial gradients (which represent the symbolic partial
991 // derivatives of some loss function `L` w.r.t. `y`).
992 // `dx` must be nullptr or have size `ny`.
993 // If `dx` is nullptr, the implementation will use dx of `OnesLike` for all
994 // shapes in `y`.
995 // The partial derivatives are returned in `dy`. `dy` should be allocated to
996 // size `nx`.
997 //
998 // Gradient nodes are automatically named under the "gradients/" prefix. To
999 // guarantee name uniqueness, subsequent calls to the same graph will
1000 // append an incremental tag to the prefix: "gradients_1/", "gradients_2/", ...
1001 // See TF_AddGradientsWithPrefix, which provides a means to specify a custom
1002 // name prefix for operations added to a graph to compute the gradients.
1003 //
1004 // WARNING: This function does not yet support all the gradients that python
1005 // supports. See
1006 // https://www.tensorflow.org/code/tensorflow/cc/gradients/README.md
1007 // for instructions on how to add C++ more gradients.
1008 TF_CAPI_EXPORT void TF_AddGradients(TF_Graph* g, TF_Output* y, int ny,
1009                                     TF_Output* x, int nx, TF_Output* dx,
1010                                     TF_Status* status, TF_Output* dy);
1011 
1012 // Adds operations to compute the partial derivatives of sum of `y`s w.r.t `x`s,
1013 // i.e., d(y_1 + y_2 + ...)/dx_1, d(y_1 + y_2 + ...)/dx_2...
1014 // This is a variant of TF_AddGradients that allows to caller to pass a custom
1015 // name prefix to the operations added to a graph to compute the gradients.
1016 //
1017 // `dx` are used as initial gradients (which represent the symbolic partial
1018 // derivatives of some loss function `L` w.r.t. `y`).
1019 // `dx` must be nullptr or have size `ny`.
1020 // If `dx` is nullptr, the implementation will use dx of `OnesLike` for all
1021 // shapes in `y`.
1022 // The partial derivatives are returned in `dy`. `dy` should be allocated to
1023 // size `nx`.
1024 // `prefix` names the scope into which all gradients operations are being added.
1025 // `prefix` must be unique within the provided graph otherwise this operation
1026 // will fail. If `prefix` is nullptr, the default prefixing behaviour takes
1027 // place, see TF_AddGradients for more details.
1028 //
1029 // WARNING: This function does not yet support all the gradients that python
1030 // supports. See
1031 // https://www.tensorflow.org/code/tensorflow/cc/gradients/README.md
1032 // for instructions on how to add C++ more gradients.
1033 TF_CAPI_EXPORT void TF_AddGradientsWithPrefix(TF_Graph* g, const char* prefix,
1034                                               TF_Output* y, int ny,
1035                                               TF_Output* x, int nx,
1036                                               TF_Output* dx, TF_Status* status,
1037                                               TF_Output* dy);
1038 
1039 // Create a TF_Function from a TF_Graph
1040 //
1041 // Params:
1042 //  fn_body - the graph whose operations (or subset of whose operations) will be
1043 //            converted to TF_Function.
1044 //  fn_name - the name of the new TF_Function. Should match the operation
1045 //            name (OpDef.name) regexp [A-Z][A-Za-z0-9_.\\-/]*.
1046 //            If `append_hash_to_fn_name` is false, `fn_name` must be distinct
1047 //            from other function and operation names (at least those
1048 //            registered in graphs where this function will be used).
1049 //  append_hash_to_fn_name - Must be 0 or 1. If set to 1, the actual name
1050 //                           of the function will be `fn_name` appended with
1051 //                           '_<hash_of_this_function's_definition>'.
1052 //                           If set to 0, the function's name will be `fn_name`.
1053 //  num_opers - `num_opers` contains the number of elements in the `opers` array
1054 //              or a special value of -1 meaning that no array is given.
1055 //              The distinction between an empty array of operations and no
1056 //              array of operations is necessary to distinguish the case of
1057 //              creating a function with no body (e.g. identity or permutation)
1058 //              and the case of creating a function whose body contains all
1059 //              the nodes in the graph (except for the automatic skipping, see
1060 //              below).
1061 //  opers - Array of operations to become the body of the function or null.
1062 //          - If no array is given (`num_opers` = -1), all the
1063 //          operations in `fn_body` will become part of the function
1064 //          except operations referenced in `inputs`. These operations
1065 //          must have a single output (these operations are typically
1066 //          placeholders created for the sole purpose of representing
1067 //          an input. We can relax this constraint if there are
1068 //          compelling use cases).
1069 //          - If an array is given (`num_opers` >= 0), all operations
1070 //          in it will become part of the function. In particular, no
1071 //          automatic skipping of dummy input operations is performed.
1072 //  ninputs - number of elements in `inputs` array
1073 //  inputs - array of TF_Outputs that specify the inputs to the function.
1074 //           If `ninputs` is zero (the function takes no inputs), `inputs`
1075 //           can be null. The names used for function inputs are normalized
1076 //           names of the operations (usually placeholders) pointed to by
1077 //           `inputs`. These operation names should start with a letter.
1078 //           Normalization will convert all letters to lowercase and
1079 //           non-alphanumeric characters to '_' to make resulting names match
1080 //           the "[a-z][a-z0-9_]*" pattern for operation argument names.
1081 //           `inputs` cannot contain the same tensor twice.
1082 //  noutputs - number of elements in `outputs` array
1083 //  outputs - array of TF_Outputs that specify the outputs of the function.
1084 //            If `noutputs` is zero (the function returns no outputs), `outputs`
1085 //            can be null. `outputs` can contain the same tensor more than once.
1086 //  output_names - The names of the function's outputs. `output_names` array
1087 //                 must either have the same length as `outputs`
1088 //                 (i.e. `noutputs`) or be null. In the former case,
1089 //                 the names should match the regular expression for ArgDef
1090 //                 names - "[a-z][a-z0-9_]*". In the latter case,
1091 //                 names for outputs will be generated automatically.
1092 //  opts - various options for the function, e.g. XLA's inlining control.
1093 //  description - optional human-readable description of this function.
1094 //  status - Set to OK on success and an appropriate error on failure.
1095 //
1096 // Note that when the same TF_Output is listed as both an input and an output,
1097 // the corresponding function's output will equal to this input,
1098 // instead of the original node's output.
1099 //
1100 // Callers must also satisfy the following constraints:
1101 // - `inputs` cannot refer to TF_Outputs within a control flow context. For
1102 //   example, one cannot use the output of "switch" node as input.
1103 // - `inputs` and `outputs` cannot have reference types. Reference types are
1104 //   not exposed through C API and are being replaced with Resources. We support
1105 //   reference types inside function's body to support legacy code. Do not
1106 //   use them in new code.
1107 // - Every node in the function's body must have all of its inputs (including
1108 //   control inputs). In other words, for every node in the body, each input
1109 //   must be either listed in `inputs` or must come from another node in
1110 //   the body. In particular, it is an error to have a control edge going from
1111 //   a node outside of the body into a node in the body. This applies to control
1112 //   edges going from nodes referenced in `inputs` to nodes in the body when
1113 //   the former nodes are not in the body (automatically skipped or not
1114 //   included in explicitly specified body).
1115 //
1116 // Returns:
1117 //  On success, a newly created TF_Function instance. It must be deleted by
1118 //  calling TF_DeleteFunction.
1119 //
1120 //  On failure, null.
1121 TF_CAPI_EXPORT extern TF_Function* TF_GraphToFunction(
1122     const TF_Graph* fn_body, const char* fn_name,
1123     unsigned char append_hash_to_fn_name, int num_opers,
1124     const TF_Operation* const* opers, int ninputs, const TF_Output* inputs,
1125     int noutputs, const TF_Output* outputs, const char* const* output_names,
1126     const TF_FunctionOptions* opts, const char* description, TF_Status* status);
1127 
1128 // Similar to TF_GraphToFunction but allows specifying control outputs of the
1129 // function.
1130 //
1131 //  The arguments of TF_GraphToFunction have the same meaning, but the new
1132 //  arguments are as follows:
1133 //
1134 //    ncontrol_outputs: Number of control outputs of the function.
1135 //    control_outputs: vector of TF_Operation objects to be marked as control
1136 //      outputs of the function. Operations marked as control outputs are
1137 //      guaranteed to execute.
1138 //    control_output_names: Optional. If not nullptr, vector of strings, one
1139 //      per control output, with their names to be added to the function's
1140 //      OpDef.
1141 TF_CAPI_EXPORT extern TF_Function* TF_GraphToFunctionWithControlOutputs(
1142     const TF_Graph* fn_body, const char* fn_name,
1143     unsigned char append_hash_to_fn_name, int num_opers,
1144     const TF_Operation* const* opers, int ninputs, const TF_Output* inputs,
1145     int noutputs, const TF_Output* outputs, const char* const* output_names,
1146     int ncontrol_outputs, const TF_Operation* const* control_outputs,
1147     const char* const* control_output_names, const TF_FunctionOptions* opts,
1148     const char* description, TF_Status* status);
1149 
1150 // Returns the name of the graph function.
1151 // The return value points to memory that is only usable until the next
1152 // mutation to *func.
1153 TF_CAPI_EXPORT extern const char* TF_FunctionName(TF_Function* func);
1154 
1155 // Write out a serialized representation of `func` (as a FunctionDef protocol
1156 // message) to `output_func_def` (allocated by TF_NewBuffer()).
1157 // `output_func_def`'s underlying buffer will be freed when TF_DeleteBuffer()
1158 // is called.
1159 //
1160 // May fail on very large graphs in the future.
1161 TF_CAPI_EXPORT extern void TF_FunctionToFunctionDef(TF_Function* func,
1162                                                     TF_Buffer* output_func_def,
1163                                                     TF_Status* status);
1164 
1165 // Construct and return the function whose FunctionDef representation is
1166 // serialized in `proto`. `proto_len` must equal the number of bytes
1167 // pointed to by `proto`.
1168 // Returns:
1169 //  On success, a newly created TF_Function instance. It must be deleted by
1170 //  calling TF_DeleteFunction.
1171 //
1172 //  On failure, null.
1173 TF_CAPI_EXPORT extern TF_Function* TF_FunctionImportFunctionDef(
1174     const void* proto, size_t proto_len, TF_Status* status);
1175 
1176 // Sets function attribute named `attr_name` to value stored in `proto`.
1177 // If this attribute is already set to another value, it is overridden.
1178 // `proto` should point to a sequence of bytes of length `proto_len`
1179 // representing a binary serialization of an AttrValue protocol
1180 // buffer.
1181 TF_CAPI_EXPORT extern void TF_FunctionSetAttrValueProto(TF_Function* func,
1182                                                         const char* attr_name,
1183                                                         const void* proto,
1184                                                         size_t proto_len,
1185                                                         TF_Status* status);
1186 
1187 // Sets `output_attr_value` to the binary-serialized AttrValue proto
1188 // representation of the value of the `attr_name` attr of `func`.
1189 // If `attr_name` attribute is not present, status is set to an error.
1190 TF_CAPI_EXPORT extern void TF_FunctionGetAttrValueProto(
1191     TF_Function* func, const char* attr_name, TF_Buffer* output_attr_value,
1192     TF_Status* status);
1193 
1194 // Frees the memory used by the `func` struct.
1195 // TF_DeleteFunction is a noop if `func` is null.
1196 // Deleting a function does not remove it from any graphs it was copied to.
1197 TF_CAPI_EXPORT extern void TF_DeleteFunction(TF_Function* func);
1198 
1199 // Attempts to evaluate `output`. This will only be possible if `output` doesn't
1200 // depend on any graph inputs (this function is safe to call if this isn't the
1201 // case though).
1202 //
1203 // If the evaluation is successful, this function returns true and `output`s
1204 // value is returned in `result`. Otherwise returns false. An error status is
1205 // returned if something is wrong with the graph or input. Note that this may
1206 // return false even if no error status is set.
1207 TF_CAPI_EXPORT extern unsigned char TF_TryEvaluateConstant(TF_Graph* graph,
1208                                                            TF_Output output,
1209                                                            TF_Tensor** result,
1210                                                            TF_Status* status);
1211 
1212 // TODO(josh11b): Register OpDef, available to all operations added
1213 // to this graph.
1214 
1215 // --------------------------------------------------------------------------
1216 // API for driving Graph execution.
1217 
1218 typedef struct TF_Session TF_Session;
1219 
1220 // Return a new execution session with the associated graph, or NULL on
1221 // error. Does not take ownership of any input parameters.
1222 //
1223 // *`graph` must be a valid graph (not deleted or nullptr). `graph` will be
1224 // kept alive for the lifetime of the returned TF_Session. New nodes can still
1225 // be added to `graph` after this call.
1226 TF_CAPI_EXPORT extern TF_Session* TF_NewSession(TF_Graph* graph,
1227                                                 const TF_SessionOptions* opts,
1228                                                 TF_Status* status);
1229 
1230 // This function creates a new TF_Session (which is created on success) using
1231 // `session_options`, and then initializes state (restoring tensors and other
1232 // assets) using `run_options`.
1233 //
1234 // Any NULL and non-NULL value combinations for (`run_options, `meta_graph_def`)
1235 // are valid.
1236 //
1237 // - `export_dir` must be set to the path of the exported SavedModel.
1238 // - `tags` must include the set of tags used to identify one MetaGraphDef in
1239 //    the SavedModel.
1240 // - `graph` must be a graph newly allocated with TF_NewGraph().
1241 //
1242 // If successful, populates `graph` with the contents of the Graph and
1243 // `meta_graph_def` with the MetaGraphDef of the loaded model.
1244 TF_CAPI_EXPORT extern TF_Session* TF_LoadSessionFromSavedModel(
1245     const TF_SessionOptions* session_options, const TF_Buffer* run_options,
1246     const char* export_dir, const char* const* tags, int tags_len,
1247     TF_Graph* graph, TF_Buffer* meta_graph_def, TF_Status* status);
1248 
1249 // Close a session.
1250 //
1251 // Contacts any other processes associated with the session, if applicable.
1252 // May not be called after TF_DeleteSession().
1253 TF_CAPI_EXPORT extern void TF_CloseSession(TF_Session*, TF_Status* status);
1254 
1255 // Destroy a session object.
1256 //
1257 // Even if error information is recorded in *status, this call discards all
1258 // local resources associated with the session.  The session may not be used
1259 // during or after this call (and the session drops its reference to the
1260 // corresponding graph).
1261 TF_CAPI_EXPORT extern void TF_DeleteSession(TF_Session*, TF_Status* status);
1262 
1263 // Run the graph associated with the session starting with the supplied inputs
1264 // (inputs[0,ninputs-1] with corresponding values in input_values[0,ninputs-1]).
1265 //
1266 // Any NULL and non-NULL value combinations for (`run_options`,
1267 // `run_metadata`) are valid.
1268 //
1269 //    - `run_options` may be NULL, in which case it will be ignored; or
1270 //      non-NULL, in which case it must point to a `TF_Buffer` containing the
1271 //      serialized representation of a `RunOptions` protocol buffer.
1272 //    - `run_metadata` may be NULL, in which case it will be ignored; or
1273 //      non-NULL, in which case it must point to an empty, freshly allocated
1274 //      `TF_Buffer` that may be updated to contain the serialized representation
1275 //      of a `RunMetadata` protocol buffer.
1276 //
1277 // The caller retains ownership of `input_values` (which can be deleted using
1278 // TF_DeleteTensor). The caller also retains ownership of `run_options` and/or
1279 // `run_metadata` (when not NULL) and should manually call TF_DeleteBuffer on
1280 // them.
1281 //
1282 // On success, the tensors corresponding to outputs[0,noutputs-1] are placed in
1283 // output_values[]. Ownership of the elements of output_values[] is transferred
1284 // to the caller, which must eventually call TF_DeleteTensor on them.
1285 //
1286 // On failure, output_values[] contains NULLs.
1287 TF_CAPI_EXPORT extern void TF_SessionRun(
1288     TF_Session* session,
1289     // RunOptions
1290     const TF_Buffer* run_options,
1291     // Input tensors
1292     const TF_Output* inputs, TF_Tensor* const* input_values, int ninputs,
1293     // Output tensors
1294     const TF_Output* outputs, TF_Tensor** output_values, int noutputs,
1295     // Target operations
1296     const TF_Operation* const* target_opers, int ntargets,
1297     // RunMetadata
1298     TF_Buffer* run_metadata,
1299     // Output status
1300     TF_Status*);
1301 
1302 // Set up the graph with the intended feeds (inputs) and fetches (outputs) for a
1303 // sequence of partial run calls.
1304 //
1305 // On success, returns a handle that is used for subsequent PRun calls. The
1306 // handle should be deleted with TF_DeletePRunHandle when it is no longer
1307 // needed.
1308 //
1309 // On failure, out_status contains a tensorflow::Status with an error
1310 // message. *handle is set to nullptr.
1311 TF_CAPI_EXPORT extern void TF_SessionPRunSetup(
1312     TF_Session*,
1313     // Input names
1314     const TF_Output* inputs, int ninputs,
1315     // Output names
1316     const TF_Output* outputs, int noutputs,
1317     // Target operations
1318     const TF_Operation* const* target_opers, int ntargets,
1319     // Output handle
1320     const char** handle,
1321     // Output status
1322     TF_Status*);
1323 
1324 // Continue to run the graph with additional feeds and fetches. The
1325 // execution state is uniquely identified by the handle.
1326 TF_CAPI_EXPORT extern void TF_SessionPRun(
1327     TF_Session*, const char* handle,
1328     // Input tensors
1329     const TF_Output* inputs, TF_Tensor* const* input_values, int ninputs,
1330     // Output tensors
1331     const TF_Output* outputs, TF_Tensor** output_values, int noutputs,
1332     // Target operations
1333     const TF_Operation* const* target_opers, int ntargets,
1334     // Output status
1335     TF_Status*);
1336 
1337 // Deletes a handle allocated by TF_SessionPRunSetup.
1338 // Once called, no more calls to TF_SessionPRun should be made.
1339 TF_CAPI_EXPORT extern void TF_DeletePRunHandle(const char* handle);
1340 
1341 // --------------------------------------------------------------------------
1342 // The deprecated session API.  Please switch to the above instead of
1343 // TF_ExtendGraph(). This deprecated API can be removed at any time without
1344 // notice.
1345 
1346 typedef struct TF_DeprecatedSession TF_DeprecatedSession;
1347 
1348 TF_CAPI_EXPORT extern TF_DeprecatedSession* TF_NewDeprecatedSession(
1349     const TF_SessionOptions*, TF_Status* status);
1350 TF_CAPI_EXPORT extern void TF_CloseDeprecatedSession(TF_DeprecatedSession*,
1351                                                      TF_Status* status);
1352 TF_CAPI_EXPORT extern void TF_DeleteDeprecatedSession(TF_DeprecatedSession*,
1353                                                       TF_Status* status);
1354 TF_CAPI_EXPORT extern void TF_Reset(const TF_SessionOptions* opt,
1355                                     const char** containers, int ncontainers,
1356                                     TF_Status* status);
1357 // Treat the bytes proto[0,proto_len-1] as a serialized GraphDef and
1358 // add the nodes in that GraphDef to the graph for the session.
1359 //
1360 // Prefer use of TF_Session and TF_GraphImportGraphDef over this.
1361 TF_CAPI_EXPORT extern void TF_ExtendGraph(TF_DeprecatedSession*,
1362                                           const void* proto, size_t proto_len,
1363                                           TF_Status*);
1364 
1365 // See TF_SessionRun() above.
1366 TF_CAPI_EXPORT extern void TF_Run(TF_DeprecatedSession*,
1367                                   const TF_Buffer* run_options,
1368                                   const char** input_names, TF_Tensor** inputs,
1369                                   int ninputs, const char** output_names,
1370                                   TF_Tensor** outputs, int noutputs,
1371                                   const char** target_oper_names, int ntargets,
1372                                   TF_Buffer* run_metadata, TF_Status*);
1373 
1374 // See TF_SessionPRunSetup() above.
1375 TF_CAPI_EXPORT extern void TF_PRunSetup(TF_DeprecatedSession*,
1376                                         const char** input_names, int ninputs,
1377                                         const char** output_names, int noutputs,
1378                                         const char** target_oper_names,
1379                                         int ntargets, const char** handle,
1380                                         TF_Status*);
1381 
1382 // See TF_SessionPRun above.
1383 TF_CAPI_EXPORT extern void TF_PRun(TF_DeprecatedSession*, const char* handle,
1384                                    const char** input_names, TF_Tensor** inputs,
1385                                    int ninputs, const char** output_names,
1386                                    TF_Tensor** outputs, int noutputs,
1387                                    const char** target_oper_names, int ntargets,
1388                                    TF_Status*);
1389 
1390 typedef struct TF_DeviceList TF_DeviceList;
1391 
1392 // Lists all devices in a TF_Session.
1393 //
1394 // Caller takes ownership of the returned TF_DeviceList* which must eventually
1395 // be freed with a call to TF_DeleteDeviceList.
1396 TF_CAPI_EXPORT extern TF_DeviceList* TF_SessionListDevices(TF_Session* session,
1397                                                            TF_Status* status);
1398 
1399 // Lists all devices in a TF_Session.
1400 //
1401 // Caller takes ownership of the returned TF_DeviceList* which must eventually
1402 // be freed with a call to TF_DeleteDeviceList.
1403 TF_CAPI_EXPORT extern TF_DeviceList* TF_DeprecatedSessionListDevices(
1404     TF_DeprecatedSession* session, TF_Status* status);
1405 
1406 // Deallocates the device list.
1407 TF_CAPI_EXPORT extern void TF_DeleteDeviceList(TF_DeviceList* list);
1408 
1409 // Counts the number of elements in the device list.
1410 TF_CAPI_EXPORT extern int TF_DeviceListCount(const TF_DeviceList* list);
1411 
1412 // Retrieves the full name of the device (e.g. /job:worker/replica:0/...)
1413 // The return value will be a pointer to a null terminated string. The caller
1414 // must not modify or delete the string. It will be deallocated upon a call to
1415 // TF_DeleteDeviceList.
1416 //
1417 // If index is out of bounds, an error code will be set in the status object,
1418 // and a null pointer will be returned.
1419 TF_CAPI_EXPORT extern const char* TF_DeviceListName(const TF_DeviceList* list,
1420                                                     int index,
1421                                                     TF_Status* status);
1422 
1423 // Retrieves the type of the device at the given index.
1424 //
1425 // The caller must not modify or delete the string. It will be deallocated upon
1426 // a call to TF_DeleteDeviceList.
1427 //
1428 // If index is out of bounds, an error code will be set in the status object,
1429 // and a null pointer will be returned.
1430 TF_CAPI_EXPORT extern const char* TF_DeviceListType(const TF_DeviceList* list,
1431                                                     int index,
1432                                                     TF_Status* status);
1433 
1434 // Retrieve the amount of memory associated with a given device.
1435 //
1436 // If index is out of bounds, an error code will be set in the status object,
1437 // and -1 will be returned.
1438 TF_CAPI_EXPORT extern int64_t TF_DeviceListMemoryBytes(
1439     const TF_DeviceList* list, int index, TF_Status* status);
1440 
1441 // Retrieve the incarnation number of a given device.
1442 //
1443 // If index is out of bounds, an error code will be set in the status object,
1444 // and 0 will be returned.
1445 TF_CAPI_EXPORT extern uint64_t TF_DeviceListIncarnation(
1446     const TF_DeviceList* list, int index, TF_Status* status);
1447 
1448 // --------------------------------------------------------------------------
1449 // Load plugins containing custom ops and kernels
1450 
1451 // TF_Library holds information about dynamically loaded TensorFlow plugins.
1452 typedef struct TF_Library TF_Library;
1453 
1454 // Load the library specified by library_filename and register the ops and
1455 // kernels present in that library.
1456 //
1457 // Pass "library_filename" to a platform-specific mechanism for dynamically
1458 // loading a library. The rules for determining the exact location of the
1459 // library are platform-specific and are not documented here.
1460 //
1461 // On success, place OK in status and return the newly created library handle.
1462 // The caller owns the library handle.
1463 //
1464 // On failure, place an error status in status and return NULL.
1465 TF_CAPI_EXPORT extern TF_Library* TF_LoadLibrary(const char* library_filename,
1466                                                  TF_Status* status);
1467 
1468 // Get the OpList of OpDefs defined in the library pointed by lib_handle.
1469 //
1470 // Returns a TF_Buffer. The memory pointed to by the result is owned by
1471 // lib_handle. The data in the buffer will be the serialized OpList proto for
1472 // ops defined in the library.
1473 TF_CAPI_EXPORT extern TF_Buffer TF_GetOpList(TF_Library* lib_handle);
1474 
1475 // Frees the memory associated with the library handle.
1476 // Does NOT unload the library.
1477 TF_CAPI_EXPORT extern void TF_DeleteLibraryHandle(TF_Library* lib_handle);
1478 
1479 // Get the OpList of all OpDefs defined in this address space.
1480 // Returns a TF_Buffer, ownership of which is transferred to the caller
1481 // (and can be freed using TF_DeleteBuffer).
1482 //
1483 // The data in the buffer will be the serialized OpList proto for ops registered
1484 // in this address space.
1485 TF_CAPI_EXPORT extern TF_Buffer* TF_GetAllOpList(void);
1486 
1487 // TF_ApiDefMap encapsulates a collection of API definitions for an operation.
1488 //
1489 // This object maps the name of a TensorFlow operation to a description of the
1490 // API to generate for it, as defined by the ApiDef protocol buffer (
1491 // https://www.tensorflow.org/code/tensorflow/core/framework/api_def.proto)
1492 //
1493 // The ApiDef messages are typically used to generate convenience wrapper
1494 // functions for TensorFlow operations in various language bindings.
1495 typedef struct TF_ApiDefMap TF_ApiDefMap;
1496 
1497 // Creates a new TF_ApiDefMap instance.
1498 //
1499 // Params:
1500 //  op_list_buffer - TF_Buffer instance containing serialized OpList
1501 //    protocol buffer. (See
1502 //    https://www.tensorflow.org/code/tensorflow/core/framework/op_def.proto
1503 //    for the OpList proto definition).
1504 //  status - Set to OK on success and an appropriate error on failure.
1505 TF_CAPI_EXPORT extern TF_ApiDefMap* TF_NewApiDefMap(TF_Buffer* op_list_buffer,
1506                                                     TF_Status* status);
1507 
1508 // Deallocates a TF_ApiDefMap.
1509 TF_CAPI_EXPORT extern void TF_DeleteApiDefMap(TF_ApiDefMap* apimap);
1510 
1511 // Add ApiDefs to the map.
1512 //
1513 // `text` corresponds to a text representation of an ApiDefs protocol message.
1514 // (https://www.tensorflow.org/code/tensorflow/core/framework/api_def.proto).
1515 //
1516 // The provided ApiDefs will be merged with existing ones in the map, with
1517 // precedence given to the newly added version in case of conflicts with
1518 // previous calls to TF_ApiDefMapPut.
1519 TF_CAPI_EXPORT extern void TF_ApiDefMapPut(TF_ApiDefMap* api_def_map,
1520                                            const char* text, size_t text_len,
1521                                            TF_Status* status);
1522 
1523 // Returns a serialized ApiDef protocol buffer for the TensorFlow operation
1524 // named `name`.
1525 TF_CAPI_EXPORT extern TF_Buffer* TF_ApiDefMapGet(TF_ApiDefMap* api_def_map,
1526                                                  const char* name,
1527                                                  size_t name_len,
1528                                                  TF_Status* status);
1529 
1530 // --------------------------------------------------------------------------
1531 // Kernel definition information.
1532 
1533 // Returns a serialized KernelList protocol buffer containing KernelDefs for all
1534 // registered kernels.
1535 TF_CAPI_EXPORT extern TF_Buffer* TF_GetAllRegisteredKernels(TF_Status* status);
1536 
1537 // Returns a serialized KernelList protocol buffer containing KernelDefs for all
1538 // kernels registered for the operation named `name`.
1539 TF_CAPI_EXPORT extern TF_Buffer* TF_GetRegisteredKernelsForOp(
1540     const char* name, TF_Status* status);
1541 
1542 // Update edge, switch input/ output in a node
1543 TF_CAPI_EXPORT extern void TF_UpdateEdge(TF_Graph* graph, TF_Output new_src,
1544                                          TF_Input dst, TF_Status* status);
1545 
1546 // --------------------------------------------------------------------------
1547 // In-process TensorFlow server functionality, for use in distributed training.
1548 // A Server instance encapsulates a set of devices and a Session target that
1549 // can participate in distributed training. A server belongs to a cluster
1550 // (specified by a ClusterSpec), and corresponds to a particular task in a
1551 // named job. The server can communicate with any other server in the same
1552 // cluster.
1553 
1554 // In-process TensorFlow server.
1555 typedef struct TF_Server TF_Server;
1556 
1557 // Creates a new in-process TensorFlow server configured using a serialized
1558 // ServerDef protocol buffer provided via `proto` and `proto_len`.
1559 //
1560 // The server will not serve any requests until TF_ServerStart is invoked.
1561 // The server will stop serving requests once TF_ServerStop or
1562 // TF_DeleteServer is invoked.
1563 TF_CAPI_EXPORT extern TF_Server* TF_NewServer(const void* proto,
1564                                               size_t proto_len,
1565                                               TF_Status* status);
1566 
1567 // Starts an in-process TensorFlow server.
1568 TF_CAPI_EXPORT extern void TF_ServerStart(TF_Server* server, TF_Status* status);
1569 
1570 // Stops an in-process TensorFlow server.
1571 TF_CAPI_EXPORT extern void TF_ServerStop(TF_Server* server, TF_Status* status);
1572 
1573 // Blocks until the server has been successfully stopped (via TF_ServerStop or
1574 // TF_ServerClose).
1575 TF_CAPI_EXPORT extern void TF_ServerJoin(TF_Server* server, TF_Status* status);
1576 
1577 // Returns the target string that can be provided to TF_SetTarget() to connect
1578 // a TF_Session to `server`.
1579 //
1580 // The returned string is valid only until TF_DeleteServer is invoked.
1581 TF_CAPI_EXPORT extern const char* TF_ServerTarget(TF_Server* server);
1582 
1583 // Destroy an in-process TensorFlow server, frees memory. If server is running
1584 // it will be stopped and joined.
1585 TF_CAPI_EXPORT extern void TF_DeleteServer(TF_Server* server);
1586 
1587 // Register a listener method that processes printed messages.
1588 //
1589 // If any listeners are registered, the print operator will call all listeners
1590 // with the printed messages and immediately return without writing to the
1591 // logs.
1592 TF_CAPI_EXPORT extern void TF_RegisterLogListener(
1593     void (*listener)(const char*));
1594 
1595 // Register a FileSystem plugin from filename `plugin_filename`.
1596 //
1597 // On success, place OK in status.
1598 // On failure, place an error status in status.
1599 TF_CAPI_EXPORT extern void TF_RegisterFilesystemPlugin(
1600     const char* plugin_filename, TF_Status* status);
1601 
1602 #ifdef __cplusplus
1603 } /* end extern "C" */
1604 #endif
1605 
1606 #endif  // TENSORFLOW_C_C_API_H_
1607