Skip to content

Commit

Permalink
[Libomptarget][NFC] Move global Libomptarget state to a struct
Browse files Browse the repository at this point in the history
Presently, there a number of global variables in libomptarget (devices,
RTLs, tables, mutexes, etc.) that are not placed within a struct. This
patch places them into a struct ``PluginManager``. All of the functions
that act on this data remain free.

Differential Revision: https://reviews.llvm.org/D90519
  • Loading branch information
atmnpatel committed Nov 3, 2020
1 parent 0d4e172 commit a95b25b
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 168 deletions.
38 changes: 19 additions & 19 deletions openmp/libomptarget/src/api.cpp
Expand Up @@ -19,13 +19,13 @@
#include <cstdlib>

EXTERN int omp_get_num_devices(void) {
RTLsMtx->lock();
size_t Devices_size = Devices.size();
RTLsMtx->unlock();
PM->RTLsMtx.lock();
size_t DevicesSize = PM->Devices.size();
PM->RTLsMtx.unlock();

DP("Call to omp_get_num_devices returning %zd\n", Devices_size);
DP("Call to omp_get_num_devices returning %zd\n", DevicesSize);

return Devices_size;
return DevicesSize;
}

EXTERN int omp_get_initial_device(void) {
Expand Down Expand Up @@ -56,7 +56,7 @@ EXTERN void *omp_target_alloc(size_t size, int device_num) {
return NULL;
}

rc = Devices[device_num].allocData(size);
rc = PM->Devices[device_num].allocData(size);
DP("omp_target_alloc returns device ptr " DPxMOD "\n", DPxPTR(rc));
return rc;
}
Expand All @@ -81,7 +81,7 @@ EXTERN void omp_target_free(void *device_ptr, int device_num) {
return;
}

Devices[device_num].deleteData(device_ptr);
PM->Devices[device_num].deleteData(device_ptr);
DP("omp_target_free deallocated device ptr\n");
}

Expand All @@ -99,16 +99,16 @@ EXTERN int omp_target_is_present(void *ptr, int device_num) {
return true;
}

