1/* 2 Copyright (c) 2014 Intel Corporation. All Rights Reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions 6 are met: 7 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. 16 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. 28*/ 29 30 31#include <omp.h> 32#include "offload.h" 33#include "compiler_if_host.h" 34 35// OpenMP API 36 37void omp_set_default_device(int num) __GOMP_NOTHROW 38{ 39 if (num >= 0) { 40 __omp_device_num = num; 41 } 42} 43 44int omp_get_default_device(void) __GOMP_NOTHROW 45{ 46 return __omp_device_num; 47} 48 49int omp_get_num_devices() __GOMP_NOTHROW 50{ 51 __offload_init_library(); 52 return mic_engines_total; 53} 54 55// OpenMP API wrappers 56 57static void omp_set_int_target( 58 TARGET_TYPE target_type, 59 int target_number, 60 int setting, 61 const char* f_name 62) 63{ 64 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 65 f_name, 0); 66 if (ofld) { 67 VarDesc vars[1] = {0}; 68 69 vars[0].type.src = c_data; 70 vars[0].type.dst = c_data; 71 vars[0].direction.bits = c_parameter_in; 72 vars[0].size = sizeof(int); 73 vars[0].count = 1; 74 vars[0].ptr = &setting; 75 76 OFFLOAD_OFFLOAD(ofld, f_name, 0, 1, vars, NULL, 0, 0, 0); 77 } 78} 79 80static int omp_get_int_target( 81 TARGET_TYPE target_type, 82 int target_number, 83 const char * f_name 84) 85{ 86 int setting = 0; 87 88 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 89 f_name, 0); 90 if (ofld) { 91 VarDesc vars[1] = {0}; 92 93 vars[0].type.src = c_data; 94 vars[0].type.dst = c_data; 95 vars[0].direction.bits = c_parameter_out; 96 vars[0].size = sizeof(int); 97 vars[0].count = 1; 98 vars[0].ptr = &setting; 99 100 OFFLOAD_OFFLOAD(ofld, f_name, 0, 1, vars, NULL, 0, 0, 0); 101 } 102 return setting; 103} 104 105void omp_set_num_threads_target( 106 TARGET_TYPE target_type, 107 int target_number, 108 int num_threads 109) 110{ 111 omp_set_int_target(target_type, target_number, num_threads, 112 "omp_set_num_threads_target"); 113} 114 115int omp_get_max_threads_target( 116 TARGET_TYPE target_type, 117 int target_number 118) 119{ 120 return omp_get_int_target(target_type, target_number, 121 "omp_get_max_threads_target"); 122} 123 124int omp_get_num_procs_target( 125 TARGET_TYPE target_type, 126 int target_number 127) 128{ 129 return omp_get_int_target(target_type, target_number, 130 "omp_get_num_procs_target"); 131} 132 133void omp_set_dynamic_target( 134 TARGET_TYPE target_type, 135 int target_number, 136 int num_threads 137) 138{ 139 omp_set_int_target(target_type, target_number, num_threads, 140 "omp_set_dynamic_target"); 141} 142 143int omp_get_dynamic_target( 144 TARGET_TYPE target_type, 145 int target_number 146) 147{ 148 return omp_get_int_target(target_type, target_number, 149 "omp_get_dynamic_target"); 150} 151 152void omp_set_nested_target( 153 TARGET_TYPE target_type, 154 int target_number, 155 int nested 156) 157{ 158 omp_set_int_target(target_type, target_number, nested, 159 "omp_set_nested_target"); 160} 161 162int omp_get_nested_target( 163 TARGET_TYPE target_type, 164 int target_number 165) 166{ 167 return omp_get_int_target(target_type, target_number, 168 "omp_get_nested_target"); 169} 170 171void omp_set_schedule_target( 172 TARGET_TYPE target_type, 173 int target_number, 174 omp_sched_t kind, 175 int modifier 176) 177{ 178 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 179 __func__, 0); 180 if (ofld != 0) { 181 VarDesc vars[2] = {0}; 182 183 vars[0].type.src = c_data; 184 vars[0].type.dst = c_data; 185 vars[0].direction.bits = c_parameter_in; 186 vars[0].size = sizeof(omp_sched_t); 187 vars[0].count = 1; 188 vars[0].ptr = &kind; 189 190 vars[1].type.src = c_data; 191 vars[1].type.dst = c_data; 192 vars[1].direction.bits = c_parameter_in; 193 vars[1].size = sizeof(int); 194 vars[1].count = 1; 195 vars[1].ptr = &modifier; 196 197 OFFLOAD_OFFLOAD(ofld, "omp_set_schedule_target", 198 0, 2, vars, NULL, 0, 0, 0); 199 } 200} 201 202void omp_get_schedule_target( 203 TARGET_TYPE target_type, 204 int target_number, 205 omp_sched_t *kind, 206 int *modifier 207) 208{ 209 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 210 __func__, 0); 211 if (ofld != 0) { 212 VarDesc vars[2] = {0}; 213 214 vars[0].type.src = c_data; 215 vars[0].type.dst = c_data; 216 vars[0].direction.bits = c_parameter_out; 217 vars[0].size = sizeof(omp_sched_t); 218 vars[0].count = 1; 219 vars[0].ptr = kind; 220 221 vars[1].type.src = c_data; 222 vars[1].type.dst = c_data; 223 vars[1].direction.bits = c_parameter_out; 224 vars[1].size = sizeof(int); 225 vars[1].count = 1; 226 vars[1].ptr = modifier; 227 228 OFFLOAD_OFFLOAD(ofld, "omp_get_schedule_target", 229 0, 2, vars, NULL, 0, 0, 0); 230 } 231} 232 233// lock API functions 234 235void omp_init_lock_target( 236 TARGET_TYPE target_type, 237 int target_number, 238 omp_lock_target_t *lock 239) 240{ 241 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 242 __func__, 0); 243 if (ofld != 0) { 244 VarDesc vars[1] = {0}; 245 246 vars[0].type.src = c_data; 247 vars[0].type.dst = c_data; 248 vars[0].direction.bits = c_parameter_out; 249 vars[0].size = sizeof(omp_lock_target_t); 250 vars[0].count = 1; 251 vars[0].ptr = lock; 252 253 OFFLOAD_OFFLOAD(ofld, "omp_init_lock_target", 254 0, 1, vars, NULL, 0, 0, 0); 255 } 256} 257 258void omp_destroy_lock_target( 259 TARGET_TYPE target_type, 260 int target_number, 261 omp_lock_target_t *lock 262) 263{ 264 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 265 __func__, 0); 266 if (ofld != 0) { 267 VarDesc vars[1] = {0}; 268 269 vars[0].type.src = c_data; 270 vars[0].type.dst = c_data; 271 vars[0].direction.bits = c_parameter_in; 272 vars[0].size = sizeof(omp_lock_target_t); 273 vars[0].count = 1; 274 vars[0].ptr = lock; 275 276 OFFLOAD_OFFLOAD(ofld, "omp_destroy_lock_target", 277 0, 1, vars, NULL, 0, 0, 0); 278 } 279} 280 281void omp_set_lock_target( 282 TARGET_TYPE target_type, 283 int target_number, 284 omp_lock_target_t *lock 285) 286{ 287 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 288 __func__, 0); 289 if (ofld != 0) { 290 VarDesc vars[1] = {0}; 291 292 vars[0].type.src = c_data; 293 vars[0].type.dst = c_data; 294 vars[0].direction.bits = c_parameter_inout; 295 vars[0].size = sizeof(omp_lock_target_t); 296 vars[0].count = 1; 297 vars[0].ptr = lock; 298 299 OFFLOAD_OFFLOAD(ofld, "omp_set_lock_target", 300 0, 1, vars, NULL, 0, 0, 0); 301 } 302} 303 304void omp_unset_lock_target( 305 TARGET_TYPE target_type, 306 int target_number, 307 omp_lock_target_t *lock 308) 309{ 310 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 311 __func__, 0); 312 if (ofld != 0) { 313 VarDesc vars[1] = {0}; 314 315 vars[0].type.src = c_data; 316 vars[0].type.dst = c_data; 317 vars[0].direction.bits = c_parameter_inout; 318 vars[0].size = sizeof(omp_lock_target_t); 319 vars[0].count = 1; 320 vars[0].ptr = lock; 321 322 OFFLOAD_OFFLOAD(ofld, "omp_unset_lock_target", 323 0, 1, vars, NULL, 0, 0, 0); 324 } 325} 326 327int omp_test_lock_target( 328 TARGET_TYPE target_type, 329 int target_number, 330 omp_lock_target_t *lock 331) 332{ 333 int result = 0; 334 335 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 336 __func__, 0); 337 if (ofld != 0) { 338 VarDesc vars[2] = {0}; 339 340 vars[0].type.src = c_data; 341 vars[0].type.dst = c_data; 342 vars[0].direction.bits = c_parameter_inout; 343 vars[0].size = sizeof(omp_lock_target_t); 344 vars[0].count = 1; 345 vars[0].ptr = lock; 346 347 vars[1].type.src = c_data; 348 vars[1].type.dst = c_data; 349 vars[1].direction.bits = c_parameter_out; 350 vars[1].size = sizeof(int); 351 vars[1].count = 1; 352 vars[1].ptr = &result; 353 354 OFFLOAD_OFFLOAD(ofld, "omp_test_lock_target", 355 0, 2, vars, NULL, 0, 0, 0); 356 } 357 return result; 358} 359 360// nested lock API functions 361 362void omp_init_nest_lock_target( 363 TARGET_TYPE target_type, 364 int target_number, 365 omp_nest_lock_target_t *lock 366) 367{ 368 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 369 __func__, 0); 370 if (ofld != 0) { 371 VarDesc vars[1] = {0}; 372 373 vars[0].type.src = c_data; 374 vars[0].type.dst = c_data; 375 vars[0].direction.bits = c_parameter_out; 376 vars[0].size = sizeof(omp_nest_lock_target_t); 377 vars[0].count = 1; 378 vars[0].ptr = lock; 379 380 OFFLOAD_OFFLOAD(ofld, "omp_init_nest_lock_target", 381 0, 1, vars, NULL, 0, 0, 0); 382 } 383} 384 385void omp_destroy_nest_lock_target( 386 TARGET_TYPE target_type, 387 int target_number, 388 omp_nest_lock_target_t *lock 389) 390{ 391 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 392 __func__, 0); 393 if (ofld != 0) { 394 VarDesc vars[1] = {0}; 395 396 vars[0].type.src = c_data; 397 vars[0].type.dst = c_data; 398 vars[0].direction.bits = c_parameter_in; 399 vars[0].size = sizeof(omp_nest_lock_target_t); 400 vars[0].count = 1; 401 vars[0].ptr = lock; 402 403 OFFLOAD_OFFLOAD(ofld, "omp_destroy_nest_lock_target", 404 0, 1, vars, NULL, 0, 0, 0); 405 } 406} 407 408void omp_set_nest_lock_target( 409 TARGET_TYPE target_type, 410 int target_number, 411 omp_nest_lock_target_t *lock 412) 413{ 414 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 415 __func__, 0); 416 if (ofld != 0) { 417 VarDesc vars[1] = {0}; 418 419 vars[0].type.src = c_data; 420 vars[0].type.dst = c_data; 421 vars[0].direction.bits = c_parameter_inout; 422 vars[0].size = sizeof(omp_nest_lock_target_t); 423 vars[0].count = 1; 424 vars[0].ptr = lock; 425 426 OFFLOAD_OFFLOAD(ofld, "omp_set_nest_lock_target", 427 0, 1, vars, NULL, 0, 0, 0); 428 } 429} 430 431void omp_unset_nest_lock_target( 432 TARGET_TYPE target_type, 433 int target_number, 434 omp_nest_lock_target_t *lock 435) 436{ 437 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 438 __func__, 0); 439 if (ofld != 0) { 440 VarDesc vars[1] = {0}; 441 442 vars[0].type.src = c_data; 443 vars[0].type.dst = c_data; 444 vars[0].direction.bits = c_parameter_inout; 445 vars[0].size = sizeof(omp_nest_lock_target_t); 446 vars[0].count = 1; 447 vars[0].ptr = lock; 448 449 OFFLOAD_OFFLOAD(ofld, "omp_unset_nest_lock_target", 450 0, 1, vars, NULL, 0, 0, 0); 451 } 452} 453 454int omp_test_nest_lock_target( 455 TARGET_TYPE target_type, 456 int target_number, 457 omp_nest_lock_target_t *lock 458) 459{ 460 int result = 0; 461 462 OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL, 463 __func__, 0); 464 if (ofld != 0) { 465 VarDesc vars[2] = {0}; 466 467 vars[0].type.src = c_data; 468 vars[0].type.dst = c_data; 469 vars[0].direction.bits = c_parameter_inout; 470 vars[0].size = sizeof(omp_nest_lock_target_t); 471 vars[0].count = 1; 472 vars[0].ptr = lock; 473 474 vars[1].type.src = c_data; 475 vars[1].type.dst = c_data; 476 vars[1].direction.bits = c_parameter_out; 477 vars[1].size = sizeof(int); 478 vars[1].count = 1; 479 vars[1].ptr = &result; 480 481 OFFLOAD_OFFLOAD(ofld, "omp_test_nest_lock_target", 482 0, 2, vars, NULL, 0, 0, 0); 483 } 484 return result; 485} 486