1*330d8983SJohannes Doerfert // Check that omp atomic is permitted and behaves when strictly nested within 2*330d8983SJohannes Doerfert // omp target teams. This is an extension to OpenMP 5.2 and is enabled by 3*330d8983SJohannes Doerfert // default. 4*330d8983SJohannes Doerfert 5*330d8983SJohannes Doerfert // RUN: %libomptarget-compile-run-and-check-generic 6*330d8983SJohannes Doerfert 7*330d8983SJohannes Doerfert #include <omp.h> 8*330d8983SJohannes Doerfert #include <stdbool.h> 9*330d8983SJohannes Doerfert #include <stdio.h> 10*330d8983SJohannes Doerfert #include <string.h> 11*330d8983SJohannes Doerfert 12*330d8983SJohannes Doerfert // High parallelism increases our chances of detecting a lack of atomicity. 13*330d8983SJohannes Doerfert #define NUM_TEAMS_TRY 256 14*330d8983SJohannes Doerfert main()15*330d8983SJohannes Doerfertint main() { 16*330d8983SJohannes Doerfert // CHECK: update: num_teams=[[#NUM_TEAMS:]]{{$}} 17*330d8983SJohannes Doerfert // CHECK-NEXT: update: x=[[#NUM_TEAMS]]{{$}} 18*330d8983SJohannes Doerfert int x = 0; 19*330d8983SJohannes Doerfert int numTeams; 20*330d8983SJohannes Doerfert #pragma omp target teams num_teams(NUM_TEAMS_TRY) map(tofrom : x, numTeams) 21*330d8983SJohannes Doerfert { 22*330d8983SJohannes Doerfert #pragma omp atomic update 23*330d8983SJohannes Doerfert ++x; 24*330d8983SJohannes Doerfert if (omp_get_team_num() == 0) 25*330d8983SJohannes Doerfert numTeams = omp_get_num_teams(); 26*330d8983SJohannes Doerfert } 27*330d8983SJohannes Doerfert printf("update: num_teams=%d\n", numTeams); 28*330d8983SJohannes Doerfert printf("update: x=%d\n", x); 29*330d8983SJohannes Doerfert 30*330d8983SJohannes Doerfert // CHECK-NEXT: capture: x=[[#NUM_TEAMS]]{{$}} 31*330d8983SJohannes Doerfert // CHECK-NEXT: capture: xCapturedCount=[[#NUM_TEAMS]]{{$}} 32*330d8983SJohannes Doerfert bool xCaptured[numTeams]; 33*330d8983SJohannes Doerfert memset(xCaptured, 0, sizeof xCaptured); 34*330d8983SJohannes Doerfert x = 0; 35*330d8983SJohannes Doerfert #pragma omp target teams num_teams(NUM_TEAMS_TRY) map(tofrom : x, numTeams) 36*330d8983SJohannes Doerfert { 37*330d8983SJohannes Doerfert int v; 38*330d8983SJohannes Doerfert #pragma omp atomic capture 39*330d8983SJohannes Doerfert v = x++; 40*330d8983SJohannes Doerfert xCaptured[v] = true; 41*330d8983SJohannes Doerfert } 42*330d8983SJohannes Doerfert printf("capture: x=%d\n", x); 43*330d8983SJohannes Doerfert int xCapturedCount = 0; 44*330d8983SJohannes Doerfert for (int i = 0; i < numTeams; ++i) { 45*330d8983SJohannes Doerfert if (xCaptured[i]) 46*330d8983SJohannes Doerfert ++xCapturedCount; 47*330d8983SJohannes Doerfert } 48*330d8983SJohannes Doerfert printf("capture: xCapturedCount=%d\n", xCapturedCount); 49*330d8983SJohannes Doerfert return 0; 50*330d8983SJohannes Doerfert } 51