[PATCH] Support reductions over where(), 2nd try

Jeffrey D. Oldham oldham at codesourcery.com
Fri Nov 21 21:23:37 UTC 2003


Richard Guenther wrote:
> Hi!
> 
> This version doesnt break any use of where as the first version did.
> Double-checked with a full build and regression test using Intel
> icpc 8.0 in -ansi mode.
> 
> This also adds the where cases I broke with the first patch to the
> array and field tests.
> 
> Ok?

Yes, but see the correction and three suggestions below.

> Richard.
> 
> 
> 2003Nov21  Richard Guenther <richard.guenther at uni-tuebingen.de>
> 
> 	* src/Evaluator/WhereProxy.h: support reduction over
> 	WhereProxy<> objects by adding Element_t.
> 	src/Evaluator/OpMask.h: Add ReductionTraits<> specialization
> 	for OpMask<T>, add Unwrap<> to unwrap OpMask<>.
> 	src/Engine/RemoteEngine.h: use unwrapped Op for final
> 	reduction over patch results.
> 	src/Evaluator/Reduction.h: likewise. Add evaluate() method
> 	handling WhereProxy to main evaluator.
> 	src/Array/tests/array_test12.cpp: Add where reduction testcases.
> 	src/Field/tests/WhereTest.cpp: likewise.
> 
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Array/tests/array_test12.cpp,v
> retrieving revision 1.13
> diff -u -u -r1.13 array_test12.cpp
> --- Array/tests/array_test12.cpp	10 Mar 2000 18:10:45 -0000	1.13
> +++ Array/tests/array_test12.cpp	21 Nov 2003 20:30:07 -0000
> @@ -109,6 +109,11 @@
>    tester.out() << std::endl;
>    tester.check("d2 < 0.000001", d2 < 0.000001);
> 
> +  int cnt = sum(where(d == 0.0, 1));
> +  tester.check("couting zeros with where reduction", cnt == 6);

s/couting/counting/

