(root)/
gcc-13.2.0/
libgomp/
testsuite/
libgomp.c-c++-common/
task-reduction-6.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 *a, int *b)
      33  {
      34    int x = 0;
      35    #pragma omp taskloop reduction (+:x) in_reduction (+:b[0])
      36    for (int i = 0; i < 64; 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 *a, unsigned long long int *b)
      46  {
      47    unsigned long long int x = 1;
      48    #pragma omp taskloop reduction (*:x) in_reduction (*:b[0])
      49    for (int i = 0; i < 64; i++)
      50      {
      51        #pragma omp task in_reduction (*:x)
      52        x *= a[i];
      53        #pragma omp task in_reduction (*:b[0])
      54        *b *= (3 - a[i]);
      55      }
      56    return x;
      57  }
      58  
      59  void
      60  baz (int i, int *a, int *c)
      61  {
      62    #pragma omp task in_reduction (*:h) in_reduction (+:g)
      63    {
      64      g.s += 7 * a[i];
      65      h.s *= (3 - c[i]);
      66      if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9))
      67        abort ();
      68    }
      69  }
      70  
      71  int
      72  main ()
      73  {
      74    int i, j, a[64], b = 0, c[64];
      75    unsigned long long int d = 1, e;
      76    int r = 0, t;
      77    struct S m = { 0, 7 };
      78    struct S n = { 1, 5 };
      79    for (i = 0; i < 64; i++)
      80      {
      81        a[i] = 2 * i;
      82        c[i] = 1 + ((i % 3) != 1);
      83      }
      84    #pragma omp parallel reduction (task, +:b) reduction(+:r) \
      85  		       reduction(task,*:d) reduction (task, +: g, m) \
      86  		       reduction (task, *: h, n) shared(t)
      87    {
      88      #pragma omp master
      89      {
      90        j = foo (a, &b);
      91        t = omp_get_num_threads ();
      92      }
      93      r++;
      94      #pragma omp single nowait
      95        e = bar (c, &d);
      96      #pragma omp master
      97      #pragma omp taskloop in_reduction (+: g, m) in_reduction (*: h, n)
      98      for (i = 0; i < 64; ++i)
      99        {
     100  	g.s += 3 * a[i];
     101  	h.s *= (3 - c[i]);
     102  	m.s += 4 * a[i];
     103  	n.s *= c[i];
     104  	if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9)
     105  	    || (m.t != 7 && m.t != 3) || (n.t != 5 && n.t != 9))
     106  	  abort ();
     107  	baz (i, a, c);
     108        }
     109    }
     110    if (n.s != (1ULL << 43) || n.t != 5)
     111      abort ();
     112    if (j != 63 * 64 || b != 63 * 64 * 2)
     113      abort ();
     114    if (e != (1ULL << 43) || d != (1ULL << 21))
     115      abort ();
     116    if (g.s != 63 * 64 * 10 || g.t != 7)
     117      abort ();
     118    if (h.s != (1ULL << 42) || h.t != 5)
     119      abort ();
     120    if (m.s != 63 * 64 * 4 || m.t != 7)
     121      abort ();
     122    if (r != t)
     123      abort ();
     124    return 0;
     125  }