diff mbox

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

Message ID 54EDF2F2.4020501@mentor.com
State New
Headers show

Commit Message

Tom de Vries Feb. 25, 2015, 4:06 p.m. UTC
On 25-02-15 12:40, Thomas Schwinge wrote:
> Hi!
>
> On Mon, 23 Feb 2015 18:14:35 +0100, Tom de Vries <Tom_deVries@mentor.com> wrote:
>> On 23-02-15 17:08, Jakub Jelinek wrote:
>>> 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.
>
> OK, thanks!
>
>> For comparison, this is a less convoluted, but longer version.
>
> Hmm, I can't quite decide which of the two to prefer.  Your call.  ;-P
> (Maybe, toss a coin if it takes more than a minute to decide.)
>
>

Committed this version, I'm happy with this one. There are now just two 
reduction macros (check_reduction_op and check_reduction_macro), which are 
reasonably readable.

Thanks,
- Tom
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_op(type, op, init, b)	\
  {						\
    type res, vres;				\
    res = (init);				\
DO_PRAGMA (acc parallel vector_length (vl))\
DO_PRAGMA (acc loop reduction (op:res))\
    for (i = 0; i < n; i++)			\
      res = res op (b);				\
						\
    vres = (init);				\
    for (i = 0; i < n; i++)			\
      vres = vres op (b);			\
						\
    if (res != vres)				\
      abort ();					\
  }

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

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

  check_reduction_op (int, +, 0, array[i]);
  check_reduction_op (int, *, 1, array[i]);
  check_reduction_op (int, &, -1, array[i]);
  check_reduction_op (int, |, 0, array[i]);
  check_reduction_op (int, ^, 0, array[i]);
}

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

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

  cmp_val = 5;
  check_reduction_op (bool, &&, true, (cmp_val > array[i]));
  check_reduction_op (bool, ||, false, (cmp_val > array[i]));
}

#define check_reduction_macro(type, op, init, b)	\
  {							\
    type res, vres;					\
    res = (init);					\
DO_PRAGMA (acc parallel vector_length (vl))\
DO_PRAGMA (acc loop reduction (op:res))\
    for (i = 0; i < n; i++)				\
      res = op (res, (b));				\
							\
    vres = (init);					\
    for (i = 0; i < n; i++)				\
      vres = op (vres, (b));				\
							\
    if (res != vres)					\
      abort ();						\
  }

#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))

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

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

  check_reduction_macro (int, min, n + 1, array[i]);
  check_reduction_macro (int, max, -1, array[i]);
}

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

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

	* testsuite/libgomp.oacc-c-c++-common/reduction-1.c (DO_PRAGMA)
	(check_reduction_op, check_reduction_macro, max, min):
	Declare.
	(test_reductions_int, test_reductions_minmax, test_reductions_bool): New
	function.
	(main): Use new functions.
---
 .../libgomp.oacc-c-c++-common/reduction-1.c        | 223 +++++++--------------
 1 file changed, 76 insertions(+), 147 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..4501f8e 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,97 @@ 
 
 #define vl 32
 
-int
-main(void)
+#define DO_PRAGMA(x) _Pragma (#x)
+
+#define check_reduction_op(type, op, init, b)	\
+  {						\
+    type res, vres;				\
+    res = (init);				\
+DO_PRAGMA (acc parallel vector_length (vl))\
+DO_PRAGMA (acc loop reduction (op:res))\
+    for (i = 0; i < n; i++)			\
+      res = res op (b);				\
+						\
+    vres = (init);				\
+    for (i = 0; i < n; i++)			\
+      vres = vres op (b);			\
+						\
+    if (res != vres)				\
+      abort ();					\
+  }
+
+static void
+test_reductions_int (void)
 {
   const int n = 1000;
   int i;
-  int vresult, result, array[n];
-  bool lvresult, lresult;
+  int array[n];
 
   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;
-
-  lresult = false;
-  lvresult = false;
+  check_reduction_op (int, +, 0, array[i]);
+  check_reduction_op (int, *, 1, array[i]);
+  check_reduction_op (int, &, -1, array[i]);
+  check_reduction_op (int, |, 0, array[i]);
+  check_reduction_op (int, ^, 0, array[i]);
+}
 
-  /* '&&' 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];
+  int cmp_val;
 
-  /* Verify the reduction.  */
   for (i = 0; i < n; i++)
-    lvresult = lresult && (result > array[i]);
-
-  if (lresult != lvresult)
-    abort ();
-
-  result = 5;
-  vresult = 5;
+    array[i] = i;
 
-  lresult = false;
-  lvresult = false;
+  cmp_val = 5;
+  check_reduction_op (bool, &&, true, (cmp_val > array[i]));
+  check_reduction_op (bool, ||, false, (cmp_val > array[i]));
+}
 
-  /* '||' reductions.  */
-#pragma acc parallel vector_length (vl)
-#pragma acc loop reduction (||:lresult)
-  for (i = 0; i < n; i++)
-    lresult = lresult || (result > array[i]);
+#define check_reduction_macro(type, op, init, b)	\
+  {							\
+    type res, vres;					\
+    res = (init);					\
+DO_PRAGMA (acc parallel vector_length (vl))\
+DO_PRAGMA (acc loop reduction (op:res))\
+    for (i = 0; i < n; i++)				\
+      res = op (res, (b));				\
+							\
+    vres = (init);					\
+    for (i = 0; i < n; i++)				\
+      vres = op (vres, (b));				\
+							\
+    if (res != vres)					\
+      abort ();						\
+  }
+
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+static void
+test_reductions_minmax (void)
+{
+  const int n = 1000;
+  int i;
+  int array[n];
 
-  /* Verify the reduction.  */
   for (i = 0; i < n; i++)
-    lvresult = lresult || (result > array[i]);
+    array[i] = i;
 
-  if (lresult != lvresult)
-    abort ();
+  check_reduction_macro (int, min, n + 1, array[i]);
+  check_reduction_macro (int, max, -1, array[i]);
+}
 
+int
+main (void)
+{
+  test_reductions_int ();
+  test_reductions_bool ();
+  test_reductions_minmax ();
   return 0;
 }
-- 
1.9.1