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_PLUGGABLE_PROFILER_PLUGGABLE_PROFILER_H_ 16 #define TENSORFLOW_C_EXPERIMENTAL_PLUGGABLE_PROFILER_PLUGGABLE_PROFILER_H_ 17 #include <stddef.h> 18 #include <stdint.h> 19 20 #include "tensorflow/c/c_api_macros.h" 21 #include "tensorflow/c/tf_status.h" 22 23 // C API for Pluggable Profiler. The API is under active development and 24 // eventually should allow registering a profiler with TensorFlow. 25 // 26 // Conventions: 27 // * Struct prefix indicates whether struct fields should be filled by the 28 // plug-in or core TensorFlow implementation: 29 // * TF_: Set/filled by core, unless marked otherwise. 30 // * TP_: Set/filled by plug-in, unless marked otherwise. 31 // * This prefix rule only applies to structures. Enumerations and methods 32 // are all prefixed with TP_. 33 // * Structs begin with two fields: 34 // * size_t struct_size: Stores the unpadded size of the struct. 35 // * void* ext: A reserved field that may be populated by a plugin in TP_* 36 // structs or potential future extension points in TF_ structs. Must be set 37 // to zero by default if it unused. 38 // * We use struct_size for version checking by both core and plug-in. 39 // * It is exempt from the TF/TP rule above and must be set both by core and 40 // plug-in. 41 // * It can be checked programmatically to determine which struct fields are 42 // available in the structure. 43 // * When a member is added to a struct, the struct size definition must be 44 // updated to use the new last member of the struct. 45 // 46 // Example usage: 47 // /* Sample TensorFlow code below, exact implementation might differ. */ 48 // // Version checking uses `struct_size`. It is exempt from the `TF/TP` rule 49 // // above and should be set both by core and the plugin." 50 // 51 // /* Plugin code below */ 52 // void profiler_start(const TP_Profiler* profiler, TF_Status* status) { 53 // /* Enable profiler */ 54 // ... 55 // } 56 // 57 // void profiler_stop(const TP_Profiler* profiler, TF_Status* status) { 58 // /* Disable Profiler */ 59 // ... 60 // } 61 // 62 // void profiler_collect_data_xspace(const TP_Profiler* profiler, uint8_t* 63 // buffer, size_t* size_in_bytes, TF_Status* status) { 64 // /* Plugin generates Xspace based on collected profiler data. */ 65 // Xspace xspace = get_my_xspace(); 66 // size_t buffer_size_in_bytes = *size_in_bytes; 67 // *size_in_bytes = xspace.ByteSizeLong(); /* get the size of Xspace */ 68 // if (buffer == nullptr) { 69 // /* TensorFlow will first get the size of Xspace, then allocate the big 70 // enough buffer and pass it to the plugin for retrieving Xspace. */ 71 // return; 72 // } 73 // bool success = xspace.SerializeToArray(buffer, buffer_size_in_bytes); 74 // } 75 // 76 // void TF_InitProfiler(TF_ProfilerRegistrationParams* params, TF_Status* 77 // status) { 78 // *params = { TF_PROFILER_REGISTRATION_PARAMS_STRUCT_SIZE }; 79 // params->profiler->struct_size = TP_PROFILER_STRUCT_SIZE; 80 // params->profiler_fns->struct_size = TP_PROFILER_FNS_STRUCT_SIZE; 81 // 82 // params->profiler->type = "MyDeviceType"; 83 // 84 // params->profiler_fns->start = profiler_start; 85 // params->profiler_fns->stop = profiler_stop; 86 // params->profiler_fns->collect_data_xspace = profiler_collect_data_xspace; 87 // params->destroy_profiler = profiler_destroy_profiler; 88 // params->destroy_profiler_fns = profiler_destroy_profiler_fns; 89 // } 90 91 #define TP_MAJOR 0 92 #define TP_MINOR 0 93 #define TP_PATCH 1 94 95 #ifdef __cplusplus 96 extern "C" { 97 #endif 98 99 // -------------------------------------------------------------------------- 100 // TP_Profiler holds a pointer to device type filed by the plug-in. 101 typedef struct TP_Profiler { 102 size_t struct_size; 103 void* ext; // free-form data set by plugin. 104 const char* device_type; 105 106 // The struct size must be updated when adding new members. 107 #define TP_PROFILER_STRUCT_SIZE TF_OFFSET_OF_END(TP_Profiler, device_type) 108 } TP_Profiler; 109 110 // -------------------------------------------------------------------------- 111 // TP_ProfilerFns holds the profiler interface function pointers filled by the 112 // plug-in. 113 typedef struct TP_ProfilerFns { 114 size_t struct_size; 115 116 void* ext; // reserved for future use. 117 // Starts profiling. 118 void (*start)(const TP_Profiler* profiler, TF_Status* status); 119 // Stops profiling. 120 void (*stop)(const TP_Profiler* profiler, TF_Status* status); 121 122 // Saves collected profile data into XSpace and serializes it to the buffer. 123 // - If `buffer` is null, returns the required buffer size in `size_in_bytes`. 124 // - If `buffer` is not null and `size_in_bytes` is the required buffer size, 125 // `buffer` is populated with profile data in serialized XSpace format. 126 // 127 // Only the first call with a non-null `buffer` following successful calls to 128 // start and stop might return data. Subsequent calls might return empty data 129 // unless start and stop are successfully called again. 130 void (*collect_data_xspace)(const TP_Profiler* profiler, uint8_t* buffer, 131 size_t* size_in_bytes, TF_Status* status); 132 133 // The struct size must be updated when adding new members. 134 #define TP_PROFILER_FNS_STRUCT_SIZE \ 135 TF_OFFSET_OF_END(TP_ProfilerFns, collect_data_xspace) 136 } TP_ProfilerFns; 137 138 // TF_ProfilerRegistrationParams holds the pointers to TP_Profiler and 139 // TP_ProfilerFns, the memory of TP_Profiler and TP_ProfilerFns is owned by Core 140 // TensorFlow and populated by the plug-in. 141 typedef struct TF_ProfilerRegistrationParams { 142 size_t struct_size; 143 void* ext; // reserved for future use 144 145 // TensorFlow Profiler C API version. 146 int32_t major_version; 147 int32_t minor_version; 148 int32_t patch_version; 149 150 // [in/out] Memory owned by core but attributes within are populated by the 151 // plugin. 152 TP_Profiler* profiler; 153 // [in/out] Memory owned by core but attributes within are populated by the 154 // plugin. 155 TP_ProfilerFns* profiler_fns; 156 // [out] Pointer to plugin's `TP_Profiler` clean up function. 157 // Cleans up fields inside `TP_Profiler` that were allocated 158 // by the plugin. `profiler` itself must not be deleted by the plugin. 159 void (*destroy_profiler)(TP_Profiler* profiler); 160 // [out] Pointer to plugin's `TP_ProfilerFns` clean up function. 161 // Cleans up fields inside `TP_ProfilerFns` that were allocated 162 // by the plugin. `profiler_fns` itself must not be deleted by the plugin. 163 void (*destroy_profiler_fns)(TP_ProfilerFns* profiler_fns); 164 165 // The struct size must be updated when adding new members. 166 #define TF_PROFILER_REGISTRATION_PARAMS_STRUCT_SIZE \ 167 TF_OFFSET_OF_END(TF_ProfilerRegistrationParams, destroy_profiler_fns) 168 } TF_ProfilerRegistrationParams; 169 170 // TF_InitProfiler to do profiler registration. 171 // Plug-in should implement TF_InitProfiler to register the profiler. 172 void TF_InitProfiler(TF_ProfilerRegistrationParams* params, TF_Status* status); 173 174 #ifdef __cplusplus 175 } // extern "C" 176 #endif 177 178 #endif // TENSORFLOW_C_EXPERIMENTAL_PLUGGABLE_PROFILER_PLUGGABLE_PROFILER_H_ 179