TensorFlow的系统结构以C API为界,将整个系统分为「前端」和「后端」两个子系统:
· 前端系统:主要扮演Client的角色,主要负责计算图的构造,并管理Session生命周期过程。是一个支持多语言的编程环境,并提供统一的编程模型支撑用户构造计算图。Client通过Session,连接TensorFlow后端的「运行时」,启动计算图的执行过程。
· 后端系统:TensorFlow的运行时系统,主要负责计算图的执行过程,包括计算图的剪枝,设备分配,子图计算等过程。
前端多语言编程环境与后端C/C++实现系统的通道归功于Swig的包装器。TensorFlow使用Bazel的构建工具,在编译之前启动Swig的代码生成过程,通过tf_session.i
自动生成了两个适配(Wrapper)文件:
· pywrap_tensorflow.py
: 负责对接上层Python调用;
· pywrap_tensorflow.cpp
: 负责对接下层C实现。
此外,pywrap_tensorflow.py
模块首次被加载时,自动地加载_pywrap_tensorflow.so
的动态链接库。从而实现了pywrap_tensorflow.py
到pywrap_tensorflow.cpp
的函数调用关系。
在pywrap_tensorflow.cpp
的实现中,静态注册了一个函数符号表。在运行时,按照Python的函数名称,匹配找到对应的C函数实现,最终转调到c_api.c
的具体实现。
阅读了 c_api.h 和 c_api.cc 的部分代码,这里附上一些对程序的标注及笔记
/* 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
#include
// --------------------------------------------------------------------------
// 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.
//
// TensorFlow 的 C API
//
// API 倾向于简单性和统一性,而不是方便,因为大多数使用将由语言特定的包装器。
//
//公约:
// * API 中的所有内容都使用前缀 TF_ 。
// * 对象总是作为指向 opaque 结构体的指针传递,这些结构体通过 API 分配/释放。
// * TF_Status 保存错误信息。它是一个对象类型,因此如上所述作为指向不透明结构的指针传递。
// * 具有 TF_Status * 参数的每个调用都会成功清除,并在失败时填写错误信息。
// * unsigned char 用于布尔值(而不是 'bool' 类型)。在 C++ 中,bool 是一个关键字,而在 C99 中,bool 是在 stdbool.h 中定义的宏。两者可能不一致。例如,C99 和 C++ 11 标准都不强制 bool 类型的字节大小,因此在 stdbool.h 中定义的宏可能与 C++ 中的 bool 关键字不一致。因此,避免使用 stdbool.h,并且使用 unsigned char 代替。
// * size_t 用于表示在调用进程的地址空间中实现的对象的字节大小。
// * int 用作数组的索引。
//
//遗留问题:
// * 某些地方可能需要一种方式让调用者提供自己的环境。
// * 也许添加封装维度信息的 TF_TensorShape。
//
//设计决策:
// * 张量存储器的备份存储器具有相关的解除分配功能。此释放功能将指向由客户端填充的张量的客户端代码。所以客户端可以跟踪NumPy数组。
// * 我们不提供 TF_OK ,因为它不是严格必要的,为方便起见,我们没有进行优化。
// * 我们假设一个会话有一个图。这应该是正常的,因为我们有能力运行子图。
// * 我们可以为一些参数允许 NULL(例如,NULL 选项 arg)。但是,由于方便不是主要目标,我们不这样做。
// * 设备不在此 API 中。相反,它们在内部创建/使用,API 只是提供对每种类型的设备数量的高级控制。
#ifdef __cplusplus
extern "C" {
#endif
{ // TF_Version
// --------------------------------------------------------------------------
// TF_Version returns a string describing version information of the
// TensorFlow library. TensorFlow using semantic versioning.
// TF_Version 返回描述 TensorFlow 库的版本信息的字符串。 TensorFlow 使用语义版本控制。
extern const char* TF_Version();
}
{ // TF_DataType
// --------------------------------------------------------------------------
// 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.
// TF_DataType 保存标量值的类型。 例如张量中的一个 slot。
// 这里的枚举值与 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.
// TF_DataTypeSize 返回与给定 TF_DataType 枚举值对应的底层类型的 sizeof()。
// 对于可变长度类型(例如 TF_STRING)或失败返回 0。
extern size_t TF_DataTypeSize(TF_DataType dt);
}
{// TF_Code
// --------------------------------------------------------------------------
// TF_Code holds an error code. The enum values here are identical to
// corresponding values in error_codes.proto.
// TF_Code 保存错误代码。 这里的枚举值与 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
// --------------------------------------------------------------------------
// TF_Status holds error information. It either has an OK code, or
// else an error code with an associated error message.
// TF_Status 保存错误信息。 它有一个 OK 代码,或者一个带有相关错误消息的错误代码。
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 in *s. Any previous information is lost.
// A common use is to clear a status: TF_SetStatus(s, TF_OK, "");
// 在 *s 中的记录 。 任何以前的信息都会丢失。
// 常见的用法是清除状态:TF_SetStatus(s, TF_OK, "");
extern void TF_SetStatus(TF_Status* s, TF_Code code, const char* msg);
// Return the code record in *s.
// 返回 *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.
// 返回 *s 中一个指向(空终止)错误消息的指针。
// 返回值指向直到下一个突变为 *s 之前才可用的内存。
// 如果TF_GetCode(TF)为TF_OK,则始终返回一个空字符串。
extern const char* TF_Message(const TF_Status* s);
}
{ // TF_Buffer
// --------------------------------------------------------------------------
// 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.
// TF_Buffer 保存指向一个数据块及其相关长度的指针。
// 通常,数据由序列化的 protocol buffer 组成,但其他数据也可以保存在 buffer 中。
//
// 默认情况下,TF_Buffer 本身不对指向块进行任何内存管理。
// 如果需要,该结构体的用户应该通过设置 `data_deallocator` 函数指针来指定如何释放该块。
typedef struct TF_Buffer {
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.
// 备份输入并设置一个适当的 data_deallocator。 用于传递只读的输入 protobufs。
extern TF_Buffer* TF_NewBufferFromString(const void* proto, size_t proto_len);
// Useful for passing *out* a protobuf.
// 用于传递输出 protobufs。
extern TF_Buffer* TF_NewBuffer();
extern void TF_DeleteBuffer(TF_Buffer*);
extern TF_Buffer TF_GetBuffer(TF_Buffer* buffer);
}
{ // TF_Tensor
// --------------------------------------------------------------------------
// 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].
// 返回一个保存字节数据 [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*);
}
{ // TF_STRING
// --------------------------------------------------------------------------
// Encode the string `src` (`src_len` bytes long) into `dst` in the format
// required by TF_STRING tensors.
// 按照 TF_STRING 张量所需的格式将字符串`src`(`src_len` bytes long)编码成`dst`。
// 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.
// 解码使用 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
// --------------------------------------------------------------------------
// TF_SessionOptions holds options that can be passed during session creation.
// TF_SessionOptions 包含可以在会话创建过程中传递的选项。
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
// 设置 TF_SessionOptions.options 中的 target。
// 目标可以为空,单个条目或逗号分隔的条目列表。
// 每个条目都是以下格式之一:
// "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.
// 设置 TF_SessionOptions.options 的 config。
// config 应该是一个序列化的 tensorflow.ConfigProto proto。
// 如果配置没有成功解析为 ConfigProto,在*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
}
{ // TF_Graph
// --------------------------------------------------------------------------
// The new graph construction API, still under development.
// 新的 graph 构建 API 仍在开发中。
// Represents a computation graph. Graphs may be shared between sessions.
// Graphs are thread-safe when used as directed below.
// 表示计算图。 Graphs 可以在会话之间共享。
// 按照以下指示使用的 Graphs 是线程安全的。
typedef struct TF_Graph TF_Graph;
// Return a new graph object.
// 返回一个新的 graph 对象。
extern TF_Graph* TF_NewGraph();
// Destroy an options object. Graph will be deleted once no more
// TFSession's are referencing it.
// 销毁选项对象。 一旦没有更多的 TFSession 引用它,Graph 将被删除。
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.
// 向 graph 中添加的操作。
// 直到图形被删除为止 -- 特别是向图形添加新的操作并不会使旧的 TF_Operation* 指针无效。
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`.
// 将`graph`中`output`引用的 Tensor 的形状设置为`dims`和`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.
// 当 TF_FinishOperation() 被调用时(假设 TF_FinishOperation() 不返回错误),操作将仅添加到 *graph 中。
// 直到 TF_FinishOperation() 被调用 *graph 才能被删除。
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.
// 指定`desc`的设备。 默认为空,意味着无约束。
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.
// 对 TF_AddInput 和 TF_AddInputList 的调用必须与 op 声明相匹配(在数字,顺序和类型中)。
//
// 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.
// 张量 list 的输入。
// 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`.
// 每个输入到 `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);
{ // TF_SetAttr*()
// 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);
}
{ // TF_Operation
// --------------------------------------------------------------------------
// 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.
// 获取操作的特定输出的当前 consumers 的数量。
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)).
// 获取操作的特定输出的所有当前 consumers 的列表。
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.
// 获取具有 `*oper` 作为控制输入的操作数。
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)).
// 获取具有`* 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.
// TF_AttrType 描述操作的属性值的类型。
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.
// TF_AttrMetadata 描述操作的属性值。
typedef struct TF_AttrMetadata {
// 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`.
// 返回关于 `oper` 属性 `attr_name` 的值的元数据 metadata。
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)).
// 赋值给 `value` 属性 `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`.
// 赋值给`values` 和 `lengths` 属性 `attr_name` 的值中的字符串列表。
//
// 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)).
// 赋值给`values` `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.
// 赋值给 `dims` 在 `oper` 和 `num_dims` 的属性 `attr_name` 中具有相应维度数的形状列表。
//
// 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`.
// 将 `value` 设置为 `oper` 的 `attr_name` 属性值的二进制序列化 TensorShapeProto
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`.
// 获取 `oper` 的 `attr_name` 的 TF_Tensor 值属性。
//
// Allocates a new TF_Tensor which the caller is expected to take
// ownership of (and can deallocate using TF_DeleteTensor).
// 分配一个新的 TF_Tensor(并且可以使用 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()).
// `output_graph_def`'s underlying buffer will be freed when TF_DeleteBuffer()
// is called.
// 将 `graph`(作为 GraphDef 协议消息)序列化的表示形式写入 `output_graph_def`(由 TF_NewBuffer() 分配)。
// 当 TF_DeleteBuffer() 被调用时,`output_graph_def` 的底层缓冲区将被释放。
//
// May fail on very large graphs in the future.
// 将来可能会在非常大的 graphs 上失败。
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);
// Set any imported nodes with input `src_name:src_index` to have that input
// replaced with `dst`. `src_name` refers to a node in the graph to be imported,
// `dst` references a node already existing in the graph being imported into.
extern void TF_ImportGraphDefOptionsAddInputMapping(
TF_ImportGraphDefOptions* opts, const char* src_name, int src_index,
TF_Output dst);
// Set any imported nodes with control input `src_name` to have that input
// replaced with `dst`. `src_name` refers to a node in the graph to be imported,
// `dst` references an operation already existing in the graph being imported
// into.
extern void TF_GraphImportGraphDefOptionsRemapControlDependency(
TF_ImportGraphDefOptions* opts, const char* src_name, TF_Operation* dst);
// Cause the imported graph to have a control dependency on `oper`. `oper`
// should exist in the graph being imported into.
extern void TF_ImportGraphDefOptionsAddControlDependency(
TF_ImportGraphDefOptions* opts, TF_Operation* oper);
// Add an output in `graph_def` to be returned via the `return_outputs` output
// parameter of TF_GraphImportGraphDef(). If the output is remapped via an input
// mapping, the corresponding existing tensor in `graph` will be returned.
extern void TF_ImportGraphDefOptionsAddReturnOutput(
TF_ImportGraphDefOptions* opts, const char* oper_name, int index);
// Returns the number of return outputs added via
// TF_ImportGraphDefOptionsAddReturnOutput().
extern int TF_ImportGraphDefOptionsNumReturnOutputs(
const TF_ImportGraphDefOptions* opts);
// Import the graph serialized in `graph_def` into `graph`.
// 将以 `graph_def` 的序列化 graph 形式导入 `graph`。
// `num_return_outputs` must be the number of return outputs added (i.e. the
// result of TF_ImportGraphDefOptionsNumReturnOutputs()). If
// `num_return_outputs` is non-zero, `return_outputs` must be of length
// `num_return_outputs`. Otherwise it can be null.
extern void TF_GraphImportGraphDefWithReturnOutputs(
TF_Graph* graph, const TF_Buffer* graph_def,
const TF_ImportGraphDefOptions* options, TF_Output* return_outputs,
int num_return_outputs, TF_Status* status);
// Import the graph serialized in `graph_def` into `graph`.
// Convenience function for when no return outputs have been added.
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);
typedef struct TF_WhileParams {
// The number of inputs to the while loop, i.e. the number of loop variables.
// This is the size of cond_inputs, body_inputs, and body_outputs.
const int ninputs;
// The while condition graph. The inputs are the current values of the loop
// variables. The output should be a scalar boolean.
TF_Graph* const cond_graph;
const TF_Output* const cond_inputs;
TF_Output cond_output;
// The loop body graph. The inputs are the current values of the loop
// variables. The outputs are the updated values of the loop variables.
TF_Graph* const body_graph;
const TF_Output* const body_inputs;
TF_Output* const body_outputs;
// Unique null-terminated name for this while loop. This is used as a prefix
// for created operations.
const char* name;
} TF_WhileParams;
// Creates a TF_WhileParams for creating a while loop in `g`. `inputs` are
// outputs that already exist in `g` used as initial values for the loop
// variables.
//
// The returned TF_WhileParams will have all fields initialized except
// `cond_output`, `body_outputs`, and `name`. The `body_outputs` buffer will be
// allocated to size `ninputs`. The caller should build `cond_graph` and
// `body_graph` starting from the inputs, and store the final outputs in
// `cond_output` and `body_outputs`.
//
// If `status` is OK, the caller must call either TF_FinishWhile or
// TF_AbortWhile on the returned TF_WhileParams. If `status` isn't OK, the
// returned TF_WhileParams is not valid, and the caller should not call
// TF_FinishWhile() or TF_AbortWhile().
//
// Missing functionality (TODO):
// - Gradients (not yet implmented for any ops)
// - Reference-type inputs
// - Directly referencing external tensors from the cond/body graphs (this is
// possible in the Python API)
TF_WhileParams TF_NewWhile(TF_Graph* g, TF_Output* inputs, int ninputs,
TF_Status* status);
// Builds the while loop specified by `params` and returns the output tensors of
// the while loop in `outputs`. `outputs` should be allocated to size
// `params.ninputs`.
//
// `params` is no longer valid once this returns.
//
// Either this or TF_AbortWhile() must be called after a successful
// TF_NewWhile() call.
void TF_FinishWhile(const TF_WhileParams* params, TF_Status* status,
TF_Output* outputs);
// Frees `params`s resources without building a while loop. `params` is no
// longer valid after this returns. Either this or TF_FinishWhile() must be
// called after a successful TF_NewWhile() call.
void TF_AbortWhile(const TF_WhileParams* params);
// 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.
}
{ // TF_Session
// --------------------------------------------------------------------------
// API for driving Graph execution. 用于驱动图执行的 API。
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.
// *graph 必须是有效的图形(没有被删除或是空指针)。
// 此函数将阻止在 TF_DeleteSession() 被调用之前 graph 被删除。
extern TF_Session* TF_NewSession(TF_Graph* graph, const TF_SessionOptions* opts,
TF_Status* status);
// 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`.
// 该函数使用 `session_options` 创建一个新的 TF_Session(成功创建),
// 然后使用 `run_options` 初始化状态(恢复 tensors 和其他 assets)。
// 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);
// 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]).
// 从提供的输入开始,运行与会话关联的图形(以输入 [0,ninputs-1] 与 input_values[0,ninputs-1] 中的相应值)
//
// Any NULL and non-NULL value combinations for (`run_options`,
// `run_metadata`) are valid.
// 对于 (`run_options`,`run_metadata`) 的任何 NULL 和非 NULL 值组合都是有效的。
//
// - `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.
// - `run_options` 可能是 NULL,在这种情况下会被忽略;或非 NULL,在这种情况下,它必须指向包含`RunOptions` 协议缓冲区的序列化表示的 `TF_Buffer` 。
// - `run_metadata` 可能是 NULL,在这种情况下它将被忽略;或非 NULL,在这种情况下,它必须指向一个空的新分配的 `TF_Buffer`,可以被更新为包含 `RunMetadata` 协议缓冲区的序列化表示。
//
// 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.
// 调用者保留 `input_values` 的所有权(可以使用 TF_DeleteTensor 进行删除)。调用者还保留 `run_options` 和/或 `run_metadata` 的所有权(当不为 NULL 时),并应手动调用 TF_DeleteBuffer。
//
// 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.
// 成功后,对应于输出 [0,noutputs-1] 的张量放在 output_values[] 中。 output_values [] 的元素的所有权转移给调用者,调用者必须最终在其上调用 TF_DeleteTensor。
//
// On failure, output_values[] contains NULLs.
// 失败时,output_values[] 包含NULL
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.
// 设置使用预期的 Feed(输入)和读取(输出)的 graph,为一个队列的部分运行调用。
// On success, returns a handle that is used for subsequent PRun calls. The
// handle should be deleted with TF_DeletePRunHandle when it is no longer
// needed.
//
// 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.
// 继续使用附加的 Feed 和 fetches 来运行图形。
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*);
// Deletes a handle allocated by TF_SessionPRunSetup.
// Once called, no more calls to TF_SessionPRun should be made.
extern void TF_DeletePRunHandle(const char* handle);
}
{ // The deprecated session API. 已弃用的 session API
// --------------------------------------------------------------------------
// The deprecated session API. Please switch to the above instead of
// TF_ExtendGraph(). This deprecated API can be removed at any time without
// notice.
// 已弃用的会话API。 请切换到上面,而不是 TF_ExtendGraph() 。 这个不推荐的API可以随时被删除,恕不另行通知。
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.
// 更推荐使用 TF_Session 和 TF_GraphImportGraphDef
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_