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 "compiler_if_target.h"
37 void omp_set_default_device(int num
) __GOMP_NOTHROW
41 int omp_get_default_device(void) __GOMP_NOTHROW
46 int omp_get_num_devices() __GOMP_NOTHROW
48 return mic_engines_total
;
53 // COI supports 3-dim multiD transfers
54 #define MAX_ARRAY_RANK 3
56 DLL_LOCAL
void omp_target_alloc_target(
60 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
61 VarDesc vars
[2] = {0};
65 vars
[0].type
.src
= c_data
;
66 vars
[0].type
.dst
= c_data
;
67 vars
[0].direction
.bits
= c_parameter_in
;
70 vars
[1].type
.src
= c_data
;
71 vars
[1].type
.dst
= c_data
;
72 vars
[1].direction
.bits
= c_parameter_out
;
73 vars
[1].ptr
= &memory
;
75 OFFLOAD_TARGET_ENTER(ofld
, 2, vars
, NULL
);
76 OFFLOAD_DEBUG_TRACE(2, "omp_target_alloc(%lld)\n", size
);
77 // We do not check for malloc returning NULL because the
78 // specification of this API includes the possibility of failure.
79 // The user will check the returned result
80 memory
= malloc(size
);
81 OFFLOAD_DEBUG_TRACE(2, "omp_target_alloc allocated at %p\n", memory
);
82 OFFLOAD_TARGET_LEAVE(ofld
);
85 DLL_LOCAL
void omp_target_free_target(
89 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
90 VarDesc vars
[1] = {0};
93 vars
[0].type
.src
= c_data
;
94 vars
[0].type
.dst
= c_data
;
95 vars
[0].direction
.bits
= c_parameter_in
;
96 vars
[0].ptr
= &memory
;
98 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
99 OFFLOAD_DEBUG_TRACE(2, "omp_target_free(%p)\n", memory
);
101 OFFLOAD_DEBUG_TRACE(2, "omp_target_free freed\n");
102 OFFLOAD_TARGET_LEAVE(ofld
);
105 DLL_LOCAL
void omp_target_memcpy_target(
109 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
110 VarDesc vars
[3] = {0};
115 vars
[0].type
.src
= c_data
;
116 vars
[0].type
.dst
= c_data
;
117 vars
[0].direction
.bits
= c_parameter_in
;
120 vars
[1].type
.src
= c_data
;
121 vars
[1].type
.dst
= c_data
;
122 vars
[1].direction
.bits
= c_parameter_in
;
125 vars
[2].type
.src
= c_data
;
126 vars
[2].type
.dst
= c_data
;
127 vars
[2].direction
.bits
= c_parameter_in
;
128 vars
[2].ptr
= &length
;
130 OFFLOAD_TARGET_ENTER(ofld
, 3, vars
, NULL
);
131 OFFLOAD_DEBUG_TRACE(2, "omp_target_memcpy(%p, %p, %lld)\n",
133 memcpy(dst
, src
, length
);
135 OFFLOAD_DEBUG_TRACE(2, "omp_target_memcpy done\n");
136 OFFLOAD_TARGET_LEAVE(ofld
);
139 static size_t bytesize_at_this_dimension(
142 const size_t* dimensions
146 return dimensions
[1] *
147 bytesize_at_this_dimension(
148 element_size
, num_dims
-1, dimensions
+1);
154 static void memcpy_rect(
159 const size_t *volume
,
160 const size_t *dst_offsets
,
161 const size_t *src_offsets
,
162 const size_t *dst_dimensions
,
163 const size_t *src_dimensions
167 int count
= volume
[0];
168 int dst_index
= dst_offsets
[0];
169 int src_index
= src_offsets
[0];
170 size_t dst_element_size
=
171 bytesize_at_this_dimension(element_size
, num_dims
, dst_dimensions
);
172 size_t src_element_size
=
173 bytesize_at_this_dimension(element_size
, num_dims
, src_dimensions
);
174 for (; count
>0; dst_index
++, src_index
++, count
--) {
175 memcpy_rect(dst
+dst_element_size
*dst_index
,
176 src
+src_element_size
*src_index
,
177 element_size
, num_dims
-1, volume
+1,
178 dst_offsets
+1, src_offsets
+1,
179 dst_dimensions
+1, src_dimensions
+1);
182 memcpy(dst
+dst_offsets
[0]*element_size
,
183 src
+src_offsets
[0]*element_size
,
184 element_size
* volume
[0]);
188 DLL_LOCAL
void omp_target_memcpy_rect_target(
192 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
193 VarDesc vars
[1] = {0};
199 size_t array_info
[MAX_ARRAY_RANK
*5];
202 vars
[0].type
.src
= c_data
;
203 vars
[0].type
.dst
= c_data
;
204 vars
[0].direction
.bits
= c_parameter_in
;
205 vars
[0].ptr
= ¶meters
;
207 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
208 OFFLOAD_DEBUG_TRACE(2, "omp_target_memcpy_rect(%p, %p, %lld, %d)\n",
209 parameters
.dst
, parameters
.src
,
210 parameters
.element_size
, parameters
.num_dims
);
212 (char*)parameters
.dst
, (char*)parameters
.src
, parameters
.element_size
,
214 ¶meters
.array_info
[0],
215 ¶meters
.array_info
[parameters
.num_dims
],
216 ¶meters
.array_info
[parameters
.num_dims
*2],
217 ¶meters
.array_info
[parameters
.num_dims
*3],
218 ¶meters
.array_info
[parameters
.num_dims
*4]);
220 OFFLOAD_DEBUG_TRACE(2, "omp_target_memcpy_rect done\n");
221 OFFLOAD_TARGET_LEAVE(ofld
);
224 // End of OpenMP 4.5 APIs
227 // OpenMP API wrappers
229 static void omp_send_int_to_host(
234 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
235 VarDesc vars
[1] = {0};
237 vars
[0].type
.src
= c_data
;
238 vars
[0].type
.dst
= c_data
;
239 vars
[0].direction
.bits
= c_parameter_out
;
240 vars
[0].ptr
= &setting
;
242 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
243 OFFLOAD_TARGET_LEAVE(ofld
);
246 static int omp_get_int_from_host(
250 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
251 VarDesc vars
[1] = {0};
254 vars
[0].type
.src
= c_data
;
255 vars
[0].type
.dst
= c_data
;
256 vars
[0].direction
.bits
= c_parameter_in
;
257 vars
[0].ptr
= &setting
;
259 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
260 OFFLOAD_TARGET_LEAVE(ofld
);
265 DLL_LOCAL
void omp_set_num_threads_lrb(
271 num_threads
= omp_get_int_from_host(ofld
);
272 omp_set_num_threads(num_threads
);
275 DLL_LOCAL
void omp_get_max_threads_lrb(
281 num_threads
= omp_get_max_threads();
282 omp_send_int_to_host(ofld
, num_threads
);
285 DLL_LOCAL
void omp_get_num_procs_lrb(
291 num_procs
= omp_get_num_procs();
292 omp_send_int_to_host(ofld
, num_procs
);
295 DLL_LOCAL
void omp_set_dynamic_lrb(
301 dynamic
= omp_get_int_from_host(ofld
);
302 omp_set_dynamic(dynamic
);
305 DLL_LOCAL
void omp_get_dynamic_lrb(
311 dynamic
= omp_get_dynamic();
312 omp_send_int_to_host(ofld
, dynamic
);
315 DLL_LOCAL
void omp_set_nested_lrb(
321 nested
= omp_get_int_from_host(ofld
);
322 omp_set_nested(nested
);
325 DLL_LOCAL
void omp_get_nested_lrb(
331 nested
= omp_get_nested();
332 omp_send_int_to_host(ofld
, nested
);
335 DLL_LOCAL
void omp_set_schedule_lrb(
339 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
340 VarDesc vars
[2] = {0};
344 vars
[0].type
.src
= c_data
;
345 vars
[0].type
.dst
= c_data
;
346 vars
[0].direction
.bits
= c_parameter_in
;
349 vars
[1].type
.src
= c_data
;
350 vars
[1].type
.dst
= c_data
;
351 vars
[1].direction
.bits
= c_parameter_in
;
352 vars
[1].ptr
= &modifier
;
354 OFFLOAD_TARGET_ENTER(ofld
, 2, vars
, NULL
);
355 omp_set_schedule(kind
, modifier
);
356 OFFLOAD_TARGET_LEAVE(ofld
);
359 DLL_LOCAL
void omp_get_schedule_lrb(
363 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
364 VarDesc vars
[2] = {0};
368 vars
[0].type
.src
= c_data
;
369 vars
[0].type
.dst
= c_data
;
370 vars
[0].direction
.bits
= c_parameter_out
;
373 vars
[1].type
.src
= c_data
;
374 vars
[1].type
.dst
= c_data
;
375 vars
[1].direction
.bits
= c_parameter_out
;
376 vars
[1].ptr
= &modifier
;
378 OFFLOAD_TARGET_ENTER(ofld
, 2, vars
, NULL
);
379 omp_get_schedule(&kind
, &modifier
);
380 OFFLOAD_TARGET_LEAVE(ofld
);
383 // lock API functions
385 DLL_LOCAL
void omp_init_lock_lrb(
389 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
390 VarDesc vars
[1] = {0};
391 omp_lock_target_t lock
;
393 vars
[0].type
.src
= c_data
;
394 vars
[0].type
.dst
= c_data
;
395 vars
[0].direction
.bits
= c_parameter_out
;
398 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
399 omp_init_lock(&lock
.lock
);
400 OFFLOAD_TARGET_LEAVE(ofld
);
403 DLL_LOCAL
void omp_destroy_lock_lrb(
407 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
408 VarDesc vars
[1] = {0};
409 omp_lock_target_t lock
;
411 vars
[0].type
.src
= c_data
;
412 vars
[0].type
.dst
= c_data
;
413 vars
[0].direction
.bits
= c_parameter_in
;
416 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
417 omp_destroy_lock(&lock
.lock
);
418 OFFLOAD_TARGET_LEAVE(ofld
);
421 DLL_LOCAL
void omp_set_lock_lrb(
425 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
426 VarDesc vars
[1] = {0};
427 omp_lock_target_t lock
;
429 vars
[0].type
.src
= c_data
;
430 vars
[0].type
.dst
= c_data
;
431 vars
[0].direction
.bits
= c_parameter_inout
;
434 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
435 omp_set_lock(&lock
.lock
);
436 OFFLOAD_TARGET_LEAVE(ofld
);
439 DLL_LOCAL
void omp_unset_lock_lrb(
443 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
444 VarDesc vars
[1] = {0};
445 omp_lock_target_t lock
;
447 vars
[0].type
.src
= c_data
;
448 vars
[0].type
.dst
= c_data
;
449 vars
[0].direction
.bits
= c_parameter_inout
;
452 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
453 omp_unset_lock(&lock
.lock
);
454 OFFLOAD_TARGET_LEAVE(ofld
);
457 DLL_LOCAL
void omp_test_lock_lrb(
461 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
462 VarDesc vars
[2] = {0};
463 omp_lock_target_t lock
;
466 vars
[0].type
.src
= c_data
;
467 vars
[0].type
.dst
= c_data
;
468 vars
[0].direction
.bits
= c_parameter_inout
;
471 vars
[1].type
.src
= c_data
;
472 vars
[1].type
.dst
= c_data
;
473 vars
[1].direction
.bits
= c_parameter_out
;
474 vars
[1].ptr
= &result
;
476 OFFLOAD_TARGET_ENTER(ofld
, 2, vars
, NULL
);
477 result
= omp_test_lock(&lock
.lock
);
478 OFFLOAD_TARGET_LEAVE(ofld
);
481 // nested lock API functions
483 DLL_LOCAL
void omp_init_nest_lock_lrb(
487 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
488 VarDesc vars
[1] = {0};
489 omp_nest_lock_target_t lock
;
491 vars
[0].type
.src
= c_data
;
492 vars
[0].type
.dst
= c_data
;
493 vars
[0].direction
.bits
= c_parameter_out
;
496 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
497 omp_init_nest_lock(&lock
.lock
);
498 OFFLOAD_TARGET_LEAVE(ofld
);
501 DLL_LOCAL
void omp_destroy_nest_lock_lrb(
505 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
506 VarDesc vars
[1] = {0};
507 omp_nest_lock_target_t lock
;
509 vars
[0].type
.src
= c_data
;
510 vars
[0].type
.dst
= c_data
;
511 vars
[0].direction
.bits
= c_parameter_in
;
514 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
515 omp_destroy_nest_lock(&lock
.lock
);
516 OFFLOAD_TARGET_LEAVE(ofld
);
519 DLL_LOCAL
void omp_set_nest_lock_lrb(
523 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
524 VarDesc vars
[1] = {0};
525 omp_nest_lock_target_t lock
;
527 vars
[0].type
.src
= c_data
;
528 vars
[0].type
.dst
= c_data
;
529 vars
[0].direction
.bits
= c_parameter_inout
;
532 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
533 omp_set_nest_lock(&lock
.lock
);
534 OFFLOAD_TARGET_LEAVE(ofld
);
537 DLL_LOCAL
void omp_unset_nest_lock_lrb(
541 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
542 VarDesc vars
[1] = {0};
543 omp_nest_lock_target_t lock
;
545 vars
[0].type
.src
= c_data
;
546 vars
[0].type
.dst
= c_data
;
547 vars
[0].direction
.bits
= c_parameter_inout
;
550 OFFLOAD_TARGET_ENTER(ofld
, 1, vars
, NULL
);
551 omp_unset_nest_lock(&lock
.lock
);
552 OFFLOAD_TARGET_LEAVE(ofld
);
555 DLL_LOCAL
void omp_test_nest_lock_lrb(
559 OFFLOAD ofld
= (OFFLOAD
) ofld_
;
560 VarDesc vars
[2] = {0};
561 omp_nest_lock_target_t lock
;
564 vars
[0].type
.src
= c_data
;
565 vars
[0].type
.dst
= c_data
;
566 vars
[0].direction
.bits
= c_parameter_inout
;
569 vars
[1].type
.src
= c_data
;
570 vars
[1].type
.dst
= c_data
;
571 vars
[1].direction
.bits
= c_parameter_out
;
572 vars
[1].ptr
= &result
;
574 OFFLOAD_TARGET_ENTER(ofld
, 2, vars
, NULL
);
575 result
= omp_test_nest_lock(&lock
.lock
);
576 OFFLOAD_TARGET_LEAVE(ofld
);
579 // Target-side stubs for the host functions (to avoid unresolveds)
580 // These are needed for the offloadm table
582 void omp_set_num_threads_target(
583 TARGET_TYPE target_type
,
590 int omp_get_max_threads_target(
591 TARGET_TYPE target_type
,
598 int omp_get_num_procs_target(
599 TARGET_TYPE target_type
,
606 void omp_set_dynamic_target(
607 TARGET_TYPE target_type
,
614 int omp_get_dynamic_target(
615 TARGET_TYPE target_type
,
622 void omp_set_nested_target(
623 TARGET_TYPE target_type
,
630 int omp_get_nested_target(
631 TARGET_TYPE target_type
,
638 void omp_set_schedule_target(
639 TARGET_TYPE target_type
,
647 void omp_get_schedule_target(
648 TARGET_TYPE target_type
,
656 void omp_init_lock_target(
657 TARGET_TYPE target_type
,
659 omp_lock_target_t
*lock
664 void omp_destroy_lock_target(
665 TARGET_TYPE target_type
,
667 omp_lock_target_t
*lock
672 void omp_set_lock_target(
673 TARGET_TYPE target_type
,
675 omp_lock_target_t
*lock
680 void omp_unset_lock_target(
681 TARGET_TYPE target_type
,
683 omp_lock_target_t
*lock
688 int omp_test_lock_target(
689 TARGET_TYPE target_type
,
691 omp_lock_target_t
*lock
697 void omp_init_nest_lock_target(
698 TARGET_TYPE target_type
,
700 omp_nest_lock_target_t
*lock
705 void omp_destroy_nest_lock_target(
706 TARGET_TYPE target_type
,
708 omp_nest_lock_target_t
*lock
713 void omp_set_nest_lock_target(
714 TARGET_TYPE target_type
,
716 omp_nest_lock_target_t
*lock
721 void omp_unset_nest_lock_target(
722 TARGET_TYPE target_type
,
724 omp_nest_lock_target_t
*lock
729 int omp_test_nest_lock_target(
730 TARGET_TYPE target_type
,
732 omp_nest_lock_target_t
*lock