xref: /llvm-project/offload/test/offloading/bug64959.c (revision 330d8983d25d08580fc1642fea48b2473f47a9da)
1*330d8983SJohannes Doerfert // RUN: %libomptarget-compile-run-and-check-generic
2*330d8983SJohannes Doerfert // RUN: %libomptarget-compileopt-run-and-check-generic
3*330d8983SJohannes Doerfert 
4*330d8983SJohannes Doerfert // TODO: This requires malloc support for the threads states.
5*330d8983SJohannes Doerfert // FIXME: Flaky on all GPU targets.
6*330d8983SJohannes Doerfert // UNSUPPORTED: amdgcn-amd-amdhsa
7*330d8983SJohannes Doerfert // UNSUPPORTED: nvptx64-nvidia-cuda
8*330d8983SJohannes Doerfert // UNSUPPORTED: nvptx64-nvidia-cuda-LTO
9*330d8983SJohannes Doerfert 
10*330d8983SJohannes Doerfert #include <omp.h>
11*330d8983SJohannes Doerfert #include <stdio.h>
12*330d8983SJohannes Doerfert #define N 10
13*330d8983SJohannes Doerfert 
isCPU()14*330d8983SJohannes Doerfert int isCPU() { return 1; }
15*330d8983SJohannes Doerfert 
16*330d8983SJohannes Doerfert #pragma omp begin declare variant match(device = {kind(gpu)})
isCPU()17*330d8983SJohannes Doerfert int isCPU() { return 0; }
18*330d8983SJohannes Doerfert #pragma omp end declare variant
19*330d8983SJohannes Doerfert 
main(void)20*330d8983SJohannes Doerfert int main(void) {
21*330d8983SJohannes Doerfert   long int aa = 0;
22*330d8983SJohannes Doerfert   int res = 0;
23*330d8983SJohannes Doerfert 
24*330d8983SJohannes Doerfert   int ng = 12;
25*330d8983SJohannes Doerfert   int cmom = 14;
26*330d8983SJohannes Doerfert   int nxyz;
27*330d8983SJohannes Doerfert 
28*330d8983SJohannes Doerfert #pragma omp target map(from : nxyz, ng, cmom)
29*330d8983SJohannes Doerfert   {
30*330d8983SJohannes Doerfert     nxyz = isCPU() ? 2 : 5000;
31*330d8983SJohannes Doerfert     ng = isCPU() ? 2 : 12;
32*330d8983SJohannes Doerfert     cmom = isCPU() ? 2 : 14;
33*330d8983SJohannes Doerfert   }
34*330d8983SJohannes Doerfert 
35*330d8983SJohannes Doerfert #pragma omp target teams distribute num_teams(nxyz)                            \
36*330d8983SJohannes Doerfert     thread_limit(ng *(cmom - 1)) map(tofrom : aa)
37*330d8983SJohannes Doerfert   for (int gid = 0; gid < nxyz; gid++) {
38*330d8983SJohannes Doerfert #pragma omp parallel for collapse(2)
39*330d8983SJohannes Doerfert     for (unsigned int g = 0; g < ng; g++) {
40*330d8983SJohannes Doerfert       for (unsigned int l = 0; l < cmom - 1; l++) {
41*330d8983SJohannes Doerfert         int a = 0;
42*330d8983SJohannes Doerfert #pragma omp parallel for reduction(+ : a)
43*330d8983SJohannes Doerfert         for (int i = 0; i < N; i++) {
44*330d8983SJohannes Doerfert           a += i;
45*330d8983SJohannes Doerfert         }
46*330d8983SJohannes Doerfert #pragma omp atomic
47*330d8983SJohannes Doerfert         aa += a;
48*330d8983SJohannes Doerfert       }
49*330d8983SJohannes Doerfert     }
50*330d8983SJohannes Doerfert   }
51*330d8983SJohannes Doerfert   long exp = (long)ng * (cmom - 1) * nxyz * (N * (N - 1) / 2);
52*330d8983SJohannes Doerfert   printf("The result is = %ld exp:%ld!\n", aa, exp);
53*330d8983SJohannes Doerfert   if (aa != exp) {
54*330d8983SJohannes Doerfert     printf("Failed %ld\n", aa);
55*330d8983SJohannes Doerfert     return 1;
56*330d8983SJohannes Doerfert   }
57*330d8983SJohannes Doerfert   // CHECK: Success
58*330d8983SJohannes Doerfert   printf("Success\n");
59*330d8983SJohannes Doerfert   return 0;
60*330d8983SJohannes Doerfert }
61