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_target.h" 34 35// OpenMP API 36 37void omp_set_default_device(int num) __GOMP_NOTHROW 38{ 39} 40 41int omp_get_default_device(void) __GOMP_NOTHROW 42{ 43 return mic_index; 44} 45 46int omp_get_num_devices() __GOMP_NOTHROW 47{ 48 return mic_engines_total; 49} 50 51// OpenMP API wrappers 52 53static void omp_send_int_to_host( 54 void *ofld_, 55 int setting 56) 57{ 58 OFFLOAD ofld = (OFFLOAD) ofld_; 59 VarDesc vars[1] = {0}; 60 61 vars[0].type.src = c_data; 62 vars[0].type.dst = c_data; 63 vars[0].direction.bits = c_parameter_out; 64 vars[0].ptr = &setting; 65 66 OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL); 67 OFFLOAD_TARGET_LEAVE(ofld); 68} 69 70static int omp_get_int_from_host( 71 void *ofld_ 72) 73{ 74 OFFLOAD ofld = (OFFLOAD) ofld_; 75 VarDesc vars[1] = {0}; 76 int setting; 77 78 vars[0].type.src = c_data; 79 vars[0].type.dst = c_data; 80 vars[0].direction.bits = c_parameter_in; 81 vars[0].ptr = &setting; 82 83 OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL); 84 OFFLOAD_TARGET_LEAVE(ofld); 85 86 return setting; 87} 88 89void omp_set_num_threads_lrb( 90 void *ofld 91) 92{ 93 int num_threads; 94 95 num_threads = omp_get_int_from_host(ofld); 96 omp_set_num_threads(num_threads); 97} 98 99void omp_get_max_threads_lrb( 100 void *ofld 101) 102{ 103 int num_threads; 104 105 num_threads = omp_get_max_threads(); 106 omp_send_int_to_host(ofld, num_threads); 107} 108 109void omp_get_num_procs_lrb( 110 void *ofld 111) 112{ 113 int num_procs; 114 115 num_procs = omp_get_num_procs(); 116 omp_send_int_to_host(ofld, num_procs); 117} 118 119void omp_set_dynamic_lrb( 120 void *ofld 121) 122{ 123 int dynamic; 124 125 dynamic = omp_get_int_from_host(ofld); 126 omp_set_dynamic(dynamic); 127} 128 129void omp_get_dynamic_lrb( 130 void *ofld 131) 132{ 133 int dynamic; 134 135 dynamic = omp_get_dynamic(); 136 omp_send_int_to_host(ofld, dynamic); 137} 138 139void omp_set_nested_lrb( 140 void *ofld 141) 142{ 143 int nested; 144 145 nested = omp_get_int_from_host(ofld); 146 omp_set_nested(nested); 147} 148 149void omp_get_nested_lrb( 150 void *ofld 151) 152{ 153 int nested; 154 155 nested = omp_get_nested(); 156 omp_send_int_to_host(ofld, nested); 157} 158 159void omp_set_schedule_lrb( 160 void *ofld_ 161) 162{ 163 OFFLOAD ofld = (OFFLOAD) ofld_; 164 VarDesc vars[2] = {0}; 165 omp_sched_t kind; 166 int modifier; 167 168 vars[0].type.src = c_data; 169 vars[0].type.dst = c_data; 170 vars[0].direction.bits = c_parameter_in; 171 vars[0].ptr = &kind; 172 173 vars[1].type.src = c_data; 174 vars[1].type.dst = c_data; 175 vars[1].direction.bits = c_parameter_in; 176 vars[1].ptr = &modifier; 177 178 OFFLOAD_TARGET_ENTER(ofld, 2, vars, NULL); 179 omp_set_schedule(kind, modifier); 180 OFFLOAD_TARGET_LEAVE(ofld); 181} 182 183void omp_get_schedule_lrb( 184 void *ofld_ 185) 186{ 187 OFFLOAD ofld = (OFFLOAD) ofld_; 188 VarDesc vars[2] = {0}; 189 omp_sched_t kind; 190 int modifier; 191 192 vars[0].type.src = c_data; 193 vars[0].type.dst = c_data; 194 vars[0].direction.bits = c_parameter_out; 195 vars[0].ptr = &kind; 196 197 vars[1].type.src = c_data; 198 vars[1].type.dst = c_data; 199 vars[1].direction.bits = c_parameter_out; 200 vars[1].ptr = &modifier; 201 202 OFFLOAD_TARGET_ENTER(ofld, 2, vars, NULL); 203 omp_get_schedule(&kind, &modifier); 204 OFFLOAD_TARGET_LEAVE(ofld); 205} 206 207// lock API functions 208 209void omp_init_lock_lrb( 210 void *ofld_ 211) 212{ 213 OFFLOAD ofld = (OFFLOAD) ofld_; 214 VarDesc vars[1] = {0}; 215 omp_lock_target_t lock; 216 217 vars[0].type.src = c_data; 218 vars[0].type.dst = c_data; 219 vars[0].direction.bits = c_parameter_out; 220 vars[0].ptr = &lock; 221 222 OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL); 223 omp_init_lock(&lock.lock); 224 OFFLOAD_TARGET_LEAVE(ofld); 225} 226 227void omp_destroy_lock_lrb( 228 void *ofld_ 229) 230{ 231 OFFLOAD ofld = (OFFLOAD) ofld_; 232 VarDesc vars[1] = {0}; 233 omp_lock_target_t lock; 234 235 vars[0].type.src = c_data; 236 vars[0].type.dst = c_data; 237 vars[0].direction.bits = c_parameter_in; 238 vars[0].ptr = &lock; 239 240 OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL); 241 omp_destroy_lock(&lock.lock); 242 OFFLOAD_TARGET_LEAVE(ofld); 243} 244 245void omp_set_lock_lrb( 246 void *ofld_ 247) 248{ 249 OFFLOAD ofld = (OFFLOAD) ofld_; 250 VarDesc vars[1] = {0}; 251 omp_lock_target_t lock; 252 253 vars[0].type.src = c_data; 254 vars[0].type.dst = c_data; 255 vars[0].direction.bits = c_parameter_inout; 256 vars[0].ptr = &lock; 257 258 OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL); 259 omp_set_lock(&lock.lock); 260 OFFLOAD_TARGET_LEAVE(ofld); 261} 262 263void omp_unset_lock_lrb( 264 void *ofld_ 265) 266{ 267 OFFLOAD ofld = (OFFLOAD) ofld_; 268 VarDesc vars[1] = {0}; 269 omp_lock_target_t lock; 270 271 vars[0].type.src = c_data; 272 vars[0].type.dst = c_data; 273 vars[0].direction.bits = c_parameter_inout; 274 vars[0].ptr = &lock; 275 276 OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL); 277 omp_unset_lock(&lock.lock); 278 OFFLOAD_TARGET_LEAVE(ofld); 279} 280 281void omp_test_lock_lrb( 282 void *ofld_ 283) 284{ 285 OFFLOAD ofld = (OFFLOAD) ofld_; 286 VarDesc vars[2] = {0}; 287 omp_lock_target_t lock; 288 int result; 289 290 vars[0].type.src = c_data; 291 vars[0].type.dst = c_data; 292 vars[0].direction.bits = c_parameter_inout; 293 vars[0].ptr = &lock; 294 295 vars[1].type.src = c_data; 296 vars[1].type.dst = c_data; 297 vars[1].direction.bits = c_parameter_out; 298 vars[1].ptr = &result; 299 300 OFFLOAD_TARGET_ENTER(ofld, 2, vars, NULL); 301 result = omp_test_lock(&lock.lock); 302 OFFLOAD_TARGET_LEAVE(ofld); 303} 304 305// nested lock API functions 306 307void omp_init_nest_lock_lrb( 308 void *ofld_ 309) 310{ 311 OFFLOAD ofld = (OFFLOAD) ofld_; 312 VarDesc vars[1] = {0}; 313 omp_nest_lock_target_t lock; 314 315 vars[0].type.src = c_data; 316 vars[0].type.dst = c_data; 317 vars[0].direction.bits = c_parameter_out; 318 vars[0].ptr = &lock; 319 320 OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL); 321 omp_init_nest_lock(&lock.lock); 322 OFFLOAD_TARGET_LEAVE(ofld); 323} 324 325void omp_destroy_nest_lock_lrb( 326 void *ofld_ 327) 328{ 329 OFFLOAD ofld = (OFFLOAD) ofld_; 330 VarDesc vars[1] = {0}; 331 omp_nest_lock_target_t lock; 332 333 vars[0].type.src = c_data; 334 vars[0].type.dst = c_data; 335 vars[0].direction.bits = c_parameter_in; 336 vars[0].ptr = &lock; 337 338 OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL); 339 omp_destroy_nest_lock(&lock.lock); 340 OFFLOAD_TARGET_LEAVE(ofld); 341} 342 343void omp_set_nest_lock_lrb( 344 void *ofld_ 345) 346{ 347 OFFLOAD ofld = (OFFLOAD) ofld_; 348 VarDesc vars[1] = {0}; 349 omp_nest_lock_target_t lock; 350 351 vars[0].type.src = c_data; 352 vars[0].type.dst = c_data; 353 vars[0].direction.bits = c_parameter_inout; 354 vars[0].ptr = &lock; 355 356 OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL); 357 omp_set_nest_lock(&lock.lock); 358 OFFLOAD_TARGET_LEAVE(ofld); 359} 360 361void omp_unset_nest_lock_lrb( 362 void *ofld_ 363) 364{ 365 OFFLOAD ofld = (OFFLOAD) ofld_; 366 VarDesc vars[1] = {0}; 367 omp_nest_lock_target_t lock; 368 369 vars[0].type.src = c_data; 370 vars[0].type.dst = c_data; 371 vars[0].direction.bits = c_parameter_inout; 372 vars[0].ptr = &lock; 373 374 OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL); 375 omp_unset_nest_lock(&lock.lock); 376 OFFLOAD_TARGET_LEAVE(ofld); 377} 378 379void omp_test_nest_lock_lrb( 380 void *ofld_ 381) 382{ 383 OFFLOAD ofld = (OFFLOAD) ofld_; 384 VarDesc vars[2] = {0}; 385 omp_nest_lock_target_t lock; 386 int result; 387 388 vars[0].type.src = c_data; 389 vars[0].type.dst = c_data; 390 vars[0].direction.bits = c_parameter_inout; 391 vars[0].ptr = &lock; 392 393 vars[1].type.src = c_data; 394 vars[1].type.dst = c_data; 395 vars[1].direction.bits = c_parameter_out; 396 vars[1].ptr = &result; 397 398 OFFLOAD_TARGET_ENTER(ofld, 2, vars, NULL); 399 result = omp_test_nest_lock(&lock.lock); 400 OFFLOAD_TARGET_LEAVE(ofld); 401} 402 403// Target-side stubs for the host functions (to avoid unresolveds) 404// These are needed for the offloadm table 405 406void omp_set_num_threads_target( 407 TARGET_TYPE target_type, 408 int target_number, 409 int num_threads 410) 411{ 412} 413 414int omp_get_max_threads_target( 415 TARGET_TYPE target_type, 416 int target_number 417) 418{ 419 return 0; 420} 421 422int omp_get_num_procs_target( 423 TARGET_TYPE target_type, 424 int target_number 425) 426{ 427 return 0; 428} 429 430void omp_set_dynamic_target( 431 TARGET_TYPE target_type, 432 int target_number, 433 int num_threads 434) 435{ 436} 437 438int omp_get_dynamic_target( 439 TARGET_TYPE target_type, 440 int target_number 441) 442{ 443 return 0; 444} 445 446void omp_set_nested_target( 447 TARGET_TYPE target_type, 448 int target_number, 449 int num_threads 450) 451{ 452} 453 454int omp_get_nested_target( 455 TARGET_TYPE target_type, 456 int target_number 457) 458{ 459 return 0; 460} 461 462void omp_set_schedule_target( 463 TARGET_TYPE target_type, 464 int target_number, 465 omp_sched_t kind, 466 int modifier 467) 468{ 469} 470 471void omp_get_schedule_target( 472 TARGET_TYPE target_type, 473 int target_number, 474 omp_sched_t *kind, 475 int *modifier 476) 477{ 478} 479 480void omp_init_lock_target( 481 TARGET_TYPE target_type, 482 int target_number, 483 omp_lock_target_t *lock 484) 485{ 486} 487 488void omp_destroy_lock_target( 489 TARGET_TYPE target_type, 490 int target_number, 491 omp_lock_target_t *lock 492) 493{ 494} 495 496void omp_set_lock_target( 497 TARGET_TYPE target_type, 498 int target_number, 499 omp_lock_target_t *lock 500) 501{ 502} 503 504void omp_unset_lock_target( 505 TARGET_TYPE target_type, 506 int target_number, 507 omp_lock_target_t *lock 508) 509{ 510} 511 512int omp_test_lock_target( 513 TARGET_TYPE target_type, 514 int target_number, 515 omp_lock_target_t *lock 516) 517{ 518 return 0; 519} 520 521void omp_init_nest_lock_target( 522 TARGET_TYPE target_type, 523 int target_number, 524 omp_nest_lock_target_t *lock 525) 526{ 527} 528 529void omp_destroy_nest_lock_target( 530 TARGET_TYPE target_type, 531 int target_number, 532 omp_nest_lock_target_t *lock 533) 534{ 535} 536 537void omp_set_nest_lock_target( 538 TARGET_TYPE target_type, 539 int target_number, 540 omp_nest_lock_target_t *lock 541) 542{ 543} 544 545void omp_unset_nest_lock_target( 546 TARGET_TYPE target_type, 547 int target_number, 548 omp_nest_lock_target_t *lock 549) 550{ 551} 552 553int omp_test_nest_lock_target( 554 TARGET_TYPE target_type, 555 int target_number, 556 omp_nest_lock_target_t *lock 557) 558{ 559 return 0; 560} 561