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