00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __GALOIS_ACCUMULATOR_H
00021 #define __GALOIS_ACCUMULATOR_H
00022
00023 #include "Galois/Runtime/PerCPU.h"
00024 #include <boost/function.hpp>
00025
00026 namespace Galois {
00027
00038 template <typename T, typename BinFunc>
00039 class GReducible: public GaloisRuntime::ThreadAware {
00040 BinFunc _func;
00041 GaloisRuntime::PerCPU<T> _data;
00042
00043 void reduce() {
00044 T& d0 = _data.get(0);
00045 for (unsigned int i = 1; i < _data.size(); ++i)
00046 _func(d0, _data.get(i));
00047 }
00048
00049 virtual void ThreadChange(bool starting) {
00050 if (!starting)
00051 reduce();
00052 }
00053
00054 public:
00058 explicit GReducible (const T& val)
00059 : _data(val) { }
00063 explicit GReducible (BinFunc F)
00064 : _func(F) { }
00069 GReducible (const T val, BinFunc F)
00070 : _func(F), _data(val) { }
00071
00072 GReducible () {}
00073
00081 const T& update (const T& _newVal) {
00082 T& lhs = _data.get();
00083 _func(lhs, _newVal);
00084 return lhs;
00085 }
00086
00091 T& get() {
00092 return _data.get();
00093 }
00094
00100 void reset(const T& d) {
00101 _data.reset(d);
00102 }
00103 };
00104
00105
00106
00107
00108 template<typename BinFunc>
00109 struct ReduceAssignWrap {
00110 BinFunc F;
00111 ReduceAssignWrap(BinFunc f = BinFunc()) :F(f) {}
00112 template<typename T>
00113 void operator()(T& lhs, const T& rhs) {
00114 lhs = F(lhs, rhs);
00115 }
00116 };
00117
00118 template<typename T>
00119 class GAccumulator : public GReducible<T, ReduceAssignWrap<std::plus<T> > > {
00120 typedef GReducible<T, ReduceAssignWrap<std::plus<T> > > SuperType;
00121 public:
00122 explicit GAccumulator (const T& val = T()): SuperType(val) {}
00123
00124 GAccumulator& operator+=(const T& rhs) {
00125 update(rhs);
00126 return *this;
00127 }
00128
00129 GAccumulator& operator-=(const T& rhs) {
00130 update(-rhs);
00131 return *this;
00132 }
00133 };
00134
00135 namespace HIDDEN {
00136 template<typename T>
00137 struct gmax {
00138 void operator()(T& lhs, const T& rhs) const {
00139 lhs = std::max(lhs,rhs);
00140 }
00141 };
00142 }
00143
00144 template<typename T>
00145 class GReduceMax : public GReducible<T, HIDDEN::gmax<T> > {};
00146
00147 template<typename T>
00148 class GReduceAverage {
00149 typedef std::pair<T, unsigned> TP;
00150 struct AVG {
00151 void operator() (TP& lhs, const TP& rhs) const {
00152 lhs.first += rhs.first;
00153 lhs.second += rhs.second;
00154 }
00155 };
00156 GReducible<std::pair<T, unsigned>, AVG> data;
00157 public:
00158 void update (const T& _newVal) {
00159 data.update(std::make_pair(_newVal, 1));
00160 }
00161
00166 const T get() {
00167 const TP& d = data.get();
00168 return d.first / d.second;
00169 }
00170
00171 void reset(const T& d) {
00172 data.reset(std::make_pair(d, 0));
00173 }
00174
00175 GReduceAverage& insert(const T& rhs) {
00176 TP& d = data.get();
00177 d.first += rhs;
00178 d.second++;
00179 return *this;
00180 }
00181 };
00182
00183 }
00184
00185 #endif