1/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14==============================================================================*/
15#ifndef TENSORFLOW_C_EAGER_C_API_UNIFIED_EXPERIMENTAL_H_
16#define TENSORFLOW_C_EAGER_C_API_UNIFIED_EXPERIMENTAL_H_
17
18#include "tensorflow/c/eager/c_api.h"
19#include "tensorflow/c/tf_datatype.h"
20#include "tensorflow/c/tf_status.h"
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26// =============================================================================
27// Unified Execution APIs for Eager and tracing backends.
28// =============================================================================
29
30// -----------------------------------------------------------------------------
31// Core APIs
32// -----------------------------------------------------------------------------
33
34// A TF_ExecutionContext stores knowledge about how to execute an operation.
35// E.g. it could know whether we're in eager mode or graph mode, keeps track
36// of gradient tapes, etc.
37typedef struct TF_ExecutionContext TF_ExecutionContext;
38
39// A TF_AbstractTensor is an input to an operation. E.g. it could be a union
40// type of eager and graph tensors. It is also the result of executing an
41// operation.
42typedef struct TF_AbstractTensor TF_AbstractTensor;
43
44// A TF_AbstractOp is the metadata we need to execute an operation. E.g. this
45// could contain the op type and other attributes.
46typedef struct TF_AbstractOp TF_AbstractOp;
47
48// Stores a function representation that can be used for execution or for
49// setting functional attributes of other composite ops e.g. control flow.
50typedef struct TF_AbstractFunction TF_AbstractFunction;
51
52// This allows the client to swap the implementation of the tracing engine.
53// Any future call to TF_CreateFunction will use the implementation defined
54// here.
55void TF_SetTracingImplementation(const char* name, TF_Status*);
56
57// Creates a new TensorFlow function. A Function is an execution context, and as
58// such it can trace operations through TF_ExecuteOperation. After completing
59// tracing, a function can be obtained by TF_FinalizeFunction.
60TF_ExecutionContext* TF_CreateFunction(const char* fn_name, TF_Status* status);
61
62// Creates a context for eager execution of operations.
63TF_ExecutionContext* TF_NewEagerExecutionContext(TFE_ContextOptions*,
64 TF_Status* s);
65void TF_DeleteExecutionContext(TF_ExecutionContext*);
66
67// Represents a (partially-defined) shape.
68typedef struct TF_Shape {
69 int num_dims; // Must be >= -1; -1 represents unknown rank.
70 int64_t* dim_sizes;
71} TF_Shape;
72
73// Add a new parameter to a TensorFlow Function.
74TF_AbstractTensor* TF_AddFunctionParameter(TF_ExecutionContext* func,
75 TF_DataType dtype, TF_Shape shape,
76 TF_Status* s);
77
78// Create an operation suitable to use with the provided context. The operation
79// requires its type (e.g. "AddV2") to be set independently.
80TF_AbstractOp* TF_NewAbstractOp(TF_ExecutionContext* ctx);
81void TF_DeleteAbstractOp(TF_AbstractOp*);
82
83// TODO(srbs): Add APIs for specifying attrs etc.
84// `op_type` must outlive `op`.
85void TF_AbstractOpSetOpType(TF_AbstractOp* op, const char* const op_type,
86 TF_Status* s);
87// `op_name` must outlive `op`.
88void TF_AbstractOpSetOpName(TF_AbstractOp* op, const char* const op_name,
89 TF_Status* s);
90// `attr_name` must outlive `op`.
91void TF_AbstractOpSetAttrType(TF_AbstractOp* op, const char* const attr_name,
92 TF_DataType value, TF_Status* s);
93
94void TF_DeleteAbstractTensor(TF_AbstractTensor*);
95
96// TF_OutputList holds the list of TF_AbstractTensor that results from executing
97// an operation, or provided to create a function.
98// When executing an operation in an eager context, the expected number of
99// outputs must be set beforehand with `TF_OutputListSetNumOutputs`.
100typedef struct TF_OutputList TF_OutputList;
101TF_OutputList* TF_NewOutputList();
102void TF_DeleteOutputList(TF_OutputList* o);
103// Prepare tracing to the expected number of output for an operation.
104void TF_OutputListSetNumOutputs(TF_OutputList* o, int num_outputs, TF_Status*);
105// Return the number of outputs in the list.
106int TF_OutputListNumOutputs(TF_OutputList* o);
107// Return the `i`th output in the list.
108TF_AbstractTensor* TF_OutputListGet(TF_OutputList* o, int i);
109// Append a tensor at the end of the output list, growing its size by one.
110void TF_OutputListPushBack(TF_OutputList* o, TF_AbstractTensor* tensor,
111 TF_Status*);
112
113// TF_ExecuteOperation will, if in eager mode, execute, if in graph mode, maybe
114// capture some inputs and then add a node in the graph. The output tensors are
115// returned through the provided TF_OutputList.
116// Any active tape will observe the effects of this execution.
117void TF_ExecuteOperation(TF_AbstractOp* op, int num_inputs,
118 TF_AbstractTensor* const* inputs, TF_OutputList* o,
119 TF_Status* s);
120
121// Creates a new TF_AbstractFunction from the current tracing states in the
122// context. The provided `ctx` is consumed by this API call and deleted.
123// The returned TF_AbstractFunction must be deleted by the client,
124// TODO(aminim): clarify the contract on the state of the context after this
125// call.
126TF_AbstractFunction* TF_FinalizeFunction(TF_ExecutionContext* ctx,
127 TF_OutputList*, TF_Status*);
128
129void TF_DeleteAbstractFunction(TF_AbstractFunction*);
130
131// Register the function with the given context. This is particularly useful for
132// making a function available to an eager context.
133void TF_ExecutionContextRegisterFunction(TF_ExecutionContext*,
134 TF_AbstractFunction*, TF_Status*);
135
136// -----------------------------------------------------------------------------
137// APIs specific to Eager modes
138// -----------------------------------------------------------------------------
139
140// Temporary APIs till we figure out how to create scalar valued Eager
141// tensors and how to get value out of eager abstract tensors.
142TF_AbstractTensor* TF_CreateAbstractTensorFromEagerTensor(TFE_TensorHandle* t,
143 TF_Status* s);
144TFE_TensorHandle* TF_AbstractTensorGetEagerTensor(TF_AbstractTensor* at,
145 TF_Status* s);
146TFE_Context* TF_ExecutionContextGetTFEContext(TF_ExecutionContext*,
147 TF_Status* s);
148
149#ifdef __cplusplus
150} /* end extern "C" */
151#endif
152
153#endif // TENSORFLOW_C_EAGER_C_API_UNIFIED_EXPERIMENTAL_H_
154