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