1 /* 2 * Copyright 2010-2016 Intel Corporation. 3 * 4 * This library is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU Lesser General Public License as published 6 * by the Free Software Foundation, version 2.1. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public 14 * License along with this library; if not, write to the Free Software 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16 * 02110-1301 USA. 17 * 18 * Disclaimer: The codes contained in these modules may be specific 19 * to the Intel Software Development Platform codenamed Knights Ferry, 20 * and the Intel product codenamed Knights Corner, and are not backward 21 * compatible with other Intel products. Additionally, Intel will NOT 22 * support the codes or instruction set in future products. 23 * 24 * Intel offers no warranty of any kind regarding the code. This code is 25 * licensed on an "AS IS" basis and Intel is not obligated to provide 26 * any support, assistance, installation, training, or other services 27 * of any kind. Intel is also not obligated to provide any updates, 28 * enhancements or extensions. Intel specifically disclaims any warranty 29 * of merchantability, non-infringement, fitness for any particular 30 * purpose, and any other warranty. 31 * 32 * Further, Intel disclaims all liability of any kind, including but 33 * not limited to liability for infringement of any proprietary rights, 34 * relating to the use of the code, even if Intel is notified of the 35 * possibility of such liability. Except as expressly stated in an Intel 36 * license agreement provided with this code and agreed upon with Intel, 37 * no license, express or implied, by estoppel or otherwise, to any 38 * intellectual property rights is granted herein. 39 */ 40 41 #ifndef _COIPIPELINE_SOURCE_H 42 #define _COIPIPELINE_SOURCE_H 43 44 /** @ingroup COIPipeline 45 * @addtogroup COIPipelineSource 46 @{ 47 * @file source/COIPipeline_source.h 48 */ 49 #ifndef DOXYGEN_SHOULD_SKIP_THIS 50 51 #include "../common/COITypes_common.h" 52 #include "../common/COIResult_common.h" 53 54 #ifdef __cplusplus 55 extern "C" { 56 #endif 57 #endif // DOXYGEN_SHOULD_SKIP_THIS 58 59 60 61 ////////////////////////////////////////////////////////////////////////////// 62 /// These flags specify how a buffer will be used within a run function. They 63 /// allow the runtime to make optimizations in how it moves the data around. 64 /// These flags can affect the correctness of an application, so they must be 65 /// set properly. For example, if a buffer is used in a run function with the 66 /// COI_SINK_READ flag and then mapped on the source, the runtime may use a 67 /// previously cached version of the buffer instead of retrieving data from 68 /// the sink. 69 typedef enum COI_ACCESS_FLAGS 70 { 71 /// Specifies that the run function will only read the associated buffer. 72 COI_SINK_READ = 1, 73 74 /// Specifies that the run function will write to the associated buffer. 75 COI_SINK_WRITE, 76 77 /// Specifies that the run function will overwrite the entire associated 78 /// buffer and therefore the buffer will not be synchronized with the 79 /// source before execution. 80 COI_SINK_WRITE_ENTIRE, 81 82 /// Specifies that the run function will only read the associated buffer 83 /// and will maintain the reference count on the buffer after 84 /// run function exit. 85 COI_SINK_READ_ADDREF, 86 87 /// Specifies that the run function will write to the associated buffer 88 /// and will maintain the reference count on the buffer after 89 /// run function exit. 90 COI_SINK_WRITE_ADDREF, 91 92 /// Specifies that the run function will overwrite the entire associated 93 /// buffer and therefore the buffer will not be synchronized with the 94 /// source before execution and will maintain the reference count on the 95 /// buffer after run function exit. 96 COI_SINK_WRITE_ENTIRE_ADDREF 97 } COI_ACCESS_FLAGS; 98 99 #define COI_PIPELINE_MAX_PIPELINES 512 100 #define COI_PIPELINE_MAX_IN_BUFFERS 16384 101 #define COI_PIPELINE_MAX_IN_MISC_DATA_LEN 32768 102 103 104 /////////////////////////////////////////////////////////////////////////////// 105 /// 106 /// Create a pipeline associated with a remote process. This pipeline can 107 /// then be used to execute remote functions and to share data using 108 /// COIBuffers. 109 /// 110 /// @param in_Process 111 /// [in] A handle to an already existing process that the pipeline 112 /// will be associated with. 113 /// 114 /// @param in_Mask 115 /// [in] An optional mask of the set of hardware threads on which the 116 /// sink pipeline command processing thread could run. 117 /// 118 /// @param in_StackSize 119 /// [in] An optional value that will be used when the pipeline 120 /// processing thread is created on the sink. If the user passes in 121 /// 0 the OS default stack size will be used. Otherwise the value 122 /// must be PTHREAD_STACK_MIN (16384) bytes or larger and must be 123 /// a multiple of a page (4096 bytes). 124 /// 125 /// @param out_pPipeline 126 /// [out] Handle returned to uniquely identify the pipeline that was 127 /// created for use in later API calls. 128 /// 129 /// 130 /// @return COI_SUCCESS if the pipeline was successfully created. 131 /// 132 /// @return COI_INVALID_HANDLE if the in_Process handle passed in was invalid. 133 /// 134 /// @return COI_INVALID_POINTER if the out_pPipeline pointer was NULL. 135 /// 136 /// @return COI_RESOURCE_EXHAUSTED if no more COIPipelines can be created. The 137 /// maximum number of pipelines allowed is COI_PIPELINE_MAX_PIPELINES. 138 /// It is recommended in most cases to not exceed the number of CPU's 139 /// that are reported on the offload device, performance will suffer. 140 /// 141 /// 142 /// @return COI_OUT_OF_RANGE if the in_StackSize > 0 && 143 /// in_StackSize < PTHREAD_STACK_MIN or if in_StackSize is not a 144 /// multiple of a page (4096 bytes). 145 /// 146 /// @return COI_OUT_OF_RANGE if the in_Mask is set to all zeroes. If no mask 147 /// is desired then the in_Mask should be passed as NULL, otherwise 148 /// at least one thread must be set. 149 /// 150 /// @return COI_TIME_OUT_REACHED if establishing the communication channel with 151 /// the remote pipeline timed out. 152 /// 153 /// @return COI_RETRY if the pipeline cannot be created due to the number of 154 /// source-to-sink connections in use. A subsequent call to 155 /// COIPipelineCreate may succeed if resources are freed up. 156 /// 157 /// @return COI_PROCESS_DIED if in_Process died. 158 /// 159 COIACCESSAPI 160 COIRESULT 161 COIPipelineCreate( 162 COIPROCESS in_Process, 163 COI_CPU_MASK in_Mask, 164 uint32_t in_StackSize, 165 COIPIPELINE *out_pPipeline); 166 167 /////////////////////////////////////////////////////////////////////////////// 168 /// 169 /// Destroys the indicated pipeline, releasing its resources. 170 /// 171 /// @param in_Pipeline 172 /// [in] Pipeline to destroy. 173 /// 174 /// 175 /// @return COI_SUCCESS if the pipeline was destroyed 176 /// 177 COIACCESSAPI 178 COIRESULT 179 COIPipelineDestroy( 180 COIPIPELINE in_Pipeline); 181 182 183 ////////////////////////////////////////////////////////////////////////////// 184 /// 185 /// Enqueues a function in the remote process binary to be executed. The 186 /// function execution is asynchronous in regards to the Source and all 187 /// run functions enqueued on a pipeline are executed in-order. The run 188 /// function will only execute when all of the required buffers are present 189 /// in the Sink's memory. 190 /// 191 /// Potential Hazards while using Runfunctions: 192 /// 193 /// 1. Proper care has to be taken while setting the input dependencies for 194 /// RunFunctions. Setting it incorrectly can lead to cyclic dependencies 195 /// and can cause the respective pipeline to stall. 196 /// 2. RunFunctions can also segfault if enough memory space is not available 197 /// on the sink for the buffers passed in. Buffers that are AddRef'd 198 /// need to be accounted for available memory space. In other 199 /// words, this memory is not available for use until it is freed up. 200 /// 3. Unexpected segmentation faults or erroneous behavior can occur if 201 /// handles or data passed in to Runfunction gets destroyed before the 202 /// RunFunction finishes. 203 /// For example, if a variable passed in as Misc data or the buffer gets 204 /// destroyed before the runtime receives the completion notification 205 /// of the Runfunction, it can cause unexpected behavior. So it is always 206 /// recommended to wait for RunFunction completion event before any related 207 /// destroy event occurs. 208 /// 209 /// The runtime expects users to handle such scenarios. COIPipelineRunFunction 210 /// returns COI_SUCCESS for above cases because it was queued up successfully. 211 /// Also if you try to destroy a pipeline with a stalled function then the 212 /// destroy call will hang. COIPipelineDestroy waits until all the functions 213 /// enqueued are finished executing. 214 /// 215 /// @param in_Pipeline 216 /// [in] Handle to a previously created pipeline that this run 217 /// function should be enqueued to. 218 /// 219 /// @param in_Function 220 /// [in] Previously returned handle from a call to 221 /// COIPipelineGetFunctionHandle() that represents a function in the 222 /// application running on the Sink process. 223 /// 224 /// @param in_NumBuffers 225 /// [in] The number of buffers that are being passed to the run 226 /// function. This number must match the number of buffers in the 227 /// in_pBuffers and in_pBufferAccessFlags arrays. Must be less than 228 /// COI_PIPELINE_MAX_IN_BUFFERS. 229 /// 230 /// @param in_pBuffers 231 /// [in] An array of COIBUFFER handles that the function is expected 232 /// to use during its execution. Each buffer when it arrives at the 233 /// Sink process will be at least 4k page aligned, thus, using a very 234 /// large number of small buffers is memory inefficient and should be 235 /// avoided. 236 /// 237 /// @param in_pBufferAccessFlags 238 /// [in] An array of flag values which correspond to the buffers 239 /// passed in the in_pBuffers parameter. These flags are used to 240 /// track dependencies between different run functions being 241 /// executed from different pipelines. 242 /// 243 /// @param in_NumDependencies 244 /// [in] The number of dependencies specified in the in_pDependencies 245 /// array. This may be 0 if the caller does not want the run function 246 /// to wait for any dependencies. 247 /// 248 /// @param in_pDependencies 249 /// [in] An optional array of COIEVENT objects that this run 250 /// function will wait for before executing. This allows the user to 251 /// create dependencies between run functions in different pipelines. 252 /// The user may pass in NULL if they do not wish to wait for any 253 /// dependencies to complete. 254 /// 255 /// @param in_pMiscData 256 /// [in] Pointer to user defined data, typically used to pass 257 /// parameters to Sink side functions. Should only be used for small 258 /// amounts data since the data will be placed directly in the 259 /// Driver's command buffer. COIBuffers should be used to pass large 260 /// amounts of data. 261 /// 262 /// @param in_MiscDataLen 263 /// [in] Size of the in_pMiscData in bytes. Must be less than 264 /// COI_PIPELINE_MAX_IN_MISC_DATA_LEN, and should usually be much 265 /// smaller, see documentation for the parameter in_pMiscData. 266 /// 267 /// @param out_pAsyncReturnValue 268 /// [out] Pointer to user-allocated memory where the return value from 269 /// the run function will be placed. This memory should not be read 270 /// until out_pCompletion has been signaled. 271 /// 272 /// @param in_AsyncReturnValueLen 273 /// [in] Size of the out_pAsyncReturnValue in bytes. 274 /// 275 /// @param out_pCompletion 276 /// [out] An optional pointer to a COIEVENT object 277 /// that will be signaled when this run function has completed 278 /// execution. The user may pass in NULL if they wish for this function 279 /// to be synchronous, otherwise if a COIEVENT object is passed in the 280 /// function is then asynchronous and closes after enqueuing the 281 /// RunFunction and passes back the COIEVENT that will be signaled 282 /// once the RunFunction has completed. 283 /// 284 /// @return COI_SUCCESS if the function was successfully placed in a 285 /// pipeline for future execution. Note that the actual 286 /// execution of the function will occur in the future. 287 /// 288 /// @return COI_OUT_OF_RANGE if in_NumBuffers is greater than 289 /// COI_PIPELINE_MAX_IN_BUFFERS or if in_MiscDataLen is greater than 290 /// COI_PIPELINE_MAX_IN_MISC_DATA_LEN. 291 /// 292 /// @return COI_INVALID_HANDLE if the pipeline handle passed in was invalid. 293 /// 294 /// @return COI_INVALID_HANDLE if the function handle passed in was invalid. 295 /// 296 /// @return COI_INVALID_HANDLE if any of the buffers passed in are invalid. 297 /// 298 /// @return COI_ARGUMENT_MISMATCH if in_NumDependencies is non-zero while 299 /// in_pDependencies was passed in as NULL. 300 /// 301 /// @return COI_ARGUMENT_MISMATCH if in_pDependencies is non-NULL but 302 /// in_NumDependencies is zero. 303 /// 304 /// @return COI_ARGUMENT_MISMATCH if in_MiscDataLen is non-zero while 305 /// in_pMiscData was passed in as NULL. 306 /// 307 /// @return COI_ARGUMENT_MISMATCH if in_pMiscData is non-NULL but 308 /// in_MiscDataLen is zero. 309 /// 310 /// @return COI_ARGUMENT_MISMATCH if in_NumBuffers is non-zero and in_pBuffers 311 /// or in_pBufferAccessFlags are NULL. 312 /// 313 /// @return COI_ARGUMENT_MISMATCH if in_pBuffers is non-NULL but 314 /// in_NumBuffers is zero. 315 /// 316 /// @return COI_ARGUMENT_MISMATCH if in_pBufferAccessFlags is non-NULL but 317 /// in_NumBuffers is zero. 318 /// 319 /// @return COI_ARGUMENT_MISMATCH if in_ReturnValueLen is non-zero while 320 /// in_pReturnValue was passed in as NULL. 321 /// 322 /// @return COI_ARGUMENT_MISMATCH if in_pReturnValue is non-NULL but 323 /// in_ReturnValueLen is zero. 324 /// 325 /// @return COI_RETRY if any input buffers are still mapped when 326 /// passed to the run function. 327 /// 328 /// @return COI_MISSING_DEPENDENCY if buffer was not created on the process 329 /// associated with the pipeline that was passed in. 330 /// 331 /// @return COI_OUT_OF_RANGE if any of the access flags in 332 /// in_pBufferAccessFlags is not a valid COI_ACCESS_FLAGS. 333 /// 334 COIACCESSAPI 335 COIRESULT 336 COIPipelineRunFunction( 337 COIPIPELINE in_Pipeline, 338 COIFUNCTION in_Function, 339 uint32_t in_NumBuffers, 340 const COIBUFFER *in_pBuffers, 341 const COI_ACCESS_FLAGS *in_pBufferAccessFlags, 342 uint32_t in_NumDependencies, 343 const COIEVENT *in_pDependencies, 344 const void *in_pMiscData, 345 uint16_t in_MiscDataLen, 346 void *out_pAsyncReturnValue, 347 uint16_t in_AsyncReturnValueLen, 348 COIEVENT *out_pCompletion); 349 350 351 ////////////////////////////////////////////////////////////////////////////// 352 /// 353 /// Retrieve the engine that the pipeline is associated with. 354 /// 355 /// @param in_Pipeline 356 /// [in] Pipeline to query. 357 /// 358 /// @param out_pEngine 359 /// [out] The handle of the Engine. 360 /// 361 /// @return COI_SUCCESS if the engine was retrieved. 362 /// 363 /// @return COI_INVALID_HANDLE if the pipeline handle passed in was invalid. 364 /// 365 /// @return COI_INVALID_POINTER if the out_pEngine parameter is NULL. 366 /// 367 /// @return COI_PROCESS_DIED if the process associated with this engine died. 368 /// 369 COIACCESSAPI 370 COIRESULT 371 COIPipelineGetEngine( 372 COIPIPELINE in_Pipeline, 373 COIENGINE *out_pEngine); 374 375 ////////////////////////////////////////////////////////////////////////////// 376 /// 377 /// Add a particular core:thread pair to a COI_CPU_MASK. 378 /// 379 /// @param in_Process 380 /// [in] A handle to an already existing process that the pipeline 381 /// will be associated with. 382 /// 383 /// @param in_CoreID 384 /// [in] Core to affinitize to; must be less than the number of cores 385 /// on the device. 386 /// 387 /// @param in_ThreadID 388 /// [in] Thread on the core to affinitize to (0 - 3). 389 /// 390 /// @param out_pMask 391 /// [out] Pointer to the mask to set. 392 /// 393 /// @warning Unless it is explicitly done, the contents of the mask may not 394 /// be zero when creating or declaring a COI_CPU_MASK variable. 395 /// 396 /// @return COI_SUCCESS if the mask was set. 397 /// 398 /// @return COI_OUT_OF_RANGE if the in_CoreID or in_ThreadID is out of range. 399 /// 400 /// @return COI_INVALID_POINTER if out_pMask is invalid. 401 /// 402 /// @return COI_INVALID_HANDLE if in_Process is invalid. 403 /// 404 COIACCESSAPI 405 COIRESULT 406 COIPipelineSetCPUMask( 407 COIPROCESS in_Process, 408 uint32_t in_CoreID, 409 uint8_t in_ThreadID, 410 COI_CPU_MASK *out_pMask); 411 412 ////////////////////////////////////////////////////////////////////////////// 413 /// 414 /// Clears a given mask. Note that the memory contents of COI_CPU_MASK are not 415 /// guaranteed to be zero when declaring a COI_CPU_MASK variable. Thus, prior 416 /// to setting a specific affinity to in_Mask it is important to call this 417 /// function first. 418 /// 419 /// @param in_Mask 420 /// [in] Pointer to the mask to clear. 421 /// 422 /// @return COI_SUCCESS if the mask was cleared. 423 /// 424 /// @return COI_INVALID_POINTER if in_Mask is invalid. 425 /// 426 COIACCESSAPI 427 COIRESULT 428 COIPipelineClearCPUMask( 429 COI_CPU_MASK *in_Mask); 430 431 #ifdef __cplusplus 432 } /* extern "C" */ 433 #endif 434 435 #endif /* _COIPIPELINE_SOURCE_H */ 436 437 /*! @} */ 438