1  /* { dg-do run } */
       2  /* { dg-additional-options "-DTESTITERS=20" { target { ! run_expensive_tests } } } */
       3  
       4  #include <stdlib.h>
       5  
       6  #define EPS 0.00001
       7  #define N 1000
       8  #ifndef TESTITERS
       9  #define TESTITERS N
      10  #endif
      11  
      12  #pragma omp declare target
      13  float Q[N][N];
      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  
      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  
      28  float accum_ref (int k)
      29  {
      30    int i;
      31    float tmp = 0.0;
      32  
      33    for (i = 0; i < N; i++)
      34      tmp += Pfun (i, k);
      35  
      36    return tmp;
      37  }
      38  
      39  float accum (int k)
      40  {
      41    int i;
      42    float tmp = 0.0;
      43  
      44    #pragma omp target map(tofrom:tmp)
      45      #pragma omp parallel for reduction(+:tmp)
      46        for (i = 0; i < N; i++)
      47  	tmp += Pfun (i, k);
      48  
      49    return tmp;
      50  }
      51  
      52  void check (float a, float b)
      53  {
      54    float err = (b == 0.0) ? a : (a - b) / b;
      55    if (((err > 0) ? err : -err) > EPS)
      56      abort ();
      57  }
      58  
      59  int main ()
      60  {
      61    int i;
      62  
      63    init ();
      64  
      65    #pragma omp target update to(Q)
      66  
      67    for (i = 0; i < TESTITERS; i++)
      68      check (accum (i), accum_ref (i));
      69  
      70    return 0;
      71  }