1 /* { dg-do run } */
2 /* { dg-require-effective-target offload_device_nonshared_as } */
3 
4 #include <omp.h>
5 #include <stdlib.h>
6 
7 #define EPS 0.000001
8 #define N 100000
9 #define THRESHOLD1 10000
10 #define THRESHOLD2 1000
11 
init(float * a1,float * a2)12 void init (float *a1, float *a2)
13 {
14   float s = -1;
15   int i;
16   for (i = 0; i < N; i++)
17     {
18       a1[i] = s;
19       a2[i] = i;
20       s = -s;
21     }
22 }
23 
check(float * a,float * b)24 void check (float *a, float *b)
25 {
26   int i;
27   for (i = 0; i < N; i++)
28     if (a[i] - b[i] > EPS || b[i] - a[i] > EPS)
29       abort ();
30 }
31 
vec_mult_ref(float * p,float * v1,float * v2)32 void vec_mult_ref (float *p, float *v1, float *v2)
33 {
34   int i;
35   for (i = 0; i < N; i++)
36     p[i] = v1[i] * v2[i];
37 }
38 
vec_mult(float * p,float * v1,float * v2)39 void vec_mult (float *p, float *v1, float *v2)
40 {
41   int i;
42   #pragma omp target if(N > THRESHOLD1) map(to: v1[0:N], v2[:N]) \
43 		     map(from: p[0:N])
44     {
45       if (omp_is_initial_device ())
46 	abort ();
47 
48       #pragma omp parallel for if(N > THRESHOLD2)
49 	for (i = 0; i < N; i++)
50 	  p[i] = v1[i] * v2[i];
51     }
52 }
53 
main()54 int main ()
55 {
56   float p1[N], p2[N];
57   float v1[N], v2[N];
58 
59   init (v1, v2);
60 
61   vec_mult_ref (p1, v1, v2);
62   vec_mult (p2, v1, v2);
63 
64   check (p1, p2);
65 
66   return 0;
67 }
68