Index: libomptarget/src/interface.cpp =================================================================== --- libomptarget/src/interface.cpp +++ libomptarget/src/interface.cpp @@ -21,6 +21,30 @@ #include #include +static inline void checkOffloadResult(int rc) { + if (rc == OFFLOAD_FAIL && TargetOffloadMode == OMP_TGT_OFFLOAD_MANDATORY) { + fprintf(stderr, "WARNING: Target offload failure, terminating application" + "\n"); + exit(OFFLOAD_FAIL); + } +} + +#define CHECK_HOST_FALLBACK_DATA() \ + { \ + if (TargetOffloadMode == OMP_TGT_OFFLOAD_DISABLED) { \ + DP("Target offload disabled, ignoring \"target data\", " \ + "\"target enter/exit data\" or \"target update\"\n"); \ + return; \ + } \ + } +#define CHECK_HOST_FALLBACK_TARGET() \ + { \ + if (TargetOffloadMode == OMP_TGT_OFFLOAD_DISABLED) { \ + DP("Target offload disabled, executing target region on the host\n"); \ + return OFFLOAD_FAIL; \ + } \ + } + //////////////////////////////////////////////////////////////////////////////// /// adds a target shared library to the target execution image EXTERN void __tgt_register_lib(__tgt_bin_desc *desc) { @@ -260,6 +284,7 @@ /// and passes the data to the device. EXTERN void __tgt_target_data_begin(int64_t device_id, int32_t arg_num, void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types) { + CHECK_HOST_FALLBACK_DATA(); DP("Entering data begin region for device %ld with %d mappings\n", device_id, arg_num); @@ -310,6 +335,7 @@ /// created by the last __tgt_target_data_begin. EXTERN void __tgt_target_data_end(int64_t device_id, int32_t arg_num, void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types) { + CHECK_HOST_FALLBACK_DATA(); DP("Entering data end region with %d mappings\n", arg_num); // No devices available? @@ -362,6 +388,7 @@ EXTERN void __tgt_target_data_update(int64_t device_id, int32_t arg_num, void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types) { + CHECK_HOST_FALLBACK_DATA(); DP("Entering data update with %d mappings\n", arg_num); // No devices available? @@ -391,6 +418,7 @@ EXTERN int __tgt_target(int64_t device_id, void *host_ptr, int32_t arg_num, void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types) { + CHECK_HOST_FALLBACK_TARGET(); DP("Entering target region with entry point " DPxMOD " and device Id %ld\n", DPxPTR(host_ptr), device_id); @@ -421,6 +449,7 @@ cleanup_map(new_arg_num, new_args_base, new_args, new_arg_sizes, new_arg_types, arg_num, args_base); + checkOffloadResult(rc); return rc; } @@ -438,6 +467,7 @@ EXTERN int __tgt_target_teams(int64_t device_id, void *host_ptr, int32_t arg_num, void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types, int32_t team_num, int32_t thread_limit) { + CHECK_HOST_FALLBACK_TARGET(); DP("Entering target region with entry point " DPxMOD " and device Id %ld\n", DPxPTR(host_ptr), device_id); @@ -469,6 +499,7 @@ cleanup_map(new_arg_num, new_args_base, new_args, new_arg_sizes, new_arg_types, arg_num, args_base); + checkOffloadResult(rc); return rc; } Index: libomptarget/src/omptarget.cpp =================================================================== --- libomptarget/src/omptarget.cpp +++ libomptarget/src/omptarget.cpp @@ -25,6 +25,9 @@ int DebugLevel = 0; #endif // OMPTARGET_DEBUG +// Target offload ICV - can be MANDATORY, DISABLED or DEFAULT. +tgt_offload_mode TargetOffloadMode = OMP_TGT_OFFLOAD_DEFAULT; + /// Map global data and execute pending ctors static int InitLibrary(DeviceTy& Device) { /* Index: libomptarget/src/private.h =================================================================== --- libomptarget/src/private.h +++ libomptarget/src/private.h @@ -46,4 +46,12 @@ #define DP(...) {} #endif // OMPTARGET_DEBUG +// Target offload ICV +enum tgt_offload_mode { + OMP_TGT_OFFLOAD_DISABLED = 0, + OMP_TGT_OFFLOAD_DEFAULT = 1, + OMP_TGT_OFFLOAD_MANDATORY = 2 +}; +extern tgt_offload_mode TargetOffloadMode; + #endif Index: libomptarget/src/rtl.cpp =================================================================== --- libomptarget/src/rtl.cpp +++ libomptarget/src/rtl.cpp @@ -118,12 +118,24 @@ DP("Registering RTL %s supporting %d devices!\n", R.RTLName.c_str(), R.NumberOfDevices); + // We have found available devices, so the target offload mode must be set + // to MANDATORY. + TargetOffloadMode = OMP_TGT_OFFLOAD_MANDATORY; + DP("Target-offload-icv set to MANDATORY\n"); + // The RTL is valid! Will save the information in the RTLs list. AllRTLs.push_back(R); } DP("RTLs loaded!\n"); + // At this point, if the target-offload-icv is still DEFAULT, it means that no + // devices were found, so the icv falls back to DISABLED. + if (TargetOffloadMode == OMP_TGT_OFFLOAD_DEFAULT) { + TargetOffloadMode = OMP_TGT_OFFLOAD_DISABLED; + DP("Target-offload-icv set to DISABLED\n"); + } + return; } @@ -192,6 +204,12 @@ // Attempt to load all plugins available in the system. std::call_once(initFlag, &RTLsTy::LoadRTLs, this); + // Return immediately if offloading has been disabled + if (TargetOffloadMode == OMP_TGT_OFFLOAD_DISABLED) { + DP("Target offload disabled, skipping registering library\n"); + return; + } + RTLsMtx.lock(); // Register the images with the RTLs that understand them, if any. for (int32_t i = 0; i < desc->NumDeviceImages; ++i) { @@ -280,6 +298,12 @@ } void RTLsTy::UnregisterLib(__tgt_bin_desc *desc) { + // Return immediately if offloading has been disabled + if (TargetOffloadMode == OMP_TGT_OFFLOAD_DISABLED) { + DP("Target offload disabled, skipping unregister library\n"); + return; + } + DP("Unloading target library!\n"); RTLsMtx.lock();