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 _COIBUFFER_SOURCE_H
42 #define _COIBUFFER_SOURCE_H
43 
44 /** @ingroup COIBuffer
45  *  @addtogroup COIBufferSource
46 @{
47 
48 * @file source\COIBuffer_source.h
49 */
50 #ifndef DOXYGEN_SHOULD_SKIP_THIS
51     #include "../common/COITypes_common.h"
52     #include "../common/COIResult_common.h"
53 #endif // DOXYGEN_SHOULD_SKIP_THIS
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 
60 ///////////////////////////////////////////////////////////////////////////////
61 /// The valid buffer types that may be created using COIBufferCreate.
62 /// Please see the COI_VALID_BUFFER_TYPES_AND_FLAGS matrix
63 /// below which describes the valid combinations of buffer types and flags.
64 ///
65 typedef enum COI_BUFFER_TYPE
66 {
67     /// Normal buffers exist as a single physical buffer in either Source or
68     /// Sink physical memory. Mapping the buffer may stall the pipelines.
69     COI_BUFFER_NORMAL = 1,
70 
71     // Reserved values, not used by COI any more
72     COI_BUFFER_RESERVED_1,
73     COI_BUFFER_RESERVED_2,
74     COI_BUFFER_RESERVED_3,
75 
76     /// OpenCL buffers are similar to Normal buffers except they don't
77     /// stall pipelines and don't follow any read write dependencies.
78     COI_BUFFER_OPENCL
79 
80 } COI_BUFFER_TYPE;
81 
82 
83 /// @name COIBUFFER creation flags.
84 /// Please see the COI_VALID_BUFFER_TYPES_AND_FLAGS matrix
85 /// below which describes the valid combinations of buffer types and flags.
86 //@{
87 
88 /// Create the buffer such that it has the same virtual address on all of the
89 /// sink processes with which it is associated.
90 #define COI_SAME_ADDRESS_SINKS             0x00000001
91 
92 /// Create the buffer such that it has the same virtual address on all of the
93 /// sink processes with which it is associated and in the source process.
94 #define COI_SAME_ADDRESS_SINKS_AND_SOURCE  0x00000002
95 
96 /// Hint to the runtime that the source will frequently read the buffer
97 #define COI_OPTIMIZE_SOURCE_READ           0x00000004
98 
99 /// Hint to the runtime that the source will frequently write the buffer
100 #define COI_OPTIMIZE_SOURCE_WRITE          0x00000008
101 
102 /// Hint to the runtime that the sink will frequently read the buffer
103 #define COI_OPTIMIZE_SINK_READ             0x00000010
104 
105 /// Hint to the runtime that the sink will frequently write the buffer
106 #define COI_OPTIMIZE_SINK_WRITE            0x00000020
107 
108 /// Used to delay the pinning of memory into physical pages, until required
109 /// for DMA. This can be used to delay the cost of time spent pinning memory
110 /// until absolutely necessary. Might speed up the execution of COIBufferCreate
111 /// calls, but slow down the first access of the buffer in
112 /// COIPipelineRunFunction(s) or other COIBuffer access API's.
113 /// Also of important note, that with this flag enabled COI will not be able to
114 /// check to see if this memory is read only. Ordinarily this is checked
115 /// and an error is thrown upon buffer creation. With this flag, the error
116 /// might occur later, and cause undetermined behavior. Be sure to always
117 /// use writable memory for COIBuffers.
118 #define COI_OPTIMIZE_NO_DMA                0x00000040
119 
120 /// Hint to the runtime to try to use huge page sizes for backing store on the
121 /// sink. Is currently not compatible with the SAME_ADDRESS
122 /// flags or the SINK_MEMORY flag. It is important to note that this is a hint
123 /// and internally the runtime may not actually promote to huge pages.
124 /// Specifically if the buffer is too small (less than 4KiB for example) then
125 /// the runtime will not promote the buffer to use huge pages.
126 #define COI_OPTIMIZE_HUGE_PAGE_SIZE        0x00000080
127 
128 /// Used to tell Intel(R) Coprocessor Offload Infrastructure (Intel(R) COI)
129 /// to create a buffer using memory that has already been
130 /// allocated on the sink. This flag is only valid when passed in to the
131 /// COIBufferCreateFromMemory API.
132 #define COI_SINK_MEMORY                    0x00000100
133 
134 //@}
135 
136 #ifndef DOXYGEN_SHOULD_SKIP_THIS
137 // Make the flag mask
138 #ifdef F
139 #undef F
140 #endif
141 #define F 0
142 #ifdef T
143 #undef T
144 #endif
145 #define T 1
146 #define MTM(_BUFFER, B1, B2, B3, B4, B5, B6, B7, B8, B9) \
147     (B1 | B2<<1 | B3<<2 | B4<<3 | B5<<4 | B6<<5 | B7<<6 | B8<<7 | B9<<8)
148 #endif
149 
150 /// \enum COI_BUFFER_TYPE
151 /// This matrix shows the valid combinations of buffer types and buffer flags
152 /// that may be passed in to COIBufferCreate and COIBufferCreateFromMemory.
153 /// \code
154 static const uint64_t
155 COI_VALID_BUFFER_TYPES_AND_FLAGS[COI_BUFFER_OPENCL + 1] =
156 {
157     /*           |       | SAME |      |       |      |       |     |      |      |
158                  | SAME  | ADDR | OPT  | OPT   | OPT  | OPT   | OPT | HUGE | COI  |
159                  | ADDR  | SINK | SRC  | SRC   | SINK | SINK  | NO  | PAGE | SINK |
160                  | SINKS | SRC  | READ | WRITE | READ | WRITE | DMA | SIZE | MEM  |
161                  +-------+------+------+-------+------+-------+-----+------+-----*/
162     MTM(INVALID   ,   F   ,   F  ,   F  ,   F   ,   F  ,   F   ,  F  ,   F  ,  F),
163     MTM(NORMAL    ,   T   ,   T  ,   T  ,   T   ,   T  ,   T   ,  T  ,   T  ,  T),
164     MTM(RESERVED1 ,   F   ,   F  ,   F  ,   F   ,   F  ,   F   ,  F  ,   F  ,  F),
165     MTM(RESERVED2 ,   F   ,   F  ,   F  ,   F   ,   F  ,   F   ,  F  ,   F  ,  F),
166     MTM(RESERVED3 ,   F   ,   F  ,   F  ,   F   ,   F  ,   F   ,  F  ,   F  ,  F),
167     MTM(OPENCL    ,   T   ,   T  ,   T  ,   T   ,   T  ,   T   ,  T  ,   T  ,  F),
168 };
169 ///\endcode
170 #undef MTM
171 
172 //////////////////////////////////////////////////////////////////////////////
173 /// These flags control how the buffer will be accessed on the source after
174 /// it is mapped.
175 /// Please see the COI_VALID_BUFFER_TYPES_AND_MAP matrix below for the
176 /// valid buffer type and map operation combinations.
177 typedef enum COI_MAP_TYPE
178 {
179     /// Allows the application to read and write the contents of the buffer
180     /// after it is mapped.
181     COI_MAP_READ_WRITE = 1,
182 
183     /// If this flag is set then the application must only read from the
184     /// buffer after it is mapped. If the application writes to the buffer
185     /// the contents will not be reflected back to the sink or stored for
186     /// the next time the buffer is mapped on the source.
187     /// This allows the runtime to make significant performance optimizations
188     /// in buffer handling.
189     COI_MAP_READ_ONLY,
190 
191     /// Setting this flag means that the source will overwrite the entire
192     /// buffer once it is mapped. The app must not read from the buffer and
193     /// must not expect the contents of the buffer to be synchronized from
194     /// the sink side during the map operation.
195     /// This allows the runtime to make significant performance optimizations
196     /// in buffer handling.
197     COI_MAP_WRITE_ENTIRE_BUFFER
198 } COI_MAP_TYPE;
199 
200 #ifndef DOXYGEN_SHOULD_SKIP_THIS
201 // Make the flag mask
202 #define MMM(_BUFFER, B1, B2, B3) \
203     {  F  , B1, B2, B3}
204 #endif
205 /// \enum COI_MAP_TYPE
206 /// This matrix shows the valid combinations of buffer types and map
207 /// operations that may be passed in to COIBufferMap.
208 /// \code
209 static const uint64_t
210 COI_VALID_BUFFER_TYPES_AND_MAP
211 [COI_BUFFER_OPENCL + 1][COI_MAP_WRITE_ENTIRE_BUFFER + 1] =
212 {
213     /*                      | MAP   | MAP   | MAP   |
214                             | READ  | READ  | WRITE |
215                             | WRITE | ONLY  | ENTIRE|
216                             +-------+-------+-------+*/
217     MMM(INVALID             ,   F   ,   F   ,   F),
218     MMM(NORMAL              ,   T   ,   T   ,   T),
219     MMM(RESERVED1           ,   F   ,   F   ,   F),
220     MMM(RESERVED2           ,   F   ,   F   ,   F),
221     MMM(RESERVED3           ,   F   ,   F   ,   F),
222     MMM(OPENCL              ,   T   ,   T   ,   T),
223 };
224 ///\endcode
225 #undef MMM
226 #ifndef DOXYGEN_SHOULD_SKIP_THIS
227 #undef F
228 #undef T
229 #endif
230 
231 //////////////////////////////////////////////////////////////////////////////
232 /// The valid copy operation types for the COIBufferWrite, COIBufferRead,
233 /// and COIBufferCopy APIs.
234 ///
235 typedef enum COI_COPY_TYPE
236 {
237     /// The runtime can pick the best suitable way to copy the data.
238     COI_COPY_UNSPECIFIED = 0,
239 
240     /// The runtime should use DMA to copy the data.
241     COI_COPY_USE_DMA,
242 
243     /// The runtime should use a CPU copy to copy the data.
244     COI_COPY_USE_CPU,
245 
246     /// Same as above, but forces moving entire buffer to target process in Ex
247     /// extended APIs, even if the full buffer is not written.
248     COI_COPY_UNSPECIFIED_MOVE_ENTIRE,
249 
250     /// Same as above, but forces moving entire buffer to target process in Ex
251     /// extended APIs, even if the full buffer is not written.
252     COI_COPY_USE_DMA_MOVE_ENTIRE,
253 
254     /// Same as above, but forces moving entire buffer to target process in Ex
255     /// extended APIs, even if the full buffer is not written.
256     COI_COPY_USE_CPU_MOVE_ENTIRE
257 
258 } COI_COPY_TYPE;
259 
260 
261 //////////////////////////////////////////////////////////////////////////////
262 /// The buffer states are used to indicate whether a buffer is available for
263 /// access in a COIPROCESS. This is used with COIBufferSetState.
264 ///
265 /// Rules on State Transition of the buffer:
266 /// -. When a Buffer is created by default it is valid only on the source,
267 ///    except for buffers created with COI_SINK_MEMORY flag which are valid
268 ///    only on the sink where the memory lies when created.
269 /// -. Apart from SetState following APIs also alters the state of the buffer
270 ///    internally:
271 ///
272 ///    - COIBufferMap alters state of buffer depending on the COI_MAP_TYPE.
273 ///      COI_MAP_READ_ONLY: Makes Valid on the Source. Doesn't affect the state
274 ///                         of the buffer on the other devices.
275 ///      COI_MAP_READ_WRITE: Makes it Valid only the Source and Invalid
276 ///                         everywhere else. OPENCL buffers are invalidated
277 ///                         only if it is not in use.
278 ///      COI_MAP_WRITE_ENTIRE_BUFFER: Makes it valid only on the Source. OPENCL
279 ///                         buffers are invalidated only if not in use.
280 ///
281 ///    - COIPipelineRunfunction alters the state of the buffer depending on the
282 ///      COI_ACCESS_FLAGS
283 ///      COI_SINK_READ: Makes it valid on the sink where RunFunction is being
284 ///                     issued. Doesn't affect the state of the buffer on other
285 ///                     devices.
286 ///      COI_SINK_WRITE: Makes it valid only on the sink where Runfunction is
287 ///                     being issued and invalid everywhere else. OPENCL
288 ///                     buffers are invalidated only if the buffer is not in
289 ///                     use.
290 ///      COI_SINK_WRITE_ENTIRE: Makes it valid only on the sink where
291 ///                     Runfunction is being issued and invalid everywhere else
292 ///                     OPENCL buffers are invalidated only if the buffer is
293 ///                     not in use.
294 ///
295 ///    - COIBufferWrite makes the buffer exclusively valid where the write
296 ///      happens. Write gives preference to Source over Sink. In other words
297 ///      if a buffer is valid on the Source and multiple Sinks, Write will
298 ///      happen on the Source and will Invalidate all other Sinks. If the
299 ///      buffer is valid on multiple Sinks ( and not on the Source) then
300 ///      Intel(R) Coprocessor Offload Infrastructure (Intel(R) COI)
301 ///      selects process handle with the lowest numerical value to do the
302 ///      exclusive write Again, OPENCL buffers are invalidated only if the
303 ///      buffer is not in use on that SINK/SOURCE.
304 ///
305 ///      The preference rule mentioned above holds true even for SetState API,
306 ///      when data needs to be moved from a valid location. The selection of
307 ///      valid location happens as stated above.
308 ///
309 /// - It is possible to alter only parts of the buffer and change it state
310 ///   In other words it is possible for different parts of the buffer to have
311 ///   different states on different devices. A byte is the minimum size at
312 ///   which state can be maintained internally. Granularity level is completely
313 ///   determined by how the buffer gets fragmented.
314 ///
315 /// Note: Buffer is considered 'in use' if is
316 ///         - Being used in RunFunction : In use on a Sink
317 ///         - Mapped: In use on a Source
318 ///         - AddRef'd: In use on Sink
319 ///
320 
321 //////////////////////////////////////////////////////////////////////////////
322 /// The buffer states used with COIBufferSetState call to indicate the new
323 /// state of the buffer on a given process
324 ///
325 typedef enum
326 {
327     COI_BUFFER_VALID = 0,      // Buffer is valid and up-to-date on the process
328     COI_BUFFER_INVALID ,       // Buffer is not valid, need valid data
329     COI_BUFFER_VALID_MAY_DROP, // Same as valid but will drop the content when
330     // evicted to avoid overwriting the shadow
331     // memory
332     COI_BUFFER_RESERVED        // Reserved for internal use
333 } COI_BUFFER_STATE;
334 ///
335 /// Note: A VALID_MAY_DROP declares a buffer's copy as secondary on a given
336 /// process. This means that there needs to be at least one primary copy of the
337 /// the buffer somewhere in order to mark the buffer as VALID_MAY_DROP on a
338 /// process. In other words to make a buffer VALID_MAY_DROP on a given process
339 /// it needs to be in COI_BUFFER_VALID state somewhere else. The operation gets
340 /// ignored (or is a nop) if there is no primary copy of the buffer. The nature
341 /// of this state to "drop the content" when evicted is a side effect of
342 /// marking the buffer as secondary copy. So when a buffer marked
343 /// VALID_MAY_DROP is evicted Intel(R) Coprocessor Offload Infrastructure
344 /// (Intel(R) COI) doesn't back it up as it is assumed that
345 /// there is a primary copy somewhere.
346 
347 //////////////////////////////////////////////////////////////////////////////
348 /// The buffer move flags are used to indicate when a buffer should be moved
349 /// when it's state is changed. This is used with COIBufferSetState.
350 typedef enum
351 {
352     COI_BUFFER_MOVE = 0,// Dirty data is moved if state change requires it
353     COI_BUFFER_NO_MOVE  // Change state without moving data
354 } COI_BUFFER_MOVE_FLAG;
355 
356 // A process handle for COIBufferSetState call to indicate all the sink
357 // processes where the given buffer is valid
358 #define COI_SINK_OWNERS ((COIPROCESS)-2)
359 
360 // Matrix descriptors used with MultiD Read/Write
361 typedef struct dim_desc
362 {
363     int64_t size;       // Size of data type
364     int64_t lindex;     // Lower index, used in Fortran
365     int64_t lower;      // Lower section bound
366     int64_t upper;      // Upper section bound
367     int64_t stride;     // Stride, or number of bytes between the start
368     // of one element and start of next one divided
369     // by size.
370 } dim_desc;
371 
372 typedef struct arr_desc
373 {
374     int64_t base;       // Base address
375     int64_t rank;       // Rank of array, i.e. number of dimensions
376     dim_desc dim[3];    // This array has as many elements as �rank�
377     // currently limited to 3.
378 } arr_desc;
379 
380 //////////////////////////////////////////////////////////////////////////////
381 ///
382 /// Creates a buffer that can be used in RunFunctions that are queued in
383 /// pipelines. The address space for the buffer is reserved when it is
384 /// created although the memory may not be committed until the buffer is
385 /// used for the first time. Please note that the Intel(R) Coprocessor Offload
386 /// Infrastructure (Intel(R) COI) runtime may also allocate space for the
387 /// source process to use as shadow memory for certain types of buffers.
388 /// If Intel(R) Coprocessor Offload Infrastructure (Intel(R) COI)
389 /// does allocate this memory it will not be released or reallocated
390 /// until the COIBuffer is destroyed.
391 ///
392 /// @param  in_Size
393 ///         [in] The number of bytes to allocate for the buffer. If in_Size
394 ///         is not page aligned, it will be rounded up.
395 ///
396 /// @param  in_Type
397 ///         [in] The type of the buffer to create.
398 ///
399 /// @param  in_Flags
400 ///         [in] A bitmask of attributes for the newly created buffer.
401 ///         Some of these flags are required for correctness while others
402 ///         are provided as hints to the runtime system so it can make
403 ///         certain performance optimizations.
404 ///
405 /// @param  in_pInitData
406 ///         [in] If non-NULL the buffer will be initialized with the data
407 ///         pointed to by pInitData. The memory at in_pInitData must hold
408 ///         at least in_Size bytes.
409 ///
410 /// @param  in_NumProcesses
411 ///         [in] The number of processes with which this buffer might be used.
412 ///
413 /// @param  in_pProcesses
414 ///         [in] An array of COIPROCESS handles identifying the processes with
415 ///         which this buffer might be used.
416 ///
417 /// @param  out_pBuffer
418 ///         [out] Pointer to a buffer handle. The handle will be filled in
419 ///         with a value that uniquely identifies the newly created buffer.
420 ///         This handle should be disposed of via COIBufferDestroy()
421 ///         once it is no longer needed.
422 ///
423 /// @return COI_SUCCESS if the buffer was created
424 ///
425 /// @return COI_ARGUMENT_MISMATCH if the in_Type and in_Flags parameters
426 ///         are not compatible with one another. Please see the
427 ///         COI_VALID_BUFFER_TYPES_AND_FLAGS map above for information about
428 ///         which flags and types are compatible.
429 ///
430 /// @return COI_OUT_OF_RANGE if in_Size is zero, if the bits set in
431 ///         the in_Flags parameter are not recognized flags, or if in_NumProcesses is zero.
432 ///
433 /// @return COI_INVALID_POINTER if the in_pProcesses or out_pBuffer parameter
434 ///         is NULL.
435 ///
436 /// @return COI_NOT_SUPPORTED if in_Type has invalid value or if
437 ///        one of the in_Flags is COI_SINK_MEMORY.
438 ///
439 /// @return COI_NOT_SUPPORTED if the flags include either
440 ///         COI_SAME_ADDRESS_SINKS or COI_SAME_ADDRESS_SINKS_AND_SOURCE and
441 ///         COI_OPTIMIZE_HUGE_PAGE_SIZE.
442 ///
443 /// @return COI_INVALID_HANDLE if one of the COIPROCESS handles in the
444 ///         in_pProcesses array does not identify a valid process.
445 ///
446 /// @return COI_OUT_OF_MEMORY if allocating the buffer fails.
447 ///
448 /// @return COI_RESOURCE_EXHAUSTED if the sink is out of buffer memory.
449 ///
450 COIACCESSAPI
451 COIRESULT
452 COIBufferCreate(
453     uint64_t            in_Size,
454     COI_BUFFER_TYPE     in_Type,
455     uint32_t            in_Flags,
456     const   void               *in_pInitData,
457     uint32_t            in_NumProcesses,
458     const   COIPROCESS         *in_pProcesses,
459     COIBUFFER          *out_pBuffer);
460 
461 //////////////////////////////////////////////////////////////////////////////
462 ///
463 /// Creates a buffer from some existing memory that can be used in
464 /// RunFunctions that are queued in pipelines. If the flag COI_SINK_MEMORY
465 /// is specified then Intel(R) Coprocessor Offload
466 /// Infrastructure (Intel(R) COI) will use that memory for the buffer on the sink.
467 /// If that flag isn't set then the memory provided is used as backing store
468 /// for the buffer on the source. In either case the memory must not be freed
469 /// before the buffer is destroyed.
470 /// While the user still owns the memory passed in they must use the
471 /// appropriate access flags when accessing the buffer in COIPipelinRunFunction
472 /// or COIBufferMap calls so that the runtime knows when the
473 /// memory has been modified. If the user just writes directly to the memory
474 /// location then those changes may not be visible when the corresponding
475 /// buffer is accessed.
476 /// Whatever values are already present in the memory location when this call
477 /// is made are preserved. The memory values are also preserved when
478 /// COIBufferDestroy is called.
479 ///
480 /// @warning: Use of this function is highly discouraged if the calling
481 /// program forks at all (including calls to system(3), popen(3), or similar
482 /// functions) during the life of this buffer. See the discussion around the
483 /// in_Memory parameter below regarding this.
484 ///
485 /// @param  in_Size
486 ///         [in] The size of in_Memory in bytes. If in_Size
487 ///         is not page aligned, it will be rounded up.
488 ///
489 /// @param  in_Type
490 ///         [in] The type of the buffer to create. Only COI_BUFFER_NORMAL
491 ///         buffer type is supported.
492 ///
493 /// @param  in_Flags
494 ///         [in] A bitmask of attributes for the newly created buffer.
495 ///         Some of these flags are required for correctness while others
496 ///         are provided as hints to the runtime system so it can make
497 ///         certain performance optimizations. Note that the flag
498 ///         COI_SAME_ADDRESS_SINKS_AND_SOURCE is still valid but may fail
499 ///         if the same address as in_Memory can not be allocated on the sink.
500 ///
501 /// @param  in_Memory
502 ///         [in] A pointer to an already allocated memory region
503 ///         that should be turned into a COIBUFFER. Although the user still
504 ///         owns this memory they should not free it before calling
505 ///         COIBufferDestroy. They must also only access the memory using
506 ///         COIBUFFER semantics, for example using COIBufferMap/COIBufferUnmap
507 ///         when they wish to read or write the data. There are no alignment
508 ///         or size requirements for this memory region.
509 ///
510 ///         WARNING:
511 ///         Since the backing memory passed in can be the target of a DMA
512 ///         the caller must ensure that there is no call to clone(2) (without
513 ///         the CLONE_VM argument) during the life of this buffer. This
514 ///         includes higher level functions that call clone such as fork(2),
515 ///         system(3), popen(3), among others).
516 ///
517 ///         For forked processes, Linux uses copy-on-write semantics for
518 ///         performance reasons. Consequently, if the parent forks and then
519 ///         writes to this memory, the physical page mapping changes causing
520 ///         the DMA to fail (and thus data corruption).
521 ///
522 ///         In Linux you can mark a set of pages to not be copied across
523 ///         across the clone by calling madvise(2) with an argument of
524 ///         MADV_DONTFORK and then safely use that memory in this scenario.
525 ///         Alternately, if the memory is from a region marked MAP_SHARED,
526 ///         this will work.
527 ///
528 /// @param  in_NumProcesses
529 ///         [in] The number of processes with which this buffer might be used.
530 ///         If the flag COI_SINK_MEMORY is specified then this must be 1.
531 ///
532 /// @param  in_pProcesses
533 ///         [in] An array of COIPROCESS handles identifying the processes with
534 ///         which this buffer might be used.
535 ///
536 /// @param  out_pBuffer
537 ///         [out] Pointer to a buffer handle. The handle will be filled in
538 ///         with a value that uniquely identifies the newly created buffer.
539 ///         This handle should be disposed of via COIBufferDestroy()
540 ///         once it is no longer needed.
541 ///
542 /// @return COI_SUCCESS if the buffer was created
543 ///
544 /// @return COI_NOT_SUPPORTED if the in_Type value is not COI_BUFFER_NORMAL,
545 ///         or COI_BUFFER_OPENCL.
546 ///
547 /// @return COI_NOT_SUPPORTED if in_Memory is read-only memory
548 ///
549 /// @return COI_NOT_SUPPORTED if one of the in_Flags is COI_SINK_MEMORY and
550 ///         in_Type is not COI_BUFFER_NORMAL
551 ///
552 /// @return COI_NOT_SUPPORTED if the flag COI_SAME_ADDRESS_SINKS is set
553 ///
554 /// @return COI_NOT_SUPPORTED if the flag COI_SAME_ADDRESS_SINKS_AND_SOURCE is
555 ///         set
556 ///
557 /// @return COI_ARGUMENT_MISMATCH if the in_Type and in_Flags parameters
558 ///         are not compatible with one another. Please see the
559 ///         COI_VALID_BUFFER_TYPES_AND_FLAGS map above for information about
560 ///         which flags and types are compatible.
561 ///
562 /// @return COI_ARGUMENT_MISMATCH if the flag COI_SINK_MEMORY is specified and
563 ///         in_NumProcesses > 1.
564 ///
565 /// @return COI_ARGUMENT_MISMATCH if the flags COI_SINK_MEMORY and
566 ///         COI_OPTIMIZE_HUGE_PAGE_SIZE are both set.
567 ///
568 /// @return COI_OUT_OF_RANGE if in_Size is zero, if the bits set in
569 ///         the in_Flags parameter are not recognized flags,  or if in_NumProcesses is zero.
570 ///
571 /// @return COI_INVALID_POINTER if in_Memory, in_pProcesses or
572 ///         out_pBuffer parameter is NULL.
573 ///
574 /// @return COI_INVALID_HANDLE if one of the COIPROCESS handles in the
575 ///         in_pProcesses array does not identify a valid process.
576 ///
577 COIACCESSAPI
578 COIRESULT
579 COIBufferCreateFromMemory(
580     uint64_t            in_Size,
581     COI_BUFFER_TYPE     in_Type,
582     uint32_t            in_Flags,
583     void               *in_Memory,
584     uint32_t            in_NumProcesses,
585     const   COIPROCESS         *in_pProcesses,
586     COIBUFFER          *out_pBuffer);
587 
588 
589 //////////////////////////////////////////////////////////////////////////////
590 ///
591 /// Destroys a buffer. Will block on completion of any operations on the
592 /// buffer, such as COIPipelineRunFunction or COIBufferCopy. Will block until
593 /// all COIBufferAddRef calls have had a matching COIBufferReleaseRef call
594 /// made. will not block on an outstanding COIBufferUnmap but will instead
595 /// return COI_RETRY.
596 ///
597 /// @param  in_Buffer
598 ///         [in] Handle of the buffer to destroy.
599 ///
600 /// @return COI_SUCCESS if the buffer was destroyed.
601 ///
602 /// @return COI_INVALID_HANDLE if the buffer handle was invalid.
603 ///
604 /// @return COI_RETRY if the buffer is currently mapped. The buffer must
605 ///         first be unmapped before it can be destroyed.
606 ///
607 /// @return COI_RETRY if the sub-buffers created from this buffer are not yet
608 ///         destroyed
609 ///
610 COIACCESSAPI
611 COIRESULT
612 COIBufferDestroy(
613     COIBUFFER           in_Buffer);
614 
615 
616 //////////////////////////////////////////////////////////////////////////////
617 ///
618 /// This call initiates a request to access a region of a buffer. Multiple
619 /// overlapping (or non overlapping) regions can be mapped simultaneously for
620 /// any given buffer. If a completion event is specified this call will
621 /// queue a request for the data which will be satisfied when the buffer is
622 /// available. Once all conditions are met the completion event will be
623 /// signaled and the user can access the data at out_ppData. The user can call
624 /// COIEventWait with out_pCompletion to find out when the map operation has
625 /// completed. If the user accesses the data before the map operation is
626 /// complete the results are undefined. If out_pCompletion is NULL then this
627 /// call blocks until the map operation completes and when this call returns
628 /// out_ppData can be safely accessed. This call returns a map instance handle
629 /// in an out parameter which must be passed into COIBufferUnmap when the user
630 /// no longer needs access to that region of the buffer.
631 ///
632 /// The address returned from COIBufferMap may point to memory that
633 /// Intel(R) Coprocessor Offload Infrastructure (Intel(R) COI)
634 /// manages on behalf of the user. The user must not free or reallocate this
635 /// memory, Intel(R) Coprocessor Offload Infrastructure (Intel(R) COI)
636 /// will perform any necessary cleanup when the buffer is
637 /// destroyed.
638 ///
639 /// Note that different types of buffers behave differently when mapped.
640 /// For instance, mapping a COI_BUFFER_NORMAL for write must stall if the
641 /// buffer is currently being written to by a run function.
642 /// The asynchronous operation of COIBufferMap will likely be most useful when
643 /// paired with a COI_BUFFER_NORMAL.
644 ///
645 /// @param  in_Buffer
646 ///         [in] Handle for the buffer to map.
647 ///
648 /// @param  in_Offset
649 ///         [in] Offset into the buffer that a pointer should be returned
650 ///         for. The value 0 can be passed in to signify that the mapped
651 ///         region should start at the beginning of the buffer.
652 ///
653 /// @param  in_Length
654 ///         [in] Length of the buffer area to map. This parameter, in
655 ///         combination with in_Offset, allows the caller to specify
656 ///         that only a subset of an entire buffer need be mapped. A
657 ///         value of 0 can be passed in only if in_Offset is 0, to signify
658 ///         that the mapped region is the entire buffer.
659 ///
660 /// @param  in_Type
661 ///         [in] The access type that is needed by the application. This will
662 ///         affect how the data can be accessed once the map operation
663 ///         completes. See the COI_MAP_TYPE enum for more details.
664 ///
665 /// @param  in_NumDependencies
666 ///         [in] The number of dependencies specified in the in_pDependencies
667 ///         array. This may be 0 if the caller does not want the map
668 ///         call initiation to wait for any events to be signaled before
669 ///         starting the map operations.
670 ///
671 /// @param  in_pDependencies
672 ///         [in] An optional array of handles to previously created COIEVENT
673 ///         objects that this map operation will wait for before starting.
674 ///         This allows the user to create dependencies between asynchronous
675 ///         map calls and other operations such as run functions or other
676 ///         asynchronous map calls. The user may pass in NULL if they do not
677 ///         wish to wait for any dependencies to complete before initiating map
678 ///         operations.
679 ///
680 /// @param  out_pCompletion
681 ///         [out] An optional pointer to a COIEVENT object
682 ///         that will be signaled when a map call with the passed in buffer
683 ///         would complete immediately, that is, the buffer memory has been
684 ///         allocated on the source and its contents updated. The user may pass
685 ///         in NULL if the user wants COIBufferMap to perform a blocking map
686 ///         operation.
687 ///
688 /// @param  out_pMapInstance
689 ///         [out] A pointer to a COIMAPINSTANCE which represents this mapping
690 ///         of the buffer and must be passed in to COIBufferUnmap when access
691 ///         to this region of the buffer data is no longer needed.
692 ///
693 /// @param  out_ppData
694 ///         [out] Pointer to the buffer data. The data will only be valid
695 ///         when the completion object is signaled, or for a synchronous
696 ///         map operation with the call to map returns.
697 ///
698 ///
699 /// @return COI_SUCCESS if the map request succeeds.
700 ///
701 /// @return COI_OUT_OF_RANGE if in_Offset of (in_Offset + in_Length) exceeds
702 ///         the size of the buffer.
703 ///
704 /// @return COI_OUT_OF_RANGE if in_Length is 0, but in_Offset is not 0.
705 ///
706 /// @return COI_OUT_OF_RANGE if in_Type is not a valid COI_MAP_TYPE.
707 ///
708 /// @return COI_ARGUMENT_MISMATCH if in_NumDependencies is non-zero while
709 ///         in_pDependencies was passed in as NULL.
710 ///
711 /// @return COI_ARGUMENT_MISMATCH if in_pDependencies is non-NULL but
712 ///         in_NumDependencies is zero.
713 ///
714 /// @return COI_ARGUMENT_MISMATCH if the in_Type of map is not a valid type
715 ///         for in_Buffer's type of buffer.
716 ///
717 /// @return COI_INVALID_HANDLE if in_Buffer is not a valid buffer handle.
718 ///
719 /// @return COI_INVALID_POINTER if out_pMapInstance or out_ppData is NULL.
720 ///
721 COIACCESSAPI
722 COIRESULT
723 COIBufferMap(
724     COIBUFFER           in_Buffer,
725     uint64_t            in_Offset,
726     uint64_t            in_Length,
727     COI_MAP_TYPE        in_Type,
728     uint32_t            in_NumDependencies,
729     const   COIEVENT           *in_pDependencies,
730     COIEVENT           *out_pCompletion,
731     COIMAPINSTANCE     *out_pMapInstance,
732     void              **out_ppData);
733 
734 //////////////////////////////////////////////////////////////////////////////
735 ///
736 /// Disables Source access to the region of the buffer that was provided
737 /// through the corresponding call to COIBufferMap. The number of calls to
738 /// COIBufferUnmap() should always match the number of calls made to
739 /// COIBufferMap(). The data pointer returned from the COIBufferMap() call
740 /// will be invalid after this call.
741 ///
742 /// @param  in_MapInstance
743 ///         [in] buffer map instance handle to unmap.
744 ///
745 /// @param  in_NumDependencies
746 ///         [in] The number of dependencies specified in the in_pDependencies
747 ///         array. This may be 0 if the caller does not want the unmap call to
748 ///         wait for any events to be signaled before performing the unmap
749 ///         operation.
750 ///
751 /// @param  in_pDependencies
752 ///         [in] An optional array of handles to previously created COIEVENT
753 ///         objects that this unmap operation will wait for before starting.
754 ///         This allows the user to create dependencies between asynchronous
755 ///         unmap calls and other operations such as run functions or other
756 ///         asynchronous unmap calls. The user may pass in NULL if they do not
757 ///         wish to wait for any dependencies to complete before initiating
758 ///         unmap operations.
759 ///
760 /// @param  out_pCompletion
761 ///         [out] An optional pointer to a COIEVENT object that will be
762 ///         signaled when the unmap is complete. The user may pass in NULL if
763 ///         the user wants COIBufferUnmap to perform a blocking unmap
764 ///         operation.
765 ///
766 /// @return COI_SUCCESS upon successful unmapping of the buffer instance.
767 ///
768 /// @return COI_INVALID_HANDLE if the passed in map instance handle was NULL.
769 ///
770 /// @return COI_ARGUMENT_MISMATCH if the in_pDependencies is non NULL but
771 ///         in_NumDependencies is 0.
772 ///
773 /// @return COI_ARGUMENT_MISMATCH if in_pDependencies is NULL but
774 ///         in_NumDependencies is not 0.
775 ///
776 COIACCESSAPI
777 COIRESULT
778 COIBufferUnmap(
779     COIMAPINSTANCE      in_MapInstance,
780     uint32_t            in_NumDependencies,
781     const   COIEVENT           *in_pDependencies,
782     COIEVENT           *out_pCompletion);
783 
784 //////////////////////////////////////////////////////////////////////////////
785 ///
786 /// Gets the Sink's virtual address of the buffer for the first process
787 /// that is using the buffer. This is the same address
788 /// that is passed to the run function on the Sink. The virtual
789 /// address assigned to the buffer for use on the sink is fixed;
790 /// the buffer will always be present at that virtual address on the sink
791 /// and will not get a different virtual address across different
792 /// RunFunctions.
793 /// This address is only valid on the Sink and should not be dereferenced on
794 /// the Source (except for the special case of buffers created with the
795 /// COI_SAME_ADDRESS flag).
796 ///
797 /// @param  in_Buffer
798 ///         [in] Buffer handle
799 ///
800 /// @param  out_pAddress
801 ///         [out] pointer to a uint64_t* that will be filled with the address.
802 ///
803 /// @return COI_SUCCESS upon successful return of the buffer's address.
804 ///
805 /// @return COI_INVALID_HANDLE if the passed in buffer handle was invalid.
806 ///
807 /// @return COI_INVALID_POINTER if the out_pAddress parameter was invalid.
808 ///
809 COIACCESSAPI
810 COIRESULT
811 COIBufferGetSinkAddress(
812     COIBUFFER           in_Buffer,
813     uint64_t           *out_pAddress);
814 
815 //////////////////////////////////////////////////////////////////////////////
816 ///
817 /// Gets the Sink's virtual address of the buffer. This is the same
818 /// address that is passed to the run function on the Sink. The virtual
819 /// address assigned to the buffer for use on the sink is fixed;
820 /// the buffer will always be present at that virtual address on the sink
821 /// and will not get a different virtual address across different
822 /// RunFunctions.
823 /// This address is only valid on the Sink and should not be dereferenced on
824 /// the Source (except for the special case of buffers created with the
825 /// COI_SAME_ADDRESS flag).
826 ///
827 /// @param  in_Process
828 ///         [in] The process for which the address should be returned.
829 ///         Special handle value 0 can be passed to the function;
830 ///         in this case, address for the first valid process will be returned
831 ///
832 /// @param  in_Buffer
833 ///         [in] Buffer handle
834 ///
835 /// @param  out_pAddress
836 ///         [out] pointer to a uint64_t* that will be filled with the address.
837 ///
838 /// @return COI_SUCCESS upon successful return of the buffer's address.
839 ///
840 /// @return COI_INVALID_HANDLE if the passed in buffer or process
841 ///         handle was invalid.
842 ///
843 /// @return COI_INVALID_POINTER if the out_pAddress parameter was invalid.
844 ///
845 /// @return COI_OUT_OF_RANGE if the in_Process is not valid for in_Buffer at the
846 ///         moment of calling the function.
847 ///
848 COIACCESSAPI
849 COIRESULT
850 COIBufferGetSinkAddressEx(
851     COIPROCESS          in_Process,
852     COIBUFFER           in_Buffer,
853     uint64_t           *out_pAddress);
854 
855 //////////////////////////////////////////////////////////////////////////////
856 ///
857 /// Copy data from a normal virtual address into an existing COIBUFFER.
858 /// Please note that COIBufferWrite does not follow implicit buffer
859 /// dependencies. If a buffer is in use in a run function or has been added
860 /// to a process using COIBufferAddRef the call to COIBufferWrite will not
861 /// wait, it will still copy data immediately.
862 /// This is to facilitate a usage model where a buffer is being used outside
863 /// of a run function, for example in a spawned thread, but data still needs
864 /// to be transferred to or from the buffer.
865 /// Additionally this means that if more than one DMA channel is enabled,
866 /// (See COIProcessConfigureDMA) operations to the same buffer may
867 /// happen in parallel if they can be assigned to different DMA hardware.
868 /// So it is highly recommended to use explicit event dependencies to
869 /// order operations where needed.
870 ///
871 /// @param  in_DestBuffer
872 ///         [in] Buffer to write into.
873 ///
874 /// @param  in_DestProcess
875 ///         [in] A pointer to the process to which the data will be written.
876 ///         Buffer is updated only in this process and invalidated in other
877 ///         processes. Only a single process can be specified.
878 ///         Can be left NULL and default behavior will be chosen, which
879 ///         chooses the first valid process in which regions are found. Other
880 ///         buffer regions are invalidated if not updated.
881 ///
882 /// @param  in_Offset
883 ///         [in] Location in the buffer to start writing to.
884 ///
885 /// @param  in_pSourceData
886 ///         [in] A pointer to local memory that should be copied into the
887 ///         provided buffer.
888 ///
889 /// @param  in_Length
890 ///         [in] The number of bytes to write from in_pSourceData into
891 ///         in_DestBuffer. Must not be larger than the size of in_DestBuffer
892 ///         and must not over run in_DestBuffer if an in_Offset is provided.
893 ///
894 /// @param  in_Type
895 ///         [in] The type of copy operation to use, one of either
896 ///         COI_COPY_UNSPECIFIED, COI_COPY_USE_DMA, COI_COPY_USE_CPU.
897 ///
898 /// @param  in_NumDependencies
899 ///         [in] The number of dependencies specified in the in_pDependencies
900 ///         array. This may be 0 if the caller does not want the write call to
901 ///         wait for any additional events to be signaled before starting the
902 ///         write operation.
903 ///
904 /// @param  in_pDependencies
905 ///         [in] An optional array of handles to previously created COIEVENT
906 ///         objects that this write operation will wait for before starting.
907 ///         This allows the user to create dependencies between buffer write
908 ///         calls and other operations such as run functions and map calls. The
909 ///         user may pass in NULL if they do not wish to wait for any
910 ///         additional dependencies to complete before doing the write.
911 ///
912 /// @param  out_pCompletion
913 ///         [out] An optional event to be signaled when the write has
914 ///         completed. This event can be used as a dependency to order
915 ///         the write with regard to future operations.
916 ///         If no completion event is passed in then the write is
917 ///         synchronous and will block until the transfer is complete.
918 ///
919 ///
920 /// @return COI_SUCCESS if the buffer was written successfully.
921 ///
922 /// @return COI_INVALID_HANDLE if the buffer handle was invalid.
923 ///
924 /// @return COI_OUT_OF_RANGE if in_Offset is beyond the end of the buffer.
925 ///
926 /// @return COI_ARGUMENT_MISMATCH if the in_pDependencies is non NULL but
927 ///         in_NumDependencies is 0.
928 ///
929 /// @return COI_ARGUMENT_MISMATCH if in_pDependencies is NULL but
930 ///         in_NumDependencies is not 0.
931 ///
932 /// @return COI_INVALID_POINTER if the in_pSourceData pointer is NULL.
933 ///
934 /// @return COI_OUT_OF_RANGE if in_Offset + in_Length exceeds the size of
935 ///         the buffer.
936 ///
937 /// @return COI_OUT_OF_RANGE if in_Length is 0.
938 ///
939 /// @return COI_RETRY if in_DestBuffer is mapped and is not COI_BUFFER_OPENCL
940 ///         buffer.
941 ///
942 COIACCESSAPI
943 COIRESULT
944 COIBufferWriteEx(
945     COIBUFFER           in_DestBuffer,
946     const   COIPROCESS          in_DestProcess,
947     uint64_t            in_Offset,
948     const   void               *in_pSourceData,
949     uint64_t            in_Length,
950     COI_COPY_TYPE       in_Type,
951     uint32_t            in_NumDependencies,
952     const   COIEVENT           *in_pDependencies,
953     COIEVENT           *out_pCompletion);
954 
955 //////////////////////////////////////////////////////////////////////////////
956 ///
957 /// Copy data specified by multi-dimensional array data structure into another
958 /// multi-dimensional array in an existing COIBUFFER.
959 /// Arrays with more than 3 dimensions are not supported.
960 /// Different numbers of elements between src and destination is not supported.
961 /// Please note that COIBufferWriteMultiD does not follow implicit buffer
962 /// dependencies. If a buffer is in use in a run function or has been added
963 /// to a process using COIBufferAddRef the call to COIBufferWriteMultiD will not
964 /// wait, it will still copy data immediately.
965 /// This is to facilitate a usage model where a buffer is being used outside
966 /// of a run function, for example in a spawned thread, but data still needs
967 /// to be transferred to or from the buffer.
968 /// Additionally this means that if more than one DMA channel is enabled,
969 /// (See COIProcessConfigureDMA) operations to the same buffer may
970 /// happen in parallel if they can be assigned to different DMA hardware.
971 /// So it is highly recommended to use explicit event dependencies to
972 /// order operations where needed.
973 ///
974 ///
975 /// @param  in_DestBuffer
976 ///         [in] Buffer to write into.
977 ///
978 /// @param  in_DestProcess
979 ///         [in] A pointer to the process to which the data will be written.
980 ///         Buffer is updated only in this process and invalidated in other
981 ///         processes. Only a single process can be specified.
982 ///         Can be left NULL and default behavior will be chosen, which
983 ///         chooses the first valid process in which regions are found. Other
984 ///         buffer regions are invalidated if not updated.
985 ///
986 /// @param  in_Offset
987 ///         [in] Start location of the destination array within the buffer.
988 ///
989 /// @param  in_DestArray
990 ///         [in] A pointer to a data structure describing the structure of
991 ///         the data array in the buffer. Total size must not be larger than
992 ///         the size of in_DestBuffer. The base field of this structure will
993 ///         be ignored.
994 ///
995 /// @param  in_SrcArray
996 ///         [in] A pointer to a data structure describing the structure of
997 ///         the data array in local memory that should be copied. in_SrcArray
998 ///         and in_DestArry must have the same number of elements. The base
999 ///         field of this structure should be the virtual pointer to the local
1000 ///         memory in which this array is located.
1001 ///
1002 /// @param  in_Type
1003 ///         [in] The type of copy operation to use, one of either
1004 ///         COI_COPY_UNSPECIFIED, COI_COPY_USE_DMA, COI_COPY_USE_CPU.
1005 ///
1006 /// @param  in_NumDependencies
1007 ///         [in] The number of dependencies specified in the in_pDependencies
1008 ///         array. This may be 0 if the caller does not want the write call to
1009 ///         wait for any additional events to be signaled before starting the
1010 ///         write operation.
1011 ///
1012 /// @param  in_pDependencies
1013 ///         [in] An optional array of handles to previously created COIEVENT
1014 ///         objects that this write operation will wait for before starting.
1015 ///         This allows the user to create dependencies between buffer write
1016 ///         calls and other operations such as run functions and map calls. The
1017 ///         user may pass in NULL if they do not wish to wait for any
1018 ///         additional dependencies to complete before doing the write.
1019 ///
1020 /// @param  out_pCompletion
1021 ///         [out] An optional event to be signaled when the write has
1022 ///         completed. This event can be used as a dependency to order
1023 ///         the write with regard to future operations.
1024 ///         If no completion event is passed in then the write is
1025 ///         synchronous and will block until the transfer is complete.
1026 ///
1027 ///
1028 /// @return COI_SUCCESS if the buffer was copied successfully.
1029 ///
1030 /// @return COI_INVALID_HANDLE if the buffer or process handle was invalid.
1031 ///
1032 /// @return COI_OUT_OF_RANGE if in_Offset is beyond the end of the buffer.
1033 ///
1034 /// @return COI_ARGUMENT_MISMATCH if the in_pDependencies is non NULL but
1035 ///         in_NumDependencies is 0.
1036 ///
1037 /// @return COI_ARGUMENT_MISMATCH if in_pDependencies is NULL but
1038 ///         in_NumDependencies is not 0.
1039 ///
1040 /// @return COI_NOT_SUPPORTED or dimension of destination or source arrays
1041 ///         are greater than 3 or less than 1
1042 ///
1043 /// @return COI_INVALID_POINTER if the pointer in_SrcArray->base is NULL.
1044 ///
1045 /// @return COI_OUT_OF_RANGE if in_Offset + size of in_DestArray exceeds the
1046 ///         size of the buffer.
1047 ///
1048 /// @return COI_OUT_OF_MEMORY if any allocation of memory fails
1049 ///
1050 /// @return COI_RETRY if in_DestBuffer is mapped and is not
1051 ///         a COI_BUFFER_OPENCL buffer.
1052 ///
1053 COIACCESSAPI
1054 COIRESULT
1055 COIBufferWriteMultiD(
1056     COIBUFFER          in_DestBuffer,
1057     const   COIPROCESS         in_DestProcess,
1058     uint64_t           in_Offset,
1059     struct arr_desc   *in_DestArray,
1060     struct arr_desc   *in_SrcArray,
1061     COI_COPY_TYPE      in_Type,
1062     uint32_t           in_NumDependencies,
1063     const   COIEVENT          *in_pDependencies,
1064     COIEVENT          *out_pCompletion);
1065 
1066 //////////////////////////////////////////////////////////////////////////////
1067 ///
1068 /// Copy data specified by multi-dimensional array data structure from an
1069 /// existing COIBUFFER to another multi-dimensional array located in memory.
1070 /// Arrays with more than 3 dimensions are not supported.
1071 /// Different numbers of elements between source and destination are not supported.
1072 /// Please note that COIBufferReadMultiD does not follow implicit buffer
1073 /// dependencies. If a buffer is in use in a run function or has been added
1074 /// to a process using COIBufferAddRef the call to COIBufferReadMultiD will not
1075 /// wait, it will still copy data immediately.
1076 /// This is to facilitate a usage model where a buffer is being used outside
1077 /// of a run function, for example in a spawned thread, but data still needs
1078 /// to be transferred to or from the buffer.
1079 /// Additionally this means that if more than one DMA channel is enabled,
1080 /// (See COIProcessConfigureDMA) operations to the same buffer may
1081 /// happen in parallel if they can be assigned to different DMA hardware.
1082 /// So it is highly recommended to use explicit event dependencies to
1083 /// order operations where needed.
1084 ///
1085 ///
1086 /// @param  in_SourceBuffer
1087 ///         [in] Buffer to read from.
1088 ///
1089 /// @param  in_Offset
1090 ///         [in] Start location of the source array within the buffer.
1091 ///
1092 /// @param  in_DestArray
1093 ///         [in] A pointer to a data structure describing the structure of
1094 ///         the data array in the buffer. Total size must not be larger than
1095 ///         the size of in_DestBuffer. The base field of this structure will
1096 ///         be ignored.
1097 ///
1098 /// @param  in_SrcArray
1099 ///         [in] A pointer to a data structure describing the structure of
1100 ///         the data array in local memory that should be copied. in_SrcArray
1101 ///         and in_DestArry must have the same number of elements. The base
1102 ///         field of this structure should be the virtual pointer to the local
1103 ///         memory in which this array is located.
1104 ///
1105 /// @param  in_Type
1106 ///         [in] The type of copy operation to use, one of either
1107 ///         COI_COPY_UNSPECIFIED, COI_COPY_USE_DMA, COI_COPY_USE_CPU.
1108 ///
1109 /// @param  in_NumDependencies
1110 ///         [in] The number of dependencies specified in the in_pDependencies
1111 ///         array. This may be 0 if the caller does not want the write call to
1112 ///         wait for any additional events to be signaled before starting the
1113 ///         write operation.
1114 ///
1115 /// @param  in_pDependencies
1116 ///         [in] An optional array of handles to previously created COIEVENT
1117 ///         objects that this write operation will wait for before starting.
1118 ///         This allows the user to create dependencies between buffer write
1119 ///         calls and other operations such as run functions and map calls. The
1120 ///         user may pass in NULL if they do not wish to wait for any
1121 ///         additional dependencies to complete before doing the write.
1122 ///
1123 /// @param  out_pCompletion
1124 ///         [out] An optional event to be signaled when the write has
1125 ///         completed. This event can be used as a dependency to order
1126 ///         the write with regard to future operations.
1127 ///         If no completion event is passed in then the write is
1128 ///         synchronous and will block until the transfer is complete.
1129 ///
1130 ///
1131 /// @return COI_SUCCESS if the buffer was written successfully.
1132 ///
1133 /// @return COI_INVALID_HANDLE if the buffer or process handle was invalid.
1134 ///
1135 /// @return COI_OUT_OF_RANGE if in_Offset is beyond the end of the buffer.
1136 ///
1137 /// @return COI_ARGUMENT_MISMATCH if the in_pDependencies is non NULL but
1138 ///         in_NumDependencies is 0.
1139 ///
1140 /// @return COI_ARGUMENT_MISMATCH if in_pDependencies is NULL but
1141 ///         in_NumDependencies is not 0.
1142 ///
1143 /// @return COI_NOT_SUPPORTED or dimension of destination or source arrays
1144 ///         are greater than 3 or less than 1
1145 ///
1146 /// @return COI_INVALID_POINTER if the pointer in_DestArray->base is NULL.
1147 ///
1148 /// @return COI_OUT_OF_RANGE if in_Offset + size of in_SourceArray exceeds the
1149 ///         size of the buffer.
1150 ///
1151 /// @return COI_OUT_OF_MEMORY if any allocation of memory fails
1152 ///
1153 /// @return COI_RETRY if in_SourceBuffer is mapped and is not
1154 ///         a COI_BUFFER_OPENCL buffer.
1155 ///
1156 COIACCESSAPI
1157 COIRESULT
1158 COIBufferReadMultiD(
1159     COIBUFFER          in_SourceBuffer,
1160     uint64_t           in_Offset,
1161     struct arr_desc   *in_DestArray,
1162     struct arr_desc   *in_SrcArray,
1163     COI_COPY_TYPE      in_Type,
1164     uint32_t           in_NumDependencies,
1165     const   COIEVENT          *in_pDependencies,
1166     COIEVENT          *out_pCompletion);
1167 
1168 //////////////////////////////////////////////////////////////////////////////
1169 ///
1170 /// Copy data from a normal virtual address into an existing COIBUFFER.
1171 /// Please note that COIBufferWrite does not follow implicit buffer
1172 /// dependencies. If a buffer is in use in a run function or has been added
1173 /// to a process using COIBufferAddRef the call to COIBufferWrite will not
1174 /// wait, it will still copy data immediately.
1175 /// This is to facilitate a usage model where a buffer is being used outside
1176 /// of a run function, for example in a spawned thread, but data still needs
1177 /// to be transferred to or from the buffer.
1178 /// Additionally this means that if more than one DMA channel is enabled,
1179 /// (See COIProcessConfigureDMA) operations to the same buffer may
1180 /// happen in parallel if they can be assigned to different DMA hardware.
1181 /// So it is highly recommended to use explicit event dependencies to
1182 /// order operations where needed.
1183 ///
1184 /// @param  in_DestBuffer
1185 ///         [in] Buffer to write into.
1186 ///
1187 /// @param  in_Offset
1188 ///         [in] Location in the buffer to start writing to.
1189 ///
1190 /// @param  in_pSourceData
1191 ///         [in] A pointer to local memory that should be copied into the
1192 ///         provided buffer.
1193 ///
1194 /// @param  in_Length
1195 ///         [in] The number of bytes to write from in_pSourceData into
1196 ///         in_DestBuffer. Must not be larger than the size of in_DestBuffer
1197 ///         and must not over run in_DestBuffer if an in_Offset is provided.
1198 ///
1199 /// @param  in_Type
1200 ///         [in] The type of copy operation to use, one of either
1201 ///         COI_COPY_UNSPECIFIED, COI_COPY_USE_DMA, COI_COPY_USE_CPU.
1202 ///
1203 /// @param  in_NumDependencies
1204 ///         [in] The number of dependencies specified in the in_pDependencies
1205 ///         array. This may be 0 if the caller does not want the write call to
1206 ///         wait for any additional events to be signaled before starting the
1207 ///         write operation.
1208 ///
1209 /// @param  in_pDependencies
1210 ///         [in] An optional array of handles to previously created COIEVENT
1211 ///         objects that this write operation will wait for before starting.
1212 ///         This allows the user to create dependencies between buffer write
1213 ///         calls and other operations such as run functions and map calls. The
1214 ///         user may pass in NULL if they do not wish to wait for any
1215 ///         additional dependencies to complete before doing the write.
1216 ///
1217 /// @param  out_pCompletion
1218 ///         [out] An optional event to be signaled when the write has
1219 ///         completed. This event can be used as a dependency to order
1220 ///         the write with regard to future operations.
1221 ///         If no completion event is passed in then the write is
1222 ///         synchronous and will block until the transfer is complete.
1223 ///
1224 ///
1225 /// @return COI_SUCCESS if the buffer was copied successfully.
1226 ///
1227 /// @return COI_INVALID_HANDLE if the buffer handle was invalid.
1228 ///
1229 /// @return COI_OUT_OF_RANGE if in_Offset is beyond the end of the buffer.
1230 ///
1231 /// @return COI_ARGUMENT_MISMATCH if the in_pDependencies is non NULL but
1232 ///         in_NumDependencies is 0.
1233 ///
1234 /// @return COI_ARGUMENT_MISMATCH if in_pDependencies is NULL but
1235 ///         in_NumDependencies is not 0.
1236 ///
1237 /// @return COI_INVALID_POINTER if the in_pSourceData pointer is NULL.
1238 ///
1239 /// @return COI_OUT_OF_RANGE if in_Offset + in_Length exceeds the size of
1240 ///         the buffer.
1241 ///
1242 /// @return COI_OUT_OF_RANGE if in_Length is 0.
1243 ///
1244 /// @return COI_RETRY if in_DestBuffer is mapped and is not
1245 ///         a COI_BUFFER_OPENCL buffer.
1246 ///
1247 COIACCESSAPI
1248 COIRESULT
1249 COIBufferWrite(
1250     COIBUFFER           in_DestBuffer,
1251     uint64_t            in_Offset,
1252     const   void               *in_pSourceData,
1253     uint64_t            in_Length,
1254     COI_COPY_TYPE       in_Type,
1255     uint32_t            in_NumDependencies,
1256     const   COIEVENT           *in_pDependencies,
1257     COIEVENT           *out_pCompletion);
1258 
1259 //////////////////////////////////////////////////////////////////////////////
1260 ///
1261 /// Copy data from a buffer into local memory.
1262 /// Please note that COIBufferRead does not follow implicit buffer
1263 /// dependencies. If a buffer is in use in a run function or has been added
1264 /// to a process using COIBufferAddRef the call to COIBufferRead will not
1265 /// wait, it will still copy data immediately.
1266 /// This is to facilitate a usage model where a buffer is being used outside
1267 /// of a run function, for example in a spawned thread, but data still needs
1268 /// to be transferred to or from the buffer.
1269 /// Additionally this means that if more than one DMA channel is enabled,
1270 /// (See COIProcessConfigureDMA) operations to the same buffer may
1271 /// happen in parallel if they can be assigned to different DMA hardware.
1272 /// So it is highly recommended to use explicit event dependencies to
1273 /// order operations where needed.
1274 ///
1275 ///
1276 /// @param  in_SourceBuffer
1277 ///         [in] Buffer to read from.
1278 ///
1279 /// @param  in_Offset
1280 ///         [in] Location in the buffer to start reading from.
1281 ///
1282 /// @param  in_pDestData
1283 ///         [in] A pointer to local memory that should be written into from
1284 ///         the provided buffer.
1285 ///
1286 /// @param  in_Length
1287 ///         [in] The number of bytes to write from in_SourceBuffer into
1288 ///         in_pDestData. Must not be larger than the size of in_SourceBuffer
1289 ///         and must not over run in_SourceBuffer if an in_Offset is provided.
1290 ///
1291 /// @param  in_Type
1292 ///         [in] The type of copy operation to use, one of either
1293 ///         COI_COPY_UNSPECIFIED, COI_COPY_USE_DMA, COI_COPY_USE_CPU.
1294 ///
1295 /// @param  in_NumDependencies
1296 ///         [in] The number of dependencies specified in the in_pDependencies
1297 ///         array. This may be 0 if the caller does not want the read call to
1298 ///         wait for any additional events to be signaled before starting the
1299 ///         read operation.
1300 ///
1301 /// @param  in_pDependencies
1302 ///         [in] An optional array of handles to previously created COIEVENT
1303 ///         objects that this read operation will wait for before starting.
1304 ///         This allows the user to create dependencies between buffer read
1305 ///         calls and other operations such as run functions and map calls. The
1306 ///         user may pass in NULL if they do not wish to wait for any
1307 ///         additional dependencies to complete before doing the read.
1308 ///
1309 /// @param  out_pCompletion
1310 ///         [out] An optional event to be signaled when the read has
1311 ///         completed. This event can be used as a dependency to order
1312 ///         the read with regard to future operations.
1313 ///         If no completion event is passed in then the read is
1314 ///         synchronous and will block until the transfer is complete.
1315 ///
1316 /// @return COI_SUCCESS if the buffer was copied successfully.
1317 ///
1318 /// @return COI_INVALID_HANDLE if the buffer handle was invalid.
1319 ///
1320 /// @return COI_OUT_OF_RANGE if in_Offset is beyond the end of the buffer.
1321 ///
1322 /// @return COI_ARGUMENT_MISMATCH if the in_pDependencies is non NULL but
1323 ///         in_NumDependencies is 0.
1324 ///
1325 /// @return COI_ARGUMENT_MISMATCH if in_pDependencies is NULL but
1326 ///         in_NumDependencies is not 0.
1327 ///
1328 /// @return COI_OUT_OF_RANGE if in_Offset + in_Length exceeds the size of
1329 ///         the buffer.
1330 ///
1331 /// @return COI_OUT_OF_RANGE if in_Length is 0.
1332 ///
1333 /// @return COI_INVALID_POINTER if the in_pDestData pointer is NULL.
1334 ///
1335 /// @return COI_RETRY if in_SourceBuffer is mapped and is not
1336 ///         a COI_BUFFER_OPENCL buffer.
1337 ///
1338 COIACCESSAPI
1339 COIRESULT
1340 COIBufferRead(
1341     COIBUFFER           in_SourceBuffer,
1342     uint64_t            in_Offset,
1343     void               *in_pDestData,
1344     uint64_t            in_Length,
1345     COI_COPY_TYPE       in_Type,
1346     uint32_t            in_NumDependencies,
1347     const   COIEVENT           *in_pDependencies,
1348     COIEVENT           *out_pCompletion);
1349 
1350 //////////////////////////////////////////////////////////////////////////////
1351 ///
1352 /// Copy data between two buffers. It also allows copying within the same
1353 /// buffer. For copy within the same buffer, if source and destination regions
1354 /// overlap then this API returns error.
1355 /// Please note that COIBufferCopy does not follow implicit buffer
1356 /// dependencies. If a buffer is in use in a run function or has been added
1357 /// to a process using COIBufferAddRef the call to COIBufferCopy will not
1358 /// wait, it will still copy data immediately.
1359 /// This is to facilitate a usage model where a buffer is being used outside
1360 /// of a run function, for example in a spawned thread, but data still needs
1361 /// to be transferred to or from the buffer.
1362 /// Additionally this means that if more than one DMA channel is enabled,
1363 /// (See COIProcessConfigureDMA) operations to the same buffer may
1364 /// happen in parallel if they can be assigned to different DMA hardware.
1365 /// So it is highly recommended to use explicit event dependencies to
1366 /// order operations where needed.
1367 /// When a destroyed buffer (destination or source) is provided to the
1368 /// function, then behavior is unspecified.
1369 ///
1370 /// @param  in_DestBuffer
1371 ///         [in] Buffer to copy into.
1372 ///
1373 /// @param  in_DestProcess
1374 ///         [in] A pointer to the process to which the data will be written.
1375 ///         Buffer is updated only in this process and invalidated in other
1376 ///         processes. Only a single process can be specified.
1377 ///         Can be left NULL and default behavior will be chosen, which
1378 ///         chooses the first valid process in which regions are found. Other
1379 ///         buffer regions are invalidated if not updated.
1380 ///
1381 /// @param  in_SourceBuffer
1382 ///         [in] Buffer to copy from.
1383 ///
1384 /// @param  in_DestOffset
1385 ///         [in] Location in the destination buffer to start writing to.
1386 ///
1387 /// @param  in_SourceOffset
1388 ///         [in] Location in the source buffer to start reading from.
1389 ///
1390 /// @param  in_Length
1391 ///         [in] The number of bytes to copy from in_SourceBuffer into
1392 ///         in_DestinationBuffer.
1393 ///         If the length is specified as zero then length to be copied
1394 //          is entire destination buffer's length.
1395 ///         Must not be larger than the size of in_SourceBuffer or
1396 ///         in_DestBuffer and must not over run in_SourceBuffer or
1397 ///         in_DestBuffer if offsets are specified.
1398 ///
1399 /// @param  in_Type
1400 ///         [in] The type of copy operation to use, one of either
1401 ///         COI_COPY_UNSPECIFIED, COI_COPY_USE_DMA, COI_COPY_USE_CPU.
1402 ///
1403 /// @param  in_NumDependencies
1404 ///         [in] The number of dependencies specified in the in_pDependencies
1405 ///         array. This may be 0 if the caller does not want the copy call to
1406 ///         wait for any additional events to be signaled before starting the
1407 ///         copy operation.
1408 ///
1409 /// @param  in_pDependencies
1410 ///         [in] An optional array of handles to previously created COIEVENT
1411 ///         objects that this copy operation will wait for before starting.
1412 ///         This allows the user to create dependencies between buffer copy
1413 ///         calls and other operations such as run functions and map calls. The
1414 ///         user may pass in NULL if they do not wish to wait for any
1415 ///         additional dependencies to complete before doing the copy.
1416 ///
1417 /// @param  out_pCompletion
1418 ///         [out] An optional event to be signaled when the copy has
1419 ///         completed. This event can be used as a dependency to order
1420 ///         the copy with regard to future operations.
1421 ///         If no completion event is passed in then the copy is
1422 ///         synchronous and will block until the transfer is complete.
1423 ///
1424 /// @return COI_SUCCESS if the buffer was copied successfully.
1425 ///
1426 /// @return COI_INVALID_HANDLE if either buffer handle was invalid.
1427 ///
1428 /// @return COI_MEMORY_OVERLAP if in_SourceBuffer and in_DestBuffer are the
1429 ///         same buffer(or have the same parent buffer) and the source and
1430 ///         destination regions overlap
1431 ///
1432 /// @return COI_OUT_OF_RANGE if in_DestOffset is is beyond the end of
1433 ///         in_DestBuffer
1434 ///
1435 /// @return COI_OUT_OF_RANGE if in_SourceOffset is beyond the end of
1436 ///         in_SourceBuffer.
1437 ///
1438 /// @return COI_OUT_OF_RANGE if in_DestOffset + in_Length exceeds the size of
1439 ///         the in_DestBuffer
1440 ///
1441 /// @return COI_OUT_OF_RANGE if in_SourceOffset + in_Length exceeds
1442 ///         the size of in_SourceBuffer.
1443 ///
1444 /// @return COI_ARGUMENT_MISMATCH if the in_pDependencies is non NULL but
1445 ///         in_NumDependencies is 0.
1446 ///
1447 /// @return COI_ARGUMENT_MISMATCH if in_pDependencies is NULL but
1448 ///         in_NumDependencies is not 0.
1449 ///
1450 /// @return COI_RETRY if in_DestBuffer or in_SourceBuffer are mapped and not
1451 ///         COI_BUFFER_OPENCL buffers.
1452 ///
1453 COIACCESSAPI
1454 COIRESULT
1455 COIBufferCopyEx(
1456     COIBUFFER           in_DestBuffer,
1457     const   COIPROCESS          in_DestProcess,
1458     COIBUFFER           in_SourceBuffer,
1459     uint64_t            in_DestOffset,
1460     uint64_t            in_SourceOffset,
1461     uint64_t            in_Length,
1462     COI_COPY_TYPE       in_Type,
1463     uint32_t            in_NumDependencies,
1464     const   COIEVENT           *in_pDependencies,
1465     COIEVENT           *out_pCompletion);
1466 
1467 //////////////////////////////////////////////////////////////////////////////
1468 ///
1469 /// Copy data between two buffers. It also allows copying within the same
1470 /// buffer. For copy within the same buffer, if source and destination regions
1471 /// overlap then this API returns error.
1472 /// Please note that COIBufferCopy does not follow implicit buffer
1473 /// dependencies. If a buffer is in use in a run function or has been added
1474 /// to a process using COIBufferAddRef the call to COIBufferCopy will not
1475 /// wait, it will still copy data immediately.
1476 /// This is to facilitate a usage model where a buffer is being used outside
1477 /// of a run function, for example in a spawned thread, but data still needs
1478 /// to be transferred to or from the buffer.
1479 /// Additionally this means that if more than one DMA channel is enabled,
1480 /// (See COIProcessConfigureDMA) operations to the same buffer may
1481 /// happen in parallel if they can be assigned to different DMA hardware.
1482 /// So it is highly recommended to use explicit event dependencies to
1483 /// order operations where needed.
1484 /// When a destroyed buffer (destination or source) is provided to the
1485 /// function, then behavior is unspecified.
1486 ///
1487 /// @param  in_DestBuffer
1488 ///         [in] Buffer to copy into.
1489 ///
1490 /// @param  in_SourceBuffer
1491 ///         [in] Buffer to copy from.
1492 ///
1493 /// @param  in_DestOffset
1494 ///         [in] Location in the destination buffer to start writing to.
1495 ///
1496 /// @param  in_SourceOffset
1497 ///         [in] Location in the source buffer to start reading from.
1498 ///
1499 /// @param  in_Length
1500 ///         [in] The number of bytes to copy from in_SourceBuffer into
1501 ///         in_DestinationBuffer.
1502 ///         If the length is specified as zero then length to be copied
1503 ///         is entire destination buffer's length.
1504 ///         Must not be larger than the size of in_SourceBuffer or
1505 ///         in_DestBuffer and must not over run in_SourceBuffer or
1506 ///         in_DestBuffer if offsets are specified.
1507 ///
1508 /// @param  in_Type
1509 ///         [in] The type of copy operation to use, one of either
1510 ///         COI_COPY_UNSPECIFIED, COI_COPY_USE_DMA, COI_COPY_USE_CPU.
1511 ///
1512 /// @param  in_NumDependencies
1513 ///         [in] The number of dependencies specified in the in_pDependencies
1514 ///         array. This may be 0 if the caller does not want the copy call to
1515 ///         wait for any additional events to be signaled before starting the
1516 ///         copy operation.
1517 ///
1518 /// @param  in_pDependencies
1519 ///         [in] An optional array of handles to previously created COIEVENT
1520 ///         objects that this copy operation will wait for before starting.
1521 ///         This allows the user to create dependencies between buffer copy
1522 ///         calls and other operations such as run functions and map calls. The
1523 ///         user may pass in NULL if they do not wish to wait for any
1524 ///         additional dependencies to complete before doing the copy.
1525 ///
1526 /// @param  out_pCompletion
1527 ///         [out] An optional event to be signaled when the copy has
1528 ///         completed. This event can be used as a dependency to order
1529 ///         the copy with regard to future operations.
1530 ///         If no completion event is passed in then the copy is
1531 ///         synchronous and will block until the transfer is complete.
1532 ///
1533 /// @return COI_SUCCESS if the buffer was copied successfully.
1534 ///
1535 /// @return COI_INVALID_HANDLE if either buffer handle was invalid.
1536 ///
1537 /// @return COI_MEMORY_OVERLAP if in_SourceBuffer and in_DestBuffer are the
1538 ///         same buffer(or have the same parent buffer) and the source and
1539 ///         destination regions overlap
1540 ///
1541 /// @return COI_OUT_OF_RANGE if in_DestOffset is is beyond the end of
1542 ///         in_DestBuffer
1543 ///
1544 /// @return COI_OUT_OF_RANGE if in_SourceOffset is beyond the end of
1545 ///         in_SourceBuffer.
1546 ///
1547 /// @return COI_OUT_OF_RANGE if in_DestOffset + in_Length exceeds the size of
1548 ///         the in_DestBuffer
1549 ///
1550 /// @return COI_OUT_OF_RANGE if in_SourceOffset + in_Length exceeds
1551 ///         the size of in_SourceBuffer.
1552 ///
1553 /// @return COI_ARGUMENT_MISMATCH if the in_pDependencies is non NULL but
1554 ///         in_NumDependencies is 0.
1555 ///
1556 /// @return COI_ARGUMENT_MISMATCH if in_pDependencies is NULL but
1557 ///         in_NumDependencies is not 0.
1558 ///
1559 /// @return COI_RETRY if in_DestBuffer or in_SourceBuffer are mapped and not
1560 ///         COI_BUFFER_OPENCL buffers.
1561 ///
1562 COIACCESSAPI
1563 COIRESULT
1564 COIBufferCopy(
1565     COIBUFFER           in_DestBuffer,
1566     COIBUFFER           in_SourceBuffer,
1567     uint64_t            in_DestOffset,
1568     uint64_t            in_SourceOffset,
1569     uint64_t            in_Length,
1570     COI_COPY_TYPE       in_Type,
1571     uint32_t            in_NumDependencies,
1572     const   COIEVENT           *in_pDependencies,
1573     COIEVENT           *out_pCompletion);
1574 
1575 //////////////////////////////////////////////////////////////////////////////
1576 ///
1577 /// This API allows an experienced Intel(R) Coprocessor Offload Infrastructure
1578 /// (Intel(R) COI) developer to set where a COIBUFFER is
1579 /// located and when the COIBUFFER's data is moved. This functionality is
1580 /// useful when the developer knows when and where a buffer is going to be
1581 /// accessed. It allows the data movement to happen sooner than if the
1582 /// Intel(R) Coprocessor Offload Infrastructure (Intel(R) COI)
1583 /// runtime tried to manage the buffer placement itself. The advantage of
1584 /// this API is that the developer knows much more about their own
1585 /// application's data access patterns and can therefore optimize the data
1586 /// access to be much more efficient than the Intel(R)Coprocessor Offload
1587 /// Infrastructure (Intel(R) COI) runtime. Using this API may yield better
1588 /// memory utilization, lower latency and overall improved workload
1589 /// throughput.
1590 /// This API does respect implicit dependencies for buffer read/write hazards.
1591 /// For example, if the buffer is being written in one COIPROCESS and the user
1592 /// requests the buffer be placed in another COIPROCESS then this API will wait
1593 /// for the first access to complete before moving the buffer.
1594 /// This API is not required for program correctness. It is intended solely
1595 /// for advanced Intel(R) Coprocessor Offload Infrastructure (Intel(R) COI)
1596 /// developers who wish to fine tune their application performance
1597 /// Cases where "a change in state" is an error condition the change just gets
1598 /// ignored without any error. This is because the SetState can be a
1599 /// nonblocking call and in such cases we can't rely on the state of the buffer
1600 /// at the time of the call. We can do the transition checks only at the time
1601 /// when the actual state change happens (which is something in future).
1602 /// Currently there is no way to report an error from something that happens in
1603 /// future and that is why such state transitions are nop. One example is using
1604 /// VALID_MAY_DROP with COI_SINK_OWNERS when buffer is not valid at source.
1605 /// This operation will be a nop if at the time of actual state change the
1606 /// buffer is not valid at source.
1607 ///
1608 /// @param  in_Buffer
1609 ///         [in] The buffer to modify.
1610 ///
1611 /// @param  in_Process
1612 ///         [in] The process where the state is being modified for this
1613 ///         buffer. To modify buffer's state on source process use
1614 ///         COI_PROCESS_SOURCE as process handle. To modify buffer's
1615 ///         state on all processes where buffer is valid use COI_SINK_OWNERS
1616 ///         as the process handle.
1617 ///
1618 /// @param  in_State
1619 ///         [in] The new state for the buffer. The buffer's state could be
1620 ///         set to invalid on one of the sink processes where it is being
1621 ///         used.
1622 ///
1623 /// @param  in_DataMove
1624 ///         [in] A flag to indicate if the buffer's data should be moved
1625 ///         when the state is changed. For instance, a buffer's state may
1626 ///         be set to valid on a process and the data move flag may be set to
1627 ///         COI_BUFFER_MOVE which would cause the buffer contents to be
1628 ///         copied to the process where it is now valid.
1629 ///
1630 /// @param  in_NumDependencies
1631 ///         [in] The number of dependencies specified in the in_pDependencies
1632 ///         array. This may be 0 if the caller does not want the SetState call
1633 ///         to wait for any additional events to be signaled before starting
1634 ///         this operation.
1635 ///
1636 /// @param  in_pDependencies
1637 ///         [in] An optional array of handles to previously created COIEVENT
1638 ///         objects that this SetState operation will wait for before starting
1639 ///         This allows the user to create dependencies between buffer
1640 ///         SetState calls and other operations such as run functions and map
1641 ///         calls. The user may pass in NULL if they do not wish to wait for
1642 ///         any additional dependencies to complete before doing the SetState
1643 ///
1644 /// @param  out_pCompletion
1645 ///         [out] An optional event to be signaled when the SetState has
1646 ///         completed. This event can be used as a dependency to order
1647 ///         the SetState with regard to future operations.
1648 ///         If no completion event is passed in then the state changing is
1649 ///         synchronous and will block until the SetState and dma transfers
1650 ///         related to this operation are complete.
1651 ///
1652 /// @return COI_SUCCESS if the buffer's state was changed successfully.
1653 ///
1654 /// @return COI_INVALID_HANDLE if in_Buffer or in_Process is invalid.
1655 ///
1656 /// @return COI_NOT_SUPPORTED if the in_Buffer is of any type other than
1657 ///         COI_BUFFER_NORMAL or COI_BUFFER_OPENCL.
1658 ///
1659 /// @return COI_ARGUMENT_MISMATCH if the in_State is COI_BUFFER_VALID_MAY_DROP
1660 ///         and the in_Process is COI_PROCESS_SOURCE.
1661 ///
1662 /// @return COI_ARGUMENT_MISMATCH if the in_Process is COI_SINK_OWNERS and the
1663 ///         COI_BUFFER_MOVE is passed as move flag.
1664 ///
1665 /// @return COI_MISSING_DEPENDENCY if buffer was not created on the process
1666 ///         handle that was passed in.
1667 ///
1668 COIACCESSAPI
1669 COIRESULT
1670 COIBufferSetState(
1671     COIBUFFER               in_Buffer,
1672     COIPROCESS              in_Process,
1673     COI_BUFFER_STATE        in_State,
1674     COI_BUFFER_MOVE_FLAG    in_DataMove,
1675     uint32_t                in_NumDependencies,
1676     const   COIEVENT               *in_pDependencies,
1677     COIEVENT               *out_pCompletion);
1678 
1679 //////////////////////////////////////////////////////////////////////////////
1680 ///
1681 /// Creates a sub-buffer that is a reference to a portion of an existing
1682 /// buffer. The returned buffer handle can be used in all API calls that the
1683 /// original buffer handle could be used in except COIBufferCreateSubBuffer.
1684 /// Sub buffers out of Huge Page Buffer are also supported but the original
1685 /// buffer needs to be a OPENCL buffer created with COI_OPTIMIZE_HUGE_PAGE_SIZE
1686 /// flag.
1687 ///
1688 /// When the sub-buffer is used only the corresponding sub-section of the
1689 /// original buffer is used or affected.
1690 ///
1691 /// @param  in_Buffer
1692 ///         [in] The original buffer that this new sub-buffer is a reference
1693 ///         to.
1694 ///
1695 /// @param  in_Length
1696 ///         [in] The length of the sub-buffer in number of bytes.
1697 ///
1698 /// @param  in_Offset
1699 ///         [in] Where in the original buffer to start this sub-buffer.
1700 ///
1701 /// @param  out_pSubBuffer
1702 ///         [out] Pointer to a buffer handle that is filled in with the newly
1703 ///         created sub-buffer.
1704 ///
1705 /// @return COI_SUCCESS if the sub-buffer was created
1706 ///
1707 /// @return COI_INVALID_HANDLE if in_Buffer is not a valid buffer handle.
1708 ///
1709 /// @return COI_OUT_OF_RANGE if in_Length is zero, or if in_Offset + in_Length
1710 ///         is greater than the size of the original buffer.
1711 ///
1712 /// @return COI_OUT_OF_MEMORY if allocating the buffer fails.
1713 ///
1714 /// @return COI_INVALID_POINTER if the out_pSubBuffer pointer is NULL.
1715 ///
1716 /// @return COI_NOT_SUPPORTED if the in_Buffer is of any type other than
1717 ///         COI_BUFFER_OPENCL
1718 ///
1719 COIACCESSAPI
1720 COIRESULT
1721 COIBufferCreateSubBuffer(
1722     COIBUFFER   in_Buffer,
1723     uint64_t    in_Length,
1724     uint64_t    in_Offset,
1725     COIBUFFER  *out_pSubBuffer);
1726 
1727 //////////////////////////////////////////////////////////////////////////////
1728 ///
1729 /// Releases the reference count on the specified buffer and process by
1730 /// in_ReleaseRefcnt. The returned result being COI_SUCCESS indicates that the
1731 /// specified process contains a reference to the specified buffer that has a
1732 /// refcnt that can be decremented. Otherwise, if the buffer or process
1733 /// specified do not exist, then COI_INVALID_HANDLE will be returned. If the
1734 /// process does not contain a reference to the specified buffer then
1735 /// COI_OUT_OF_RANGE will be returned.
1736 ///
1737 ///
1738 /// @param  in_Process
1739 ///         [in] The COI Process whose reference count for the specified buffer
1740 ///         the user wants to decrement.
1741 ///
1742 /// @param  in_Buffer
1743 ///         [in] The buffer used in the specified coi process in which the user
1744 ///         wants to decrement the reference count.
1745 ///
1746 /// @param  in_ReleaseRefcnt
1747 ///         [in] The value the reference count will be decremented by.
1748 ///
1749 /// @return COI_SUCCESS if the reference count was successfully decremented.
1750 ///
1751 /// @return COI_INVALID_HANDLE if in_Buffer or in_Process are invalid handles.
1752 ///
1753 /// @return COI_OUT_OF_RANGE if the reference for the specified buffer or
1754 ///         process does not exist.
1755 ///
1756 
1757 COIACCESSAPI
1758 COIRESULT
1759 COIBufferReleaseRefcnt(
1760     COIPROCESS          in_Process,
1761     COIBUFFER           in_Buffer,
1762     uint64_t            in_ReleaseRefcnt);
1763 
1764 //////////////////////////////////////////////////////////////////////////////
1765 ///
1766 /// Increments the reference count on the specified buffer and process by
1767 /// in_AddRefcnt. The returned result being COI_SUCCESS indicates that the
1768 /// specified process contains a reference to the specified buffer or a new
1769 /// reference has been created and that reference has a new refcnt. Otherwise,
1770 /// if the buffer or process specified do not exist, then COI_INVALID_HANDLE
1771 /// will be returned. If the input buffer is not valid on the target process
1772 /// then COI_NOT_INITIALIZED will be returned since the buffer is not current
1773 /// or allocated on the process.
1774 ///
1775 /// @param  in_Process
1776 ///         [in] The COI Process whose reference count for the specified buffer
1777 ///         the user wants to increment.
1778 ///
1779 /// @param  in_Buffer
1780 ///         [in] The buffer used in the specified coi process in which the user
1781 ///         wants to increment the reference count.
1782 ///
1783 /// @param  in_AddRefcnt
1784 ///         [in] The value the reference count will be incremented by.
1785 ///
1786 /// @return COI_SUCCESS if the reference count was successfully incremented.
1787 ///
1788 /// @return COI_INVALID_HANDLE if in_Buffer or in_Process are invalid handles.
1789 ///
1790 /// @return COI_NOT_INITIALIZED if in_Buffer does not have a buffer state of
1791 ///         COI_BUFFER_VALID on the in_Process.
1792 ///
1793 COIACCESSAPI
1794 COIRESULT
1795 COIBufferAddRefcnt(
1796     COIPROCESS          in_Process,
1797     COIBUFFER           in_Buffer,
1798     uint64_t            in_AddRefcnt);
1799 
1800 #ifdef __cplusplus
1801 } /* extern "C" */
1802 #endif
1803 
1804 #endif /* _COIBUFFER_SOURCE_H */
1805 
1806 /*! @} */
1807