• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 in 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