src/Field/ReductionLoc.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // include files
00027 #include "Field/ReductionLoc.h"
00028 #include "Index/NDIndex.h"
00029 #include "Field/AssignDefs.h"
00030 #include "Message/Message.h"
00031 #include "Message/GlobalComm.h"
00032 
00033 
00035 //
00036 // Reduce and find the location.
00037 //
00039 
00040 template<class T, class LOC>
00041 struct ReduceLoc
00042 {
00043   T Val;
00044   LOC Loc;
00045   ReduceLoc() {}
00046   ReduceLoc(const T& t, const LOC& l) : Val(t), Loc(l) {}
00047   Message& putMessage(Message& mess)
00048     {
00049       ::putMessage(mess,Val);      
00050       ::putMessage(mess,Loc);      
00051       return mess;
00052     }
00053   Message& getMessage(Message& mess)
00054     {
00055       ::getMessage(mess,Val);      
00056       ::getMessage(mess,Loc);
00057       return mess;
00058     }
00059   bool operator<(const ReduceLoc<T,LOC>& rhs) const
00060     {
00061       return Val < rhs.Val;
00062     }
00063 };
00064 
00065 template <class T1, class T2, class LOC>
00066 inline
00067 ReduceLoc<typename PETEBinaryReturn<T1,T2,FnMin>::type, LOC>
00068 Min(const ReduceLoc<T1,LOC>& lhs, const ReduceLoc<T2,LOC>& rhs)
00069 {
00070   typedef typename PETEBinaryReturn<T1,T2,FnMin>::type T0;
00071   if (lhs < rhs)
00072     return ReduceLoc<T0,LOC>(lhs.Val,lhs.Loc);
00073   else
00074     return ReduceLoc<T0,LOC>(rhs.Val,rhs.Loc);
00075 }
00076 
00077 template <class T1, class T2, class LOC>
00078 inline
00079 ReduceLoc<typename PETEBinaryReturn<T1,T2,FnMax>::type, LOC>
00080 Max(const ReduceLoc<T1,LOC>& lhs, const ReduceLoc<T2,LOC>& rhs)
00081 {
00082   typedef typename PETEBinaryReturn<T1,T2,FnMax>::type T0;
00083   if (lhs < rhs)
00084     return ReduceLoc<T0,LOC>(rhs.Val,rhs.Loc);
00085   else
00086     return ReduceLoc<T0,LOC>(lhs.Val,lhs.Loc);
00087 }
00088 
00089 
00090 
00091 
00092 template<class T, class CompOp, class AccOp, unsigned D>
00093 typename T::PETE_Return_t
00094 Reduction(const PETE_Expr<T>& const_expr,
00095           CompOp comp_op,
00096           AccOp  acc_op,
00097           NDIndex<D>& loc)
00098 {
00099   TAU_TYPE_STRING(taustr, "T::PETE_Return_t (" + CT(const_expr) + ", " + CT(acc_op) 
00100     + ", " + CT(loc) + " )" );
00101   TAU_PROFILE("Reduction()", taustr, TAU_FIELD);
00102   
00103   // Extract the expression. 
00104   typename T::PETE_Expr_t expr ( const_expr.PETE_unwrap().MakeExpression() );
00105 
00106   // The type and value that we will return. 
00107   typedef typename T::PETE_Return_t R;
00108   ReduceLoc< R, NDIndex<D> > global_rloc;
00109 
00110   // Get the number of elements we will be looping over. 
00111   // The combiner makes sure each term has 
00112   // the same number of elements. 
00113   int n = for_each(expr,PETE_CountElems(),AssertEquals());
00114   if (n > 0) {
00115     // Get the first value. 
00116     R ret = for_each(expr,EvalFunctor_0());
00117 
00118     // Make an operator that will store the location in loc.
00119     FindLocation<D> find_loc(loc);
00120 
00121     // Get the first location. 
00122     for_each(expr,find_loc,PETE_NullCombiner());
00123 
00124     // Loop over all the local elements. 
00125     for (int i=1; i<n; ++i) {
00126       // Increment the pointers. 
00127       for_each(expr,PETE_Increment(),PETE_NullCombiner());
00128       // check and see if this is the new min. 
00129       R val = for_each(expr,EvalFunctor_0());
00130       if ( PETE_apply(comp_op,val,ret) ) {
00131         // Record the value.
00132         ret = val;
00133         // Record the current location.
00134         for_each(expr,find_loc,PETE_NullCombiner());
00135       }
00136     }
00137 
00138     // Do the cross processor reduction.
00139     ReduceLoc< R, NDIndex<D> > rloc( ret , loc );
00140     reduce_masked(rloc, global_rloc, acc_op, true);
00141   } else {
00142     // do reduction, but indicate we have no local contribution
00143     reduce_masked(global_rloc, global_rloc, acc_op, false);
00144   }
00145 
00146   // Return the calculated values
00147   loc = global_rloc.Loc;
00148   return global_rloc.Val;
00149 }
00150 
00151 /***************************************************************************
00152  * $RCSfile: ReductionLoc.cpp,v $   $Author: adelmann $
00153  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:26 $
00154  * IPPL_VERSION_ID: $Id: ReductionLoc.cpp,v 1.1.1.1 2003/01/23 07:40:26 adelmann Exp $ 
00155  ***************************************************************************/

Generated on Mon Jan 16 13:23:46 2006 for IPPL by  doxygen 1.4.6