This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Use DO_PRAGMA in libgomp.oacc-c-c++-common/reduction-1.c


Hi,

this patch is a rewrite of libgomp.oacc-c-c++-common/reduction-1.c (included as a whole in the patch prefix).

The patch attempts to get rid of the errorprone copy-paste style. An example of such an error in this test-case is:
...
  result = 5;
  vresult = 5;

  lresult = false;
  lvresult = false;

  /* '||' reductions.  */
#pragma acc parallel vector_length (vl)
#pragma acc loop reduction (||:lresult)
  for (i = 0; i < n; i++)
    lresult = lresult || (result > array[i]);

  /* Verify the reduction.  */
  for (i = 0; i < n; i++)
    lvresult = lresult || (result > array[i]);

  if (lresult != lvresult)
    abort ();
...
In the verification loop lvresult should have been used instead of lresult (and probably the intention was to use vresult instead of result there. Now vresult is assigned to but not used).

The patch factors out the common parts and uses parameters for the non-common parts. Since the common parts involve the acc pragma, I'm using DO_PRAGMA ( https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html ). [ Unfortunately, I haven't found something similar to use for fortran. ]

Furthermore, I've updated the initial values in order to prevent cases where the initial value of the reduction variable is the same as the final one (f.i. we were doing a multiply reduction with initial value 0).

The only thing I'm not sure about is the two-level pragma expansion using the apply pragmas. It maximizes factoring out common parts, but it makes things less readable.

Tested on x86_64.

OK for stage4?

Thanks,
- Tom
/* { dg-do run } */

/* Integer reductions.  */

#include <stdlib.h>
#include <stdbool.h>

#define vl 32

#define DO_PRAGMA(x) _Pragma (#x)

#define check_reduction(pragmaop,op,res,vres,init,apply)	\
  res = (init);							\
DO_PRAGMA (acc parallel vector_length (vl))\
DO_PRAGMA (acc loop reduction (pragmaop:res))\
  for (i = 0; i < n; i++)					\
    res = apply (res, op, array[i]);				\
								\
  vres = (init);						\
  for (i = 0; i < n; i++)					\
    vres = apply (vres, op, array[i]);				\
								\
  if (res != vres)						\
    abort ();

#define apply_bin_int_op(a, op, b) ((a) op (b))
#define check_reduction_int(op, init)					\
  check_reduction (op, op, result, vresult, init, apply_bin_int_op)

static void
test_reductions_int (void)
{
  const int n = 1000;
  int i;
  int vresult, result, array[n];

  for (i = 0; i < n; i++)
    array[i] = i;

  check_reduction_int (+, 0);
  check_reduction_int (*, 1);
  check_reduction_int (&, -1);
  check_reduction_int (|, 0);
  check_reduction_int (^, 0);
}

#define apply_max_op(a, op, b) (((a) > (b)) ? (a) : (b))
#define apply_min_op(a, op, b) (((a) < (b)) ? (a) : (b))
#define check_reduction_minmax(pragmaop,apply,init)		\
  check_reduction (pragmaop, , result, vresult, init, apply)

static void
test_reductions_minmax (void)
{
  const int n = 1000;
  int i;
  int vresult, result, array[n];

  for (i = 0; i < n; i++)
    array[i] = i;

  check_reduction_minmax (min, apply_min_op, n + 1);
  check_reduction_minmax (max, apply_max_op, -1);
}

#define apply_bin_bool_op(a, op, b) (a op (cmp_val > b))
#define check_reduction_bool(op, init)					\
  check_reduction (op, op, lresult, lvresult, init, apply_bin_bool_op)

static void
test_reductions_bool (void)
{
  const int n = 1000;
  int i;
  int array[n];
  bool lvresult, lresult;
  int cmp_val;

  for (i = 0; i < n; i++)
    array[i] = i;

  cmp_val = 5;
  check_reduction_bool (&&, true);
  check_reduction_bool (||, false);
}

