task-reduction-16.C 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. extern "C" void abort ();
  2. struct S { S (); S (long long int, int); ~S (); static int cnt1, cnt2, cnt3; long long int s; int t; };
  3. int S::cnt1;
  4. int S::cnt2;
  5. int S::cnt3;
  6. S::S ()
  7. {
  8. #pragma omp atomic
  9. cnt1++;
  10. }
  11. S::S (long long int x, int y) : s (x), t (y)
  12. {
  13. #pragma omp atomic update
  14. ++cnt2;
  15. }
  16. S::~S ()
  17. {
  18. #pragma omp atomic
  19. cnt3 = cnt3 + 1;
  20. if (t < 3 || t > 9 || (t & 1) == 0)
  21. abort ();
  22. }
  23. void
  24. bar (S *p, S *o)
  25. {
  26. p->s = 1;
  27. if (o->t != 5)
  28. abort ();
  29. p->t = 9;
  30. }
  31. static inline void
  32. baz (S *o, S *i)
  33. {
  34. if (o->t != 5 || i->t != 9)
  35. abort ();
  36. o->s *= i->s;
  37. }
  38. #pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
  39. #pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
  40. S as = { 0LL, 7 };
  41. S &a = as;
  42. S bs (1LL, 5);
  43. S &b = bs;
  44. void
  45. foo (S &c, S &d)
  46. {
  47. int i;
  48. for (i = 0; i < 2; i++)
  49. #pragma omp task in_reduction (+: c) in_reduction (*: b, d) in_reduction (+: a)
  50. {
  51. a.s += 7;
  52. b.s *= 2;
  53. c.s += 9;
  54. d.s *= 3;
  55. if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
  56. || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
  57. abort ();
  58. }
  59. }
  60. void
  61. test ()
  62. {
  63. S cs = { 0LL, 7 };
  64. S &c = cs;
  65. S ds (1LL, 5);
  66. #pragma omp parallel if (0)
  67. {
  68. S &d = ds;
  69. #pragma omp parallel shared (a, b, c, d)
  70. {
  71. #pragma omp for schedule (static, 1) reduction (task, +: a, c) reduction (task, *: b, d)
  72. for (int i = 0; i < 4; i++)
  73. #pragma omp task in_reduction (*: b, d) in_reduction (+: a, c)
  74. {
  75. int j;
  76. a.s += 7;
  77. b.s *= 2;
  78. for (j = 0; j < 2; j++)
  79. #pragma omp task in_reduction (+: a) in_reduction (*: b) \
  80. in_reduction (+: c) in_reduction (*: d)
  81. {
  82. a.s += 7;
  83. b.s *= 2;
  84. c.s += 9;
  85. d.s *= 3;
  86. foo (c, d);
  87. if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
  88. || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
  89. abort ();
  90. }
  91. c.s += 9;
  92. d.s *= 3;
  93. if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
  94. || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
  95. abort ();
  96. }
  97. #define THREEP7 (3LL * 3LL * 3LL * 3LL * 3LL * 3LL * 3LL)
  98. if (d.s != (THREEP7 * THREEP7 * THREEP7 * THREEP7) || d.t != 5)
  99. abort ();
  100. if (a.s != 28 * 7 || a.t != 7 || b.s != (1L << 28) || b.t != 5
  101. || c.s != 28 * 9 || c.t != 7)
  102. abort ();
  103. }
  104. }
  105. if (a.s != 28 * 7 || a.t != 7 || b.s != (1L << 28) || b.t != 5
  106. || c.s != 28 * 9 || c.t != 7)
  107. abort ();
  108. if (ds.s != (THREEP7 * THREEP7 * THREEP7 * THREEP7) || ds.t != 5)
  109. abort ();
  110. }
  111. int
  112. main ()
  113. {
  114. int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
  115. test ();
  116. if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
  117. abort ();
  118. }