forked from N-BodyShop/changa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Reductions.cpp
129 lines (105 loc) · 4.23 KB
/
Reductions.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/** @file Reductions.cpp
*/
#include "Reductions.h"
#include "OrientedBox.h"
#include "dumpframe.h"
CkReduction::reducerType growOrientedBox_float;
CkReduction::reducerType growOrientedBox_double;
CkReduction::reducerType minmax_int;
CkReduction::reducerType minmax_long;
CkReduction::reducerType minmax_float;
CkReduction::reducerType minmax_double;
CkReduction::reducerType max_count;
CkReduction::reducerType callbackReduction;
CkReduction::reducerType boxReduction;
CkReduction::reducerType dfImageReduction;
/// Combine reduction messages to grow a box
template <typename T>
CkReductionMsg* boxGrowth(int nMsg, CkReductionMsg** msgs) {
CkAssert(msgs[0]->getSize() == sizeof(OrientedBox<T>));
OrientedBox<T>* pbox = static_cast<OrientedBox<T> *>(msgs[0]->getData());
OrientedBox<T>* msgpbox;
for(int i = 1; i < nMsg; i++) {
CkAssert(msgs[i]->getSize() == sizeof(OrientedBox<T>));
msgpbox = static_cast<OrientedBox<T> *>(msgs[i]->getData());
pbox->grow(*msgpbox);
}
return CkReductionMsg::buildNew(sizeof(OrientedBox<T>), pbox);
}
/// Combine reduction messages to get min/max pair
template <typename T>
CkReductionMsg* minmax(int nMsg, CkReductionMsg** msgs) {
T* pminmax = static_cast<T *>(msgs[0]->getData());
T* msgpminmax;
for(int i = 1; i < nMsg; i++) {
msgpminmax = static_cast<T *>(msgs[i]->getData());
if(msgpminmax[0] < pminmax[0])
pminmax[0] = msgpminmax[0];
if(msgpminmax[1] > pminmax[1])
pminmax[1] = msgpminmax[1];
}
return CkReductionMsg::buildNew(2 * sizeof(T), pminmax);
}
/// Reduction for determining both the maximum timestep rung
/// (iMaxRung) and the number of particles in that rung (nMaxRung).
///
CkReductionMsg* max_count_reduce(int nMsg, CkReductionMsg** msgs) {
int64_t* pmaxcount = static_cast<int64_t *>(msgs[0]->getData());
int iMaxRung = pmaxcount[0]; // maxmimum rung
int64_t nMaxRung = pmaxcount[1]; // count in maximum rung
int iMaxRungGas = pmaxcount[2]; // maximum rung for gas
for(int i = 1; i < nMsg; i++) {
pmaxcount = static_cast<int64_t *>(msgs[i]->getData());
if(pmaxcount[0] > iMaxRung) {
iMaxRung = pmaxcount[0];
nMaxRung = pmaxcount[1];
}
else if(pmaxcount[0] == iMaxRung) {
nMaxRung += pmaxcount[1];
}
if(pmaxcount[2] > iMaxRungGas) {
iMaxRungGas = pmaxcount[2];
}
}
int64_t newcount[3];
newcount[0] = iMaxRung;
newcount[1] = nMaxRung;
newcount[2] = iMaxRungGas;
return CkReductionMsg::buildNew(3 * sizeof(int64_t), newcount);
}
/// Return a single object, given many copies of it
template <typename T>
CkReductionMsg* same(int nMsg, CkReductionMsg** msgs) {
return CkReductionMsg::buildNew(sizeof(T), static_cast<T *>(msgs[0]->getData()));
}
/// Merge images for DumpFrame
/// Messages consist of a struct inDumpFrame header followed by the
/// image data.
CkReductionMsg* dfImageReducer(int nMsg, CkReductionMsg** msgs) {
struct inDumpFrame *in = (struct inDumpFrame *)msgs[0]->getData();
int nImage1 = in->nxPix*in->nyPix*sizeof(DFIMAGE);
CkAssert(msgs[0]->getSize() == (sizeof(struct inDumpFrame) + nImage1));
void *ImageOut = ((char *)msgs[0]->getData()) + sizeof(struct inDumpFrame);
for(int i = 1; i < nMsg; i++) {
void *Image2 = ((char *)msgs[i]->getData())
+ sizeof(struct inDumpFrame);
int nImage2 = in->nxPix*in->nyPix*sizeof(DFIMAGE);
CkAssert(msgs[i]->getSize() == (sizeof(struct inDumpFrame) + nImage2));
dfMergeImage( in, ImageOut, &nImage1, Image2, &nImage2);
}
return CkReductionMsg::buildNew(msgs[0]->getSize(), msgs[0]->getData());
}
/// Create custom reducers in the charm runtime.
void registerReductions() {
growOrientedBox_float = CkReduction::addReducer(boxGrowth<float>);
growOrientedBox_double = CkReduction::addReducer(boxGrowth<double>);
minmax_int = CkReduction::addReducer(minmax<int>);
minmax_long = CkReduction::addReducer(minmax<int64_t>);
minmax_float = CkReduction::addReducer(minmax<float>);
minmax_double = CkReduction::addReducer(minmax<double>);
max_count = CkReduction::addReducer(max_count_reduce);
callbackReduction = CkReduction::addReducer(same<CkCallback>);
boxReduction = CkReduction::addReducer(same<OrientedBox<float> >);
dfImageReduction = CkReduction::addReducer(dfImageReducer);
}
#include "Reductions.def.h"