00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
00104 typename T::PETE_Expr_t expr ( const_expr.PETE_unwrap().MakeExpression() );
00105
00106
00107 typedef typename T::PETE_Return_t R;
00108 ReduceLoc< R, NDIndex<D> > global_rloc;
00109
00110
00111
00112
00113 int n = for_each(expr,PETE_CountElems(),AssertEquals());
00114 if (n > 0) {
00115
00116 R ret = for_each(expr,EvalFunctor_0());
00117
00118
00119 FindLocation<D> find_loc(loc);
00120
00121
00122 for_each(expr,find_loc,PETE_NullCombiner());
00123
00124
00125 for (int i=1; i<n; ++i) {
00126
00127 for_each(expr,PETE_Increment(),PETE_NullCombiner());
00128
00129 R val = for_each(expr,EvalFunctor_0());
00130 if ( PETE_apply(comp_op,val,ret) ) {
00131
00132 ret = val;
00133
00134 for_each(expr,find_loc,PETE_NullCombiner());
00135 }
00136 }
00137
00138
00139 ReduceLoc< R, NDIndex<D> > rloc( ret , loc );
00140 reduce_masked(rloc, global_rloc, acc_op, true);
00141 } else {
00142
00143 reduce_masked(global_rloc, global_rloc, acc_op, false);
00144 }
00145
00146
00147 loc = global_rloc.Loc;
00148 return global_rloc.Val;
00149 }
00150
00151
00152
00153
00154
00155