1 /* Copyright 2021 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_EXPERIMENTAL_GRAPPLER_GRAPPLER_H_ 16 #define TENSORFLOW_C_EXPERIMENTAL_GRAPPLER_GRAPPLER_H_ 17 18 #include <stddef.h> 19 #include <stdint.h> 20 21 #include "tensorflow/c/c_api.h" 22 #include "tensorflow/c/c_api_macros.h" 23 #include "tensorflow/c/tf_status.h" 24 25 // -------------------------------------------------------------------------- 26 // C API for Graph. The API is under active development and eventually 27 // should allow registering a plugin graph optimizer with TensorFlow. 28 // 29 // Conventions: 30 // * Struct prefix indicates whether struct fields should be filled by the 31 // plugin or core implementation: 32 // * Struct that should be filled by the plugin: `TP_OptimizerConfigs`, 33 // `TP_Optimizer`, `TP_OptimizerRegistrationParams` 34 // * Struct that should be filled by the proper: `TF_GrapplerItem`, 35 // `TF_GraphProperties`, `TF_FunctionLibraryDefinition` 36 // * We use `struct_size` for version checking. It should be set both by 37 // core and the plugin. 38 // * For example, `TF_InitGraph` function receives 39 // `TP_OptimizerRegistrationParams*` as input with `struct_size` 40 // populated by core. The plugin is responsible for setting 41 // `struct_size` as well, along with all other fields. 42 // * Refer to "TensorFlow Versioning Strategy" section at 43 // https://github.com/tensorflow/community/pull/257/files. 44 // * Note that the API is still under active development and doesn't have 45 // versioning guarantees yet. 46 // * `void* ext` is a free-form field that can be populated by 47 // a plugin in `TP_*` structs or potential future extension points . 48 // 49 // Example usage: 50 // 51 // /* Sample TensorFlow code below, exact implementation might differ. */ 52 // // Version checking uses `struct_size`. It should be set both by core 53 // // and the plugin. 54 // TP_OptimizerRegistrationParams params{ 55 // TP_OPTIMIZER_REGISTRATION_PARAMS_STRUCT_SIZE}; 56 // TP_Optimizer optimizer{TP_OPTIMIZER_STRUCT_SIZE}; 57 // TP_OptimizerConfigs configs{TP_OPTIMIZER_CONFIGS_STRUCT_SIZE}; 58 // params.optimizer = &optimizer; 59 // params.configs = &configs; 60 // 61 // /* Plugin code below */ 62 // void TF_InitGraph(TP_OptimizerRegistrationParams* params, 63 // TF_Status* status) { 64 // params->struct_size = TP_OPTIMIZER_REGISTRATION_PARAMS_STRUCT_SIZE; 65 // params->device_type = "MY_DEVICE"; 66 // 67 // // Disable certain optimizer. 68 // params->optimizer_configs->struct_size = 69 // TP_OPTIMIZER_CONFIGS_STRUCT_SIZE; params->optimizer_configs->remapping = 70 // TF_TriState_Off; 71 // 72 // // Set functions to create a new optimizer. 73 // params->optimizer->struct_size = TP_OPTIMIZER_STRUCT_SIZE; 74 // params->optimizer->create_func = (My_optimizer::create_func); 75 // } 76 77 #define GO_MAJOR 0 78 #define GO_MINOR 0 79 #define GO_PATCH 1 80 81 #ifdef __cplusplus 82 extern "C" { 83 #endif 84 85 // TF_TriState is the C API typedef for tri-state. 86 typedef enum TF_TriState { 87 TF_TriState_Default = 0, 88 TF_TriState_Off, 89 TF_TriState_On, 90 } TF_TriState; 91 92 // TF_GrapplerItem represents a combination of a graph, one of more fetch nodes, 93 // and potentially a set of nodes to feed. 94 typedef struct TF_GrapplerItem TF_GrapplerItem; 95 96 // Flags indicating whether existing optimizers should be turned off. 97 // It's optional for plugin to set functions to return true/false. If not 98 // set, proper uses configuration set by user. 99 typedef struct TP_OptimizerConfigs { 100 size_t struct_size; 101 void* ext; // reserved for future use 102 TF_TriState disable_model_pruning; 103 TF_TriState implementation_selector; 104 TF_TriState function_optimization; 105 TF_TriState common_subgraph_elimination; 106 TF_TriState arithmetic_optimization; 107 TF_TriState debug_stripper; 108 TF_TriState constant_folding; 109 TF_TriState shape_optimization; 110 TF_TriState auto_mixed_precision; 111 TF_TriState auto_mixed_precision_mkl; 112 TF_TriState pin_to_host_optimization; 113 TF_TriState layout_optimizer; 114 TF_TriState remapping; 115 TF_TriState loop_optimization; 116 TF_TriState dependency_optimization; 117 TF_TriState auto_parallel; 118 TF_TriState memory_optimization; 119 TF_TriState scoped_allocator_optimization; 120 } TP_OptimizerConfigs; 121 122 #define TP_OPTIMIZER_CONFIGS_STRUCT_SIZE \ 123 TF_OFFSET_OF_END(TP_OptimizerConfigs, scoped_allocator_optimization) 124 125 // Struct for Optimizer. Plugin authors must provide an optimize function. 126 // Creation and deletion functions are optional. 127 typedef struct TP_Optimizer { 128 size_t struct_size; 129 void* ext; // reserved for future use 130 131 // [Optional] 132 // Create function for optimizer. 133 void* (*create_func)(); 134 135 // Optimizer function for optimizer. The first param is an optimizer created 136 // by create_func. The second param is input graph. The third param is 137 // GrapplerItem. The fourth param is output graph. 138 void (*optimize_func)(void*, const TF_Buffer*, const TF_GrapplerItem*, 139 TF_Buffer*, TF_Status*); 140 141 // [Optional] 142 // Destroy function for optimizer. If Create function is provided, destroy 143 // function is must. 144 void (*destroy_func)(void*); 145 } TP_Optimizer; 146 147 #define TP_OPTIMIZER_STRUCT_SIZE TF_OFFSET_OF_END(TP_Optimizer, destroy_func) 148 149 typedef struct TP_OptimizerRegistrationParams { 150 size_t struct_size; 151 void* ext; // reserved for future use 152 153 // Graph C API version. 154 int32_t major_version; 155 int32_t minor_version; 156 int32_t patch_version; 157 158 // Backend device type supported by the optimizer. 159 const char* device_type; 160 TP_OptimizerConfigs* optimizer_configs; // output, set by plugin 161 TP_Optimizer* optimizer; // output, set by plugin 162 } TP_OptimizerRegistrationParams; 163 164 #define TP_OPTIMIZER_REGISTRATION_PARAMS_STRUCT_SIZE \ 165 TF_OFFSET_OF_END(TP_OptimizerRegistrationParams, optimizer) 166 167 // TF_InitGraph is used to do graph optimizer registration. 168 // Plugin should implement TF_InitGraph to register graph optimizers. 169 void TF_InitGraph(TP_OptimizerRegistrationParams* params, TF_Status* status); 170 171 // Get a set of node names that must be preserved. They can not be transformed 172 // or removed during the graph transformation. This includes feed and fetch 173 // nodes, keep_ops, init_ops. Fills in `num_values` and `storage_size`, they 174 // will be used in `TF_GetNodesToPreserveList`. 175 void TF_GetNodesToPreserveListSize(const TF_GrapplerItem* item, int* num_values, 176 size_t* storage_size, TF_Status* status); 177 178 // Get a set of node names that must be preserved. They can not be transformed 179 // or removed during the graph transformation. This includes feed and fetch 180 // nodes, keep_ops, init_ops. Fills in `values` and `lengths`, each of which 181 // must point to an array of length at least `num_values`. 182 // 183 // The elements of values will point to addresses in `storage` which must be at 184 // least `storage_size` bytes in length. `num_values` and `storage` can be 185 // obtained from TF_GetNodesToPreserveSize 186 // 187 // Fails if storage_size is too small to hold the requested number of strings. 188 void TF_GetNodesToPreserveList(const TF_GrapplerItem* item, char** values, 189 size_t* lengths, int num_values, void* storage, 190 size_t storage_size, TF_Status* status); 191 192 // Get a set of node names for fetch nodes. Fills in `values` and `lengths`, 193 // they will be used in `TF_GetFetchNodesList` 194 void TF_GetFetchNodesListSize(const TF_GrapplerItem* item, int* num_values, 195 size_t* storage_size, TF_Status* status); 196 197 // Get a set of node names for fetch nodes. Fills in `values` and `lengths`, 198 // each of which must point to an array of length at least `num_values`. 199 // 200 // The elements of values will point to addresses in `storage` which must be at 201 // least `storage_size` bytes in length. `num_values` and `storage` can be 202 // obtained from TF_GetFetchNodesSize 203 // 204 // Fails if storage_size is too small to hold the requested number of strings. 205 void TF_GetFetchNodesList(const TF_GrapplerItem* item, char** values, 206 size_t* lengths, int num_values, void* storage, 207 size_t storage_size, TF_Status* status); 208 209 // Infer OpInfo::TensorProperties for graph nodes inputs/outputs. 210 // 211 // Typical use case, is to infer tensor properties from a graph, before doing 212 // optimization pass. Nodes modified during optimization pass have to be 213 // invalidated, to prevent further incorrect optimizations based on wrong shape 214 // and data type properties. 215 typedef struct TF_GraphProperties TF_GraphProperties; 216 217 // Create GraphProperties. The item must outlive the properties. 218 TF_GraphProperties* TF_NewGraphProperties(const TF_GrapplerItem* item); 219 220 // Delete GraphProperties. 221 void TF_DeleteGraphProperties(TF_GraphProperties* graph_properties); 222 223 // Infer tensor shapes through abstract interpretation. 224 // If assume_valid_feeds is true, it can help infer shapes in the fanout of fed 225 // nodes. This may cause incorrectness in graph analyses, but is useful for 226 // simulation or scheduling. 227 // If aggressive_shape_inference is true, nodes are executed on the host to 228 // identify output values when possible and does other aggressive strategies. 229 // This may cause incorrectness in graph analyses, but is useful for simulation 230 // or scheduling. 231 // If include_input_tensor_values is true, the values of constant 232 // tensors will included in the input properties. 233 // If include_output_tensor_values is true, the values of constant tensors will 234 // be included in the output properties. 235 void TF_InferStatically(TF_GraphProperties* graph_properties, 236 TF_Bool assume_valid_feeds, 237 TF_Bool aggressive_shape_inference, 238 TF_Bool include_input_tensor_values, 239 TF_Bool include_output_tensor_values, TF_Status* s); 240 241 // Get the size of input OpInfo::TensorProperties given node name. 242 void TF_GetInputPropertiesListSize(TF_GraphProperties* graph_properties, 243 const char* name, int* num_values, 244 TF_Status* status); 245 246 // Get the size of output OpInfo::TensorProperties given node name. 247 void TF_GetOutputPropertiesListSize(TF_GraphProperties* graph_properties, 248 const char* name, int* num_values, 249 TF_Status* status); 250 251 // Get a list of input OpInfo::TensorProperties given node name. 252 // Return the serialized list `properties`. 253 void TF_GetInputPropertiesList(TF_GraphProperties* graph_properties, 254 const char* name, TF_Buffer** properties, 255 int num_values, TF_Status* status); 256 257 // Get a list of output OpInfo::TensorProperties given node name. 258 // Return the serialized list `properties`. 259 void TF_GetOutputPropertiesList(TF_GraphProperties* graph_properties, 260 const char* name, TF_Buffer** properties, 261 int num_values, TF_Status* status); 262 263 // Helper to maintain a map between function names in a given 264 // FunctionDefLibrary and function definitions. 265 // Typical use case, is to look up an OpDef by type name. 266 typedef struct TF_FunctionLibraryDefinition TF_FunctionLibraryDefinition; 267 268 // Create NewFunctionLibraryDefinition. 269 TF_FunctionLibraryDefinition* TF_NewFunctionLibraryDefinition( 270 TF_Buffer* graph_buf, TF_Status* status); 271 272 // Delete NewFunctionLibraryDefinition. 273 void TF_DeleteFunctionLibraryDefinition(TF_FunctionLibraryDefinition* fn_lib); 274 275 // Shorthand for calling LookUp to get the OpDef from FunctionLibraryDefinition 276 // given op name. The returned OpDef is represented by TF_Buffer. 277 void TF_LookUpOpDef(TF_FunctionLibraryDefinition* fn_lib, const char* name, 278 TF_Buffer* buf, TF_Status* s); 279 280 #ifdef __cplusplus 281 } // extern "C" 282 #endif 283 284 #endif // TENSORFLOW_C_EXPERIMENTAL_GRAPPLER_GRAPPLER_H_ 285