Skip to content

Commit 12561c4

Browse files
committed
[Offload]: Skip copying of unused kernel-mapped data
1 parent 6e42d52 commit 12561c4

File tree

4 files changed

+132
-15
lines changed

4 files changed

+132
-15
lines changed

offload/include/OpenMP/Mapping.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,13 @@ struct LookupResult {
386386
LookupResult() : Flags({0, 0, 0}), TPR() {}
387387

388388
TargetPointerResultTy TPR;
389+
390+
bool isEmpty() const {
391+
bool IsEmpty = Flags.IsContained == 0
392+
& Flags.ExtendsBefore == 0
393+
& Flags.ExtendsAfter == 0;
394+
return IsEmpty;
395+
}
389396
};
390397

391398
// This structure stores information of a mapped memory region.

offload/include/Shared/Debug.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ enum OpenMPInfoType : uint32_t {
5858
OMP_INFOTYPE_DATA_TRANSFER = 0x0020,
5959
// Print whenever data does not have a viable device counterpart.
6060
OMP_INFOTYPE_EMPTY_MAPPING = 0x0040,
61+
// Print whenever data does not need to be transferred
62+
OMP_INFOTYPE_REDUNDANT_TRANSFER = 0x0080,
6163
// Enable every flag.
6264
OMP_INFOTYPE_ALL = 0xffffffff,
6365
};

offload/libomptarget/omptarget.cpp

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,30 +1197,66 @@ class PrivateArgumentManagerTy {
11971197
}
11981198
};
11991199

