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