[OpenMP] Encapsulate more in checkDeviceAndCtors

This patch just encapsulates some repeated code.  To do so, it
relocates some functions from interface.cpp to omptarget.cpp.  It also
adjusts them to the LLVM coding style.

This patch is almost NFC except some `DP` messages are a bit
different.  For example, messages like "Entering target region" are
now emitted even if offload is disabled, but a subsequent "Offload is
disabled" is then emitted.

Reviewed By: jdoerfert, grokos

Differential Revision: https://reviews.llvm.org/D97908
This commit is contained in:
Joel E. Denny 2021-03-04 11:19:13 -05:00
parent bfe5452b93
commit d0eb25a643
3 changed files with 121 additions and 221 deletions

View File

@ -21,69 +21,6 @@
#include <cstdlib>
#include <mutex>
////////////////////////////////////////////////////////////////////////////////
/// manage the success or failure of a target construct
static void HandleDefaultTargetOffload() {
PM->TargetOffloadMtx.lock();
if (PM->TargetOffloadPolicy == tgt_default) {
if (omp_get_num_devices() > 0) {
DP("Default TARGET OFFLOAD policy is now mandatory "
"(devices were found)\n");
PM->TargetOffloadPolicy = tgt_mandatory;
} else {
DP("Default TARGET OFFLOAD policy is now disabled "
"(no devices were found)\n");
PM->TargetOffloadPolicy = tgt_disabled;
}
}
PM->TargetOffloadMtx.unlock();
}
static int IsOffloadDisabled() {
if (PM->TargetOffloadPolicy == tgt_default)
HandleDefaultTargetOffload();
return PM->TargetOffloadPolicy == tgt_disabled;
}
static void HandleTargetOutcome(bool success, ident_t *loc = nullptr) {
switch (PM->TargetOffloadPolicy) {
case tgt_disabled:
if (success) {
FATAL_MESSAGE0(1, "expected no offloading while offloading is disabled");
}
break;
case tgt_default:
FATAL_MESSAGE0(1, "default offloading policy must be switched to "
"mandatory or disabled");
break;
case tgt_mandatory:
if (!success) {
if (getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE)
for (auto &Device : PM->Devices)
dumpTargetPointerMappings(loc, Device);
else
FAILURE_MESSAGE("Run with LIBOMPTARGET_DEBUG=%d to dump host-target "
"pointer mappings.\n",
OMP_INFOTYPE_DUMP_TABLE);
SourceInfo info(loc);
if (info.isAvailible())
fprintf(stderr, "%s:%d:%d: ", info.getFilename(), info.getLine(),
info.getColumn());
else
FAILURE_MESSAGE("Source location information not present. Compile with "
"-g or -gline-tables-only.\n");
FATAL_MESSAGE0(
1, "failure of target construct while offloading is mandatory");
} else {
if (getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE)
for (auto &Device : PM->Devices)
dumpTargetPointerMappings(loc, Device);
}
break;
}
}
////////////////////////////////////////////////////////////////////////////////
/// adds requires flags
EXTERN void __tgt_register_requires(int64_t flags) {
@ -152,34 +89,10 @@ EXTERN void __tgt_target_data_begin_mapper(ident_t *loc, int64_t device_id,
map_var_info_t *arg_names,
void **arg_mappers) {
TIMESCOPE_WITH_IDENT(loc);
if (IsOffloadDisabled())
return;
DP("Entering data begin region for device %" PRId64 " with %d mappings\n",
device_id, arg_num);
// No devices available?
if (device_id == OFFLOAD_DEVICE_DEFAULT) {
device_id = omp_get_default_device();
DP("Use default device id %" PRId64 "\n", device_id);
}
// Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669.
if (omp_get_num_devices() == 0) {
DP("omp_get_num_devices() == 0 but offload is manadatory\n");
HandleTargetOutcome(false, loc);
return;
}
if (device_id == omp_get_initial_device()) {
DP("Device is host (%" PRId64 "), returning as if offload is disabled\n",
device_id);
return;
}
if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
DP("Failed to get device %" PRId64 " ready\n", device_id);
HandleTargetOutcome(false, loc);
if (checkDeviceAndCtors(device_id, loc) != OFFLOAD_SUCCESS) {
DP("Not offloading to device %" PRId64 "\n", device_id);
return;
}
@ -202,7 +115,7 @@ EXTERN void __tgt_target_data_begin_mapper(ident_t *loc, int64_t device_id,
arg_types, arg_names, arg_mappers, AsyncInfo);
if (rc == OFFLOAD_SUCCESS)
rc = AsyncInfo.synchronize();
HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
handleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
}
EXTERN void __tgt_target_data_begin_nowait_mapper(
@ -250,31 +163,9 @@ EXTERN void __tgt_target_data_end_mapper(ident_t *loc, int64_t device_id,
map_var_info_t *arg_names,
void **arg_mappers) {
TIMESCOPE_WITH_IDENT(loc);
if (IsOffloadDisabled())
return;
DP("Entering data end region with %d mappings\n", arg_num);
// No devices available?
if (device_id == OFFLOAD_DEVICE_DEFAULT) {
device_id = omp_get_default_device();
}
// Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669.
if (omp_get_num_devices() == 0) {
DP("omp_get_num_devices() == 0 but offload is manadatory\n");
HandleTargetOutcome(false, loc);
return;
}
if (device_id == omp_get_initial_device()) {
DP("Device is host (%" PRId64 "), returning as if offload is disabled\n",
device_id);
return;
}
if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
DP("Failed to get device %" PRId64 " ready\n", device_id);
HandleTargetOutcome(false, loc);
if (checkDeviceAndCtors(device_id, loc) != OFFLOAD_SUCCESS) {
DP("Not offloading to device %" PRId64 "\n", device_id);
return;
}
@ -297,7 +188,7 @@ EXTERN void __tgt_target_data_end_mapper(ident_t *loc, int64_t device_id,
arg_types, arg_names, arg_mappers, AsyncInfo);
if (rc == OFFLOAD_SUCCESS)
rc = AsyncInfo.synchronize();
HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
handleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
}
EXTERN void __tgt_target_data_end_nowait_mapper(
@ -340,31 +231,9 @@ EXTERN void __tgt_target_data_update_mapper(ident_t *loc, int64_t device_id,
map_var_info_t *arg_names,
void **arg_mappers) {
TIMESCOPE_WITH_IDENT(loc);
if (IsOffloadDisabled())
return;
DP("Entering data update with %d mappings\n", arg_num);
// No devices available?
if (device_id == OFFLOAD_DEVICE_DEFAULT) {
device_id = omp_get_default_device();
}
// Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669.
if (omp_get_num_devices() == 0) {
DP("omp_get_num_devices() == 0 but offload is manadatory\n");
HandleTargetOutcome(false, loc);
return;
}
if (device_id == omp_get_initial_device()) {
DP("Device is host (%" PRId64 "), returning as if offload is disabled\n",
device_id);
return;
}
if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
DP("Failed to get device %" PRId64 " ready\n", device_id);
HandleTargetOutcome(false, loc);
if (checkDeviceAndCtors(device_id, loc) != OFFLOAD_SUCCESS) {
DP("Not offloading to device %" PRId64 "\n", device_id);
return;
}
@ -378,7 +247,7 @@ EXTERN void __tgt_target_data_update_mapper(ident_t *loc, int64_t device_id,
arg_types, arg_names, arg_mappers, AsyncInfo);
if (rc == OFFLOAD_SUCCESS)
rc = AsyncInfo.synchronize();
HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
handleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
}
EXTERN void __tgt_target_data_update_nowait_mapper(
@ -420,33 +289,11 @@ EXTERN int __tgt_target_mapper(ident_t *loc, int64_t device_id, void *host_ptr,
int64_t *arg_sizes, int64_t *arg_types,
map_var_info_t *arg_names, void **arg_mappers) {
TIMESCOPE_WITH_IDENT(loc);
if (IsOffloadDisabled())
return OFFLOAD_FAIL;
DP("Entering target region with entry point " DPxMOD " and device Id %" PRId64
"\n",
DPxPTR(host_ptr), device_id);
if (device_id == OFFLOAD_DEVICE_DEFAULT) {
device_id = omp_get_default_device();
}
// Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669.
if (omp_get_num_devices() == 0) {
DP("omp_get_num_devices() == 0 but offload is manadatory\n");
HandleTargetOutcome(false, loc);
return OFFLOAD_FAIL;
}
if (device_id == omp_get_initial_device()) {
DP("Device is host (%" PRId64 "), returning OFFLOAD_FAIL as if offload is "
"disabled\n",
device_id);
return OFFLOAD_FAIL;
}
if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
REPORT("Failed to get device %" PRId64 " ready\n", device_id);
HandleTargetOutcome(false, loc);
if (checkDeviceAndCtors(device_id, loc) != OFFLOAD_SUCCESS) {
DP("Not offloading to device %" PRId64 "\n", device_id);
return OFFLOAD_FAIL;
}
@ -469,7 +316,7 @@ EXTERN int __tgt_target_mapper(ident_t *loc, int64_t device_id, void *host_ptr,
AsyncInfo);
if (rc == OFFLOAD_SUCCESS)
rc = AsyncInfo.synchronize();
HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
handleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
return rc;
}
@ -519,33 +366,11 @@ EXTERN int __tgt_target_teams_mapper(ident_t *loc, int64_t device_id,
map_var_info_t *arg_names,
void **arg_mappers, int32_t team_num,
int32_t thread_limit) {
if (IsOffloadDisabled())
return OFFLOAD_FAIL;
DP("Entering target region with entry point " DPxMOD " and device Id %" PRId64
"\n",
DPxPTR(host_ptr), device_id);
if (device_id == OFFLOAD_DEVICE_DEFAULT) {
device_id = omp_get_default_device();
}
// Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669.
if (omp_get_num_devices() == 0) {
DP("omp_get_num_devices() == 0 but offload is manadatory\n");
HandleTargetOutcome(false, loc);
return OFFLOAD_FAIL;
}
if (device_id == omp_get_initial_device()) {
DP("Device is host (%" PRId64 "), returning OFFLOAD_FAIL as if offload is "
"disabled\n",
device_id);
return OFFLOAD_FAIL;
}
if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
REPORT("Failed to get device %" PRId64 " ready\n", device_id);
HandleTargetOutcome(false, loc);
if (checkDeviceAndCtors(device_id, loc) != OFFLOAD_SUCCESS) {
DP("Not offloading to device %" PRId64 "\n", device_id);
return OFFLOAD_FAIL;
}
@ -568,7 +393,7 @@ EXTERN int __tgt_target_teams_mapper(ident_t *loc, int64_t device_id,
true /*team*/, AsyncInfo);
if (rc == OFFLOAD_SUCCESS)
rc = AsyncInfo.synchronize();
HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
handleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
return rc;
}
@ -615,29 +440,8 @@ EXTERN void __tgt_push_mapper_component(void *rt_mapper_handle, void *base,
EXTERN void __kmpc_push_target_tripcount(ident_t *loc, int64_t device_id,
uint64_t loop_tripcount) {
TIMESCOPE_WITH_IDENT(loc);
if (IsOffloadDisabled())
return;
if (device_id == OFFLOAD_DEVICE_DEFAULT) {
device_id = omp_get_default_device();
}
// Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669.
if (omp_get_num_devices() == 0) {
DP("omp_get_num_devices() == 0 but offload is manadatory\n");
HandleTargetOutcome(false, loc);
return;
}
if (device_id == omp_get_initial_device()) {
DP("Device is host (%" PRId64 "), returning as if offload is disabled\n",
device_id);
return;
}
if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
DP("Failed to get device %" PRId64 " ready\n", device_id);
HandleTargetOutcome(false, loc);
if (checkDeviceAndCtors(device_id, loc) != OFFLOAD_SUCCESS) {
DP("Not offloading to device %" PRId64 "\n", device_id);
return;
}

View File

@ -205,24 +205,119 @@ static int InitLibrary(DeviceTy &Device) {
return OFFLOAD_SUCCESS;
}
// Check whether a device has been initialized, global ctors have been
// executed and global data has been mapped; do so if not already done.
int CheckDeviceAndCtors(int64_t device_id) {
void handleTargetOutcome(bool Success, ident_t *Loc) {
switch (PM->TargetOffloadPolicy) {
case tgt_disabled:
if (Success) {
FATAL_MESSAGE0(1, "expected no offloading while offloading is disabled");
}
break;
case tgt_default:
FATAL_MESSAGE0(1, "default offloading policy must be switched to "
"mandatory or disabled");
break;
case tgt_mandatory:
if (!Success) {
if (getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE)
for (auto &Device : PM->Devices)
dumpTargetPointerMappings(Loc, Device);
else
FAILURE_MESSAGE("Run with LIBOMPTARGET_DEBUG=%d to dump host-target "
"pointer mappings.\n",
OMP_INFOTYPE_DUMP_TABLE);
SourceInfo info(Loc);
if (info.isAvailible())
fprintf(stderr, "%s:%d:%d: ", info.getFilename(), info.getLine(),
info.getColumn());
else
FAILURE_MESSAGE("Source location information not present. Compile with "
"-g or -gline-tables-only.\n");
FATAL_MESSAGE0(
1, "failure of target construct while offloading is mandatory");
} else {
if (getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE)
for (auto &Device : PM->Devices)
dumpTargetPointerMappings(Loc, Device);
}
break;
}
}
static void handleDefaultTargetOffload() {
PM->TargetOffloadMtx.lock();
if (PM->TargetOffloadPolicy == tgt_default) {
if (omp_get_num_devices() > 0) {
DP("Default TARGET OFFLOAD policy is now mandatory "
"(devices were found)\n");
PM->TargetOffloadPolicy = tgt_mandatory;
} else {
DP("Default TARGET OFFLOAD policy is now disabled "
"(no devices were found)\n");
PM->TargetOffloadPolicy = tgt_disabled;
}
}
PM->TargetOffloadMtx.unlock();
}
static bool isOffloadDisabled() {
if (PM->TargetOffloadPolicy == tgt_default)
handleDefaultTargetOffload();
return PM->TargetOffloadPolicy == tgt_disabled;
}
// If offload is enabled, ensure that device DeviceID has been initialized,
// global ctors have been executed, and global data has been mapped.
//
// There are three possible results:
// - Return OFFLOAD_SUCCESS if the device is ready for offload.
// - Return OFFLOAD_FAIL without reporting a runtime error if offload is
// disabled, perhaps because the initial device was specified.
// - Report a runtime error and return OFFLOAD_FAIL.
//
// If DeviceID == OFFLOAD_DEVICE_DEFAULT, set DeviceID to the default device.
// This step might be skipped if offload is disabled.
int checkDeviceAndCtors(int64_t &DeviceID, ident_t *Loc) {
if (isOffloadDisabled()) {
DP("Offload is disabled\n");
return OFFLOAD_FAIL;
}
if (DeviceID == OFFLOAD_DEVICE_DEFAULT) {
DeviceID = omp_get_default_device();
DP("Use default device id %" PRId64 "\n", DeviceID);
}
// Proposed behavior for OpenMP 5.2 in OpenMP spec github issue 2669.
if (omp_get_num_devices() == 0) {
DP("omp_get_num_devices() == 0 but offload is manadatory\n");
handleTargetOutcome(false, Loc);
return OFFLOAD_FAIL;
}
if (DeviceID == omp_get_initial_device()) {
DP("Device is host (%" PRId64 "), returning as if offload is disabled\n",
DeviceID);
return OFFLOAD_FAIL;
}
// Is device ready?
if (!device_is_ready(device_id)) {
REPORT("Device %" PRId64 " is not ready.\n", device_id);
if (!device_is_ready(DeviceID)) {
REPORT("Device %" PRId64 " is not ready.\n", DeviceID);
handleTargetOutcome(false, Loc);
return OFFLOAD_FAIL;
}
// Get device info.
DeviceTy &Device = PM->Devices[device_id];
DeviceTy &Device = PM->Devices[DeviceID];
// Check whether global data has been mapped for this device
Device.PendingGlobalsMtx.lock();
bool hasPendingGlobals = Device.HasPendingGlobals;
Device.PendingGlobalsMtx.unlock();
if (hasPendingGlobals && InitLibrary(Device) != OFFLOAD_SUCCESS) {
REPORT("Failed to init globals on device %" PRId64 "\n", device_id);
REPORT("Failed to init globals on device %" PRId64 "\n", DeviceID);
handleTargetOutcome(false, Loc);
return OFFLOAD_FAIL;
}

View File

@ -44,7 +44,8 @@ extern int target(ident_t *loc, DeviceTy &Device, void *HostPtr, int32_t ArgNum,
void **ArgMappers, int32_t TeamNum, int32_t ThreadLimit,
int IsTeamConstruct, AsyncInfoTy &AsyncInfo);
extern int CheckDeviceAndCtors(int64_t device_id);
extern void handleTargetOutcome(bool Success, ident_t *Loc);
extern int checkDeviceAndCtors(int64_t &DeviceID, ident_t *Loc);
// This structure stores information of a mapped memory region.
struct MapComponentInfoTy {