task-reduction-6.c 2.6 KB

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