task-reduction-8.c 3.2 KB

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