int
main (void)
{
  test_reductions_int ();
  test_reductions_minmax ();
  test_reductions_bool ();
  return 0;
}

2015-02-23  Tom de Vries  <tom@codesourcery.com>

	* testsuite/libgomp.oacc-c-c++-common/reduction-1.c
	(DO_PRAGMA, check_reduction, apply_bin_int_op, check_reduction_int)
	(apply_max_op, apply_min_op, check_reduction_minmax, apply_bin_bool_op)
	(check_reduction_bool): Declare.
	(test_reductions_int, test_reductions_minmax, test_reductions_bool): New
	function.
	(main): Use new functions.
---
 .../libgomp.oacc-c-c++-common/reduction-1.c        | 208 +++++++--------------
 1 file changed, 64 insertions(+), 144 deletions(-)

diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-1.c
index acf9540..87afaf4 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-1.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-1.c
@@ -7,168 +7,88 @@
 
 #define vl 32
 
-int
-main(void)
+#define DO_PRAGMA(x) _Pragma (#x)
+
+#define check_reduction(pragmaop,op,res,vres,init,apply)	\
+  res = (init);							\
+DO_PRAGMA (acc parallel vector_length (vl))\
+DO_PRAGMA (acc loop reduction (pragmaop:res))\
+  for (i = 0; i < n; i++)					\
+    res = apply (res, op, array[i]);				\
+								\
+  vres = (init);						\
+  for (i = 0; i < n; i++)					\
+    vres = apply (vres, op, array[i]);				\
+								\
+  if (res != vres)						\
+    abort ();
+
+#define apply_bin_int_op(a, op, b) ((a) op (b))
+#define check_reduction_int(op, init)					\
+  check_reduction (op, op, result, vresult, init, apply_bin_int_op)
+
+static void
+test_reductions_int (void)
 {
   const int n = 1000;
   int i;
   int vresult, result, array[n];
-  bool lvresult, lresult;
 
   for (i = 0; i < n; i++)
     array[i] = i;
 
-  result = 0;
-  vresult = 0;
-
-  /* '+' reductions.  */
-#pragma acc parallel vector_length (vl)
-#pragma acc loop reduction (+:result)
-  for (i = 0; i < n; i++)
-    result += array[i];
-
-  /* Verify the reduction.  */
-  for (i = 0; i < n; i++)
-    vresult += array[i];
-
-  if (result != vresult)
-    abort ();
-
-  result = 0;
-  vresult = 0;
-
-  /* '*' reductions.  */
-#pragma acc parallel vector_length (vl)
-#pragma acc loop reduction (*:result)
-  for (i = 0; i < n; i++)
-    result *= array[i];
-
-  /* Verify the reduction.  */
-  for (i = 0; i < n; i++)
-    vresult *= array[i];
-
-  if (result != vresult)
-    abort ();
-
-//   result = 0;
-//   vresult = 0;
-// 
-//   /* 'max' reductions.  */
-// #pragma acc parallel vector_length (vl)
-// #pragma acc loop reduction (+:result)
-//   for (i = 0; i < n; i++)
-//       result = result > array[i] ? result : array[i];
-// 
-//   /* Verify the reduction.  */
-//   for (i = 0; i < n; i++)
-//       vresult = vresult > array[i] ? vresult : array[i];
-// 
-//   printf("%d != %d\n", result, vresult);
-//   if (result != vresult)
-//     abort ();
-// 
-//   result = 0;
-//   vresult = 0;
-// 
-//   /* 'min' reductions.  */
-// #pragma acc parallel vector_length (vl)
-// #pragma acc loop reduction (+:result)
-//   for (i = 0; i < n; i++)
-//       result = result < array[i] ? result : array[i];
-// 
-//   /* Verify the reduction.  */
-//   for (i = 0; i < n; i++)
-//       vresult = vresult < array[i] ? vresult : array[i];
-// 
-//   printf("%d != %d\n", result, vresult);
-//   if (result != vresult)
-//     abort ();
-
-  result = 0;
-  vresult = 0;
-
-  /* '&' reductions.  */
-#pragma acc parallel vector_length (vl)
-#pragma acc loop reduction (&:result)
-  for (i = 0; i < n; i++)
-    result &= array[i];
-
-  /* Verify the reduction.  */
-  for (i = 0; i < n; i++)
-    vresult &= array[i];
-
-  if (result != vresult)
-    abort ();
-
-  result = 0;
-  vresult = 0;
-
-  /* '|' reductions.  */
-#pragma acc parallel vector_length (vl)
-#pragma acc loop reduction (|:result)
-  for (i = 0; i < n; i++)
-    result |= array[i];
-
-  /* Verify the reduction.  */
-  for (i = 0; i < n; i++)
-    vresult |= array[i];
-
-  if (result != vresult)
-    abort ();
-
-  result = 0;
-  vresult = 0;
-
-  /* '^' reductions.  */
-#pragma acc parallel vector_length (vl)
-#pragma acc loop reduction (^:result)
-  for (i = 0; i < n; i++)
-    result ^= array[i];
-
-  /* Verify the reduction.  */
-  for (i = 0; i < n; i++)
-    vresult ^= array[i];
-
-  if (result != vresult)
-    abort ();
-
-  result = 5;
-  vresult = 5;
+  check_reduction_int (+, 0);
+  check_reduction_int (*, 1);
+  check_reduction_int (&, -1);
+  check_reduction_int (|, 0);
+  check_reduction_int (^, 0);
+}
 
