1 /* { dg-do run { target vect_simd_clones } } */
2 /* { dg-additional-options "-msse2" { target sse2_runtime } } */
3 /* { dg-additional-options "-mavx" { target avx_runtime } } */
4 
5 #include <stdlib.h>
6 
7 #define EPS 0.00001
8 #define N 10000
9 #define M 1024
10 
11 #pragma omp declare target
12 float Q[N][N];
13 #pragma omp declare simd uniform(i) linear(k) notinbranch
Pfun(const int i,const int k)14 float Pfun (const int i, const int k)
15 {
16   return Q[i][k] * Q[k][i];
17 }
18 #pragma omp end declare target
19 
init()20 void init ()
21 {
22   int i, j;
23   for (i = 0; i < N; i++)
24     for (j = 0; j < N; j++)
25       Q[i][j] = 0.001 * i * j;
26 }
27 
accum_ref()28 float accum_ref ()
29 {
30   int i, k;
31   float tmp = 0.0;
32 
33   for (i = 0; i < N; i++)
34     {
35       float tmp1 = 0.0;
36 
37       for (k = 0; k < M; k++)
38 	tmp1 += Pfun(i,k);
39 
40       tmp += tmp1;
41     }
42 
43   return tmp;
44 }
45 
accum()46 float accum ()
47 {
48   int i, k;
49   float tmp = 0.0;
50 
51   #pragma omp target map(tofrom:tmp)
52     #pragma omp parallel for reduction(+:tmp)
53       for (i = 0; i < N; i++)
54 	{
55 	  float tmp1 = 0.0;
56 
57 	  #pragma omp simd reduction(+:tmp1)
58 	    for (k = 0; k < M; k++)
59 	      tmp1 += Pfun(i,k);
60 
61 	  tmp += tmp1;
62 	}
63 
64   return tmp;
65 }
66 
check(float a,float b)67 void check (float a, float b)
68 {
69   float err = (b == 0.0) ? a : (a - b) / b;
70   if (((err > 0) ? err : -err) > EPS)
71     abort ();
72 }
73 
main()74 int main ()
75 {
76   init ();
77 
78   #pragma omp target update to(Q)
79 
80   check (accum (), accum_ref ());
81 
82   return 0;
83 }
84