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