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.00001
       8  #define N 10000
       9  
      10  #pragma omp declare target
      11  void init (float *a, float *b, int n)
      12  {
      13    int i;
      14    for (i = 0; i < n; i++)
      15      {
      16        a[i] = 0.1 * i;
      17        b[i] = 0.01 * i * i;
      18      }
      19  }
      20  #pragma omp end declare target
      21  
      22  void vec_mult_ref(float *p, int n)
      23  {
      24    float *v1, *v2;
      25    int i;
      26  
      27    v1 = (float *) malloc (n * sizeof (float));
      28    v2 = (float *) malloc (n * sizeof (float));
      29  
      30    init (v1, v2, n);
      31  
      32    for (i = 0; i < n; i++)
      33      p[i] = v1[i] * v2[i];
      34  
      35    free (v1);
      36    free (v2);
      37  }
      38  
      39  void vec_mult(float *p, int n)
      40  {
      41    float *v1, *v2;
      42    int i;
      43  
      44    #pragma omp task shared(v1, v2) depend(out: v1, v2)
      45      #pragma omp target map(v1, v2)
      46        {
      47  	if (omp_is_initial_device ())
      48  	  abort ();
      49  
      50  	v1 = (float *) malloc (n * sizeof (float));
      51  	v2 = (float *) malloc (n * sizeof (float));
      52  
      53  	init (v1, v2, n);
      54        }
      55  
      56    #pragma omp task shared(v1, v2) depend(in: v1, v2)
      57      #pragma omp target map(to: v1, v2) map(from: p[0:n])
      58        {
      59  	if (omp_is_initial_device ())
      60  	  abort ();
      61  
      62  	#pragma omp parallel for
      63  	  for (i = 0; i < n; i++)
      64  	    p[i] = v1[i] * v2[i];
      65  
      66  	  free (v1);
      67  	  free (v2);
      68        }
      69  
      70    #pragma omp taskwait
      71  }
      72  
      73  void check (float *a, float *b, int n)
      74  {
      75    int i;
      76    for (i = 0 ; i < n ; i++)
      77      {
      78        float err = (a[i] == 0.0) ? b[i] : (b[i] - a[i]) / a[i];
      79        if (((err > 0) ? err : -err) > EPS)
      80  	abort ();
      81      }
      82  }
      83  
      84  int main ()
      85  {
      86    float *p1 = (float *) malloc (N * sizeof (float));
      87    float *p2 = (float *) malloc (N * sizeof (float));
      88  
      89    vec_mult_ref (p1, N);
      90    vec_mult (p2, N);
      91  
      92    check (p1, p2, N);
      93  
      94    free (p1);
      95    free (p2);
      96  
      97    return 0;
      98  }