1 // RUN: %compilexx-run-and-check
2 
3 #include <stdio.h>
4 #include <omp.h>
5 
main(void)6 int main(void) {
7   int isHost = -1;
8   int ParallelLevel1 = -1, ParallelLevel2 = -1;
9   int Count = 0;
10 
11 #pragma omp target parallel for map(tofrom                                     \
12                                     : isHost, ParallelLevel1, ParallelLevel2), reduction(+: Count) schedule(static, 1)
13   for (int J = 0; J < 10; ++J) {
14 #pragma omp critical
15     {
16       isHost = (isHost < 0 || isHost == 0) ? omp_is_initial_device() : isHost;
17       ParallelLevel1 = (ParallelLevel1 < 0 || ParallelLevel1 == 1)
18                            ? omp_get_level()
19                            : ParallelLevel1;
20     }
21     if (omp_get_thread_num() > 5) {
22       int L2;
23 #pragma omp parallel for schedule(dynamic) lastprivate(L2) reduction(+: Count)
24       for (int I = 0; I < 10; ++I) {
25         L2 = omp_get_level();
26         Count += omp_get_level(); // (10-6)*10*2 = 80
27       }
28 #pragma omp critical
29       ParallelLevel2 =
30           (ParallelLevel2 < 0 || ParallelLevel2 == 2) ? L2 : ParallelLevel2;
31     } else {
32       Count += omp_get_level(); // 6 * 1 = 6
33     }
34   }
35 
36   if (isHost < 0) {
37     printf("Runtime error, isHost=%d\n", isHost);
38   }
39 
40   // CHECK: Target region executed on the device
41   printf("Target region executed on the %s\n", isHost ? "host" : "device");
42   // CHECK: Parallel level in SPMD mode: L1 is 1, L2 is 2
43   printf("Parallel level in SPMD mode: L1 is %d, L2 is %d\n", ParallelLevel1,
44          ParallelLevel2);
45   // Final result of Count is (10-6)(num of loops)*10(num of iterations)*2(par
46   // level) + 6(num of iterations) * 1(par level)
47   // CHECK: Expected count = 86
48   printf("Expected count = %d\n", Count);
49 
50   return isHost;
51 }
52