1 //===-------- interface.cpp - Target independent OpenMP target RTL --------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Implementation of the interface to be used by Clang during the codegen of a 10 // target region. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "device.h" 15 #include "omptarget.h" 16 #include "private.h" 17 #include "rtl.h" 18 19 #include <cassert> 20 #include <cstdio> 21 #include <cstdlib> 22 #include <mutex> 23 24 //////////////////////////////////////////////////////////////////////////////// 25 /// manage the success or failure of a target construct 26 static void HandleDefaultTargetOffload() { 27 PM->TargetOffloadMtx.lock(); 28 if (PM->TargetOffloadPolicy == tgt_default) { 29 if (omp_get_num_devices() > 0) { 30 DP("Default TARGET OFFLOAD policy is now mandatory " 31 "(devices were found)\n"); 32 PM->TargetOffloadPolicy = tgt_mandatory; 33 } else { 34 DP("Default TARGET OFFLOAD policy is now disabled " 35 "(no devices were found)\n"); 36 PM->TargetOffloadPolicy = tgt_disabled; 37 } 38 } 39 PM->TargetOffloadMtx.unlock(); 40 } 41 42 static int IsOffloadDisabled() { 43 if (PM->TargetOffloadPolicy == tgt_default) 44 HandleDefaultTargetOffload(); 45 return PM->TargetOffloadPolicy == tgt_disabled; 46 } 47 48 static void HandleTargetOutcome(bool success, ident_t *loc = nullptr) { 49 switch (PM->TargetOffloadPolicy) { 50 case tgt_disabled: 51 if (success) { 52 FATAL_MESSAGE0(1, "expected no offloading while offloading is disabled"); 53 } 54 break; 55 case tgt_default: 56 FATAL_MESSAGE0(1, "default offloading policy must be switched to " 57 "mandatory or disabled"); 58 break; 59 case tgt_mandatory: 60 if (!success) { 61 if (getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE) 62 for (auto &Device : PM->Devices) 63 dumpTargetPointerMappings(loc, Device); 64 else 65 FAILURE_MESSAGE("Run with LIBOMPTARGET_DEBUG=%d to dump host-target " 66 "pointer mappings.\n", 67 OMP_INFOTYPE_DUMP_TABLE); 68 69 SourceInfo info(loc); 70 if (info.isAvailible()) 71 fprintf(stderr, "%s:%d:%d: ", info.getFilename(), info.getLine(), 72 info.getColumn()); 73 else 74 FAILURE_MESSAGE("Source location information not present. Compile with " 75 "-g or -gline-tables-only.\n"); 76 FATAL_MESSAGE0( 77 1, "failure of target construct while offloading is mandatory"); 78 } else { 79 if (getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE) 80 for (auto &Device : PM->Devices) 81 dumpTargetPointerMappings(loc, Device); 82 } 83 break; 84 } 85 } 86 87 //////////////////////////////////////////////////////////////////////////////// 88 /// adds requires flags 89 EXTERN void __tgt_register_requires(int64_t flags) { 90 TIMESCOPE(); 91 PM->RTLs.RegisterRequires(flags); 92 } 93 94 //////////////////////////////////////////////////////////////////////////////// 95 /// adds a target shared library to the target execution image 96 EXTERN void __tgt_register_lib(__tgt_bin_desc *desc) { 97 TIMESCOPE(); 98 std::call_once(PM->RTLs.initFlag, &RTLsTy::LoadRTLs, &PM->RTLs); 99 for (auto &RTL : PM->RTLs.AllRTLs) { 100 if (RTL.register_lib) { 101 if ((*RTL.register_lib)(desc) != OFFLOAD_SUCCESS) { 102 DP("Could not register library with %s", RTL.RTLName.c_str()); 103 } 104 } 105 } 106 PM->RTLs.RegisterLib(desc); 107 } 108 109 //////////////////////////////////////////////////////////////////////////////// 110 /// unloads a target shared library 111 EXTERN void __tgt_unregister_lib(__tgt_bin_desc *desc) { 112 TIMESCOPE(); 113 PM->RTLs.UnregisterLib(desc); 114 for (auto &RTL : PM->RTLs.UsedRTLs) { 115 if (RTL->unregister_lib) { 116 if ((*RTL->unregister_lib)(desc) != OFFLOAD_SUCCESS) { 117 DP("Could not register library with %s", RTL->RTLName.c_str()); 118 } 119 } 120 } 121 } 122 123 /// creates host-to-target data mapping, stores it in the 124 /// libomptarget.so internal structure (an entry in a stack of data maps) 125 /// and passes the data to the device. 126 EXTERN void __tgt_target_data_begin(int64_t device_id, int32_t arg_num, 127 void **args_base, void **args, 128 int64_t *arg_sizes, int64_t *arg_types) { 129 TIMESCOPE(); 130 __tgt_target_data_begin_mapper(nullptr, device_id, arg_num, args_base, args, 131 arg_sizes, arg_types, nullptr, nullptr); 132 } 133 134 EXTERN void __tgt_target_data_begin_nowait(int64_t device_id, int32_t arg_num, 135 void **args_base, void **args, 136 int64_t *arg_sizes, 137 int64_t *arg_types, int32_t depNum, 138 void *depList, int32_t noAliasDepNum, 139 void *noAliasDepList) { 140 TIMESCOPE(); 141 if (depNum + noAliasDepNum > 0) 142 __kmpc_omp_taskwait(NULL, __kmpc_global_thread_num(NULL)); 143 144 __tgt_target_data_begin_mapper(nullptr, device_id, arg_num, args_base, args, 145 arg_sizes, arg_types, nullptr, nullptr); 146 } 147 148 EXTERN void __tgt_target_data_begin_mapper(ident_t *loc, int64_t device_id, 149 int32_t arg_num, void **args_base, 150 void **args, int64_t *arg_sizes, 151 int64_t *arg_types, 152 map_var_info_t *arg_names, 153 void **arg_mappers) { 154 TIMESCOPE_WITH_IDENT(loc); 155 if (IsOffloadDisabled()) 156 return; 157 158 DP("Entering data begin region for device %" PRId64 " with %d mappings\n", 159 device_id, arg_num); 160 161 // No devices available? 162 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 163 device_id = omp_get_default_device(); 164 DP("Use default device id %" PRId64 "\n", device_id); 165 } 166 167 // Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669. 168 if (omp_get_num_devices() == 0) { 169 DP("omp_get_num_devices() == 0 but offload is manadatory\n"); 170 HandleTargetOutcome(false, loc); 171 return; 172 } 173 174 if (device_id == omp_get_initial_device()) { 175 DP("Device is host (%" PRId64 "), returning as if offload is disabled\n", 176 device_id); 177 return; 178 } 179 180 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 181 DP("Failed to get device %" PRId64 " ready\n", device_id); 182 HandleTargetOutcome(false, loc); 183 return; 184 } 185 186 DeviceTy &Device = PM->Devices[device_id]; 187 188 if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS) 189 printKernelArguments(loc, device_id, arg_num, arg_sizes, arg_types, 190 arg_names, "Entering OpenMP data region"); 191 #ifdef OMPTARGET_DEBUG 192 for (int i = 0; i < arg_num; ++i) { 193 DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64 194 ", Type=0x%" PRIx64 ", Name=%s\n", 195 i, DPxPTR(args_base[i]), DPxPTR(args[i]), arg_sizes[i], arg_types[i], 196 (arg_names) ? getNameFromMapping(arg_names[i]).c_str() : "unknown"); 197 } 198 #endif 199 200 AsyncInfoTy AsyncInfo(Device); 201 int rc = targetDataBegin(loc, Device, arg_num, args_base, args, arg_sizes, 202 arg_types, arg_names, arg_mappers, AsyncInfo); 203 if (rc == OFFLOAD_SUCCESS) 204 rc = AsyncInfo.synchronize(); 205 HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc); 206 } 207 208 EXTERN void __tgt_target_data_begin_nowait_mapper( 209 ident_t *loc, int64_t device_id, int32_t arg_num, void **args_base, 210 void **args, int64_t *arg_sizes, int64_t *arg_types, 211 map_var_info_t *arg_names, void **arg_mappers, int32_t depNum, 212 void *depList, int32_t noAliasDepNum, void *noAliasDepList) { 213 TIMESCOPE_WITH_IDENT(loc); 214 if (depNum + noAliasDepNum > 0) 215 __kmpc_omp_taskwait(loc, __kmpc_global_thread_num(loc)); 216 217 __tgt_target_data_begin_mapper(loc, device_id, arg_num, args_base, args, 218 arg_sizes, arg_types, arg_names, arg_mappers); 219 } 220 221 /// passes data from the target, releases target memory and destroys 222 /// the host-target mapping (top entry from the stack of data maps) 223 /// created by the last __tgt_target_data_begin. 224 EXTERN void __tgt_target_data_end(int64_t device_id, int32_t arg_num, 225 void **args_base, void **args, 226 int64_t *arg_sizes, int64_t *arg_types) { 227 TIMESCOPE(); 228 __tgt_target_data_end_mapper(nullptr, device_id, arg_num, args_base, args, 229 arg_sizes, arg_types, nullptr, nullptr); 230 } 231 232 EXTERN void __tgt_target_data_end_nowait(int64_t device_id, int32_t arg_num, 233 void **args_base, void **args, 234 int64_t *arg_sizes, int64_t *arg_types, 235 int32_t depNum, void *depList, 236 int32_t noAliasDepNum, 237 void *noAliasDepList) { 238 TIMESCOPE(); 239 if (depNum + noAliasDepNum > 0) 240 __kmpc_omp_taskwait(NULL, __kmpc_global_thread_num(NULL)); 241 242 __tgt_target_data_end_mapper(nullptr, device_id, arg_num, args_base, args, 243 arg_sizes, arg_types, nullptr, nullptr); 244 } 245 246 EXTERN void __tgt_target_data_end_mapper(ident_t *loc, int64_t device_id, 247 int32_t arg_num, void **args_base, 248 void **args, int64_t *arg_sizes, 249 int64_t *arg_types, 250 map_var_info_t *arg_names, 251 void **arg_mappers) { 252 TIMESCOPE_WITH_IDENT(loc); 253 if (IsOffloadDisabled()) 254 return; 255 DP("Entering data end region with %d mappings\n", arg_num); 256 257 // No devices available? 258 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 259 device_id = omp_get_default_device(); 260 } 261 262 // Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669. 263 if (omp_get_num_devices() == 0) { 264 DP("omp_get_num_devices() == 0 but offload is manadatory\n"); 265 HandleTargetOutcome(false, loc); 266 return; 267 } 268 269 if (device_id == omp_get_initial_device()) { 270 DP("Device is host (%" PRId64 "), returning as if offload is disabled\n", 271 device_id); 272 return; 273 } 274 275 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 276 DP("Failed to get device %" PRId64 " ready\n", device_id); 277 HandleTargetOutcome(false, loc); 278 return; 279 } 280 281 DeviceTy &Device = PM->Devices[device_id]; 282 283 if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS) 284 printKernelArguments(loc, device_id, arg_num, arg_sizes, arg_types, 285 arg_names, "Exiting OpenMP data region"); 286 #ifdef OMPTARGET_DEBUG 287 for (int i = 0; i < arg_num; ++i) { 288 DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64 289 ", Type=0x%" PRIx64 ", Name=%s\n", 290 i, DPxPTR(args_base[i]), DPxPTR(args[i]), arg_sizes[i], arg_types[i], 291 (arg_names) ? getNameFromMapping(arg_names[i]).c_str() : "unknown"); 292 } 293 #endif 294 295 AsyncInfoTy AsyncInfo(Device); 296 int rc = targetDataEnd(loc, Device, arg_num, args_base, args, arg_sizes, 297 arg_types, arg_names, arg_mappers, AsyncInfo); 298 if (rc == OFFLOAD_SUCCESS) 299 rc = AsyncInfo.synchronize(); 300 HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc); 301 } 302 303 EXTERN void __tgt_target_data_end_nowait_mapper( 304 ident_t *loc, int64_t device_id, int32_t arg_num, void **args_base, 305 void **args, int64_t *arg_sizes, int64_t *arg_types, 306 map_var_info_t *arg_names, void **arg_mappers, int32_t depNum, 307 void *depList, int32_t noAliasDepNum, void *noAliasDepList) { 308 TIMESCOPE_WITH_IDENT(loc); 309 if (depNum + noAliasDepNum > 0) 310 __kmpc_omp_taskwait(loc, __kmpc_global_thread_num(loc)); 311 312 __tgt_target_data_end_mapper(loc, device_id, arg_num, args_base, args, 313 arg_sizes, arg_types, arg_names, arg_mappers); 314 } 315 316 EXTERN void __tgt_target_data_update(int64_t device_id, int32_t arg_num, 317 void **args_base, void **args, 318 int64_t *arg_sizes, int64_t *arg_types) { 319 TIMESCOPE(); 320 __tgt_target_data_update_mapper(nullptr, device_id, arg_num, args_base, args, 321 arg_sizes, arg_types, nullptr, nullptr); 322 } 323 324 EXTERN void __tgt_target_data_update_nowait( 325 int64_t device_id, int32_t arg_num, void **args_base, void **args, 326 int64_t *arg_sizes, int64_t *arg_types, int32_t depNum, void *depList, 327 int32_t noAliasDepNum, void *noAliasDepList) { 328 TIMESCOPE(); 329 if (depNum + noAliasDepNum > 0) 330 __kmpc_omp_taskwait(NULL, __kmpc_global_thread_num(NULL)); 331 332 __tgt_target_data_update_mapper(nullptr, device_id, arg_num, args_base, args, 333 arg_sizes, arg_types, nullptr, nullptr); 334 } 335 336 EXTERN void __tgt_target_data_update_mapper(ident_t *loc, int64_t device_id, 337 int32_t arg_num, void **args_base, 338 void **args, int64_t *arg_sizes, 339 int64_t *arg_types, 340 map_var_info_t *arg_names, 341 void **arg_mappers) { 342 TIMESCOPE_WITH_IDENT(loc); 343 if (IsOffloadDisabled()) 344 return; 345 DP("Entering data update with %d mappings\n", arg_num); 346 347 // No devices available? 348 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 349 device_id = omp_get_default_device(); 350 } 351 352 // Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669. 353 if (omp_get_num_devices() == 0) { 354 DP("omp_get_num_devices() == 0 but offload is manadatory\n"); 355 HandleTargetOutcome(false, loc); 356 return; 357 } 358 359 if (device_id == omp_get_initial_device()) { 360 DP("Device is host (%" PRId64 "), returning as if offload is disabled\n", 361 device_id); 362 return; 363 } 364 365 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 366 DP("Failed to get device %" PRId64 " ready\n", device_id); 367 HandleTargetOutcome(false, loc); 368 return; 369 } 370 371 if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS) 372 printKernelArguments(loc, device_id, arg_num, arg_sizes, arg_types, 373 arg_names, "Updating OpenMP data"); 374 375 DeviceTy &Device = PM->Devices[device_id]; 376 AsyncInfoTy AsyncInfo(Device); 377 int rc = targetDataUpdate(loc, Device, arg_num, args_base, args, arg_sizes, 378 arg_types, arg_names, arg_mappers, AsyncInfo); 379 if (rc == OFFLOAD_SUCCESS) 380 rc = AsyncInfo.synchronize(); 381 HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc); 382 } 383 384 EXTERN void __tgt_target_data_update_nowait_mapper( 385 ident_t *loc, int64_t device_id, int32_t arg_num, void **args_base, 386 void **args, int64_t *arg_sizes, int64_t *arg_types, 387 map_var_info_t *arg_names, void **arg_mappers, int32_t depNum, 388 void *depList, int32_t noAliasDepNum, void *noAliasDepList) { 389 TIMESCOPE_WITH_IDENT(loc); 390 if (depNum + noAliasDepNum > 0) 391 __kmpc_omp_taskwait(loc, __kmpc_global_thread_num(loc)); 392 393 __tgt_target_data_update_mapper(loc, device_id, arg_num, args_base, args, 394 arg_sizes, arg_types, arg_names, arg_mappers); 395 } 396 397 EXTERN int __tgt_target(int64_t device_id, void *host_ptr, int32_t arg_num, 398 void **args_base, void **args, int64_t *arg_sizes, 399 int64_t *arg_types) { 400 TIMESCOPE(); 401 return __tgt_target_mapper(nullptr, device_id, host_ptr, arg_num, args_base, 402 args, arg_sizes, arg_types, nullptr, nullptr); 403 } 404 405 EXTERN int __tgt_target_nowait(int64_t device_id, void *host_ptr, 406 int32_t arg_num, void **args_base, void **args, 407 int64_t *arg_sizes, int64_t *arg_types, 408 int32_t depNum, void *depList, 409 int32_t noAliasDepNum, void *noAliasDepList) { 410 TIMESCOPE(); 411 if (depNum + noAliasDepNum > 0) 412 __kmpc_omp_taskwait(NULL, __kmpc_global_thread_num(NULL)); 413 414 return __tgt_target_mapper(nullptr, device_id, host_ptr, arg_num, args_base, 415 args, arg_sizes, arg_types, nullptr, nullptr); 416 } 417 418 EXTERN int __tgt_target_mapper(ident_t *loc, int64_t device_id, void *host_ptr, 419 int32_t arg_num, void **args_base, void **args, 420 int64_t *arg_sizes, int64_t *arg_types, 421 map_var_info_t *arg_names, void **arg_mappers) { 422 TIMESCOPE_WITH_IDENT(loc); 423 if (IsOffloadDisabled()) 424 return OFFLOAD_FAIL; 425 DP("Entering target region with entry point " DPxMOD " and device Id %" PRId64 426 "\n", 427 DPxPTR(host_ptr), device_id); 428 429 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 430 device_id = omp_get_default_device(); 431 } 432 433 // Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669. 434 if (omp_get_num_devices() == 0) { 435 DP("omp_get_num_devices() == 0 but offload is manadatory\n"); 436 HandleTargetOutcome(false, loc); 437 return OFFLOAD_FAIL; 438 } 439 440 if (device_id == omp_get_initial_device()) { 441 DP("Device is host (%" PRId64 "), returning OFFLOAD_FAIL as if offload is " 442 "disabled\n", 443 device_id); 444 return OFFLOAD_FAIL; 445 } 446 447 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 448 REPORT("Failed to get device %" PRId64 " ready\n", device_id); 449 HandleTargetOutcome(false, loc); 450 return OFFLOAD_FAIL; 451 } 452 453 if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS) 454 printKernelArguments(loc, device_id, arg_num, arg_sizes, arg_types, 455 arg_names, "Entering OpenMP kernel"); 456 #ifdef OMPTARGET_DEBUG 457 for (int i = 0; i < arg_num; ++i) { 458 DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64 459 ", Type=0x%" PRIx64 ", Name=%s\n", 460 i, DPxPTR(args_base[i]), DPxPTR(args[i]), arg_sizes[i], arg_types[i], 461 (arg_names) ? getNameFromMapping(arg_names[i]).c_str() : "unknown"); 462 } 463 #endif 464 465 DeviceTy &Device = PM->Devices[device_id]; 466 AsyncInfoTy AsyncInfo(Device); 467 int rc = target(loc, Device, host_ptr, arg_num, args_base, args, arg_sizes, 468 arg_types, arg_names, arg_mappers, 0, 0, false /*team*/, 469 AsyncInfo); 470 if (rc == OFFLOAD_SUCCESS) 471 rc = AsyncInfo.synchronize(); 472 HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc); 473 return rc; 474 } 475 476 EXTERN int __tgt_target_nowait_mapper( 477 ident_t *loc, int64_t device_id, void *host_ptr, int32_t arg_num, 478 void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types, 479 map_var_info_t *arg_names, void **arg_mappers, int32_t depNum, 480 void *depList, int32_t noAliasDepNum, void *noAliasDepList) { 481 TIMESCOPE_WITH_IDENT(loc); 482 if (depNum + noAliasDepNum > 0) 483 __kmpc_omp_taskwait(loc, __kmpc_global_thread_num(loc)); 484 485 return __tgt_target_mapper(loc, device_id, host_ptr, arg_num, args_base, args, 486 arg_sizes, arg_types, arg_names, arg_mappers); 487 } 488 489 EXTERN int __tgt_target_teams(int64_t device_id, void *host_ptr, 490 int32_t arg_num, void **args_base, void **args, 491 int64_t *arg_sizes, int64_t *arg_types, 492 int32_t team_num, int32_t thread_limit) { 493 TIMESCOPE(); 494 return __tgt_target_teams_mapper(nullptr, device_id, host_ptr, arg_num, 495 args_base, args, arg_sizes, arg_types, 496 nullptr, nullptr, team_num, thread_limit); 497 } 498 499 EXTERN int __tgt_target_teams_nowait(int64_t device_id, void *host_ptr, 500 int32_t arg_num, void **args_base, 501 void **args, int64_t *arg_sizes, 502 int64_t *arg_types, int32_t team_num, 503 int32_t thread_limit, int32_t depNum, 504 void *depList, int32_t noAliasDepNum, 505 void *noAliasDepList) { 506 TIMESCOPE(); 507 if (depNum + noAliasDepNum > 0) 508 __kmpc_omp_taskwait(NULL, __kmpc_global_thread_num(NULL)); 509 510 return __tgt_target_teams_mapper(nullptr, device_id, host_ptr, arg_num, 511 args_base, args, arg_sizes, arg_types, 512 nullptr, nullptr, team_num, thread_limit); 513 } 514 515 EXTERN int __tgt_target_teams_mapper(ident_t *loc, int64_t device_id, 516 void *host_ptr, int32_t arg_num, 517 void **args_base, void **args, 518 int64_t *arg_sizes, int64_t *arg_types, 519 map_var_info_t *arg_names, 520 void **arg_mappers, int32_t team_num, 521 int32_t thread_limit) { 522 if (IsOffloadDisabled()) 523 return OFFLOAD_FAIL; 524 DP("Entering target region with entry point " DPxMOD " and device Id %" PRId64 525 "\n", 526 DPxPTR(host_ptr), device_id); 527 528 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 529 device_id = omp_get_default_device(); 530 } 531 532 // Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669. 533 if (omp_get_num_devices() == 0) { 534 DP("omp_get_num_devices() == 0 but offload is manadatory\n"); 535 HandleTargetOutcome(false, loc); 536 return OFFLOAD_FAIL; 537 } 538 539 if (device_id == omp_get_initial_device()) { 540 DP("Device is host (%" PRId64 "), returning OFFLOAD_FAIL as if offload is " 541 "disabled\n", 542 device_id); 543 return OFFLOAD_FAIL; 544 } 545 546 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 547 REPORT("Failed to get device %" PRId64 " ready\n", device_id); 548 HandleTargetOutcome(false, loc); 549 return OFFLOAD_FAIL; 550 } 551 552 if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS) 553 printKernelArguments(loc, device_id, arg_num, arg_sizes, arg_types, 554 arg_names, "Entering OpenMP kernel"); 555 #ifdef OMPTARGET_DEBUG 556 for (int i = 0; i < arg_num; ++i) { 557 DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64 558 ", Type=0x%" PRIx64 ", Name=%s\n", 559 i, DPxPTR(args_base[i]), DPxPTR(args[i]), arg_sizes[i], arg_types[i], 560 (arg_names) ? getNameFromMapping(arg_names[i]).c_str() : "unknown"); 561 } 562 #endif 563 564 DeviceTy &Device = PM->Devices[device_id]; 565 AsyncInfoTy AsyncInfo(Device); 566 int rc = target(loc, Device, host_ptr, arg_num, args_base, args, arg_sizes, 567 arg_types, arg_names, arg_mappers, team_num, thread_limit, 568 true /*team*/, AsyncInfo); 569 if (rc == OFFLOAD_SUCCESS) 570 rc = AsyncInfo.synchronize(); 571 HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc); 572 return rc; 573 } 574 575 EXTERN int __tgt_target_teams_nowait_mapper( 576 ident_t *loc, int64_t device_id, void *host_ptr, int32_t arg_num, 577 void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types, 578 map_var_info_t *arg_names, void **arg_mappers, int32_t team_num, 579 int32_t thread_limit, int32_t depNum, void *depList, int32_t noAliasDepNum, 580 void *noAliasDepList) { 581 TIMESCOPE_WITH_IDENT(loc); 582 if (depNum + noAliasDepNum > 0) 583 __kmpc_omp_taskwait(loc, __kmpc_global_thread_num(loc)); 584 585 return __tgt_target_teams_mapper(loc, device_id, host_ptr, arg_num, args_base, 586 args, arg_sizes, arg_types, arg_names, 587 arg_mappers, team_num, thread_limit); 588 } 589 590 // Get the current number of components for a user-defined mapper. 591 EXTERN int64_t __tgt_mapper_num_components(void *rt_mapper_handle) { 592 TIMESCOPE(); 593 auto *MapperComponentsPtr = (struct MapperComponentsTy *)rt_mapper_handle; 594 int64_t size = MapperComponentsPtr->Components.size(); 595 DP("__tgt_mapper_num_components(Handle=" DPxMOD ") returns %" PRId64 "\n", 596 DPxPTR(rt_mapper_handle), size); 597 return size; 598 } 599 600 // Push back one component for a user-defined mapper. 601 EXTERN void __tgt_push_mapper_component(void *rt_mapper_handle, void *base, 602 void *begin, int64_t size, int64_t type, 603 void *name) { 604 TIMESCOPE(); 605 DP("__tgt_push_mapper_component(Handle=" DPxMOD 606 ") adds an entry (Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64 607 ", Type=0x%" PRIx64 ", Name=%s).\n", 608 DPxPTR(rt_mapper_handle), DPxPTR(base), DPxPTR(begin), size, type, 609 (name) ? getNameFromMapping(name).c_str() : "unknown"); 610 auto *MapperComponentsPtr = (struct MapperComponentsTy *)rt_mapper_handle; 611 MapperComponentsPtr->Components.push_back( 612 MapComponentInfoTy(base, begin, size, type, name)); 613 } 614 615 EXTERN void __kmpc_push_target_tripcount(ident_t *loc, int64_t device_id, 616 uint64_t loop_tripcount) { 617 TIMESCOPE_WITH_IDENT(loc); 618 if (IsOffloadDisabled()) 619 return; 620 621 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 622 device_id = omp_get_default_device(); 623 } 624 625 // Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669. 626 if (omp_get_num_devices() == 0) { 627 DP("omp_get_num_devices() == 0 but offload is manadatory\n"); 628 HandleTargetOutcome(false, loc); 629 return; 630 } 631 632 if (device_id == omp_get_initial_device()) { 633 DP("Device is host (%" PRId64 "), returning as if offload is disabled\n", 634 device_id); 635 return; 636 } 637 638 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 639 DP("Failed to get device %" PRId64 " ready\n", device_id); 640 HandleTargetOutcome(false, loc); 641 return; 642 } 643 644 DP("__kmpc_push_target_tripcount(%" PRId64 ", %" PRIu64 ")\n", device_id, 645 loop_tripcount); 646 PM->TblMapMtx.lock(); 647 PM->Devices[device_id].LoopTripCnt.emplace(__kmpc_global_thread_num(NULL), 648 loop_tripcount); 649 PM->TblMapMtx.unlock(); 650 } 651