forked from OSchip/llvm-project
[OPENMP][NVPTX]Fix dynamic scheduling in L2+ SPMD parallel regions.
Summary: If the kernel is executed in SPMD mode and the L2+ parallel for region with the dynamic scheduling is executed, dynamic scheduling functions are called. They expect full runtime support, but SPMD kernels may be executed without the full runtime. It leads to the runtime crash of the compiled program. Patch fixes this problem + fixes handling of the parallelism level in SPMD mode, which is required as part of this patch. Reviewers: gtbercea, kkwli0, grokos Subscribers: guansong, jdoerfert, openmp-commits, caomhin Tags: #openmp Differential Revision: https://reviews.llvm.org/D60578 llvm-svn: 358442
This commit is contained in:
parent
407dd4d169
commit
13532ea623
|
@ -164,7 +164,8 @@ EXTERN int omp_get_level(void) {
|
|||
if (isRuntimeUninitialized()) {
|
||||
ASSERT0(LT_FUSSY, isSPMDMode(),
|
||||
"Expected SPMD mode only with uninitialized runtime.");
|
||||
return parallelLevel;
|
||||
// parallelLevel starts from 0, need to add 1 for correct level.
|
||||
return parallelLevel + 1;
|
||||
}
|
||||
int level = 0;
|
||||
omptarget_nvptx_TaskDescr *currTaskDescr =
|
||||
|
|
|
@ -205,8 +205,12 @@ public:
|
|||
INLINE static void dispatch_init(kmp_Ident *loc, int32_t threadId,
|
||||
kmp_sched_t schedule, T lb, T ub, ST st,
|
||||
ST chunk) {
|
||||
ASSERT0(LT_FUSSY, checkRuntimeInitialized(loc),
|
||||
"Expected non-SPMD mode + initialized runtime.");
|
||||
if (checkRuntimeUninitialized(loc)) {
|
||||
// In SPMD mode no need to check parallelism level - dynamic scheduling
|
||||
// may appear only in L2 parallel regions with lightweight runtime.
|
||||
ASSERT0(LT_FUSSY, checkSPMDMode(loc), "Expected non-SPMD mode.");
|
||||
return;
|
||||
}
|
||||
int tid = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||
omptarget_nvptx_TaskDescr *currTaskDescr = getMyTopTaskDescriptor(tid);
|
||||
T tnum = currTaskDescr->ThreadsInTeam();
|
||||
|
@ -439,8 +443,15 @@ public:
|
|||
|
||||
INLINE static int dispatch_next(kmp_Ident *loc, int32_t gtid, int32_t *plast,
|
||||
T *plower, T *pupper, ST *pstride) {
|
||||
ASSERT0(LT_FUSSY, checkRuntimeInitialized(loc),
|
||||
"Expected non-SPMD mode + initialized runtime.");
|
||||
if (checkRuntimeUninitialized(loc)) {
|
||||
// In SPMD mode no need to check parallelism level - dynamic scheduling
|
||||
// may appear only in L2 parallel regions with lightweight runtime.
|
||||
ASSERT0(LT_FUSSY, checkSPMDMode(loc), "Expected non-SPMD mode.");
|
||||
if (*plast)
|
||||
return DISPATCH_FINISHED;
|
||||
*plast = 1;
|
||||
return DISPATCH_NOTFINISHED;
|
||||
}
|
||||
// ID of a thread in its own warp
|
||||
|
||||
// automatically selects thread or warp ID based on selected implementation
|
||||
|
|
|
@ -407,7 +407,7 @@ EXTERN uint16_t __kmpc_parallel_level(kmp_Ident *loc, uint32_t global_tid) {
|
|||
if (checkRuntimeUninitialized(loc)) {
|
||||
ASSERT0(LT_FUSSY, checkSPMDMode(loc),
|
||||
"Expected SPMD mode with uninitialized runtime.");
|
||||
return parallelLevel;
|
||||
return parallelLevel + 1;
|
||||
}
|
||||
|
||||
int threadId = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// RUN: %compilexx-run-and-check
|
||||
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
|
||||
int main(void) {
|
||||
int isHost = -1;
|
||||
int ParallelLevel1, ParallelLevel2 = -1;
|
||||
|
||||
#pragma omp target parallel map(from: isHost, ParallelLevel1, ParallelLevel2)
|
||||
{
|
||||
isHost = omp_is_initial_device();
|
||||
ParallelLevel1 = omp_get_level();
|
||||
#pragma omp parallel for schedule(dynamic) lastprivate(ParallelLevel2)
|
||||
for (int I = 0; I < 10; ++I)
|
||||
ParallelLevel2 = omp_get_level();
|
||||
}
|
||||
|
||||
if (isHost < 0) {
|
||||
printf("Runtime error, isHost=%d\n", isHost);
|
||||
}
|
||||
|
||||
// CHECK: Target region executed on the device
|
||||
printf("Target region executed on the %s\n", isHost ? "host" : "device");
|
||||
// CHECK: Parallel level in SPMD mode: L1 is 1, L2 is 2
|
||||
printf("Parallel level in SPMD mode: L1 is %d, L2 is %d\n", ParallelLevel1,
|
||||
ParallelLevel2);
|
||||
|
||||
return isHost;
|
||||
}
|
Loading…
Reference in New Issue