RTLsMtx->lock();
size_t Devices_size = Devices.size();
RTLsMtx->unlock();
if (Devices_size <= (size_t)device_num) {
PM->RTLsMtx.lock();
size_t DevicesSize = PM->Devices.size();
PM->RTLsMtx.unlock();
if (DevicesSize <= (size_t)device_num) {
DP("Call to omp_target_is_present with invalid device ID, returning "
"false\n");
return false;
}

DeviceTy& Device = Devices[device_num];
DeviceTy &Device = PM->Devices[device_num];
bool IsLast; // not used
bool IsHostPtr;
void *TgtPtr = Device.getTgtPtrBegin(ptr, 0, IsLast, false, IsHostPtr);
Expand All @@ -117,7 +117,7 @@ EXTERN int omp_target_is_present(void *ptr, int device_num) {
// getTgtPtrBegin() function which means that there is no device
// corresponding point for ptr. This function should return false
// in that situation.
if (RTLs->RequiresFlags & OMP_REQ_UNIFIED_SHARED_MEMORY)
if (PM->RTLs.RequiresFlags & OMP_REQ_UNIFIED_SHARED_MEMORY)
rc = !IsHostPtr;
DP("Call to omp_target_is_present returns %d\n", rc);
return rc;
Expand Down Expand Up @@ -157,16 +157,16 @@ EXTERN int omp_target_memcpy(void *dst, void *src, size_t length,
rc = OFFLOAD_FAIL;
} else if (src_device == omp_get_initial_device()) {
DP("copy from host to device\n");
DeviceTy& DstDev = Devices[dst_device];
DeviceTy &DstDev = PM->Devices[dst_device];
rc = DstDev.submitData(dstAddr, srcAddr, length, nullptr);
} else if (dst_device == omp_get_initial_device()) {
DP("copy from device to host\n");
DeviceTy& SrcDev = Devices[src_device];
DeviceTy &SrcDev = PM->Devices[src_device];
rc = SrcDev.retrieveData(dstAddr, srcAddr, length, nullptr);
} else {
DP("copy from device to device\n");
DeviceTy &SrcDev = Devices[src_device];
DeviceTy &DstDev = Devices[dst_device];
DeviceTy &SrcDev = PM->Devices[src_device];
DeviceTy &DstDev = PM->Devices[dst_device];
// First try to use D2D memcpy which is more efficient. If fails, fall back
// to unefficient way.
if (SrcDev.isDataExchangable(DstDev)) {
Expand Down Expand Up @@ -263,7 +263,7 @@ EXTERN int omp_target_associate_ptr(void *host_ptr, void *device_ptr,
return OFFLOAD_FAIL;
}

DeviceTy& Device = Devices[device_num];
DeviceTy &Device = PM->Devices[device_num];
void *device_addr = (void *)((uint64_t)device_ptr + (uint64_t)device_offset);
int rc = Device.associatePtr(host_ptr, device_addr, size);
DP("omp_target_associate_ptr returns %d\n", rc);
Expand All @@ -290,7 +290,7 @@ EXTERN int omp_target_disassociate_ptr(void *host_ptr, int device_num) {
return OFFLOAD_FAIL;
}

DeviceTy& Device = Devices[device_num];
DeviceTy &Device = PM->Devices[device_num];
int rc = Device.disassociatePtr(host_ptr);
DP("omp_target_disassociate_ptr returns %d\n", rc);
return rc;
Expand Down
22 changes: 10 additions & 12 deletions openmp/libomptarget/src/device.cpp
Expand Up @@ -20,9 +20,6 @@
#include <cstdio>
#include <string>

/// Map between Device ID (i.e. openmp device id) and its DeviceTy.
DevicesTy Devices;

DeviceTy::DeviceTy(const DeviceTy &D)
: DeviceID(D.DeviceID), RTL(D.RTL), RTLDeviceID(D.RTLDeviceID),
IsInit(D.IsInit), InitFlag(), HasPendingGlobals(D.HasPendingGlobals),
Expand Down Expand Up @@ -239,7 +236,7 @@ void *DeviceTy::getOrAllocTgtPtr(void *HstPtrBegin, void *HstPtrBase,
MESSAGE("device mapping required by 'present' map type modifier does not "
"exist for host address " DPxMOD " (%" PRId64 " bytes)",
DPxPTR(HstPtrBegin), Size);
} else if (RTLs->RequiresFlags & OMP_REQ_UNIFIED_SHARED_MEMORY &&
} else if (PM->RTLs.RequiresFlags & OMP_REQ_UNIFIED_SHARED_MEMORY &&
!HasCloseModifier) {
// If unified shared memory is active, implicitly mapped variables that are
// not privatized use host address. Any explicitly mapped variables also use
Expand Down Expand Up @@ -305,7 +302,7 @@ void *DeviceTy::getTgtPtrBegin(void *HstPtrBegin, int64_t Size, bool &IsLast,
Size, (UpdateRefCount ? " updated" : ""),
HT.isRefCountInf() ? "INF" : std::to_string(HT.getRefCount()).c_str());
rc = (void *)tp;
} else if (RTLs->RequiresFlags & OMP_REQ_UNIFIED_SHARED_MEMORY) {
} else if (PM->RTLs.RequiresFlags & OMP_REQ_UNIFIED_SHARED_MEMORY) {
// If the value isn't found in the mapping and unified shared memory
// is on then it means we have stumbled upon a value which we need to
// use directly from the host.
Expand Down Expand Up @@ -335,7 +332,8 @@ void *DeviceTy::getTgtPtrBegin(void *HstPtrBegin, int64_t Size) {

int DeviceTy::deallocTgtPtr(void *HstPtrBegin, int64_t Size, bool ForceDelete,
bool HasCloseModifier) {
if (RTLs->RequiresFlags & OMP_REQ_UNIFIED_SHARED_MEMORY && !HasCloseModifier)
if (PM->RTLs.RequiresFlags & OMP_REQ_UNIFIED_SHARED_MEMORY &&
!HasCloseModifier)
return OFFLOAD_SUCCESS;
// Check if the pointer is contained in any sub-nodes.
int rc;
Expand Down Expand Up @@ -370,7 +368,7 @@ int DeviceTy::deallocTgtPtr(void *HstPtrBegin, int64_t Size, bool ForceDelete,
void DeviceTy::init() {
// Make call to init_requires if it exists for this plugin.
if (RTL->init_requires)
RTL->init_requires(RTLs->RequiresFlags);
RTL->init_requires(PM->RTLs.RequiresFlags);
int32_t Ret = RTL->init_device(RTLDeviceID);
if (Ret != OFFLOAD_SUCCESS)
return;
Expand Down Expand Up @@ -512,16 +510,16 @@ bool device_is_ready(int device_num) {
DP("Checking whether device %d is ready.\n", device_num);
// Devices.size() can only change while registering a new
// library, so try to acquire the lock of RTLs' mutex.
RTLsMtx->lock();
size_t Devices_size = Devices.size();
RTLsMtx->unlock();
if (Devices_size <= (size_t)device_num) {
PM->RTLsMtx.lock();
size_t DevicesSize = PM->Devices.size();
PM->RTLsMtx.unlock();
if (DevicesSize <= (size_t)device_num) {
DP("Device ID %d does not have a matching RTL\n", device_num);
return false;
}

// Get device info
DeviceTy &Device = Devices[device_num];
DeviceTy &Device = PM->Devices[device_num];

DP("Is the device %d (local ID %d) initialized? %d\n", device_num,
Device.RTLDeviceID, Device.IsInit);
Expand Down
35 changes: 34 additions & 1 deletion openmp/libomptarget/src/device.h
Expand Up @@ -22,13 +22,23 @@
#include <set>
#include <vector>

#include "rtl.h"

// Forward declarations.
struct RTLInfoTy;
struct __tgt_bin_desc;
struct __tgt_target_table;
struct __tgt_async_info;
class MemoryManagerTy;

// enum for OMP_TARGET_OFFLOAD; keep in sync with kmp.h definition
enum kmp_target_offload_kind {
tgt_disabled = 0,
tgt_default = 1,
tgt_mandatory = 2
};
typedef enum kmp_target_offload_kind kmp_target_offload_kind_t;

/// Map between host data and target data.
struct HostDataToTargetTy {
uintptr_t HstPtrBase; // host info.
Expand Down Expand Up @@ -221,8 +231,31 @@ struct DeviceTy {

/// Map between Device ID (i.e. openmp device id) and its DeviceTy.
typedef std::vector<DeviceTy> DevicesTy;
extern DevicesTy Devices;

extern bool device_is_ready(int device_num);

/// Struct for the data required to handle plugins
struct PluginManager {
/// RTLs identified on the host
RTLsTy RTLs;

/// Devices associated with RTLs
DevicesTy Devices;
std::mutex RTLsMtx; ///< For RTLs and Devices

/// Translation table retreived from the binary
HostEntriesBeginToTransTableTy HostEntriesBeginToTransTable;
std::mutex TrlTblMtx; ///< For Translation Table

/// Map from ptrs on the host to an entry in the Translation Table
HostPtrToTableMapTy HostPtrToTableMap;
std::mutex TblMapMtx; ///< For HostPtrToTableMap

// Store target policy (disabled, mandatory, default)
kmp_target_offload_kind_t TargetOffloadPolicy = tgt_default;
std::mutex TargetOffloadMtx; ///< For TargetOffloadPolicy
};

extern PluginManager *PM;

#endif
92 changes: 45 additions & 47 deletions openmp/libomptarget/src/interface.cpp
Expand Up @@ -20,75 +20,73 @@
#include <cstdlib>
#include <mutex>

// Store target policy (disabled, mandatory, default)
kmp_target_offload_kind_t TargetOffloadPolicy = tgt_default;
std::mutex TargetOffloadMtx;

////////////////////////////////////////////////////////////////////////////////
/// manage the success or failure of a target construct
static void HandleDefaultTargetOffload() {
TargetOffloadMtx.lock();
if (TargetOffloadPolicy == tgt_default) {
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");
TargetOffloadPolicy = tgt_mandatory;
PM->TargetOffloadPolicy = tgt_mandatory;
} else {
DP("Default TARGET OFFLOAD policy is now disabled "
"(no devices were found)\n");
TargetOffloadPolicy = tgt_disabled;
PM->TargetOffloadPolicy = tgt_disabled;
}
}
TargetOffloadMtx.unlock();
PM->TargetOffloadMtx.unlock();
}

static int IsOffloadDisabled() {
if (TargetOffloadPolicy == tgt_default) HandleDefaultTargetOffload();
return TargetOffloadPolicy == tgt_disabled;
if (PM->TargetOffloadPolicy == tgt_default)
HandleDefaultTargetOffload();
return PM->TargetOffloadPolicy == tgt_disabled;
}

static void HandleTargetOutcome(bool success) {
switch (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() > 1)
for (const auto &Device : Devices)
dumpTargetPointerMappings(Device);
else
FAILURE_MESSAGE("run with env LIBOMPTARGET_INFO>1 to dump host-target"
"pointer maps\n");

FATAL_MESSAGE0(1, "failure of target construct while offloading is mandatory");
}
break;
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() > 1)
for (const auto &Device : PM->Devices)
dumpTargetPointerMappings(Device);
else
FAILURE_MESSAGE("run with env LIBOMPTARGET_INFO>1 to dump host-target"
"pointer maps\n");

FATAL_MESSAGE0(
1, "failure of target construct while offloading is mandatory");
}
break;
}
}

////////////////////////////////////////////////////////////////////////////////
/// adds requires flags
EXTERN void __tgt_register_requires(int64_t flags) {
RTLs->RegisterRequires(flags);
PM->RTLs.RegisterRequires(flags);
}

////////////////////////////////////////////////////////////////////////////////
/// adds a target shared library to the target execution image
EXTERN void __tgt_register_lib(__tgt_bin_desc *desc) {
RTLs->RegisterLib(desc);
PM->RTLs.RegisterLib(desc);
}

////////////////////////////////////////////////////////////////////////////////
/// unloads a target shared library
EXTERN void __tgt_unregister_lib(__tgt_bin_desc *desc) {
RTLs->UnregisterLib(desc);
PM->RTLs.UnregisterLib(desc);
}

/// creates host-to-target data mapping, stores it in the
Expand Down Expand Up @@ -131,7 +129,7 @@ EXTERN void __tgt_target_data_begin_mapper(int64_t device_id, int32_t arg_num,
return;
}

DeviceTy &Device = Devices[device_id];
DeviceTy &Device = PM->Devices[device_id];

#ifdef OMPTARGET_DEBUG
for (int i = 0; i < arg_num; ++i) {
Expand Down Expand Up @@ -188,16 +186,16 @@ EXTERN void __tgt_target_data_end_mapper(int64_t device_id, int32_t arg_num,
device_id = omp_get_default_device();
}

RTLsMtx->lock();
size_t Devices_size = Devices.size();
RTLsMtx->unlock();
if (Devices_size <= (size_t)device_id) {
PM->RTLsMtx.lock();
size_t DevicesSize = PM->Devices.size();
PM->RTLsMtx.unlock();
if (DevicesSize <= (size_t)device_id) {
DP("Device ID %" PRId64 " does not have a matching RTL.\n", device_id);
HandleTargetOutcome(false);
return;
}

DeviceTy &Device = Devices[device_id];
DeviceTy &Device = PM->Devices[device_id];
if (!Device.IsInit) {
DP("Uninit device: ignore");
HandleTargetOutcome(false);
Expand Down Expand Up @@ -262,7 +260,7 @@ EXTERN void __tgt_target_data_update_mapper(int64_t device_id, int32_t arg_num,
return;
}

DeviceTy& Device = Devices[device_id];
DeviceTy &Device = PM->Devices[device_id];
int rc = target_data_update(Device, arg_num, args_base,
args, arg_sizes, arg_types, arg_mappers);
HandleTargetOutcome(rc == OFFLOAD_SUCCESS);
Expand Down Expand Up @@ -439,8 +437,8 @@ EXTERN void __kmpc_push_target_tripcount(int64_t device_id,

DP("__kmpc_push_target_tripcount(%" PRId64 ", %" PRIu64 ")\n", device_id,
loop_tripcount);
TblMapMtx->lock();
Devices[device_id].LoopTripCnt.emplace(__kmpc_global_thread_num(NULL),
loop_tripcount);
TblMapMtx->unlock();
PM->TblMapMtx.lock();
PM->Devices[device_id].LoopTripCnt.emplace(__kmpc_global_thread_num(NULL),
loop_tripcount);
PM->TblMapMtx.unlock();
}

0 comments on commit a95b25b

Please sign in to comment.