aboutsummaryrefslogtreecommitdiff
path: root/libomptarget
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-04-15 20:15:20 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2019-04-15 20:15:20 +0000
commit6c198765a02de84ab1655caf083539bcb288c66d (patch)
tree9b616ba9c29bbdf20e8745a5bbf099ae5611cc0c /libomptarget
parentc1629ee2315dc59c5a56acd1588f362ba5fe43ec (diff)
[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 git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@358442 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'libomptarget')
-rw-r--r--libomptarget/deviceRTLs/nvptx/src/libcall.cu3
-rw-r--r--libomptarget/deviceRTLs/nvptx/src/loop.cu19
-rw-r--r--libomptarget/deviceRTLs/nvptx/src/parallel.cu2
-rw-r--r--libomptarget/deviceRTLs/nvptx/test/parallel/spmd_parallel_regions.cpp30
4 files changed, 48 insertions, 6 deletions
diff --git a/libomptarget/deviceRTLs/nvptx/src/libcall.cu b/libomptarget/deviceRTLs/nvptx/src/libcall.cu
index bf33c2a..9bc3f2c 100644
--- a/libomptarget/deviceRTLs/nvptx/src/libcall.cu
+++ b/libomptarget/deviceRTLs/nvptx/src/libcall.cu
@@ -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 =
diff --git a/libomptarget/deviceRTLs/nvptx/src/loop.cu b/libomptarget/deviceRTLs/nvptx/src/loop.cu
index 7422d3c..aad32f0 100644
--- a/libomptarget/deviceRTLs/nvptx/src/loop.cu
+++ b/libomptarget/deviceRTLs/nvptx/src/loop.cu
@@ -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
diff --git a/libomptarget/deviceRTLs/nvptx/src/parallel.cu b/libomptarget/deviceRTLs/nvptx/src/parallel.cu
index 8f3943d..273e15c 100644
--- a/libomptarget/deviceRTLs/nvptx/src/parallel.cu
+++ b/libomptarget/deviceRTLs/nvptx/src/parallel.cu
@@ -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));
diff --git a/libomptarget/deviceRTLs/nvptx/test/parallel/spmd_parallel_regions.cpp b/libomptarget/deviceRTLs/nvptx/test/parallel/spmd_parallel_regions.cpp
new file mode 100644
index 0000000..bf5843b
--- /dev/null
+++ b/libomptarget/deviceRTLs/nvptx/test/parallel/spmd_parallel_regions.cpp
@@ -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;
+}