2 Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 //#include "offload.h"
34 #include "compiler_if_host.h"
39 void omp_set_default_device(int num
) __GOMP_NOTHROW
42 __omp_device_num
= num
;
46 int omp_get_default_device(void) __GOMP_NOTHROW
48 return __omp_device_num
;
51 int omp_get_num_devices() __GOMP_NOTHROW
53 __offload_init_library();
54 return mic_engines_total
;
59 // COI supports 3-dim multiD transfers
60 #define MAX_ARRAY_RANK 3
62 int omp_get_initial_device(
69 void* omp_target_alloc(
74 __offload_init_library();
76 OFFLOAD_TRACE(2, "omp_target_alloc(%lld, %d)\n", size
, device_num
);
78 if (device_num
< -1) {
79 LIBOFFLOAD_ERROR(c_invalid_device_number
);
86 if (device_num
== -1) {
87 // We do not check for malloc returning NULL because the
88 // specification of this API includes the possibility of failure.
89 // The user will check the returned result
90 result
= malloc(size
);
94 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(
95 TARGET_MIC
, device_num
, 0, NULL
, __func__
, 0);
97 VarDesc vars
[2] = {0};
99 vars
[0].type
.src
= c_data
;
100 vars
[0].type
.dst
= c_data
;
101 vars
[0].direction
.bits
= c_parameter_in
;
102 vars
[0].size
= sizeof(size
);
106 vars
[1].type
.src
= c_data
;
107 vars
[1].type
.dst
= c_data
;
108 vars
[1].direction
.bits
= c_parameter_out
;
109 vars
[1].size
= sizeof(result
);
111 vars
[1].ptr
= &result
;
113 OFFLOAD_OFFLOAD(ofld
, "omp_target_alloc_target",
114 0, 2, vars
, NULL
, 0, 0, 0);
119 void omp_target_free(
124 __offload_init_library();
126 OFFLOAD_TRACE(2, "omp_target_free(%p, %d)\n", device_ptr
, device_num
);
128 if (device_num
< -1) {
129 LIBOFFLOAD_ERROR(c_invalid_device_number
);
134 if (device_num
== -1) {
139 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(
140 TARGET_MIC
, device_num
, 0, NULL
, __func__
, 0);
142 VarDesc vars
[1] = {0};
144 vars
[0].type
.src
= c_data
;
145 vars
[0].type
.dst
= c_data
;
146 vars
[0].direction
.bits
= c_parameter_in
;
147 vars
[0].size
= sizeof(device_ptr
);
149 vars
[0].ptr
= &device_ptr
;
151 OFFLOAD_OFFLOAD(ofld
, "omp_target_free_target",
152 0, 1, vars
, NULL
, 0, 0, 0);
156 int omp_target_is_present(
161 __offload_init_library();
163 OFFLOAD_TRACE(2, "omp_target_is_present(%p, %d)\n", ptr
, device_num
);
165 if (device_num
< -1) {
166 LIBOFFLOAD_ERROR(c_invalid_device_number
);
170 if (device_num
== -1) {
174 // If OpenMP allows wrap-around for device numbers, enable next line
175 //device_num %= mic_engines_total;
177 // lookup existing association in pointer table
178 PtrData
* ptr_data
= mic_engines
[device_num
].find_ptr_data(ptr
);
180 OFFLOAD_TRACE(3, "Address %p is not mapped on device %d\n",
185 OFFLOAD_TRACE(3, "Address %p found mapped on device %d\n",
190 int omp_target_memcpy(
200 __offload_init_library();
202 OFFLOAD_TRACE(2, "omp_target_memcpy(%p, %p, %lld, %lld, %lld, %d, %d)\n",
203 dst
, src
, length
, dst_offset
, src_offset
, dst_device
, src_device
);
205 if (dst_device
< -1 || src_device
< -1) {
206 LIBOFFLOAD_ERROR(c_invalid_device_number
);
210 char* srcp
= (char *)src
+ src_offset
;
211 char* dstp
= (char *)dst
+ dst_offset
;
213 if (src_device
== -1) {
215 if (dst_device
== -1) {
217 memcpy(dstp
, srcp
, length
);
222 // If OpenMP allows wrap-around for device numbers, enable next line
223 //dst_device %= mic_engines_total;
225 OFFLOAD_TRACE(3, "Creating buffer from sink memory %llx\n", dstp
);
227 COIRESULT res
= COI::BufferCreateFromMemory(length
,
228 COI_BUFFER_NORMAL
, COI_SINK_MEMORY
, dstp
,
229 1, &mic_engines
[dst_device
].get_process(),
231 if (res
!= COI_SUCCESS
) {
232 LIBOFFLOAD_ERROR(c_buf_create_from_mem
, res
);
235 res
= COI::BufferWrite(mic_buf
, 0, srcp
, length
,
236 COI_COPY_UNSPECIFIED
, 0, 0, 0);
237 if (res
!= COI_SUCCESS
) {
238 LIBOFFLOAD_ERROR(c_buf_write
, res
);
241 res
= COI::BufferDestroy(mic_buf
);
242 if (res
!= COI_SUCCESS
) {
243 LIBOFFLOAD_ERROR(c_buf_destroy
, res
);
250 if (dst_device
== -1) {
254 // If OpenMP allows wrap-around for device numbers, enable next line
255 //src_device %= mic_engines_total;
257 OFFLOAD_TRACE(3, "Creating buffer from sink memory %llx\n", srcp
);
259 COIRESULT res
= COI::BufferCreateFromMemory(length
,
260 COI_BUFFER_NORMAL
, COI_SINK_MEMORY
, srcp
,
261 1, &mic_engines
[src_device
].get_process(),
263 if (res
!= COI_SUCCESS
) {
264 LIBOFFLOAD_ERROR(c_buf_create_from_mem
, res
);
267 res
= COI::BufferRead(mic_buf
, 0, dstp
, length
,
268 COI_COPY_UNSPECIFIED
, 0, 0, 0);
269 if (res
!= COI_SUCCESS
) {
270 LIBOFFLOAD_ERROR(c_buf_read
, res
);
273 res
= COI::BufferDestroy(mic_buf
);
274 if (res
!= COI_SUCCESS
) {
275 LIBOFFLOAD_ERROR(c_buf_destroy
, res
);
280 // some MIC -> some MIC
281 if (src_device
== dst_device
) {
282 // MIC local copy will be done as remote memcpy
284 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(TARGET_MIC
, src_device
,
285 0, NULL
, __func__
, 0);
287 VarDesc vars
[3] = {0};
289 vars
[0].type
.src
= c_data
;
290 vars
[0].type
.dst
= c_data
;
291 vars
[0].direction
.bits
= c_parameter_in
;
292 vars
[0].size
= sizeof(dstp
);
296 vars
[1].type
.src
= c_data
;
297 vars
[1].type
.dst
= c_data
;
298 vars
[1].direction
.bits
= c_parameter_in
;
299 vars
[1].size
= sizeof(srcp
);
303 vars
[2].type
.src
= c_data
;
304 vars
[2].type
.dst
= c_data
;
305 vars
[2].direction
.bits
= c_parameter_in
;
306 vars
[2].size
= sizeof(length
);
308 vars
[2].ptr
= &length
;
310 OFFLOAD_OFFLOAD(ofld
, "omp_target_memcpy_target",
311 0, 3, vars
, NULL
, 0, 0, 0);
318 // Allocate CPU buffer
319 char *cpu_mem
= (char *)malloc(length
);
321 LIBOFFLOAD_ERROR(c_malloc
);
325 if (omp_target_memcpy(
326 cpu_mem
, srcp
, length
, 0, 0, -1, src_device
) == 0) {
327 retval
= omp_target_memcpy(
328 dstp
, cpu_mem
, length
, 0, 0, dst_device
, -1);
337 static size_t bytesize_at_this_dimension(
340 const size_t* dimensions
344 return dimensions
[1] *
345 bytesize_at_this_dimension(
346 element_size
, num_dims
-1, dimensions
+1);
352 static void memcpy_rect(
357 const size_t *volume
,
358 const size_t *dst_offsets
,
359 const size_t *src_offsets
,
360 const size_t *dst_dimensions
,
361 const size_t *src_dimensions
365 int count
= volume
[0];
366 int dst_index
= dst_offsets
[0];
367 int src_index
= src_offsets
[0];
368 size_t dst_element_size
=
369 bytesize_at_this_dimension(element_size
, num_dims
, dst_dimensions
);
370 size_t src_element_size
=
371 bytesize_at_this_dimension(element_size
, num_dims
, src_dimensions
);
372 for (; count
>0; dst_index
++, src_index
++, count
--) {
373 memcpy_rect(dst
+dst_element_size
*dst_index
,
374 src
+src_element_size
*src_index
,
375 element_size
, num_dims
-1, volume
+1,
376 dst_offsets
+1, src_offsets
+1,
377 dst_dimensions
+1, src_dimensions
+1);
380 memcpy(dst
+dst_offsets
[0]*element_size
,
381 src
+src_offsets
[0]*element_size
,
382 element_size
* volume
[0]);
386 int omp_target_memcpy_rect(
391 const size_t *volume
,
392 const size_t *dst_offsets
,
393 const size_t *src_offsets
,
394 const size_t *dst_dimensions
,
395 const size_t *src_dimensions
,
400 char *dst
= (char *)dst_
;
401 char *src
= (char *)src_
;
403 __offload_init_library();
405 OFFLOAD_TRACE(2, "omp_target_memcpy_rect(%p, %p, %lld, %d, "
406 "%p, %p, %p, %p, %p, %d, %d)\n",
407 dst
, src
, element_size
, num_dims
,
408 volume
, dst_offsets
, src_offsets
,
409 dst_dimensions
, src_dimensions
, dst_device
, src_device
);
411 // MAX_ARRAY_RANK dimensions are supported
412 if (dst
== 0 && src
== 0) {
413 return MAX_ARRAY_RANK
;
416 if (num_dims
< 1 || num_dims
> MAX_ARRAY_RANK
||
418 volume
== 0 || dst_offsets
== 0 || src_offsets
== 0 ||
419 dst_dimensions
== 0 || src_dimensions
== 0) {
423 if (dst_device
< -1 || src_device
< -1) {
424 LIBOFFLOAD_ERROR(c_invalid_device_number
);
428 if (src_device
== -1) {
430 if (dst_device
== -1) {
432 memcpy_rect((char*)dst
, (char*)src
, element_size
, num_dims
, volume
,
433 dst_offsets
, src_offsets
,
434 dst_dimensions
, src_dimensions
);
438 // COIBufferWriteMultiD
439 struct arr_desc dst_desc
;
440 struct arr_desc src_desc
;
442 dst_desc
.base
= (int64_t)dst
;
443 dst_desc
.rank
= num_dims
;
445 src_desc
.base
= (int64_t)src
;
446 src_desc
.rank
= num_dims
;
448 for (int i
=0; i
<num_dims
; i
++)
450 dst_desc
.dim
[i
].size
= bytesize_at_this_dimension(
454 dst_desc
.dim
[i
].lindex
= 0;
455 dst_desc
.dim
[i
].lower
= dst_offsets
[i
];
456 dst_desc
.dim
[i
].upper
= dst_offsets
[i
] + volume
[i
] - 1;
457 dst_desc
.dim
[i
].stride
= 1;
459 src_desc
.dim
[i
].size
= bytesize_at_this_dimension(
463 src_desc
.dim
[i
].lindex
= 0;
464 src_desc
.dim
[i
].lower
= src_offsets
[i
];
465 src_desc
.dim
[i
].upper
= src_offsets
[i
] + volume
[i
] - 1;
466 src_desc
.dim
[i
].stride
= 1;
468 __arr_desc_dump("", "dst", (const Arr_Desc
*)&dst_desc
, false, false);
469 __arr_desc_dump("", "src", (const Arr_Desc
*)&src_desc
, false, false);
471 // If OpenMP allows wrap-around for device numbers, enable next line
472 //dst_device %= mic_engines_total;
474 // Compute MIC buffer size
475 size_t dst_length
= dst_dimensions
[0] * bytesize_at_this_dimension(
481 "Creating buffer from sink memory %llx of size %lld\n",
484 COIRESULT res
= COI::BufferCreateFromMemory(dst_length
,
485 COI_BUFFER_NORMAL
, COI_SINK_MEMORY
, dst
,
486 1, &mic_engines
[dst_device
].get_process(),
488 if (res
!= COI_SUCCESS
) {
489 LIBOFFLOAD_ERROR(c_buf_create_from_mem
, res
);
492 res
= COI::BufferWriteMultiD(mic_buf
,
493 mic_engines
[dst_device
].get_process(),
494 0, &dst_desc
, &src_desc
,
495 COI_COPY_UNSPECIFIED
, 0, 0, 0);
496 if (res
!= COI_SUCCESS
) {
497 LIBOFFLOAD_ERROR(c_buf_write
, res
);
500 res
= COI::BufferDestroy(mic_buf
);
501 if (res
!= COI_SUCCESS
) {
502 LIBOFFLOAD_ERROR(c_buf_destroy
, res
);
509 if (dst_device
== -1) {
510 // COIBufferReadMultiD
511 struct arr_desc dst_desc
;
512 struct arr_desc src_desc
;
514 dst_desc
.base
= (int64_t)dst
;
515 dst_desc
.rank
= num_dims
;
517 src_desc
.base
= (int64_t)src
;
518 src_desc
.rank
= num_dims
;
520 for (int i
=0; i
<num_dims
; i
++)
522 dst_desc
.dim
[i
].size
= bytesize_at_this_dimension(
526 dst_desc
.dim
[i
].lindex
= 0;
527 dst_desc
.dim
[i
].lower
= dst_offsets
[i
];
528 dst_desc
.dim
[i
].upper
= dst_offsets
[i
] + volume
[i
] - 1;
529 dst_desc
.dim
[i
].stride
= 1;
531 src_desc
.dim
[i
].size
= bytesize_at_this_dimension(
535 src_desc
.dim
[i
].lindex
= 0;
536 src_desc
.dim
[i
].lower
= src_offsets
[i
];
537 src_desc
.dim
[i
].upper
= src_offsets
[i
] + volume
[i
] - 1;
538 src_desc
.dim
[i
].stride
= 1;
540 __arr_desc_dump("", "dst", (const Arr_Desc
*)&dst_desc
, false, false);
541 __arr_desc_dump("", "src", (const Arr_Desc
*)&src_desc
, false, false);
543 // If OpenMP allows wrap-around for device numbers, enable next line
544 //src_device %= mic_engines_total;
546 // Compute MIC buffer size
547 size_t src_length
= src_dimensions
[0] * bytesize_at_this_dimension(
553 "Creating buffer from sink memory %llx of size %lld\n",
556 COIRESULT res
= COI::BufferCreateFromMemory(src_length
,
557 COI_BUFFER_NORMAL
, COI_SINK_MEMORY
, src
,
558 1, &mic_engines
[src_device
].get_process(),
560 if (res
!= COI_SUCCESS
) {
561 LIBOFFLOAD_ERROR(c_buf_create_from_mem
, res
);
564 res
= COI::BufferReadMultiD(mic_buf
, 0,
565 &dst_desc
, &src_desc
,
566 COI_COPY_UNSPECIFIED
, 0, 0, 0);
567 if (res
!= COI_SUCCESS
) {
568 LIBOFFLOAD_ERROR(c_buf_write
, res
);
571 res
= COI::BufferDestroy(mic_buf
);
572 if (res
!= COI_SUCCESS
) {
573 LIBOFFLOAD_ERROR(c_buf_destroy
, res
);
578 // some MIC -> some MIC
579 if (src_device
== dst_device
) {
580 // MIC local copy will be done as remote memcpy_rect
586 size_t array_info
[MAX_ARRAY_RANK
*5];
587 } parameters
= {dst
, src
, element_size
, num_dims
};
590 for (int i
=0; i
<num_dims
; i
++)
592 parameters
.array_info
[i
] = volume
[i
];
593 parameters
.array_info
[i
+num_dims
] = dst_offsets
[i
];
594 parameters
.array_info
[i
+num_dims
*2] = src_offsets
[i
];
595 parameters
.array_info
[i
+num_dims
*3] = dst_dimensions
[i
];
596 parameters
.array_info
[i
+num_dims
*4] = src_dimensions
[i
];
599 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(TARGET_MIC
, src_device
,
600 0, NULL
, __func__
, 0);
602 VarDesc vars
[1] = {0};
604 vars
[0].type
.src
= c_data
;
605 vars
[0].type
.dst
= c_data
;
606 vars
[0].direction
.bits
= c_parameter_in
;
607 vars
[0].size
= sizeof(parameters
) -
608 (MAX_ARRAY_RANK
- num_dims
) *
611 vars
[0].ptr
= ¶meters
;
613 OFFLOAD_OFFLOAD(ofld
, "omp_target_memcpy_rect_target",
614 0, 1, vars
, NULL
, 0, 0, 0);
622 // Compute transfer byte-count
623 size_t dst_length
= element_size
;
624 for (int i
=0; i
<num_dims
; i
++) {
625 dst_length
*= volume
[i
];
628 // Allocate CPU buffer
629 char *cpu_mem
= (char *)malloc(dst_length
);
631 LIBOFFLOAD_ERROR(c_malloc
);
635 // Create CPU offset and dimension arrays
636 // The CPU array collects the data in a contiguous block
637 size_t cpu_offsets
[MAX_ARRAY_RANK
];
638 size_t cpu_dimensions
[MAX_ARRAY_RANK
];
639 for (int i
=0; i
<num_dims
; i
++) {
641 cpu_dimensions
[i
] = volume
[i
];
645 if (omp_target_memcpy_rect(
646 cpu_mem
, src
, element_size
, num_dims
, volume
,
647 cpu_offsets
, src_offsets
,
648 cpu_dimensions
, src_dimensions
,
649 -1, src_device
) == 0) {
650 retval
= omp_target_memcpy_rect(
651 dst
, cpu_mem
, element_size
, num_dims
, volume
,
652 dst_offsets
, cpu_offsets
,
653 dst_dimensions
, cpu_dimensions
,
663 // host_ptr is key in table that yields association on device
664 // A COIBUFFER of specified size is created from the memory at
665 // device_ptr+device_offset on device_num
666 int omp_target_associate_ptr(
670 size_t device_offset
,
676 __offload_init_library();
678 OFFLOAD_TRACE(2, "omp_target_associate_ptr(%p, %p, %lld, %lld, %d)\n",
679 host_ptr
, device_ptr
, size
, device_offset
, device_num
);
681 if (device_num
< -1) {
682 LIBOFFLOAD_ERROR(c_invalid_device_number
);
686 // Associating to CPU is treated as failure
687 if (device_num
== -1) {
691 // An incorrect size is treated as failure
696 // If OpenMP allows wrap-around for device numbers, enable next line
697 //Engine& device = mic_engines[device_num % mic_engines_total];
698 Engine
& device
= mic_engines
[device_num
];
700 // Does host pointer have association already?
701 // lookup existing association in pointer table
702 PtrData
* ptr_data
= device
.find_ptr_data(host_ptr
);
704 OFFLOAD_TRACE(3, "Address %p is already mapped on device %d\n",
705 host_ptr
, device_num
);
706 // Is current device pointer and offset same as existing?
707 if ((void*)ptr_data
->mic_addr
== device_ptr
&&
708 (size_t)ptr_data
->alloc_disp
== device_offset
) {
715 // Create association
716 OFFLOAD_TRACE(3, "Creating association for data: addr %p, length %lld\n",
720 ptr_data
= device
.insert_ptr_data(host_ptr
, size
, is_new
);
721 ptr_data
->is_omp_associate
= true;
725 "Creating buffer from source memory %p, length %lld\n",
728 // result is not checked because we can continue without cpu
729 // buffer. In this case we will use COIBufferRead/Write
730 // instead of COIBufferCopy.
732 COI::BufferCreateFromMemory(size
,
737 &device
.get_process(),
742 "Creating buffer from sink memory: addr %p, size %lld\n",
743 (char *)device_ptr
+ device_offset
, size
);
744 res
= COI::BufferCreateFromMemory(size
,
749 &device
.get_process(),
751 if (res
!= COI_SUCCESS
) {
752 ptr_data
->alloc_ptr_data_lock
.unlock();
756 // make buffer valid on the device.
757 res
= COI::BufferSetState(ptr_data
->mic_buf
,
758 device
.get_process(),
762 if (res
!= COI_SUCCESS
) {
763 ptr_data
->alloc_ptr_data_lock
.unlock();
767 res
= COI::BufferSetState(ptr_data
->mic_buf
,
772 if (res
!= COI_SUCCESS
) {
773 ptr_data
->alloc_ptr_data_lock
.unlock();
776 ptr_data
->alloc_disp
= device_offset
;
777 ptr_data
->alloc_ptr_data_lock
.unlock();
782 int omp_target_disassociate_ptr(
789 __offload_init_library();
791 OFFLOAD_TRACE(2, "omp_target_disassociate_ptr(%p, %d)\n",
792 host_ptr
, device_num
);
794 if (device_num
< -1) {
795 LIBOFFLOAD_ERROR(c_invalid_device_number
);
799 // Dissociating from CPU is treated as failure
800 if (device_num
== -1) {
804 // If OpenMP allows wrap-around for device numbers, enable next line
805 //Engine& device = mic_engines[device_num % mic_engines_total];
806 Engine
& device
= mic_engines
[device_num
];
808 // Lookup existing association in pointer table
809 PtrData
* ptr_data
= device
.find_ptr_data(host_ptr
);
811 // Attempt to disassociate unassociated pointer is a failure
817 if (ptr_data
->cpu_buf
!= 0) {
818 OFFLOAD_TRACE(3, "Destroying CPU buffer %p\n", ptr_data
->cpu_buf
);
819 COI::BufferDestroy(ptr_data
->cpu_buf
);
821 if (ptr_data
->mic_buf
!= 0) {
822 OFFLOAD_TRACE(3, "Destroying MIC buffer %p\n", ptr_data
->mic_buf
);
823 COI::BufferDestroy(ptr_data
->mic_buf
);
826 // Remove association from map
827 OFFLOAD_TRACE(3, "Removing association for addr %p\n",
828 ptr_data
->cpu_addr
.start());
829 device
.remove_ptr_data(ptr_data
->cpu_addr
.start());
834 // End of OpenMP 4.5 APIs
837 // OpenMP API wrappers
839 static void omp_set_int_target(
840 TARGET_TYPE target_type
,
846 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
849 VarDesc vars
[1] = {0};
851 vars
[0].type
.src
= c_data
;
852 vars
[0].type
.dst
= c_data
;
853 vars
[0].direction
.bits
= c_parameter_in
;
854 vars
[0].size
= sizeof(int);
856 vars
[0].ptr
= &setting
;
858 OFFLOAD_OFFLOAD(ofld
, f_name
, 0, 1, vars
, NULL
, 0, 0, 0);
862 static int omp_get_int_target(
863 TARGET_TYPE target_type
,
870 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
873 VarDesc vars
[1] = {0};
875 vars
[0].type
.src
= c_data
;
876 vars
[0].type
.dst
= c_data
;
877 vars
[0].direction
.bits
= c_parameter_out
;
878 vars
[0].size
= sizeof(int);
880 vars
[0].ptr
= &setting
;
882 OFFLOAD_OFFLOAD(ofld
, f_name
, 0, 1, vars
, NULL
, 0, 0, 0);
887 void omp_set_num_threads_target(
888 TARGET_TYPE target_type
,
893 omp_set_int_target(target_type
, target_number
, num_threads
,
894 "omp_set_num_threads_target");
897 int omp_get_max_threads_target(
898 TARGET_TYPE target_type
,
902 return omp_get_int_target(target_type
, target_number
,
903 "omp_get_max_threads_target");
906 int omp_get_num_procs_target(
907 TARGET_TYPE target_type
,
911 return omp_get_int_target(target_type
, target_number
,
912 "omp_get_num_procs_target");
915 void omp_set_dynamic_target(
916 TARGET_TYPE target_type
,
921 omp_set_int_target(target_type
, target_number
, num_threads
,
922 "omp_set_dynamic_target");
925 int omp_get_dynamic_target(
926 TARGET_TYPE target_type
,
930 return omp_get_int_target(target_type
, target_number
,
931 "omp_get_dynamic_target");
934 void omp_set_nested_target(
935 TARGET_TYPE target_type
,
940 omp_set_int_target(target_type
, target_number
, nested
,
941 "omp_set_nested_target");
944 int omp_get_nested_target(
945 TARGET_TYPE target_type
,
949 return omp_get_int_target(target_type
, target_number
,
950 "omp_get_nested_target");
953 void omp_set_schedule_target(
954 TARGET_TYPE target_type
,
960 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
963 VarDesc vars
[2] = {0};
965 vars
[0].type
.src
= c_data
;
966 vars
[0].type
.dst
= c_data
;
967 vars
[0].direction
.bits
= c_parameter_in
;
968 vars
[0].size
= sizeof(omp_sched_t
);
972 vars
[1].type
.src
= c_data
;
973 vars
[1].type
.dst
= c_data
;
974 vars
[1].direction
.bits
= c_parameter_in
;
975 vars
[1].size
= sizeof(int);
977 vars
[1].ptr
= &modifier
;
979 OFFLOAD_OFFLOAD(ofld
, "omp_set_schedule_target",
980 0, 2, vars
, NULL
, 0, 0, 0);
984 void omp_get_schedule_target(
985 TARGET_TYPE target_type
,
991 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
994 VarDesc vars
[2] = {0};
996 vars
[0].type
.src
= c_data
;
997 vars
[0].type
.dst
= c_data
;
998 vars
[0].direction
.bits
= c_parameter_out
;
999 vars
[0].size
= sizeof(omp_sched_t
);
1003 vars
[1].type
.src
= c_data
;
1004 vars
[1].type
.dst
= c_data
;
1005 vars
[1].direction
.bits
= c_parameter_out
;
1006 vars
[1].size
= sizeof(int);
1008 vars
[1].ptr
= modifier
;
1010 OFFLOAD_OFFLOAD(ofld
, "omp_get_schedule_target",
1011 0, 2, vars
, NULL
, 0, 0, 0);
1015 // lock API functions
1017 void omp_init_lock_target(
1018 TARGET_TYPE target_type
,
1020 omp_lock_target_t
*lock
1023 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
1026 VarDesc vars
[1] = {0};
1028 vars
[0].type
.src
= c_data
;
1029 vars
[0].type
.dst
= c_data
;
1030 vars
[0].direction
.bits
= c_parameter_out
;
1031 vars
[0].size
= sizeof(omp_lock_target_t
);
1035 OFFLOAD_OFFLOAD(ofld
, "omp_init_lock_target",
1036 0, 1, vars
, NULL
, 0, 0, 0);
1040 void omp_destroy_lock_target(
1041 TARGET_TYPE target_type
,
1043 omp_lock_target_t
*lock
1046 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
1049 VarDesc vars
[1] = {0};
1051 vars
[0].type
.src
= c_data
;
1052 vars
[0].type
.dst
= c_data
;
1053 vars
[0].direction
.bits
= c_parameter_in
;
1054 vars
[0].size
= sizeof(omp_lock_target_t
);
1058 OFFLOAD_OFFLOAD(ofld
, "omp_destroy_lock_target",
1059 0, 1, vars
, NULL
, 0, 0, 0);
1063 void omp_set_lock_target(
1064 TARGET_TYPE target_type
,
1066 omp_lock_target_t
*lock
1069 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
1072 VarDesc vars
[1] = {0};
1074 vars
[0].type
.src
= c_data
;
1075 vars
[0].type
.dst
= c_data
;
1076 vars
[0].direction
.bits
= c_parameter_inout
;
1077 vars
[0].size
= sizeof(omp_lock_target_t
);
1081 OFFLOAD_OFFLOAD(ofld
, "omp_set_lock_target",
1082 0, 1, vars
, NULL
, 0, 0, 0);
1086 void omp_unset_lock_target(
1087 TARGET_TYPE target_type
,
1089 omp_lock_target_t
*lock
1092 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
1095 VarDesc vars
[1] = {0};
1097 vars
[0].type
.src
= c_data
;
1098 vars
[0].type
.dst
= c_data
;
1099 vars
[0].direction
.bits
= c_parameter_inout
;
1100 vars
[0].size
= sizeof(omp_lock_target_t
);
1104 OFFLOAD_OFFLOAD(ofld
, "omp_unset_lock_target",
1105 0, 1, vars
, NULL
, 0, 0, 0);
1109 int omp_test_lock_target(
1110 TARGET_TYPE target_type
,
1112 omp_lock_target_t
*lock
1117 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
1120 VarDesc vars
[2] = {0};
1122 vars
[0].type
.src
= c_data
;
1123 vars
[0].type
.dst
= c_data
;
1124 vars
[0].direction
.bits
= c_parameter_inout
;
1125 vars
[0].size
= sizeof(omp_lock_target_t
);
1129 vars
[1].type
.src
= c_data
;
1130 vars
[1].type
.dst
= c_data
;
1131 vars
[1].direction
.bits
= c_parameter_out
;
1132 vars
[1].size
= sizeof(int);
1134 vars
[1].ptr
= &result
;
1136 OFFLOAD_OFFLOAD(ofld
, "omp_test_lock_target",
1137 0, 2, vars
, NULL
, 0, 0, 0);
1142 // nested lock API functions
1144 void omp_init_nest_lock_target(
1145 TARGET_TYPE target_type
,
1147 omp_nest_lock_target_t
*lock
1150 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
1153 VarDesc vars
[1] = {0};
1155 vars
[0].type
.src
= c_data
;
1156 vars
[0].type
.dst
= c_data
;
1157 vars
[0].direction
.bits
= c_parameter_out
;
1158 vars
[0].size
= sizeof(omp_nest_lock_target_t
);
1162 OFFLOAD_OFFLOAD(ofld
, "omp_init_nest_lock_target",
1163 0, 1, vars
, NULL
, 0, 0, 0);
1167 void omp_destroy_nest_lock_target(
1168 TARGET_TYPE target_type
,
1170 omp_nest_lock_target_t
*lock
1173 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
1176 VarDesc vars
[1] = {0};
1178 vars
[0].type
.src
= c_data
;
1179 vars
[0].type
.dst
= c_data
;
1180 vars
[0].direction
.bits
= c_parameter_in
;
1181 vars
[0].size
= sizeof(omp_nest_lock_target_t
);
1185 OFFLOAD_OFFLOAD(ofld
, "omp_destroy_nest_lock_target",
1186 0, 1, vars
, NULL
, 0, 0, 0);
1190 void omp_set_nest_lock_target(
1191 TARGET_TYPE target_type
,
1193 omp_nest_lock_target_t
*lock
1196 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
1199 VarDesc vars
[1] = {0};
1201 vars
[0].type
.src
= c_data
;
1202 vars
[0].type
.dst
= c_data
;
1203 vars
[0].direction
.bits
= c_parameter_inout
;
1204 vars
[0].size
= sizeof(omp_nest_lock_target_t
);
1208 OFFLOAD_OFFLOAD(ofld
, "omp_set_nest_lock_target",
1209 0, 1, vars
, NULL
, 0, 0, 0);
1213 void omp_unset_nest_lock_target(
1214 TARGET_TYPE target_type
,
1216 omp_nest_lock_target_t
*lock
1219 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
1222 VarDesc vars
[1] = {0};
1224 vars
[0].type
.src
= c_data
;
1225 vars
[0].type
.dst
= c_data
;
1226 vars
[0].direction
.bits
= c_parameter_inout
;
1227 vars
[0].size
= sizeof(omp_nest_lock_target_t
);
1231 OFFLOAD_OFFLOAD(ofld
, "omp_unset_nest_lock_target",
1232 0, 1, vars
, NULL
, 0, 0, 0);
1236 int omp_test_nest_lock_target(
1237 TARGET_TYPE target_type
,
1239 omp_nest_lock_target_t
*lock
1244 OFFLOAD ofld
= OFFLOAD_TARGET_ACQUIRE(target_type
, target_number
, 0, NULL
,
1247 VarDesc vars
[2] = {0};
1249 vars
[0].type
.src
= c_data
;
1250 vars
[0].type
.dst
= c_data
;
1251 vars
[0].direction
.bits
= c_parameter_inout
;
1252 vars
[0].size
= sizeof(omp_nest_lock_target_t
);
1256 vars
[1].type
.src
= c_data
;
1257 vars
[1].type
.dst
= c_data
;
1258 vars
[1].direction
.bits
= c_parameter_out
;
1259 vars
[1].size
= sizeof(int);
1261 vars
[1].ptr
= &result
;
1263 OFFLOAD_OFFLOAD(ofld
, "omp_test_nest_lock_target",
1264 0, 2, vars
, NULL
, 0, 0, 0);