1200-
static std::unique_ptr<int64_t[]> maskIgnorableMappings(int64_t DeviceId, int32_t ArgNum, int64_t *ArgTypes,
1201-
int64_t *ArgSizes, map_var_info_t *ArgNames) {
1200+
/// Try to find redundant mappings associated with a kernel launch,
1201+
/// and provide a masked version of the kernel argument types that
1202+
/// avoid redundant to data transfers between the host and device.
1203+
static std::unique_ptr<int64_t[]> maskRedundantTransfers(DeviceTy &Device, int32_t ArgNum,
1204+
int64_t *ArgTypes, int64_t *ArgSizes,
1205+
map_var_info_t *ArgNames, void **ArgPtrs,
1206+
void **ArgMappers) {
12021207
std::unique_ptr<int64_t[]> ArgTypesOverride = std::make_unique<int64_t[]>(ArgNum);
12031208

1209+
MappingInfoTy &MappingInfo = Device.getMappingInfo();
1210+
MappingInfoTy::HDTTMapAccessorTy HDTTMap = MappingInfo
1211+
.HostDataToTargetMap.getExclusiveAccessor();
1212+
1213+
int64_t UnusedArgs = 0;
1214+
12041215
for (int32_t I = 0; I < ArgNum; ++I) {
1205-
bool IsTargetParam = ArgTypes[I] & OMP_TGT_MAPTYPE_TARGET_PARAM;
1216+
tgt_map_type ArgType = (tgt_map_type) ArgTypes[I];
1217+
1218+
// Check for unused implicit mappings
1219+
bool IsArgUnused = ArgType == OMP_TGT_MAPTYPE_NONE;
1220+
1221+
// Check for unused `map(buf[0:size])` mappings
1222+
IsArgUnused |= ArgType == OMP_TGT_MAPTYPE_FROM
1223+
|| ArgType == OMP_TGT_MAPTYPE_TO
1224+
|| ArgType == (OMP_TGT_MAPTYPE_FROM | OMP_TGT_MAPTYPE_TO);
1225+
1226+
// Check for unused `map(wrapper.buf[0:size])` mappings
1227+
IsArgUnused |= UnusedArgs == ArgNum - 1 && ArgType & OMP_TGT_MAPTYPE_MEMBER_OF
1228+
&& ((ArgType & ~OMP_TGT_MAPTYPE_MEMBER_OF) == OMP_TGT_MAPTYPE_PTR_AND_OBJ
1229+
|| (ArgType & ~OMP_TGT_MAPTYPE_MEMBER_OF) == (OMP_TGT_MAPTYPE_PTR_AND_OBJ | OMP_TGT_MAPTYPE_TO)
1230+
|| (ArgType & ~OMP_TGT_MAPTYPE_MEMBER_OF) == (OMP_TGT_MAPTYPE_PTR_AND_OBJ | OMP_TGT_MAPTYPE_FROM | OMP_TGT_MAPTYPE_TO));
12061231

1207-
bool IsMapTo = ArgTypes[I] & OMP_TGT_MAPTYPE_TO;
1208-
if (IsTargetParam || !IsMapTo) {
1232+
bool IsExistingMapping = !MappingInfo.lookupMapping(HDTTMap, ArgPtrs[I], ArgSizes[I]).isEmpty();
1233+
1234+
bool IsCustomMapped = ArgMappers && ArgMappers[I];
1235+
1236+
if (IsExistingMapping | IsCustomMapped | !IsArgUnused) {
12091237
ArgTypesOverride[I] = ArgTypes[I];
12101238
continue;
12111239
}
12121240

1213-
bool IsMapFrom = ArgTypes[I] & OMP_TGT_MAPTYPE_FROM;
1214-
const char *Type = IsMapFrom ? "tofrom" : "to";
1241+
const std::string Name = ArgNames && ArgNames[I] ?
1242+
getNameFromMapping(ArgNames[I]) : std::string("unknown");
1243+
1244+
bool IsArgFrom = ArgType & OMP_TGT_MAPTYPE_FROM;
1245+
bool IsArgTo = ArgType & OMP_TGT_MAPTYPE_TO;
1246+
1247+
const char *Type = IsArgFrom && IsArgTo ? "tofrom"
1248+
: IsArgFrom ? "from"
1249+
: IsArgTo ? "to"
1250+
: "unknown";
12151251

1216-
// Optimisation: A 'to' or 'tofrom' mapping is not
1217-
// used by the kernel. Change its type such that
1218-
// no new mapping is created, but any existing
1219-
// mapping has its counter decremented.
1220-
INFO(OMP_INFOTYPE_ALL, DeviceId, "%s(%s)[%" PRId64 "] %s\n", Type,
1221-
getNameFromMapping(ArgNames[I]).c_str(), ArgSizes[I], "is not used and will not be copied");
1252+
// Optimisation:
1253+
// A new mapping is not used by the kernel.
1254+
// Change the type such that no data is transferred to and/or from the device.
1255+
INFO(OMP_INFOTYPE_REDUNDANT_TRANSFER, Device.DeviceID, "%s(%s)[%" PRId64 "] %s\n", Type,
1256+
Name.c_str(), ArgSizes[I], "is not used and will not be copied");
12221257

12231258
ArgTypesOverride[I] = ArgTypes[I] & ~(OMP_TGT_MAPTYPE_TO | OMP_TGT_MAPTYPE_FROM);
1259+
UnusedArgs++;
12241260
}
12251261

12261262
return ArgTypesOverride;
@@ -1448,8 +1484,8 @@ int target(ident_t *Loc, DeviceTy &Device, void *HostPtr,
14481484
int Ret = OFFLOAD_SUCCESS;
14491485

14501486
std::unique_ptr<int64_t[]> ArgTypesOverride =
1451-
maskIgnorableMappings(DeviceId, NumClangLaunchArgs, KernelArgs.ArgTypes,
1452-
KernelArgs.ArgSizes, KernelArgs.ArgNames);
1487+
maskRedundantTransfers(Device, NumClangLaunchArgs, KernelArgs.ArgTypes,
1488+
KernelArgs.ArgSizes, KernelArgs.ArgNames, KernelArgs.ArgPtrs, KernelArgs.ArgMappers);
14531489

14541490
if (NumClangLaunchArgs) {
14551491
// Process data, such as data mapping, before launching the kernel
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// clang-format off
2+
// RUN: %libomptarget-compilexx-generic
3+
// RUN: env LIBOMPTARGET_INFO=128 %libomptarget-run-generic 2>&1 \
4+
// RUN: | %fcheck-generic
5+
6+
// REQUIRES: gpu
7+
// clang-format on
8+
9+
int main() {
10+
float DataStack = 0;
11+
12+
// CHECK-NOT: omptarget device 0 info: from(unknown)[4] is not used and will not be copied
13+
#pragma omp target map(from: DataStack)
14+
{
15+
DataStack = 1;
16+
}
17+
18+
// CHECK-NOT: omptarget device 0 info: to(unknown)[4] is not used and will not be copied
19+
#pragma omp target map(always to: DataStack)
20+
;
21+
22+
// CHECK: omptarget device 0 info: tofrom(unknown)[4] is not used and will not be copied
23+
#pragma omp target map(tofrom: DataStack)
24+
;
25+
26+
int Size = 16;
27+
double *Data = new double[Size];
28+
29+
// CHECK-NOT: omptarget device 0 info: tofrom(unknown)[8] is not used and will not be copied
30+
#pragma omp target map(tofrom: Data[0:1])
31+
{
32+
Data[0] = 1;
33+
}
34+
35+
// CHECK-NOT: omptarget device 0 info: tofrom(unknown)[16] is not used and will not be copied
36+
#pragma omp target map(always tofrom: Data[0:2])
37+
;
38+
39+
// CHECK: omptarget device 0 info: from(unknown)[24] is not used and will not be copied
40+
#pragma omp target map(from: Data[0:3])
41+
;
42+
43+
// CHECK: omptarget device 0 info: to(unknown)[24] is not used and will not be copied
44+
#pragma omp target map(to: Data[0:3])
45+
;
46+
47+
// CHECK: omptarget device 0 info: tofrom(unknown)[32] is not used and will not be copied
48+
#pragma omp target map(tofrom: Data[0:4])
49+
;
50+
51+
// CHECK-NOT: omptarget device 0 info: to(unknown)[40] is not used and will not be copied
52+
#pragma omp target map(to: Data[0:5])
53+
{
54+
#pragma omp teams
55+
Data[0] = 1;
56+
}
57+
58+
struct {
59+
double *Data;
60+
} Wrapper { .Data = Data };
61+
62+
// CHECK-NOT: omptarget device 0 info: tofrom(unknown)[48] is not used and will not be copied
63+
#pragma omp target map(tofrom: Wrapper.Data[0:6])
64+
{
65+
Wrapper.Data[0] = 1;
66+
}
67+
68+
// CHECK: omptarget device 0 info: unknown(unknown)[8] is not used and will not be copied
69+
// CHECK: omptarget device 0 info: tofrom(unknown)[56] is not used and will not be copied
70+
#pragma omp target map(tofrom: Wrapper.Data[0:7])
71+
;
72+
}

0 commit comments

Comments
 (0)