> +
> +  tester.check("where reduction", prod(where(d == 0.0, d)) == 0.0);
> +
>    int ret = tester.results("array_test12");
>    Pooma::finalize();
>    return ret;
> Index: Engine/RemoteEngine.h
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Engine/RemoteEngine.h,v
> retrieving revision 1.37
> diff -u -u -r1.37 RemoteEngine.h
> --- Engine/RemoteEngine.h	22 Oct 2003 19:38:07 -0000	1.37
> +++ Engine/RemoteEngine.h	21 Nov 2003 20:30:08 -0000
> @@ -2069,7 +2069,7 @@
>        {
>  	ret = vals[0];
>  	for (j = 1; j < n; j++)
> -	  op(ret, vals[j]);
> +	  Unwrap<Op>::unwrap(op)(ret, vals[j]);
>        }
> 
>      delete [] vals;
> Index: Evaluator/OpMask.h
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Evaluator/OpMask.h,v
> retrieving revision 1.20
> diff -u -u -r1.20 OpMask.h
> --- Evaluator/OpMask.h	22 Oct 2003 20:43:26 -0000	1.20
> +++ Evaluator/OpMask.h	21 Nov 2003 20:30:08 -0000
> @@ -169,6 +169,28 @@
>    typedef T1 &Type_t;
>  };
> 
> +template <class Op>
> +struct Unwrap {
> +  typedef Op Op_t;
> +  static inline const Op_t& unwrap(const Op &op) { return op; }
> +};
> +
> +template <class Op>
> +struct Unwrap<OpMask<Op> > {
> +  typedef typename Unwrap<Op>::Op_t Op_t;
> +  static inline const Op_t& unwrap(const OpMask<Op> &op) { return Unwrap<Op>::unwrap(op.op_m); }
> +};
> +
> +template <class Op, class T>
> +struct ReductionTraits;
> +
> +template <class Op, class T>
> +struct ReductionTraits<OpMask<Op>, T>
> +{
> +  static T identity() { return ReductionTraits<Op, T>::identity(); }
> +};
> +
> +
>  //-----------------------------------------------------------------------------
>  //
>  //-----------------------------------------------------------------------------
> Index: Evaluator/Reduction.h
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Evaluator/Reduction.h,v
> retrieving revision 1.12
> diff -u -u -r1.12 Reduction.h
> --- Evaluator/Reduction.h	21 Nov 2003 17:36:10 -0000	1.12
> +++ Evaluator/Reduction.h	21 Nov 2003 20:30:08 -0000
> @@ -53,7 +53,9 @@
>  #include "Engine/IntersectEngine.h"
>  #include "Evaluator/ReductionKernel.h"
>  #include "Evaluator/EvaluatorTags.h"
> +#include "Evaluator/WhereProxy.h"
>  #include "Threads/PoomaCSem.h"
> +#include "Utilities/PerformUpdate.h"
> 
>  #include <vector>
>  #include <iterator>
> @@ -109,6 +111,14 @@
>      return e.centeringSize() == 1 && e.numMaterials() == 1;
>    }
> 
> +  /// Un-wrap where() expression operation and pass on to generic evaluator.
> +
> +  template<class T, class Op, class Cond, class Expr>
> +  void evaluate(T &ret, const Op &op, const WhereProxy<Cond, Expr> &w) const
> +  {
> +    evaluate(ret, w.opMask(op), w.whereMask());
> +  }
> +
>    /// Input an expression and cause it to be reduced.
>    /// We just pass the buck to a special reduction after updating
>    /// the expression leafs and checking its validity (we can handle
> @@ -249,7 +259,7 @@
> 
>      ret = vals[0];
>      for (j = 1; j < n; j++)
> -      op(ret, vals[j]);
> +      Unwrap<Op>::unwrap(op)(ret, vals[j]);
>      delete [] vals;
>    }
>  };
> Index: Evaluator/WhereProxy.h
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Evaluator/WhereProxy.h,v
> retrieving revision 1.5
> diff -u -u -r1.5 WhereProxy.h
> --- Evaluator/WhereProxy.h	22 Oct 2003 20:43:26 -0000	1.5
> +++ Evaluator/WhereProxy.h	21 Nov 2003 20:30:08 -0000
> @@ -48,6 +48,7 @@
> 
>  #include "Evaluator/OpMask.h"
>  #include "Pooma/PETE/ExpressionTraits.h"
> +#include "Engine/ExpressionEngine.h"
> 
>  //-----------------------------------------------------------------------------
>  /// We need the tools to convert a WhereProxy into an Array or Field or
> @@ -84,6 +85,8 @@
>    typedef typename ExpressionTraits<Tree_t>::Type_t           ETrait_t;
>    typedef typename ConvertWhereProxy<ETrait_t,Tree_t>::Make_t MakeFromTree_t;
>    typedef typename MakeFromTree_t::Expression_t               WhereMask_t;
> +  typedef typename ForEach<typename CreateLeaf<B>::Leaf_t,
> +			   EvalLeaf<1>, OpCombine>::Type_t    Element_t;
> 
>    inline WhereMask_t
>    whereMask() const
> Index: Field/tests/WhereTest.cpp
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Field/tests/WhereTest.cpp,v
> retrieving revision 1.2
> diff -u -u -r1.2 WhereTest.cpp
> --- Field/tests/WhereTest.cpp	23 Jan 2003 19:21:49 -0000	1.2
> +++ Field/tests/WhereTest.cpp	21 Nov 2003 20:30:09 -0000
> @@ -86,6 +86,7 @@
>    // Now, we can declare a field.
> 
>    Centering<2> allFace = canonicalCentering<2>(FaceType, Continuous);
> +  Centering<2> allCell = canonicalCentering<2>(CellType, Continuous);
> 
>    typedef UniformRectilinearMesh<2> Geometry_t;
> 
> @@ -103,6 +104,9 @@
>    Field_t a(allFace, layout, origin, spacings);
>    Field_t b(allFace, layout, origin, spacings);
>    Field_t c(allFace, layout, origin, spacings);
> +  Field_t d(allCell, layout, origin, spacings);
> +  Field_t e(allCell, layout, origin, spacings);
> +  Field_t f(allCell, layout, origin, spacings);
> 
>    PositionsTraits<Geometry_t>::Type_t x = positions(a);
> 
> @@ -154,6 +158,43 @@
>    tester.check("twoarg where result dirtied part, centering one",
>                 all(where(dot(x.subField(0, 1), line) > 8.0,
>                     b.subField(0, 1), c.subField(0, 1)) == a.subField(0, 1)));
> +
> +  // 2-arg where reduction
> +
> +  d = 1.0;
> +  e = positions(e).read(e.physicalDomain()).comp(0);
> +  tester.check("reduction over twoarg where",
> +	       sum(where(e(e.physicalDomain()) < 4.0, d)) == 4.0*9.0);
> +
> +  // 3-arg where reduction
> +
> +  d = 1.0;
> +  f = 0.0;
> +  e = positions(e).read(e.physicalDomain()).comp(0);
> +  tester.check("reduction over twoarg where",
> +	       sum(where(e(e.physicalDomain()) < 4.0, d, f)) == 4.0*9.0);
> +
> +  // 2-arg where with scalar expression and reduction variant thereof
> +
> +  d = where(e(e.physicalDomain()) >= 4.0, 0.0);
> +  tester.check("counting reduction",
> +	       sum(where(d(d.physicalDomain()) != 0.0, 1)) == 4*9);
> +
> +  // 2-arg where with scalar test and reduction variant thereof
> +
> +  d = where(true, f);
> +  tester.check("stupid where", all(d(d.physicalDomain()) == 0.0));
> +  tester.check("stupid where reduction", prod(where(true, d)) == 0.0);

I would prefer to use the word "simple", not "stupid".

> +
> +  // note that where with both expression and test being scalar does not
> +  // work because of
> +  // src/Pooma/PETE/ExpressionTraits.h:121:
> +  // error: no type named `Type_t' in
> +  //        `struct CombineExpressionTraits<ExpressionIsScalar, ExpressionIsScalar>'
> +  // and that is probably not the only reason.
> +  //
> +  // d = where(true, 1.0);
> +  // tester.check("even more stupid where", all(d(d.physicalDomain()) == 1.0));

Likewise.

> 
>    int ret = tester.results("WhereTest");
>    Pooma::finalize();


-- 
Jeffrey D. Oldham
oldham at codesourcery.com




More information about the pooma-dev mailing list