xref: /llvm-project/offload/test/offloading/target-teams-atomic.c (revision 330d8983d25d08580fc1642fea48b2473f47a9da)
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 Doerfert int 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