1 | /* Copyright 2020 The TensorFlow Authors. All Rights Reserved. |
2 | |
3 | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | you may not use this file except in compliance with the License. |
5 | You may obtain a copy of the License at |
6 | |
7 | http://www.apache.org/licenses/LICENSE-2.0 |
8 | |
9 | Unless required by applicable law or agreed to in writing, software |
10 | distributed under the License is distributed on an "AS IS" BASIS, |
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | See the License for the specific language governing permissions and |
13 | limitations under the License. |
14 | ==============================================================================*/ |
15 | #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 |
23 | extern "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. |
37 | typedef 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. |
42 | typedef 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. |
46 | typedef 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. |
50 | typedef 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. |
55 | void 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. |
60 | TF_ExecutionContext* TF_CreateFunction(const char* fn_name, TF_Status* status); |
61 | |
62 | // Creates a context for eager execution of operations. |
63 | TF_ExecutionContext* TF_NewEagerExecutionContext(TFE_ContextOptions*, |
64 | TF_Status* s); |
65 | void TF_DeleteExecutionContext(TF_ExecutionContext*); |
66 | |
67 | // Represents a (partially-defined) shape. |
68 | typedef 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. |
74 | TF_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. |
80 | TF_AbstractOp* TF_NewAbstractOp(TF_ExecutionContext* ctx); |
81 | void TF_DeleteAbstractOp(TF_AbstractOp*); |
82 | |
83 | // TODO(srbs): Add APIs for specifying attrs etc. |
84 | // `op_type` must outlive `op`. |
85 | void TF_AbstractOpSetOpType(TF_AbstractOp* op, const char* const op_type, |
86 | TF_Status* s); |
87 | // `op_name` must outlive `op`. |
88 | void TF_AbstractOpSetOpName(TF_AbstractOp* op, const char* const op_name, |
89 | TF_Status* s); |
90 | // `attr_name` must outlive `op`. |
91 | void TF_AbstractOpSetAttrType(TF_AbstractOp* op, const char* const attr_name, |
92 | TF_DataType value, TF_Status* s); |
93 | |
94 | void 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`. |
100 | typedef struct TF_OutputList TF_OutputList; |
101 | TF_OutputList* TF_NewOutputList(); |
102 | void TF_DeleteOutputList(TF_OutputList* o); |
103 | // Prepare tracing to the expected number of output for an operation. |
104 | void TF_OutputListSetNumOutputs(TF_OutputList* o, int num_outputs, TF_Status*); |
105 | // Return the number of outputs in the list. |
106 | int TF_OutputListNumOutputs(TF_OutputList* o); |
107 | // Return the `i`th output in the list. |
108 | TF_AbstractTensor* TF_OutputListGet(TF_OutputList* o, int i); |
109 | // Append a tensor at the end of the output list, growing its size by one. |
110 | void 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. |
117 | void 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. |
126 | TF_AbstractFunction* TF_FinalizeFunction(TF_ExecutionContext* ctx, |
127 | TF_OutputList*, TF_Status*); |
128 | |
129 | void 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. |
133 | void 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. |
142 | TF_AbstractTensor* TF_CreateAbstractTensorFromEagerTensor(TFE_TensorHandle* t, |
143 | TF_Status* s); |
144 | TFE_TensorHandle* TF_AbstractTensorGetEagerTensor(TF_AbstractTensor* at, |
145 | TF_Status* s); |
146 | TFE_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 | |