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