(root)/
gcc-13.2.0/
libgomp/
testsuite/
libgomp.c-c++-common/
taskloop-reduction-1.c
       1  extern
       2  #ifdef __cplusplus
       3  "C"
       4  #endif
       5  void abort (void);
       6  
       7  struct S { unsigned long long int s, t; };
       8  
       9  void
      10  rbar (struct S *p, struct S *o)
      11  {
      12    p->s = 1;
      13    if (o->t != 5)
      14      abort ();
      15    p->t = 9;
      16  }
      17  
      18  static inline void
      19  rbaz (struct S *o, struct S *i)
      20  {
      21    if (o->t != 5 || i->t != 9)
      22      abort ();
      23    o->s *= i->s;
      24  }
      25  
      26  #pragma omp declare reduction (+: struct S : omp_out.s += omp_in.s) \
      27    initializer (omp_priv = { 0, 3 })
      28  #pragma omp declare reduction (*: struct S : rbaz (&omp_out, &omp_in)) \
      29    initializer (rbar (&omp_priv, &omp_orig))
      30  
      31  struct S g = { 0, 7 };
      32  struct S h = { 1, 5 };
      33  
      34  int
      35  foo (int *a, int *b)
      36  {
      37    int x = 0;
      38    #pragma omp taskloop reduction (+:x) in_reduction (+:b[0])
      39    for (int i = 0; i < 64; i++)
      40      {
      41        x += a[i];
      42        *b += a[i] * 2;
      43      }
      44    return x;
      45  }
      46  
      47  unsigned long long int
      48  bar (int *a, unsigned long long int *b)
      49  {
      50    unsigned long long int x = 1;
      51    #pragma omp taskloop reduction (*:x) in_reduction (*:b[0])
      52    for (int i = 0; i < 64; i++)
      53      {
      54        #pragma omp task in_reduction (*:x)
      55        x *= a[i];
      56        #pragma omp task in_reduction (*:b[0])
      57        *b *= (3 - a[i]);
      58      }
      59    return x;
      60  }
      61  
      62  void
      63  baz (int i, int *a, int *c)
      64  {
      65    #pragma omp task in_reduction (*:h) in_reduction (+:g)
      66    {
      67      g.s += 7 * a[i];
      68      h.s *= (3 - c[i]);
      69      if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9))
      70        abort ();
      71    }
      72  }
      73  
      74  int
      75  main ()
      76  {
      77    int i, j, a[64], b = 0, c[64];
      78    unsigned long long int d = 1, e;
      79    struct S m = { 0, 7 };
      80    for (i = 0; i < 64; i++)
      81      {
      82        a[i] = 2 * i;
      83        c[i] = 1 + ((i % 3) != 1);
      84      }
      85    #pragma omp parallel
      86    #pragma omp master
      87    {
      88      struct S n = { 1, 5 };
      89      #pragma omp taskgroup task_reduction (+:b)
      90        j = foo (a, &b);
      91      #pragma omp taskgroup task_reduction (*:d)
      92        e = bar (c, &d);
      93      #pragma omp taskloop reduction (+: g, m) reduction (*: h, n)
      94      for (i = 0; i < 64; ++i)
      95        {
      96  	g.s += 3 * a[i];
      97  	h.s *= (3 - c[i]);
      98  	m.s += 4 * a[i];
      99  	n.s *= c[i];
     100  	if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9)
     101  	    || (m.t != 7 && m.t != 3) || (n.t != 5 && n.t != 9))
     102  	  abort ();
     103  	baz (i, a, c);
     104        }
     105      if (n.s != (1ULL << 43) || n.t != 5)
     106        abort ();
     107    }
     108    if (j != 63 * 64 || b != 63 * 64 * 2)
     109      abort ();
     110    if (e != (1ULL << 43) || d != (1ULL << 21))
     111      abort ();
     112    if (g.s != 63 * 64 * 10 || g.t != 7)
     113      abort ();
     114    if (h.s != (1ULL << 42) || h.t != 5)
     115      abort ();
     116    if (m.s != 63 * 64 * 4 || m.t != 7)
     117      abort ();
     118    return 0;
     119  }