1  /* { dg-do run } */
       2  
       3  #include <stdlib.h>
       4  
       5  #define EPS 0.0001
       6  #define N 1024*1024
       7  
       8  void init (float B[], float C[], int n)
       9  {
      10    int i;
      11    for (i = 0; i < n; i++)
      12      {
      13        B[i] = 0.1 * i;
      14        C[i] = 0.01 * i * i;
      15      }
      16  }
      17  
      18  float dotprod_ref (float B[], float C[], int n)
      19  {
      20    int i;
      21    float sum = 0.0;
      22  
      23    for (i = 0; i < n; i++)
      24      sum += B[i] * C[i];
      25  
      26    return sum;
      27  }
      28  
      29  float dotprod (float B[], float C[], int n)
      30  {
      31    int i;
      32    float sum = 0;
      33  
      34    #pragma omp target map(to: B[0:n], C[0:n]) map(tofrom:sum)
      35      #pragma omp teams num_teams(8) thread_limit(16) reduction(+:sum)
      36        #pragma omp distribute parallel for reduction(+:sum) \
      37  					  dist_schedule(static, 1024) \
      38  					  schedule(static, 64)
      39  	for (i = 0; i < n; i++)
      40  	  sum += B[i] * C[i];
      41  
      42    return sum;
      43  }
      44  
      45  void check (float a, float b)
      46  {
      47    float err = (b == 0.0) ? a : (a - b) / b;
      48    if (((err > 0) ? err : -err) > EPS)
      49      abort ();
      50  }
      51  
      52  int main ()
      53  {
      54    float *v1 = (float *) malloc (N * sizeof (float));
      55    float *v2 = (float *) malloc (N * sizeof (float));
      56  
      57    float p1, p2;
      58  
      59    init (v1, v2, N);
      60  
      61    p1 = dotprod_ref (v1, v2, N);
      62    p2 = dotprod (v1, v2, N);
      63  
      64    check (p1, p2);
      65  
      66    free (v1);
      67    free (v2);
      68  
      69    return 0;
      70  }