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