Tensorflow C++
class member functions C++ API
Note: By default, tensorflow.org shows docs for the most recent stable version. The instructions in this doc require building from the source. You will probably want to build from the master
version of tensorflow. You should, as a result, be sure you are following the
master
version of this doc, in case there have been any changes.
[TOC]
TensorFlow's C++ API provides mechanisms for constructing and executing a data flow graph. The API is designed to be simple and concise: graph operations are clearly expressed using a "functional" construction style, including easy specification of names, device placement, etc., and the resulting graph can be efficiently run and the desired outputs fetched in a few lines of code. This guide explains the basic concepts and data structures needed to get started with TensorFlow graph construction and execution in C++.
The Basics
Let's start with a simple example that illustrates graph construction and execution using the C++ API.
Place this example code in the file tensorflow/cc/example/example.cc
inside a clone of the TensorFlow github repository. Also, place aBUILD
file in the same directory with the following contents:
Use tf_cc_binary
rather than Bazel's native cc_binary
to link in necessary symbols from libtensorflow_framework.so
. You should be able to build and run the example using the following command (be sure to run ./configure
in your build sandbox first):
This example shows some of the important features of the C++ API, such as the following:
Constructing tensor constants from C++ nested initializer lists
Constructing and naming of TensorFlow operations
Specifying optional attributes to operation constructors
Executing and fetching the tensor values from the TensorFlow session.
We will delve into the details of each below.
Graph Construction
Scope
The Scope
object returned by Scope::NewRootScope
is referred to as the root scope. "Child" scopes can be constructed from the root scope by calling various member functions of the Scope
class, thus forming a hierarchy of scopes. A child scope inherits all of the properties of the parent scope and typically has one property added or changed. For instance, NewSubScope(name)
appends name
to the prefix of names for operations created using the returnedScope
object.
Here are some of the properties controlled by a Scope
object:
Operation names
Set of control dependencies for an operation
Device placement for an operation
Kernel attribute for an operation
Operation Constructors
You can create graph operations with operation constructors, one C++ class per TensorFlow operation. Unlike the Python API, which uses snake-case to name the operation constructors, the C++ API uses camel-case to conform to the C++ coding style. For instance, the MatMul the
operation has a C++ class with the same name.
Using this class-per-operation method, it is possible, though not recommended, to construct an operation as follows:
Instead, we recommend the following "functional" style for constructing operations:
The first parameter for all operation constructors is always an Scope
object. Tensor inputs and mandatory attributes from the rest of the arguments.
For optional arguments, constructors have an optional parameter that allows optional attributes. For operations with optional arguments, the constructor's last optional parameter is a struct
type called [operation]:Attrs
that contains data members for each optional attribute. You can construct suchAttrs
in multiple ways:
You can specify a single optional attribute by constructing an
Attrs
object using thestatic
functions provided in the C++ class for the operation. For example:
You can specify multiple optional attributes by chaining together functions available in the
Attrs
struct. For example:
The arguments and return values of operations are handled in different ways depending on their type:
For operations that return single tensors, the object returned by the operation object can be passed directly to other operation constructors. For example:
For operations producing multiple outputs, the object returned by the operation constructor has a member for each of the outputs. The names of those members are identical to the names present in the
OpDef
for the operation. For example:
Operations producing a list-typed output return an object that can be indexed using the
[]
operator. That object can also be directly passed to other constructors that expect list-typed inputs. For example:
Constants
Scalars
Nested initializer lists
Shapes explicitly specified
You may directly pass constants to other operation constructors, either by explicitly constructing one using the Const
function, or implicitly as any of the above types of C++ values. For example:
Graph Execution
Similarly, the object returned by the operation constructor can be used as the argument to specify a value being fed when executing the graph. Furthermore, the value to feed can be specified with the different kinds of C++ values used to specify tensor constants. For example:
Last updated