-  lresult = false;
-  lvresult = false;
+#define apply_max_op(a, op, b) (((a) > (b)) ? (a) : (b))
+#define apply_min_op(a, op, b) (((a) < (b)) ? (a) : (b))
+#define check_reduction_minmax(pragmaop,apply,init)		\
+  check_reduction (pragmaop, , result, vresult, init, apply)
 
-  /* '&&' reductions.  */
-#pragma acc parallel vector_length (vl)
-#pragma acc loop reduction (&&:lresult)
-  for (i = 0; i < n; i++)
-    lresult = lresult && (result > array[i]);
+static void
+test_reductions_minmax (void)
+{
+  const int n = 1000;
+  int i;
+  int vresult, result, array[n];
 
-  /* Verify the reduction.  */
   for (i = 0; i < n; i++)
-    lvresult = lresult && (result > array[i]);
-
-  if (lresult != lvresult)
-    abort ();
+    array[i] = i;
 
-  result = 5;
-  vresult = 5;
+  check_reduction_minmax (min, apply_min_op, n + 1);
+  check_reduction_minmax (max, apply_max_op, -1);
+}
 
-  lresult = false;
-  lvresult = false;
+#define apply_bin_bool_op(a, op, b) (a op (cmp_val > b))
+#define check_reduction_bool(op, init)					\
+  check_reduction (op, op, lresult, lvresult, init, apply_bin_bool_op)
 
-  /* '||' reductions.  */
-#pragma acc parallel vector_length (vl)
-#pragma acc loop reduction (||:lresult)
-  for (i = 0; i < n; i++)
-    lresult = lresult || (result > array[i]);
+static void
+test_reductions_bool (void)
+{
+  const int n = 1000;
+  int i;
+  int array[n];
+  bool lvresult, lresult;
+  int cmp_val;
 
-  /* Verify the reduction.  */
   for (i = 0; i < n; i++)
-    lvresult = lresult || (result > array[i]);
+    array[i] = i;
 
-  if (lresult != lvresult)
-    abort ();
+  cmp_val = 5;
+  check_reduction_bool (&&, true);
+  check_reduction_bool (||, false);
+}
 
+int
+main (void)
+{
+  test_reductions_int ();
+  test_reductions_minmax ();
+  test_reductions_bool ();
   return 0;
 }
-- 
1.9.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]