1 extern
2 #ifdef __cplusplus
3 "C"
4 #endif
5 void abort (void);
6 
7 void
fn1(double * x,double * y,int z)8 fn1 (double *x, double *y, int z)
9 {
10   int i;
11   for (i = 0; i < z; i++)
12     {
13       x[i] = i & 31;
14       y[i] = (i & 63) - 30;
15     }
16 }
17 
18 #pragma omp declare target
19 int tgtv = 6;
20 int
tgt(void)21 tgt (void)
22 {
23   #pragma omp atomic update
24     tgtv++;
25   return 0;
26 }
27 #pragma omp end declare target
28 
29 double
fn2(int x,int y,int z)30 fn2 (int x, int y, int z)
31 {
32   double b[1024], c[1024], s = 0;
33   int i, j;
34   fn1 (b, c, x);
35   #pragma omp target data map(to: b)
36   {
37     #pragma omp target map(tofrom: c, s)
38       #pragma omp teams num_teams(y) thread_limit(z) reduction(+:s) firstprivate(x)
39 	#pragma omp distribute dist_schedule(static, 4) collapse(1)
40 	  for (j=0; j < x; j += y)
41 	    #pragma omp parallel for reduction(+:s)
42 	      for (i = j; i < j + y; i++)
43 		tgt (), s += b[i] * c[i];
44     #pragma omp target update from(b, tgtv)
45   }
46   return s;
47 }
48 
49 double
fn3(int x)50 fn3 (int x)
51 {
52   double b[1024], c[1024], s = 0;
53   int i;
54   fn1 (b, c, x);
55   #pragma omp target map(to: b, c) map(tofrom:s)
56     #pragma omp parallel for reduction(+:s)
57       for (i = 0; i < x; i++)
58 	tgt (), s += b[i] * c[i];
59   return s;
60 }
61 
62 double
fn4(int x,double * p)63 fn4 (int x, double *p)
64 {
65   double b[1024], c[1024], d[1024], s = 0;
66   int i;
67   fn1 (b, c, x);
68   fn1 (d + x, p + x, x);
69   #pragma omp target map(to: b, c[0:x], d[x:x]) map(to:p[x:64 + (x & 31)]) \
70 		     map(tofrom: s)
71     #pragma omp parallel for reduction(+:s)
72       for (i = 0; i < x; i++)
73 	s += b[i] * c[i] + d[x + i] + p[x + i];
74   return s;
75 }
76 
77 int
main()78 main ()
79 {
80   double a = fn2 (128, 4, 6);
81   int b = tgtv;
82   double c = fn3 (61);
83   #pragma omp target update from(tgtv)
84   int d = tgtv;
85   double e[1024];
86   double f = fn4 (64, e);
87   if (a != 13888.0 || b != 6 + 128 || c != 4062.0 || d != 6 + 128 + 61
88       || f != 8032.0)
89     abort ();
90   return 0;
91 }
92