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