Skip to content

Commit fe6f137

Browse files
authored
[OpenMP][NFC] Move mapping related code into OpenMP/Mapping.cpp (#75239)
DeviceTy provides an abstraction for "middle-level" operations that can be done with a offload device. Mapping was tied into it but is not strictly necessary. Other languages do not track mapping, and even OpenMP can be used completely without mapping. This simply moves the relevant code into the OpenMP/Mapping.cpp as part of a new class MappingInfoTy. Each device still has one, but it does not clutter the device.cpp anymore.
1 parent 61ee923 commit fe6f137

File tree

7 files changed

+642
-610
lines changed

7 files changed

+642
-610
lines changed

openmp/libomptarget/include/ExclusiveAccess.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#ifndef OMPTARGET_EXCLUSIVE_ACCESS
1212
#define OMPTARGET_EXCLUSIVE_ACCESS
1313

14+
#include <cassert>
1415
#include <cstddef>
1516
#include <cstdint>
1617
#include <mutex>

openmp/libomptarget/include/OpenMP/Mapping.h

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef OMPTARGET_OPENMP_MAPPING_H
1414
#define OMPTARGET_OPENMP_MAPPING_H
1515

16+
#include "ExclusiveAccess.h"
1617
#include "Shared/EnvironmentVar.h"
1718
#include "omptarget.h"
1819

@@ -443,4 +444,94 @@ int targetDataUpdate(ident_t *Loc, DeviceTy &Device, int32_t ArgNum,
443444
void **ArgMappers, AsyncInfoTy &AsyncInfo,
444445
bool FromMapper = false);
445446

447+
struct MappingInfoTy {
448+
MappingInfoTy(DeviceTy &Device) : Device(Device) {}
449+
450+
/// Host data to device map type with a wrapper key indirection that allows
451+
/// concurrent modification of the entries without invalidating the underlying
452+
/// entries.
453+
using HostDataToTargetListTy =
454+
std::set<HostDataToTargetMapKeyTy, std::less<>>;
455+
456+
/// The HDTTMap is a protected object that can only be accessed by one thread
457+
/// at a time.
458+
ProtectedObj<HostDataToTargetListTy> HostDataToTargetMap;
459+
460+
/// The type used to access the HDTT map.
461+
using HDTTMapAccessorTy = decltype(HostDataToTargetMap)::AccessorTy;
462+
463+
/// Lookup the mapping of \p HstPtrBegin in \p HDTTMap. The accessor ensures
464+
/// exclusive access to the HDTT map.
465+
LookupResult lookupMapping(HDTTMapAccessorTy &HDTTMap, void *HstPtrBegin,
466+
int64_t Size,
467+
HostDataToTargetTy *OwnedTPR = nullptr);
468+
469+
/// Get the target pointer based on host pointer begin and base. If the
470+
/// mapping already exists, the target pointer will be returned directly. In
471+
/// addition, if required, the memory region pointed by \p HstPtrBegin of size
472+
/// \p Size will also be transferred to the device. If the mapping doesn't
473+
/// exist, and if unified shared memory is not enabled, a new mapping will be
474+
/// created and the data will also be transferred accordingly. nullptr will be
475+
/// returned because of any of following reasons:
476+
/// - Data allocation failed;
477+
/// - The user tried to do an illegal mapping;
478+
/// - Data transfer issue fails.
479+
TargetPointerResultTy getTargetPointer(
480+
HDTTMapAccessorTy &HDTTMap, void *HstPtrBegin, void *HstPtrBase,
481+
int64_t TgtPadding, int64_t Size, map_var_info_t HstPtrName,
482+
bool HasFlagTo, bool HasFlagAlways, bool IsImplicit, bool UpdateRefCount,
483+
bool HasCloseModifier, bool HasPresentModifier, bool HasHoldModifier,
484+
AsyncInfoTy &AsyncInfo, HostDataToTargetTy *OwnedTPR = nullptr,
485+
bool ReleaseHDTTMap = true);
486+
487+
/// Return the target pointer for \p HstPtrBegin in \p HDTTMap. The accessor
488+
/// ensures exclusive access to the HDTT map.
489+
void *getTgtPtrBegin(HDTTMapAccessorTy &HDTTMap, void *HstPtrBegin,
490+
int64_t Size);
491+
492+
/// Return the target pointer begin (where the data will be moved).
493+
/// Used by targetDataBegin, targetDataEnd, targetDataUpdate and target.
494+
/// - \p UpdateRefCount and \p UseHoldRefCount controls which and if the entry
495+
/// reference counters will be decremented.
496+
/// - \p MustContain enforces that the query must not extend beyond an already
497+
/// mapped entry to be valid.
498+
/// - \p ForceDelete deletes the entry regardless of its reference counting
499+
/// (unless it is infinite).
500+
/// - \p FromDataEnd tracks the number of threads referencing the entry at
501+
/// targetDataEnd for delayed deletion purpose.
502+
[[nodiscard]] TargetPointerResultTy
503+
getTgtPtrBegin(void *HstPtrBegin, int64_t Size, bool UpdateRefCount,
504+
bool UseHoldRefCount, bool MustContain = false,
505+
bool ForceDelete = false, bool FromDataEnd = false);
506+
507+
/// Remove the \p Entry from the data map. Expect the entry's total reference
508+
/// count to be zero and the caller thread to be the last one using it. \p
509+
/// HDTTMap ensure the caller holds exclusive access and can modify the map.
510+
/// Return \c OFFLOAD_SUCCESS if the map entry existed, and return \c
511+
/// OFFLOAD_FAIL if not. It is the caller's responsibility to skip calling
512+
/// this function if the map entry is not expected to exist because \p
513+
/// HstPtrBegin uses shared memory.
514+
[[nodiscard]] int eraseMapEntry(HDTTMapAccessorTy &HDTTMap,
515+
HostDataToTargetTy *Entry, int64_t Size);
516+
517+
/// Deallocate the \p Entry from the device memory and delete it. Return \c
518+
/// OFFLOAD_SUCCESS if the deallocation operations executed successfully, and
519+
/// return \c OFFLOAD_FAIL otherwise.
520+
[[nodiscard]] int deallocTgtPtrAndEntry(HostDataToTargetTy *Entry,
521+
int64_t Size);
522+
523+
int associatePtr(void *HstPtrBegin, void *TgtPtrBegin, int64_t Size);
524+
int disassociatePtr(void *HstPtrBegin);
525+
526+
/// Print information about the transfer from \p HstPtr to \p TgtPtr (or vice
527+
/// versa if \p H2D is false). If there is an existing mapping, or if \p Entry
528+
/// is set, the associated metadata will be printed as well.
529+
void printCopyInfo(void *TgtPtr, void *HstPtr, int64_t Size, bool H2D,
530+
HostDataToTargetTy *Entry,
531+
MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr);
532+
533+
private:
534+
DeviceTy &Device;
535+
};
536+
446537
#endif // OMPTARGET_OPENMP_MAPPING_H

openmp/libomptarget/include/device.h

Lines changed: 15 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,6 @@ struct DeviceTy {
5353

5454
bool HasMappedGlobalData = false;
5555

56-
/// Host data to device map type with a wrapper key indirection that allows
57-
/// concurrent modification of the entries without invalidating the underlying
58-
/// entries.
59-
using HostDataToTargetListTy =
60-
std::set<HostDataToTargetMapKeyTy, std::less<>>;
61-
62-
/// The HDTTMap is a protected object that can only be accessed by one thread
63-
/// at a time.
64-
ProtectedObj<HostDataToTargetListTy> HostDataToTargetMap;
65-
66-
/// The type used to access the HDTT map.
67-
using HDTTMapAccessorTy = decltype(HostDataToTargetMap)::AccessorTy;
68-
6956
PendingCtorsDtorsPerLibrary PendingCtorsDtors;
7057

7158
std::mutex PendingGlobalsMtx;
@@ -80,71 +67,8 @@ struct DeviceTy {
8067
/// Try to initialize the device and return any failure.
8168
llvm::Error init();
8269

83-
// Return true if data can be copied to DstDevice directly
84-
bool isDataExchangable(const DeviceTy &DstDevice);
85-
86-
/// Lookup the mapping of \p HstPtrBegin in \p HDTTMap. The accessor ensures
87-
/// exclusive access to the HDTT map.
88-
LookupResult lookupMapping(HDTTMapAccessorTy &HDTTMap, void *HstPtrBegin,
89-
int64_t Size,
90-
HostDataToTargetTy *OwnedTPR = nullptr);
91-
92-
/// Get the target pointer based on host pointer begin and base. If the
93-
/// mapping already exists, the target pointer will be returned directly. In
94-
/// addition, if required, the memory region pointed by \p HstPtrBegin of size
95-
/// \p Size will also be transferred to the device. If the mapping doesn't
96-
/// exist, and if unified shared memory is not enabled, a new mapping will be
97-
/// created and the data will also be transferred accordingly. nullptr will be
98-
/// returned because of any of following reasons:
99-
/// - Data allocation failed;
100-
/// - The user tried to do an illegal mapping;
101-
/// - Data transfer issue fails.
102-
TargetPointerResultTy getTargetPointer(
103-
HDTTMapAccessorTy &HDTTMap, void *HstPtrBegin, void *HstPtrBase,
104-
int64_t TgtPadding, int64_t Size, map_var_info_t HstPtrName,
105-
bool HasFlagTo, bool HasFlagAlways, bool IsImplicit, bool UpdateRefCount,
106-
bool HasCloseModifier, bool HasPresentModifier, bool HasHoldModifier,
107-
AsyncInfoTy &AsyncInfo, HostDataToTargetTy *OwnedTPR = nullptr,
108-
bool ReleaseHDTTMap = true);
109-
110-
/// Return the target pointer for \p HstPtrBegin in \p HDTTMap. The accessor
111-
/// ensures exclusive access to the HDTT map.
112-
void *getTgtPtrBegin(HDTTMapAccessorTy &HDTTMap, void *HstPtrBegin,
113-
int64_t Size);
114-
115-
/// Return the target pointer begin (where the data will be moved).
116-
/// Used by targetDataBegin, targetDataEnd, targetDataUpdate and target.
117-
/// - \p UpdateRefCount and \p UseHoldRefCount controls which and if the entry
118-
/// reference counters will be decremented.
119-
/// - \p MustContain enforces that the query must not extend beyond an already
120-
/// mapped entry to be valid.
121-
/// - \p ForceDelete deletes the entry regardless of its reference counting
122-
/// (unless it is infinite).
123-
/// - \p FromDataEnd tracks the number of threads referencing the entry at
124-
/// targetDataEnd for delayed deletion purpose.
125-
[[nodiscard]] TargetPointerResultTy
126-
getTgtPtrBegin(void *HstPtrBegin, int64_t Size, bool UpdateRefCount,
127-
bool UseHoldRefCount, bool MustContain = false,
128-
bool ForceDelete = false, bool FromDataEnd = false);
129-
130-
/// Remove the \p Entry from the data map. Expect the entry's total reference
131-
/// count to be zero and the caller thread to be the last one using it. \p
132-
/// HDTTMap ensure the caller holds exclusive access and can modify the map.
133-
/// Return \c OFFLOAD_SUCCESS if the map entry existed, and return \c
134-
/// OFFLOAD_FAIL if not. It is the caller's responsibility to skip calling
135-
/// this function if the map entry is not expected to exist because \p
136-
/// HstPtrBegin uses shared memory.
137-
[[nodiscard]] int eraseMapEntry(HDTTMapAccessorTy &HDTTMap,
138-
HostDataToTargetTy *Entry, int64_t Size);
139-
140-
/// Deallocate the \p Entry from the device memory and delete it. Return \c
141-
/// OFFLOAD_SUCCESS if the deallocation operations executed successfully, and
142-
/// return \c OFFLOAD_FAIL otherwise.
143-
[[nodiscard]] int deallocTgtPtrAndEntry(HostDataToTargetTy *Entry,
144-
int64_t Size);
145-
146-
int associatePtr(void *HstPtrBegin, void *TgtPtrBegin, int64_t Size);
147-
int disassociatePtr(void *HstPtrBegin);
70+
/// Provide access to the mapping handler.
71+
MappingInfoTy &getMappingInfo() { return MappingInfo; }
14872

14973
__tgt_target_table *loadBinary(__tgt_device_image *Img);
15074

@@ -159,6 +83,7 @@ struct DeviceTy {
15983
/// be used (host, shared, device).
16084
void *allocData(int64_t Size, void *HstPtr = nullptr,
16185
int32_t Kind = TARGET_ALLOC_DEFAULT);
86+
16287
/// Deallocates memory which \p TgtPtrBegin points at and returns
16388
/// OFFLOAD_SUCCESS/OFFLOAD_FAIL when succeeds/fails. p Kind dictates what
16489
/// allocator should be used (host, shared, device).
@@ -170,12 +95,16 @@ struct DeviceTy {
17095
int32_t submitData(void *TgtPtrBegin, void *HstPtrBegin, int64_t Size,
17196
AsyncInfoTy &AsyncInfo,
17297
HostDataToTargetTy *Entry = nullptr,
173-
DeviceTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr);
98+
MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr);
99+
174100
// Copy data from device back to host
175101
int32_t retrieveData(void *HstPtrBegin, void *TgtPtrBegin, int64_t Size,
176102
AsyncInfoTy &AsyncInfo,
177103
HostDataToTargetTy *Entry = nullptr,
178-
DeviceTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr);
104+
MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr);
105+
106+
// Return true if data can be copied to DstDevice directly
107+
bool isDataExchangable(const DeviceTy &DstDevice);
179108

180109
// Copy data from current device to destination device directly
181110
int32_t dataExchange(void *SrcPtr, DeviceTy &DstDev, void *DstPtr,
@@ -240,7 +169,12 @@ struct DeviceTy {
240169
void deinit();
241170

242171
/// All offload entries available on this device.
243-
llvm::DenseMap<llvm::StringRef, OffloadEntryTy *> DeviceOffloadEntries;
172+
using DeviceOffloadEntriesMapTy =
173+
llvm::DenseMap<llvm::StringRef, OffloadEntryTy *>;
174+
ProtectedObj<DeviceOffloadEntriesMapTy> DeviceOffloadEntries;
175+
176+
/// Handler to collect and organize host-2-device mapping information.
177+
MappingInfoTy MappingInfo;
244178
};
245179

246180
#endif

openmp/libomptarget/src/OpenMP/API.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ EXTERN int omp_target_is_present(const void *Ptr, int DeviceNum) {
150150
// only check 1 byte. Cannot set size 0 which checks whether the pointer (zero
151151
// lengh array) is mapped instead of the referred storage.
152152
TargetPointerResultTy TPR =
153-
DeviceOrErr->getTgtPtrBegin(const_cast<void *>(Ptr), 1,
154-
/*UpdateRefCount=*/false,
155-
/*UseHoldRefCount=*/false);
153+
DeviceOrErr->getMappingInfo().getTgtPtrBegin(const_cast<void *>(Ptr), 1,
154+
/*UpdateRefCount=*/false,
155+
/*UseHoldRefCount=*/false);
156156
int Rc = TPR.isPresent();
157157
DP("Call to omp_target_is_present returns %d\n", Rc);
158158
return Rc;
@@ -544,8 +544,8 @@ EXTERN int omp_target_associate_ptr(const void *HostPtr, const void *DevicePtr,
544544
FATAL_MESSAGE(DeviceNum, "%s", toString(DeviceOrErr.takeError()).c_str());
545545

546546
void *DeviceAddr = (void *)((uint64_t)DevicePtr + (uint64_t)DeviceOffset);
547-
int Rc = DeviceOrErr->associatePtr(const_cast<void *>(HostPtr),
548-
const_cast<void *>(DeviceAddr), Size);
547+
int Rc = DeviceOrErr->getMappingInfo().associatePtr(
548+
const_cast<void *>(HostPtr), const_cast<void *>(DeviceAddr), Size);
549549
DP("omp_target_associate_ptr returns %d\n", Rc);
550550
return Rc;
551551
}
@@ -571,7 +571,8 @@ EXTERN int omp_target_disassociate_ptr(const void *HostPtr, int DeviceNum) {
571571
if (!DeviceOrErr)
572572
FATAL_MESSAGE(DeviceNum, "%s", toString(DeviceOrErr.takeError()).c_str());
573573

574-
int Rc = DeviceOrErr->disassociatePtr(const_cast<void *>(HostPtr));
574+
int Rc = DeviceOrErr->getMappingInfo().disassociatePtr(
575+
const_cast<void *>(HostPtr));
575576
DP("omp_target_disassociate_ptr returns %d\n", Rc);
576577
return Rc;
577578
}
@@ -603,9 +604,9 @@ EXTERN void *omp_get_mapped_ptr(const void *Ptr, int DeviceNum) {
603604
FATAL_MESSAGE(DeviceNum, "%s", toString(DeviceOrErr.takeError()).c_str());
604605

605606
TargetPointerResultTy TPR =
606-
DeviceOrErr->getTgtPtrBegin(const_cast<void *>(Ptr), 1,
607-
/*UpdateRefCount=*/false,
608-
/*UseHoldRefCount=*/false);
607+
DeviceOrErr->getMappingInfo().getTgtPtrBegin(const_cast<void *>(Ptr), 1,
608+
/*UpdateRefCount=*/false,
609+
/*UseHoldRefCount=*/false);
609610
if (!TPR.isPresent()) {
610611
DP("Ptr " DPxMOD "is not present on device %d, returning nullptr.\n",
611612
DPxPTR(Ptr), DeviceNum);

0 commit comments

Comments
 (0)