diff mbox

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

Message ID 54EB4CD8.1010302@mentor.com
State New
Headers show

Commit Message

Tom de Vries Feb. 23, 2015, 3:52 p.m. UTC
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

Comments

Jakub Jelinek Feb. 23, 2015, 4:08 p.m. UTC | #1
On Mon, Feb 23, 2015 at 04:52:56PM +0100, Tom de Vries wrote:
> 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?

If Thomas is ok with that, it is ok with me too.

	Jakub
diff mbox

Patch

/* { 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