tensorflow 0.1.0.0 → 0.1.0.1
raw patch · 2 files changed
+1039/−1 lines, 2 files
Files
- tensorflow.cabal +2/−1
- third_party/tensorflow/c/c_api.h +1037/−0
tensorflow.cabal view
@@ -1,5 +1,5 @@ name: tensorflow-version: 0.1.0.0+version: 0.1.0.1 synopsis: TensorFlow bindings. description: This library provides an interface to the TensorFlow@@ -19,6 +19,7 @@ category: Machine Learning build-type: Simple cabal-version: >=1.22+extra-source-files: third_party/tensorflow/c/c_api.h library hs-source-dirs: src
+ third_party/tensorflow/c/c_api.h view
@@ -0,0 +1,1037 @@+/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+==============================================================================*/++#ifndef TENSORFLOW_C_C_API_H_+#define TENSORFLOW_C_C_API_H_++#include <stddef.h>+#include <stdint.h>++// --------------------------------------------------------------------------+// C API for TensorFlow.+//+// The API leans towards simplicity and uniformity instead of convenience+// since most usage will be by language specific wrappers.+//+// Conventions:+// * We use the prefix TF_ for everything in the API.+// * Objects are always passed around as pointers to opaque structs+// and these structs are allocated/deallocated via the API.+// * TF_Status holds error information. It is an object type+// and therefore is passed around as a pointer to an opaque+// struct as mentioned above.+// * Every call that has a TF_Status* argument clears it on success+// and fills it with error info on failure.+// * unsigned char is used for booleans (instead of the 'bool' type).+// In C++ bool is a keyword while in C99 bool is a macro defined+// in stdbool.h. It is possible for the two to be inconsistent.+// For example, neither the C99 nor the C++11 standard force a byte+// size on the bool type, so the macro defined in stdbool.h could+// be inconsistent with the bool keyword in C++. Thus, the use+// of stdbool.h is avoided and unsigned char is used instead.+// * size_t is used to represent byte sizes of objects that are+// materialized in the address space of the calling process.+// * int is used as an index into arrays.+//+// Questions left to address:+// * Might at some point need a way for callers to provide their own Env.+// * Maybe add TF_TensorShape that encapsulates dimension info.+//+// Design decisions made:+// * Backing store for tensor memory has an associated deallocation+// function. This deallocation function will point to client code+// for tensors populated by the client. So the client can do things+// like shadowing a numpy array.+// * We do not provide TF_OK since it is not strictly necessary and we+// are not optimizing for convenience.+// * We make assumption that one session has one graph. This should be+// fine since we have the ability to run sub-graphs.+// * We could allow NULL for some arguments (e.g., NULL options arg).+// However since convenience is not a primary goal, we don't do this.+// * Devices are not in this API. Instead, they are created/used internally+// and the API just provides high level controls over the number of+// devices of each type.++#ifdef __cplusplus+extern "C" {+#endif++// --------------------------------------------------------------------------+// TF_Version returns a string describing version information of the+// TensorFlow library. TensorFlow using semantic versioning.+extern const char* TF_Version();++// --------------------------------------------------------------------------+// TF_DataType holds the type for a scalar value. E.g., one slot in a tensor.+// The enum values here are identical to corresponding values in types.proto.+typedef enum {+ TF_FLOAT = 1,+ TF_DOUBLE = 2,+ TF_INT32 = 3, // Int32 tensors are always in 'host' memory.+ TF_UINT8 = 4,+ TF_INT16 = 5,+ TF_INT8 = 6,+ TF_STRING = 7,+ TF_COMPLEX64 = 8, // Single-precision complex+ TF_COMPLEX = 8, // Old identifier kept for API backwards compatibility+ TF_INT64 = 9,+ TF_BOOL = 10,+ TF_QINT8 = 11, // Quantized int8+ TF_QUINT8 = 12, // Quantized uint8+ TF_QINT32 = 13, // Quantized int32+ TF_BFLOAT16 = 14, // Float32 truncated to 16 bits. Only for cast ops.+ TF_QINT16 = 15, // Quantized int16+ TF_QUINT16 = 16, // Quantized uint16+ TF_UINT16 = 17,+ TF_COMPLEX128 = 18, // Double-precision complex+ TF_HALF = 19,+ TF_RESOURCE = 20,+} TF_DataType;++// TF_DataTypeSize returns the sizeof() for the underlying type corresponding+// to the given TF_DataType enum value. Returns 0 for variable length types+// (eg. TF_STRING) or on failure.+extern size_t TF_DataTypeSize(TF_DataType dt);++// --------------------------------------------------------------------------+// TF_Code holds an error code. The enum values here are identical to+// corresponding values in error_codes.proto.+typedef enum {+ TF_OK = 0,+ TF_CANCELLED = 1,+ TF_UNKNOWN = 2,+ TF_INVALID_ARGUMENT = 3,+ TF_DEADLINE_EXCEEDED = 4,+ TF_NOT_FOUND = 5,+ TF_ALREADY_EXISTS = 6,+ TF_PERMISSION_DENIED = 7,+ TF_UNAUTHENTICATED = 16,+ TF_RESOURCE_EXHAUSTED = 8,+ TF_FAILED_PRECONDITION = 9,+ TF_ABORTED = 10,+ TF_OUT_OF_RANGE = 11,+ TF_UNIMPLEMENTED = 12,+ TF_INTERNAL = 13,+ TF_UNAVAILABLE = 14,+ TF_DATA_LOSS = 15,+} TF_Code;++// --------------------------------------------------------------------------+// TF_Status holds error information. It either has an OK code, or+// else an error code with an associated error message.+typedef struct TF_Status TF_Status;++// Return a new status object.+extern TF_Status* TF_NewStatus();++// Delete a previously created status object.+extern void TF_DeleteStatus(TF_Status*);++// Record <code, msg> in *s. Any previous information is lost.+// A common use is to clear a status: TF_SetStatus(s, TF_OK, "");+extern void TF_SetStatus(TF_Status* s, TF_Code code, const char* msg);++// Return the code record in *s.+extern TF_Code TF_GetCode(const TF_Status* s);++// Return a pointer to the (null-terminated) error message in *s. The+// return value points to memory that is only usable until the next+// mutation to *s. Always returns an empty string if TF_GetCode(s) is+// TF_OK.+extern const char* TF_Message(const TF_Status* s);++// --------------------------------------------------------------------------+// TF_Buffer holds a pointer to a block of data and its associated length.+// Typically, the data consists of a serialized protocol buffer, but other data+// may also be held in a buffer.+//+// By default, TF_Buffer itself does not do any memory management of the+// pointed-to block. If need be, users of this struct should specify how to+// deallocate the block by setting the `data_deallocator` function pointer.+typedef struct {+ const void* data;+ size_t length;+ void (*data_deallocator)(void* data, size_t length);+} TF_Buffer;++// Makes a copy of the input and sets an appropriate deallocator. Useful for+// passing in read-only, input protobufs.+extern TF_Buffer* TF_NewBufferFromString(const void* proto, size_t proto_len);++// Useful for passing *out* a protobuf.+extern TF_Buffer* TF_NewBuffer();++extern void TF_DeleteBuffer(TF_Buffer*);++extern TF_Buffer TF_GetBuffer(TF_Buffer* buffer);++// --------------------------------------------------------------------------+// TF_Tensor holds a multi-dimensional array of elements of a single data type.+// For all types other than TF_STRING, the data buffer stores elements+// in row major order. E.g. if data is treated as a vector of TF_DataType:+//+// element 0: index (0, ..., 0)+// element 1: index (0, ..., 1)+// ...+//+// The format for TF_STRING tensors is:+// start_offset: array[uint64]+// data: byte[...]+//+// The string length (as a varint), followed by the contents of the string+// is encoded at data[start_offset[i]]]. TF_StringEncode and TF_StringDecode+// facilitate this encoding.++typedef struct TF_Tensor TF_Tensor;++// Return a new tensor that holds the bytes data[0,len-1].+//+// The data will be deallocated by a subsequent call to TF_DeleteTensor via:+// (*deallocator)(data, len, deallocator_arg)+// Clients must provide a custom deallocator function so they can pass in+// memory managed by something like numpy.+extern TF_Tensor* TF_NewTensor(TF_DataType, const int64_t* dims, int num_dims,+ void* data, size_t len,+ void (*deallocator)(void* data, size_t len,+ void* arg),+ void* deallocator_arg);++// Allocate and return a new Tensor.+//+// This function is an alternative to TF_NewTensor and should be used when+// memory is allocated to pass the Tensor to the C API. The allocated memory+// satisfies TensorFlow's memory alignment preferences and should be preferred+// over calling malloc and free.+//+// The caller must set the Tensor values by writing them to the pointer returned+// by TF_TensorData with length TF_TensorByteSize.+extern TF_Tensor* TF_AllocateTensor(TF_DataType, const int64_t* dims,+ int num_dims, size_t len);++// Destroy a tensor.+extern void TF_DeleteTensor(TF_Tensor*);++// Return the type of a tensor element.+extern TF_DataType TF_TensorType(const TF_Tensor*);++// Return the number of dimensions that the tensor has.+extern int TF_NumDims(const TF_Tensor*);++// Return the length of the tensor in the "dim_index" dimension.+// REQUIRES: 0 <= dim_index < TF_NumDims(tensor)+extern int64_t TF_Dim(const TF_Tensor* tensor, int dim_index);++// Return the size of the underlying data in bytes.+extern size_t TF_TensorByteSize(const TF_Tensor*);++// Return a pointer to the underlying data buffer.+extern void* TF_TensorData(const TF_Tensor*);++// --------------------------------------------------------------------------+// Encode the string `src` (`src_len` bytes long) into `dst` in the format+// required by TF_STRING tensors. Does not write to memory more than `dst_len`+// bytes beyond `*dst`. `dst_len` should be at least+// TF_StringEncodedSize(src_len).+//+// On success returns the size in bytes of the encoded string.+// Returns an error into `status` otherwise.+extern size_t TF_StringEncode(const char* src, size_t src_len, char* dst,+ size_t dst_len, TF_Status* status);++// Decode a string encoded using TF_StringEncode.+//+// On success, sets `*dst` to the start of the decoded string and `*dst_len` to+// its length. Returns the number of bytes starting at `src` consumed while+// decoding. `*dst` points to memory within the encoded buffer. On failure,+// `*dst` and `*dst_len` are undefined and an error is set in `status`.+//+// Does not read memory more than `src_len` bytes beyond `src`.+extern size_t TF_StringDecode(const char* src, size_t src_len, const char** dst,+ size_t* dst_len, TF_Status* status);++// Return the size in bytes required to encode a string `len` bytes long into a+// TF_STRING tensor.+extern size_t TF_StringEncodedSize(size_t len);++// --------------------------------------------------------------------------+// TF_SessionOptions holds options that can be passed during session creation.+typedef struct TF_SessionOptions TF_SessionOptions;++// Return a new options object.+extern TF_SessionOptions* TF_NewSessionOptions();++// Set the target in TF_SessionOptions.options.+// target can be empty, a single entry, or a comma separated list of entries.+// Each entry is in one of the following formats :+// "local"+// ip:port+// host:port+extern void TF_SetTarget(TF_SessionOptions* options, const char* target);++// Set the config in TF_SessionOptions.options.+// config should be a serialized tensorflow.ConfigProto proto.+// If config was not parsed successfully as a ConfigProto, record the+// error information in *status.+extern void TF_SetConfig(TF_SessionOptions* options, const void* proto,+ size_t proto_len, TF_Status* status);++// Destroy an options object.+extern void TF_DeleteSessionOptions(TF_SessionOptions*);++// TODO(jeff,sanjay):+// - export functions to set Config fields++// --------------------------------------------------------------------------+// The new graph construction API, still under development.++// Represents a computation graph. Graphs may be shared between sessions.+// Graphs are thread-safe when used as directed below.+typedef struct TF_Graph TF_Graph;++// Return a new graph object.+extern TF_Graph* TF_NewGraph();++// Destroy an options object. Graph will be deleted once no more+// TFSession's are referencing it.+extern void TF_DeleteGraph(TF_Graph*);++// Operation being built. The underlying graph must outlive this.+typedef struct TF_OperationDescription TF_OperationDescription;++// Operation that has been added to the graph. Valid until the graph is+// deleted -- in particular adding a new operation to the graph does not+// invalidate old TF_Operation* pointers.+typedef struct TF_Operation TF_Operation;++// Represents a specific input of an operation.+typedef struct TF_Input {+ TF_Operation* oper;+ int index; // The index of the input within oper.+} TF_Input;++// Represents a specific output of an operation.+typedef struct TF_Output {+ TF_Operation* oper;+ int index; // The index of the output within oper.+} TF_Output;++// Sets the shape of the Tensor referenced by `output` in `graph` to+// the shape described by `dims` and `num_dims`.+//+// If the number of dimensions is unknown, `num_dims` must be+// set to -1 and dims can be null. If a dimension is unknown,+// the corresponding entry in the `dims` array must be -1.+//+// This does not overwrite the existing shape associated with `output`,+// but merges the input shape with the existing shape. For example,+// setting a shape of [-1, 2] with an existing shape [2, -1] would set+// a final shape of [2, 2] based on shape merging semantics.+//+// Returns an error into `status` if:+// * `output` is not in `graph`.+// * An invalid shape is being set (e.g., the shape being set+// is incompatible with the existing shape).+extern void TF_GraphSetTensorShape(TF_Graph* graph, TF_Output output,+ const int64_t* dims, const int num_dims,+ TF_Status* status);++// Returns the number of dimensions of the Tensor referenced by `output`+// in `graph`.+//+// If the number of dimensions in the shape is unknown, returns -1.+//+// Returns an error into `status` if:+// * `output` is not in `graph`.+extern int TF_GraphGetTensorNumDims(TF_Graph* graph, TF_Output output,+ TF_Status* status);++// Returns the shape of the Tensor referenced by `output` in `graph`+// into `dims`. `dims` must be an array large enough to hold `num_dims`+// entries (e.g., the return value of TF_GraphGetTensorNumDims).+//+// If the number of dimensions in the shape is unknown or the shape is+// a scalar, `dims` will remain untouched. Otherwise, each element of+// `dims` will be set corresponding to the size of the dimension. An+// unknown dimension is represented by `-1`.+//+// Returns an error into `status` if:+// * `output` is not in `graph`.+// * `num_dims` does not match the actual number of dimensions.+extern void TF_GraphGetTensorShape(TF_Graph* graph, TF_Output output,+ int64_t* dims, int num_dims,+ TF_Status* status);++// Operation will only be added to *graph when TF_FinishOperation() is+// called (assuming TF_FinishOperation() does not return an error).+// *graph must not be deleted until after TF_FinishOperation() is+// called.+extern TF_OperationDescription* TF_NewOperation(TF_Graph* graph,+ const char* op_type,+ const char* oper_name);++// Specify the device for `desc`. Defaults to empty, meaning unconstrained.+extern void TF_SetDevice(TF_OperationDescription* desc, const char* device);++// The calls to TF_AddInput and TF_AddInputList must match (in number,+// order, and type) the op declaration. For example, the "Concat" op+// has registration:+// REGISTER_OP("Concat")+// .Input("concat_dim: int32")+// .Input("values: N * T")+// .Output("output: T")+// .Attr("N: int >= 2")+// .Attr("T: type");+// that defines two inputs, "concat_dim" and "values" (in that order).+// You must use TF_AddInput() for the first input (since it takes a+// single tensor), and TF_AddInputList() for the second input (since+// it takes a list, even if you were to pass a list with a single+// tensor), as in:+// TF_OperationDescription* desc = TF_NewOperation(graph, "Concat", "c");+// TF_Output concat_dim_input = {...};+// TF_AddInput(desc, concat_dim_input);+// TF_Output values_inputs[5] = {{...}, ..., {...}};+// TF_AddInputList(desc, values_inputs, 5);++// For inputs that take a single tensor.+extern void TF_AddInput(TF_OperationDescription* desc, TF_Output input);++// For inputs that take a list of tensors.+// inputs must point to TF_Output[num_inputs].+extern void TF_AddInputList(TF_OperationDescription* desc,+ const TF_Output* inputs, int num_inputs);++// Call once per control input to `desc`.+extern void TF_AddControlInput(TF_OperationDescription* desc,+ TF_Operation* input);++// Request that `desc` be co-located on the device where `op`+// is placed.+//+// Use of this is discouraged since the implementation of device placement is+// subject to change. Primarily intended for internal libraries+extern void TF_ColocateWith(TF_OperationDescription* desc, TF_Operation* op);++// Call some TF_SetAttr*() function for every attr that is not+// inferred from an input and doesn't have a default value you wish to+// keep.++// `value` must point to a string of length `length` bytes.+extern void TF_SetAttrString(TF_OperationDescription* desc,+ const char* attr_name, const void* value,+ size_t length);+// `values` and `lengths` each must have lengths `num_values`.+// `values[i]` must point to a string of length `lengths[i]` bytes.+extern void TF_SetAttrStringList(TF_OperationDescription* desc,+ const char* attr_name,+ const void* const* values,+ const size_t* lengths, int num_values);+extern void TF_SetAttrInt(TF_OperationDescription* desc, const char* attr_name,+ int64_t value);+extern void TF_SetAttrIntList(TF_OperationDescription* desc,+ const char* attr_name, const int64_t* values,+ int num_values);+extern void TF_SetAttrFloat(TF_OperationDescription* desc,+ const char* attr_name, float value);+extern void TF_SetAttrFloatList(TF_OperationDescription* desc,+ const char* attr_name, const float* values,+ int num_values);+extern void TF_SetAttrBool(TF_OperationDescription* desc, const char* attr_name,+ unsigned char value);+extern void TF_SetAttrBoolList(TF_OperationDescription* desc,+ const char* attr_name,+ const unsigned char* values, int num_values);+extern void TF_SetAttrType(TF_OperationDescription* desc, const char* attr_name,+ TF_DataType value);+extern void TF_SetAttrTypeList(TF_OperationDescription* desc,+ const char* attr_name, const TF_DataType* values,+ int num_values);++// Set `num_dims` to -1 to represent "unknown rank". Otherwise,+// `dims` points to an array of length `num_dims`. `dims[i]` must be+// >= -1, with -1 meaning "unknown dimension".+extern void TF_SetAttrShape(TF_OperationDescription* desc,+ const char* attr_name, const int64_t* dims,+ int num_dims);+// `dims` and `num_dims` must point to arrays of length `num_shapes`.+// Set `num_dims[i]` to -1 to represent "unknown rank". Otherwise,+// `dims[i]` points to an array of length `num_dims[i]`. `dims[i][j]`+// must be >= -1, with -1 meaning "unknown dimension".+extern void TF_SetAttrShapeList(TF_OperationDescription* desc,+ const char* attr_name,+ const int64_t* const* dims, const int* num_dims,+ int num_shapes);+// `proto` must point to an array of `proto_len` bytes representing a+// binary-serialized TensorShapeProto.+extern void TF_SetAttrTensorShapeProto(TF_OperationDescription* desc,+ const char* attr_name, const void* proto,+ size_t proto_len, TF_Status* status);+// `protos` and `proto_lens` must point to arrays of length `num_shapes`.+// `protos[i]` must point to an array of `proto_lens[i]` bytes+// representing a binary-serialized TensorShapeProto.+extern void TF_SetAttrTensorShapeProtoList(TF_OperationDescription* desc,+ const char* attr_name,+ const void* const* protos,+ const size_t* proto_lens,+ int num_shapes, TF_Status* status);++extern void TF_SetAttrTensor(TF_OperationDescription* desc,+ const char* attr_name, TF_Tensor* value,+ TF_Status* status);+extern void TF_SetAttrTensorList(TF_OperationDescription* desc,+ const char* attr_name,+ TF_Tensor* const* values, int num_values,+ TF_Status* status);++// `proto` should point to a sequence of bytes of length `proto_len`+// representing a binary serialization of an AttrValue protocol+// buffer.+extern void TF_SetAttrValueProto(TF_OperationDescription* desc,+ const char* attr_name, const void* proto,+ size_t proto_len, TF_Status* status);++// If this function succeeds:+// * *status is set to an OK value,+// * a TF_Operation is added to the graph,+// * a non-null value pointing to the added operation is returned --+// this value is valid until the underlying graph is deleted.+// Otherwise:+// * *status is set to a non-OK value,+// * the graph is not modified,+// * a null value is returned.+// In either case, it deletes `desc`.+extern TF_Operation* TF_FinishOperation(TF_OperationDescription* desc,+ TF_Status* status);++// TF_Operation functions. Operations are immutable once created, so+// these are all query functions.++extern const char* TF_OperationName(TF_Operation* oper);+extern const char* TF_OperationOpType(TF_Operation* oper);+extern const char* TF_OperationDevice(TF_Operation* oper);++extern int TF_OperationNumOutputs(TF_Operation* oper);+extern TF_DataType TF_OperationOutputType(TF_Output oper_out);+extern int TF_OperationOutputListLength(TF_Operation* oper,+ const char* arg_name,+ TF_Status* status);++extern int TF_OperationNumInputs(TF_Operation* oper);+extern TF_DataType TF_OperationInputType(TF_Input oper_in);+extern int TF_OperationInputListLength(TF_Operation* oper, const char* arg_name,+ TF_Status* status);++// In this code:+// TF_Output producer = TF_OperationInput(consumer);+// There is an edge from producer.oper's output (given by+// producer.index) to consumer.oper's input (given by consumer.index).+extern TF_Output TF_OperationInput(TF_Input oper_in);++// Get the number of current consumers of a specific output of an+// operation. Note that this number can change when new operations+// are added to the graph.+extern int TF_OperationOutputNumConsumers(TF_Output oper_out);++// Get list of all current consumers of a specific output of an+// operation. `consumers` must point to an array of length at least+// `max_consumers` (ideally set to+// TF_OperationOutputNumConsumers(oper_out)). Beware that a concurrent+// modification of the graph can increase the number of consumers of+// an operation. Returns the number of output consumers (should match+// TF_OperationOutputNumConsumers(oper_out)).+extern int TF_OperationOutputConsumers(TF_Output oper_out, TF_Input* consumers,+ int max_consumers);++// Get the number of control inputs to an operation.+extern int TF_OperationNumControlInputs(TF_Operation* oper);++// Get list of all control inputs to an operation. `control_inputs` must+// point to an array of length `max_control_inputs` (ideally set to+// TF_OperationNumControlInputs(oper)). Returns the number of control+// inputs (should match TF_OperationNumControlInputs(oper)).+extern int TF_OperationGetControlInputs(TF_Operation* oper,+ TF_Operation** control_inputs,+ int max_control_inputs);++// Get the number of operations that have `*oper` as a control input.+// Note that this number can change when new operations are added to+// the graph.+extern int TF_OperationNumControlOutputs(TF_Operation* oper);++// Get the list of operations that have `*oper` as a control input.+// `control_outputs` must point to an array of length at least+// `max_control_outputs` (ideally set to+// TF_OperationNumControlOutputs(oper)). Beware that a concurrent+// modification of the graph can increase the number of control+// outputs. Returns the number of control outputs (should match+// TF_OperationNumControlOutputs(oper)).+extern int TF_OperationGetControlOutputs(TF_Operation* oper,+ TF_Operation** control_outputs,+ int max_control_outputs);++// TF_AttrType describes the type of the value of an attribute on an operation.+typedef enum {+ TF_ATTR_STRING = 0,+ TF_ATTR_INT = 1,+ TF_ATTR_FLOAT = 2,+ TF_ATTR_BOOL = 3,+ TF_ATTR_TYPE = 4,+ TF_ATTR_SHAPE = 5,+ TF_ATTR_TENSOR = 6,+ TF_ATTR_PLACEHOLDER = 7,+ TF_ATTR_FUNC = 8,+} TF_AttrType;++// TF_AttrMetadata describes the value of an attribute on an operation.+typedef struct {+ // A boolean: 1 if the attribute value is a list, 0 otherwise.+ unsigned char is_list;++ // Length of the list if is_list is true. Undefined otherwise.+ int64_t list_size;++ // Type of elements of the list if is_list != 0.+ // Type of the single value stored in the attribute if is_list == 0.+ TF_AttrType type;++ // Total size the attribute value.+ // The units of total_size depend on is_list and type.+ // (1) If type == TF_ATTR_STRING and is_list == 0+ // then total_size is the byte size of the string+ // valued attribute.+ // (2) If type == TF_ATTR_STRING and is_list == 1+ // then total_size is the cumulative byte size+ // of all the strings in the list.+ // (3) If type == TF_ATTR_SHAPE and is_list == 0+ // then total_size is the number of dimensions+ // of the shape valued attribute, or -1+ // if its rank is unknown.+ // (4) If type == TF_ATTR_SHAPE and is_list == 1+ // then total_size is the cumulative number+ // of dimensions of all shapes in the list.+ // (5) Otherwise, total_size is undefined.+ int64_t total_size;+} TF_AttrMetadata;++// Returns metadata about the value of the attribute `attr_name` of `oper`.+extern TF_AttrMetadata TF_OperationGetAttrMetadata(TF_Operation* oper,+ const char* attr_name,+ TF_Status* status);++// Fills in `value` with the value of the attribute `attr_name`. `value` must+// point to an array of length at least `max_length` (ideally set to+// TF_AttrMetadata.total_size from TF_OperationGetAttrMetadata(oper,+// attr_name)).+extern void TF_OperationGetAttrString(TF_Operation* oper, const char* attr_name,+ void* value, size_t max_length,+ TF_Status* status);++// Get the list of strings in the value of the attribute `attr_name`. Fills in+// `values` and `lengths`, each of which must point to an array of length at+// least `max_values`.+//+// The elements of values will point to addresses in `storage` which must be at+// least `storage_size` bytes in length. Ideally, max_values would be set to+// TF_AttrMetadata.list_size and `storage` would be at least+// TF_AttrMetadata.total_size, obtained from TF_OperationGetAttrMetadata(oper,+// attr_name).+//+// Fails if storage_size is too small to hold the requested number of strings.+extern void TF_OperationGetAttrStringList(TF_Operation* oper,+ const char* attr_name, void** values,+ size_t* lengths, int max_values,+ void* storage, size_t storage_size,+ TF_Status* status);++extern void TF_OperationGetAttrInt(TF_Operation* oper, const char* attr_name,+ int64_t* value, TF_Status* status);++// Fills in `values` with the value of the attribute `attr_name` of `oper`.+// `values` must point to an array of length at least `max_values` (ideally set+// TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,+// attr_name)).+extern void TF_OperationGetAttrIntList(TF_Operation* oper,+ const char* attr_name, int64_t* values,+ int max_values, TF_Status* status);++extern void TF_OperationGetAttrFloat(TF_Operation* oper, const char* attr_name,+ float* value, TF_Status* status);++// Fills in `values` with the value of the attribute `attr_name` of `oper`.+// `values` must point to an array of length at least `max_values` (ideally set+// to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,+// attr_name)).+extern void TF_OperationGetAttrFloatList(TF_Operation* oper,+ const char* attr_name, float* values,+ int max_values, TF_Status* status);++extern void TF_OperationGetAttrBool(TF_Operation* oper, const char* attr_name,+ unsigned char* value, TF_Status* status);++// Fills in `values` with the value of the attribute `attr_name` of `oper`.+// `values` must point to an array of length at least `max_values` (ideally set+// to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,+// attr_name)).+extern void TF_OperationGetAttrBoolList(TF_Operation* oper,+ const char* attr_name,+ unsigned char* values, int max_values,+ TF_Status* status);++extern void TF_OperationGetAttrType(TF_Operation* oper, const char* attr_name,+ TF_DataType* value, TF_Status* status);++// Fills in `values` with the value of the attribute `attr_name` of `oper`.+// `values` must point to an array of length at least `max_values` (ideally set+// to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,+// attr_name)).+extern void TF_OperationGetAttrTypeList(TF_Operation* oper,+ const char* attr_name,+ TF_DataType* values, int max_values,+ TF_Status* status);++// Fills in `value` with the value of the attribute `attr_name` of `oper`.+// `values` must point to an array of length at least `num_dims` (ideally set to+// TF_Attr_Meta.size from TF_OperationGetAttrMetadata(oper, attr_name)).+extern void TF_OperationGetAttrShape(TF_Operation* oper, const char* attr_name,+ int64_t* value, int num_dims,+ TF_Status* status);++// Fills in `dims` with the list of shapes in the attribute `attr_name` of+// `oper` and `num_dims` with the corresponding number of dimensions. On return,+// for every i where `num_dims[i]` > 0, `dims[i]` will be an array of+// `num_dims[i]` elements. A value of -1 for `num_dims[i]` indicates that the+// i-th shape in the list is unknown.+//+// The elements of `dims` will point to addresses in `storage` which must be+// large enough to hold at least `storage_size` int64_ts. Ideally, `num_shapes`+// would be set to TF_AttrMetadata.list_size and `storage_size` would be set to+// TF_AttrMetadata.total_size from TF_OperationGetAttrMetadata(oper,+// attr_name).+//+// Fails if storage_size is insufficient to hold the requested shapes.+extern void TF_OperationGetAttrShapeList(TF_Operation* oper,+ const char* attr_name, int64_t** dims,+ int* num_dims, int num_shapes,+ int64_t* storage, int storage_size,+ TF_Status* status);++// Sets `value` to the binary-serialized TensorShapeProto of the value of+// `attr_name` attribute of `oper`'.+extern void TF_OperationGetAttrTensorShapeProto(TF_Operation* oper,+ const char* attr_name,+ TF_Buffer* value,+ TF_Status* status);++// Fills in `values` with binary-serialized TensorShapeProto values of the+// attribute `attr_name` of `oper`. `values` must point to an array of length at+// least `num_values` (ideally set to TF_AttrMetadata.list_size from+// TF_OperationGetAttrMetadata(oper, attr_name)).+extern void TF_OperationGetAttrTensorShapeProtoList(TF_Operation* oper,+ const char* attr_name,+ TF_Buffer** values,+ int max_values,+ TF_Status* status);++// Gets the TF_Tensor valued attribute of `attr_name` of `oper`.+//+// Allocates a new TF_Tensor which the caller is expected to take+// ownership of (and can deallocate using TF_DeleteTensor).+extern void TF_OperationGetAttrTensor(TF_Operation* oper, const char* attr_name,+ TF_Tensor** value, TF_Status* status);++// Fills in `values` with the TF_Tensor values of the attribute `attr_name` of+// `oper`. `values` must point to an array of TF_Tensor* of length at least+// `max_values` (ideally set to TF_AttrMetadata.list_size from+// TF_OperationGetAttrMetadata(oper, attr_name)).+//+// The caller takes ownership of all the non-null TF_Tensor* entries in `values`+// (which can be deleted using TF_DeleteTensor(values[i])).+extern void TF_OperationGetAttrTensorList(TF_Operation* oper,+ const char* attr_name,+ TF_Tensor** values, int max_values,+ TF_Status* status);++// Sets `output_attr_value` to the binary-serialized AttrValue proto+// representation of the value of the `attr_name` attr of `oper`.+extern void TF_OperationGetAttrValueProto(TF_Operation* oper,+ const char* attr_name,+ TF_Buffer* output_attr_value,+ TF_Status* status);++// Returns the operation in the graph with `oper_name`. Returns nullptr if+// no operation found.+extern TF_Operation* TF_GraphOperationByName(TF_Graph* graph,+ const char* oper_name);++// Iterate through the operations of a graph. To use:+// size_t pos = 0;+// TF_Operation* oper;+// while ((oper = TF_GraphNextOperation(graph, &pos)) != nullptr) {+// DoSomethingWithOperation(oper);+// }+extern TF_Operation* TF_GraphNextOperation(TF_Graph* graph, size_t* pos);++// Write out a serialized representation of `graph` (as a GraphDef protocol+// message) to `output_graph_def` (allocated by TF_NewBuffer()).+//+// May fail on very large graphs in the future.+extern void TF_GraphToGraphDef(TF_Graph* graph, TF_Buffer* output_graph_def,+ TF_Status* status);++// TF_ImportGraphDefOptions holds options that can be passed to+// TF_GraphImportGraphDef.+typedef struct TF_ImportGraphDefOptions TF_ImportGraphDefOptions;++extern TF_ImportGraphDefOptions* TF_NewImportGraphDefOptions();+extern void TF_DeleteImportGraphDefOptions(TF_ImportGraphDefOptions* opts);++// Set the prefix to be prepended to the names of nodes in `graph_def` that will+// be imported into `graph`.+extern void TF_ImportGraphDefOptionsSetPrefix(TF_ImportGraphDefOptions* opts,+ const char* prefix);++// Import the graph serialized in `graph_def` into `graph`.+extern void TF_GraphImportGraphDef(TF_Graph* graph, const TF_Buffer* graph_def,+ const TF_ImportGraphDefOptions* options,+ TF_Status* status);++// Note: The following function may fail on very large protos in the future.++extern void TF_OperationToNodeDef(TF_Operation* oper,+ TF_Buffer* output_node_def,+ TF_Status* status);++// TODO(andydavis): Function to add gradients to a graph.++// TODO(josh11b): Register OpDef, available to all operations added+// to this graph.++// The following two may both benefit from a subgraph-definition API+// that re-uses most of the graph-definition API.+// TODO(andydavis): Add functions to a graph.+// TODO(yuanbyu): Add while loop to graph.++// --------------------------------------------------------------------------+// API for driving Graph execution.++typedef struct TF_Session TF_Session;++// Return a new execution session with the associated graph, or NULL on error.+//+// *graph must be a valid graph (not deleted or nullptr). This function will+// prevent the graph from being deleted until TF_DeleteSession() is called.+// Does not take ownership of opts.+extern TF_Session* TF_NewSession(TF_Graph* graph, const TF_SessionOptions* opts,+ TF_Status* status);++#ifndef __ANDROID__+// TODO(ashankar): Remove the __ANDROID__ guard. This will require ensuring that+// the tensorflow/cc/saved_model:loader build target is Android friendly.++// This function creates a new TF_Session (which is created on success) using+// `session_options`, and then initializes state (restoring tensors and other+// assets) using `run_options`.+//+// Any NULL and non-NULL value combinations for (`run_options, `meta_graph_def`)+// are valid.+//+// - `export_dir` must be set to the path of the exported SavedModel.+// - `tags` must include the set of tags used to identify one MetaGraphDef in+// the SavedModel.+// - `graph` must be a graph newly allocated with TF_NewGraph().+//+// If successful, populates `graph` with the contents of the Graph and+// `meta_graph_def` with the MetaGraphDef of the loaded model.+TF_Session* TF_LoadSessionFromSavedModel(+ const TF_SessionOptions* session_options, const TF_Buffer* run_options,+ const char* export_dir, const char* const* tags, int tags_len,+ TF_Graph* graph, TF_Buffer* meta_graph_def, TF_Status* status);+#endif // __ANDROID__++// Close a session.+//+// Contacts any other processes associated with the session, if applicable.+// May not be called after TF_DeleteSession().+extern void TF_CloseSession(TF_Session*, TF_Status* status);++// Destroy a session object.+//+// Even if error information is recorded in *status, this call discards all+// local resources associated with the session. The session may not be used+// during or after this call (and the session drops its reference to the+// corresponding graph).+extern void TF_DeleteSession(TF_Session*, TF_Status* status);++// Run the graph associated with the session starting with the supplied inputs+// (inputs[0,ninputs-1] with corresponding values in input_values[0,ninputs-1]).+//+// Any NULL and non-NULL value combinations for (`run_options`,+// `run_metadata`) are valid.+//+// - `run_options` may be NULL, in which case it will be ignored; or+// non-NULL, in which case it must point to a `TF_Buffer` containing the+// serialized representation of a `RunOptions` protocol buffer.+// - `run_metadata` may be NULL, in which case it will be ignored; or+// non-NULL, in which case it must point to an empty, freshly allocated+// `TF_Buffer` that may be updated to contain the serialized representation+// of a `RunMetadata` protocol buffer.+//+// The caller retains ownership of `input_values` (which can be deleted using+// TF_DeleteTensor). The caller also retains ownership of `run_options` and/or+// `run_metadata` (when not NULL) and should manually call TF_DeleteBuffer on+// them.+//+// On success, the tensors corresponding to outputs[0,noutputs-1] are placed in+// output_values[]. Ownership of the elements of output_values[] is transferred+// to the caller, which must eventually call TF_DeleteTensor on them.+//+// On failure, output_values[] contains NULLs.+extern void TF_SessionRun(TF_Session* session,+ // RunOptions+ const TF_Buffer* run_options,+ // Input tensors+ const TF_Output* inputs,+ TF_Tensor* const* input_values, int ninputs,+ // Output tensors+ const TF_Output* outputs, TF_Tensor** output_values,+ int noutputs,+ // Target operations+ const TF_Operation* const* target_opers, int ntargets,+ // RunMetadata+ TF_Buffer* run_metadata,+ // Output status+ TF_Status*);++// Set up the graph with the intended feeds (inputs) and fetches (outputs) for a+// sequence of partial run calls.+//+// On success, returns a handle that is used for subsequent PRun calls.+//+// On failure, out_status contains a tensorflow::Status with an error+// message.+// NOTE: This is EXPERIMENTAL and subject to change.+extern void TF_SessionPRunSetup(TF_Session*,+ // Input names+ const TF_Output* inputs, int ninputs,+ // Output names+ const TF_Output* outputs, int noutputs,+ // Target operations+ const TF_Operation* const* target_opers,+ int ntargets,+ // Output handle+ const char** handle,+ // Output status+ TF_Status*);++// Continue to run the graph with additional feeds and fetches. The+// execution state is uniquely identified by the handle.+// NOTE: This is EXPERIMENTAL and subject to change.+extern void TF_SessionPRun(TF_Session*, const char* handle,+ // Input tensors+ const TF_Output* inputs,+ TF_Tensor* const* input_values, int ninputs,+ // Output tensors+ const TF_Output* outputs, TF_Tensor** output_values,+ int noutputs,+ // Target operations+ const TF_Operation* const* target_opers,+ int ntargets,+ // Output status+ TF_Status*);++// --------------------------------------------------------------------------+// The deprecated session API. Please switch to the above instead of+// TF_ExtendGraph(). This deprecated API can be removed at any time without+// notice.++typedef struct TF_DeprecatedSession TF_DeprecatedSession;++extern TF_DeprecatedSession* TF_NewDeprecatedSession(const TF_SessionOptions*,+ TF_Status* status);+extern void TF_CloseDeprecatedSession(TF_DeprecatedSession*, TF_Status* status);+extern void TF_DeleteDeprecatedSession(TF_DeprecatedSession*,+ TF_Status* status);+extern void TF_Reset(const TF_SessionOptions* opt, const char** containers,+ int ncontainers, TF_Status* status);+// Treat the bytes proto[0,proto_len-1] as a serialized GraphDef and+// add the nodes in that GraphDef to the graph for the session.+//+// Prefer use of TF_Session and TF_GraphImportGraphDef over this.+extern void TF_ExtendGraph(TF_DeprecatedSession*, const void* proto,+ size_t proto_len, TF_Status*);++// See TF_SessionRun() above.+extern void TF_Run(TF_DeprecatedSession*, const TF_Buffer* run_options,+ const char** input_names, TF_Tensor** inputs, int ninputs,+ const char** output_names, TF_Tensor** outputs, int noutputs,+ const char** target_oper_names, int ntargets,+ TF_Buffer* run_metadata, TF_Status*);++// See TF_SessionPRunSetup() above.+extern void TF_PRunSetup(TF_DeprecatedSession*, const char** input_names,+ int ninputs, const char** output_names, int noutputs,+ const char** target_oper_names, int ntargets,+ const char** handle, TF_Status*);++// See TF_SessionPRun above.+extern void TF_PRun(TF_DeprecatedSession*, const char* handle,+ const char** input_names, TF_Tensor** inputs, int ninputs,+ const char** output_names, TF_Tensor** outputs,+ int noutputs, const char** target_oper_names, int ntargets,+ TF_Status*);++// --------------------------------------------------------------------------+// Load plugins containing custom ops and kernels++// TF_Library holds information about dynamically loaded TensorFlow plugins.+typedef struct TF_Library TF_Library;++// Load the library specified by library_filename and register the ops and+// kernels present in that library.+//+// Pass "library_filename" to a platform-specific mechanism for dynamically+// loading a library. The rules for determining the exact location of the+// library are platform-specific and are not documented here.+//+// On success, place OK in status and return the newly created library handle.+// The caller owns the library handle.+//+// On failure, place an error status in status and return NULL.+extern TF_Library* TF_LoadLibrary(const char* library_filename,+ TF_Status* status);++// Get the OpList of OpDefs defined in the library pointed by lib_handle.+//+// Returns a TF_Buffer. The memory pointed to by the result is owned by+// lib_handle. The data in the buffer will be the serialized OpList proto for+// ops defined in the library.+extern TF_Buffer TF_GetOpList(TF_Library* lib_handle);++// Frees the memory associated with the library handle.+// Does NOT unload the library.+extern void TF_DeleteLibraryHandle(TF_Library* lib_handle);++// Get the OpList of all OpDefs defined in this address space.+// Returns a TF_Buffer, ownership of which is transferred to the caller+// (and can be freed using TF_DeleteBuffer).+//+// The data in the buffer will be the serialized OpList proto for ops registered+// in this address space.+extern TF_Buffer* TF_GetAllOpList();++#ifdef __cplusplus+} /* end extern "C" */+#endif++#endif // TENSORFLOW_C_C_API_H_