1 | #ifndef included_ALE_ParallelMapping_hh
|
---|
2 | #define included_ALE_ParallelMapping_hh
|
---|
3 |
|
---|
4 | #ifndef included_ALE_BasicCommunication_hh
|
---|
5 | #include <sieve/BasicCommunication.hh>
|
---|
6 | #endif
|
---|
7 |
|
---|
8 | #ifndef included_ALE_IField_hh
|
---|
9 | #include <sieve/IField.hh>
|
---|
10 | #endif
|
---|
11 |
|
---|
12 | #ifndef included_ALE_Sections_hh
|
---|
13 | #include <sieve/Sections.hh>
|
---|
14 | #endif
|
---|
15 |
|
---|
16 | #include <functional>
|
---|
17 | #include <valarray>
|
---|
18 |
|
---|
19 | namespace ALE {
|
---|
20 | template<class _Tp>
|
---|
21 | struct Identity : public std::unary_function<_Tp,_Tp>
|
---|
22 | {
|
---|
23 | _Tp& operator()(_Tp& x) const {return x;}
|
---|
24 | const _Tp& operator()(const _Tp& x) const {return x;}
|
---|
25 | };
|
---|
26 |
|
---|
27 | template<class _Tp>
|
---|
28 | struct IsEqual : public std::unary_function<_Tp, bool>, public std::binary_function<_Tp, _Tp, bool>
|
---|
29 | {
|
---|
30 | const _Tp& x;
|
---|
31 | IsEqual(const _Tp& x) : x(x) {};
|
---|
32 | bool operator()(_Tp& y) const {return x == y;}
|
---|
33 | bool operator()(const _Tp& y) const {return x == y;}
|
---|
34 | bool operator()(_Tp& y, _Tp& dummy) const {return x == y;}
|
---|
35 | bool operator()(const _Tp& y, const _Tp& dummy) const {return x == y;}
|
---|
36 | };
|
---|
37 |
|
---|
38 | // Creates new global point names and renames local points globally
|
---|
39 | template<typename Point>
|
---|
40 | class PointFactory : ALE::ParallelObject {
|
---|
41 | public:
|
---|
42 | typedef Point point_type;
|
---|
43 | typedef std::map<point_type,point_type> renumbering_type;
|
---|
44 | typedef std::map<int,std::map<point_type,point_type> > remote_renumbering_type;
|
---|
45 | protected:
|
---|
46 | point_type originalMax;
|
---|
47 | point_type currentMax;
|
---|
48 | renumbering_type renumbering;
|
---|
49 | renumbering_type invRenumbering;
|
---|
50 | remote_renumbering_type remoteRenumbering;
|
---|
51 | protected:
|
---|
52 | PointFactory(MPI_Comm comm, const int debug = 0) : ALE::ParallelObject(comm, debug), originalMax(-1) {};
|
---|
53 | public:
|
---|
54 | ~PointFactory() {};
|
---|
55 | public:
|
---|
56 | static PointFactory& singleton(MPI_Comm comm, const point_type& maxPoint, const int debug = 0, bool cleanup = false) {
|
---|
57 | static PointFactory *_singleton = NULL;
|
---|
58 |
|
---|
59 | if (cleanup) {
|
---|
60 | if (debug) {std::cout << "Destroying PointFactory" << std::endl;}
|
---|
61 | if (_singleton) {delete _singleton;}
|
---|
62 | _singleton = NULL;
|
---|
63 | } else if (_singleton == NULL) {
|
---|
64 | if (debug) {std::cout << "Creating new PointFactory" << std::endl;}
|
---|
65 | _singleton = new PointFactory(comm, debug);
|
---|
66 | _singleton->setMax(maxPoint);
|
---|
67 | }
|
---|
68 | return *_singleton;
|
---|
69 | };
|
---|
70 | void setMax(const point_type& maxPoint) {
|
---|
71 | PetscErrorCode ierr = MPI_Allreduce((void *) &maxPoint, &this->originalMax, 1, MPI_INT, MPI_MAX, this->comm());CHKERRXX(ierr);
|
---|
72 | ++this->originalMax;
|
---|
73 | this->currentMax = this->originalMax;
|
---|
74 | };
|
---|
75 | void clear() {
|
---|
76 | this->currentMax = this->originalMax;
|
---|
77 | this->renumbering.clear();
|
---|
78 | this->invRenumbering.clear();
|
---|
79 | };
|
---|
80 | public:
|
---|
81 | template<typename Iterator>
|
---|
82 | void renumberPoints(const Iterator& begin, const Iterator& end) {
|
---|
83 | renumberPoints(begin, end, Identity<typename Iterator::value_type>());
|
---|
84 | }
|
---|
85 | template<typename Iterator, typename KeyExtractor>
|
---|
86 | void renumberPoints(const Iterator& begin, const Iterator& end, const KeyExtractor& ex) {
|
---|
87 | int numPoints = 0, numGlobalPoints, firstPoint;
|
---|
88 |
|
---|
89 | for(Iterator p_iter = begin; p_iter != end; ++p_iter) ++numPoints;
|
---|
90 | MPI_Allreduce(&numPoints, &numGlobalPoints, 1, MPI_INT, MPI_SUM, this->comm());
|
---|
91 | MPI_Scan(&numPoints, &firstPoint, 1, MPI_INT, MPI_SUM, this->comm());
|
---|
92 | firstPoint += this->currentMax - numPoints;
|
---|
93 | this->currentMax += numGlobalPoints;
|
---|
94 | for(Iterator p_iter = begin; p_iter != end; ++p_iter, ++firstPoint) {
|
---|
95 | if (this->debug()) {std::cout << "["<<this->commRank()<<"]: New point " << ex(*p_iter) << " --> " << firstPoint << std::endl;}
|
---|
96 | this->renumbering[firstPoint] = ex(*p_iter);
|
---|
97 | this->invRenumbering[ex(*p_iter)] = firstPoint;
|
---|
98 | }
|
---|
99 | }
|
---|
100 | public:
|
---|
101 | void constructRemoteRenumbering() {
|
---|
102 | const int localSize = this->renumbering.size();
|
---|
103 | int *remoteSizes = new int[this->commSize()];
|
---|
104 | int *localMap = new int[localSize*2];
|
---|
105 | int *recvCounts = new int[this->commSize()];
|
---|
106 | int *displs = new int[this->commSize()];
|
---|
107 |
|
---|
108 | // Populate arrays
|
---|
109 | int r = 0;
|
---|
110 | for(typename renumbering_type::const_iterator r_iter = renumbering.begin(); r_iter != renumbering.end(); ++r_iter, ++r) {
|
---|
111 | localMap[r*2+0] = r_iter->first;
|
---|
112 | localMap[r*2+1] = r_iter->second;
|
---|
113 | }
|
---|
114 | // Communicate renumbering sizes
|
---|
115 | MPI_Allgather((void*) &localSize, 1, MPI_INT, remoteSizes, 1, MPI_INT, this->comm());
|
---|
116 | for(int p = 0; p < this->commSize(); ++p) {
|
---|
117 | recvCounts[p] = remoteSizes[p]*2;
|
---|
118 | if (p == 0) {
|
---|
119 | displs[p] = 0;
|
---|
120 | } else {
|
---|
121 | displs[p] = displs[p-1] + recvCounts[p-1];
|
---|
122 | }
|
---|
123 | }
|
---|
124 | int *remoteMaps = new int[displs[this->commSize()-1]+recvCounts[this->commSize()-1]];
|
---|
125 | // Communicate renumberings
|
---|
126 | MPI_Allgatherv(localMap, localSize*2, MPI_INT, remoteMaps, recvCounts, displs, MPI_INT, this->comm());
|
---|
127 | // Populate maps
|
---|
128 | for(int p = 0; p < this->commSize(); ++p) {
|
---|
129 | if (p == this->commRank()) continue;
|
---|
130 | int offset = displs[p];
|
---|
131 |
|
---|
132 | for(int r = 0; r < remoteSizes[p]; ++r) {
|
---|
133 | this->remoteRenumbering[p][remoteMaps[r*2+0+offset]] = remoteMaps[r*2+1+offset];
|
---|
134 | if (this->debug()) {std::cout << "["<<this->commRank()<<"]: Remote renumbering["<<p<<"] " << remoteMaps[r*2+0+offset] << " --> " << remoteMaps[r*2+1+offset] << std::endl;}
|
---|
135 | }
|
---|
136 | }
|
---|
137 | // Cleanup
|
---|
138 | delete [] recvCounts;
|
---|
139 | delete [] displs;
|
---|
140 | delete [] localMap;
|
---|
141 | delete [] remoteMaps;
|
---|
142 | delete [] remoteSizes;
|
---|
143 | };
|
---|
144 | public:
|
---|
145 | // global point --> local point
|
---|
146 | renumbering_type& getRenumbering() {
|
---|
147 | return this->renumbering;
|
---|
148 | };
|
---|
149 | // local point --> global point
|
---|
150 | renumbering_type& getInvRenumbering() {
|
---|
151 | return this->invRenumbering;
|
---|
152 | };
|
---|
153 | // rank --> global point --> local point
|
---|
154 | remote_renumbering_type& getRemoteRenumbering() {
|
---|
155 | return this->remoteRenumbering;
|
---|
156 | };
|
---|
157 | };
|
---|
158 |
|
---|
159 | template<typename Alloc_ = malloc_allocator<int> >
|
---|
160 | class OverlapBuilder {
|
---|
161 | public:
|
---|
162 | typedef Alloc_ alloc_type;
|
---|
163 | protected:
|
---|
164 | template<typename T>
|
---|
165 | struct lessPair: public std::binary_function<std::pair<T,T>, std::pair<T,T>, bool> {
|
---|
166 | bool operator()(const std::pair<T,T>& x, const std::pair<T,T>& y) const {
|
---|
167 | return x.first < y.first;
|
---|
168 | }
|
---|
169 | };
|
---|
170 | template<typename T>
|
---|
171 | struct mergePair: public std::binary_function<std::pair<T,T>, std::pair<T,T>, bool> {
|
---|
172 | std::pair<T,std::pair<T,T> > operator()(const std::pair<T,T>& x, const std::pair<T,T>& y) const {
|
---|
173 | return std::pair<T,std::pair<T,T> >(x.first, std::pair<T,T>(x.second, y.second));
|
---|
174 | }
|
---|
175 | };
|
---|
176 | template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare, typename _Merge>
|
---|
177 | static _OutputIterator set_intersection_merge(_InputIterator1 __first1, _InputIterator1 __last1,
|
---|
178 | _InputIterator2 __first2, _InputIterator2 __last2,
|
---|
179 | _OutputIterator __result, _Compare __comp, _Merge __merge)
|
---|
180 | {
|
---|
181 | while(__first1 != __last1 && __first2 != __last2) {
|
---|
182 | if (__comp(*__first1, *__first2))
|
---|
183 | ++__first1;
|
---|
184 | else if (__comp(*__first2, *__first1))
|
---|
185 | ++__first2;
|
---|
186 | else
|
---|
187 | {
|
---|
188 | *__result = __merge(*__first1, *__first2);
|
---|
189 | ++__first1;
|
---|
190 | ++__first2;
|
---|
191 | ++__result;
|
---|
192 | }
|
---|
193 | }
|
---|
194 | return __result;
|
---|
195 | }
|
---|
196 | public:
|
---|
197 | template<typename Sequence, typename Renumbering, typename SendOverlap, typename RecvOverlap>
|
---|
198 | static void constructOverlap(const Sequence& points, Renumbering& renumbering, const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap) {
|
---|
199 | typedef typename SendOverlap::source_type point_type;
|
---|
200 | typedef std::pair<point_type,point_type> pointPair;
|
---|
201 | typedef std::pair<point_type,pointPair> pointTriple;
|
---|
202 | alloc_type allocator;
|
---|
203 | typename alloc_type::template rebind<point_type>::other point_allocator;
|
---|
204 | typename alloc_type::template rebind<pointPair>::other pointPair_allocator;
|
---|
205 | const MPI_Comm comm = sendOverlap->comm();
|
---|
206 | const int commSize = sendOverlap->commSize();
|
---|
207 | const int commRank = sendOverlap->commRank();
|
---|
208 | point_type *sendBuf = point_allocator.allocate(points.size()*2);
|
---|
209 | for(size_t i = 0; i < points.size()*2; ++i) {point_allocator.construct(sendBuf+i, point_type());}
|
---|
210 | int size = 0;
|
---|
211 | const int debug = sendOverlap->debug();
|
---|
212 | for(typename Sequence::const_iterator l_iter = points.begin(); l_iter != points.end(); ++l_iter) {
|
---|
213 | if (debug) {std::cout << "["<<commRank<<"]Send point["<<size<<"]: " << *l_iter << " " << renumbering[*l_iter] << std::endl;}
|
---|
214 | sendBuf[size++] = *l_iter;
|
---|
215 | sendBuf[size++] = renumbering[*l_iter];
|
---|
216 | }
|
---|
217 | int *sizes = allocator.allocate(commSize*3+2); // [size] The number of points coming from each process
|
---|
218 | for(int i = 0; i < commSize*3+2; ++i) {allocator.construct(sizes+i, 0);}
|
---|
219 | int *offsets = sizes+commSize; // [size+1] Prefix sums for sizes
|
---|
220 | int *oldOffs = offsets+commSize+1; // [size+1] Temporary storage
|
---|
221 | pointPair *remotePoints = NULL; // The points from each process
|
---|
222 | int *remoteRanks = NULL; // The rank and number of overlap points of each process that overlaps another
|
---|
223 | int numRemotePoints = 0;
|
---|
224 | int numRemoteRanks = 0;
|
---|
225 |
|
---|
226 | // Change to Allgather() for the correct binning algorithm
|
---|
227 | MPI_Gather(&size, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm);
|
---|
228 | if (commRank == 0) {
|
---|
229 | offsets[0] = 0;
|
---|
230 | for(int p = 1; p <= commSize; p++) {
|
---|
231 | offsets[p] = offsets[p-1] + sizes[p-1];
|
---|
232 | }
|
---|
233 | numRemotePoints = offsets[commSize];
|
---|
234 | remotePoints = pointPair_allocator.allocate(numRemotePoints/2);
|
---|
235 | for(int i = 0; i < numRemotePoints/2; ++i) {pointPair_allocator.construct(remotePoints+i, pointPair());}
|
---|
236 | }
|
---|
237 | MPI_Gatherv(sendBuf, size, MPI_INT, remotePoints, sizes, offsets, MPI_INT, 0, comm);
|
---|
238 | for(size_t i = 0; i < points.size(); ++i) {point_allocator.destroy(sendBuf+i);}
|
---|
239 | point_allocator.deallocate(sendBuf, points.size());
|
---|
240 | std::map<int, std::map<int, std::set<pointTriple> > > overlapInfo; // Maps (p,q) to their set of overlap points
|
---|
241 |
|
---|
242 | if (commRank == 0) {
|
---|
243 | for(int p = 0; p <= commSize; p++) {
|
---|
244 | offsets[p] /= 2;
|
---|
245 | }
|
---|
246 | for(int p = 0; p < commSize; p++) {
|
---|
247 | std::sort(&remotePoints[offsets[p]], &remotePoints[offsets[p+1]], lessPair<point_type>());
|
---|
248 | }
|
---|
249 | for(int p = 0; p <= commSize; p++) {
|
---|
250 | oldOffs[p] = offsets[p];
|
---|
251 | }
|
---|
252 | for(int p = 0; p < commSize; p++) {
|
---|
253 | for(int q = 0; q < commSize; q++) {
|
---|
254 | if (p == q) continue;
|
---|
255 | set_intersection_merge(&remotePoints[oldOffs[p]], &remotePoints[oldOffs[p+1]],
|
---|
256 | &remotePoints[oldOffs[q]], &remotePoints[oldOffs[q+1]],
|
---|
257 | std::insert_iterator<std::set<pointTriple> >(overlapInfo[p][q], overlapInfo[p][q].begin()),
|
---|
258 | lessPair<point_type>(), mergePair<point_type>());
|
---|
259 | }
|
---|
260 | sizes[p] = overlapInfo[p].size()*2;
|
---|
261 | offsets[p+1] = offsets[p] + sizes[p];
|
---|
262 | }
|
---|
263 | numRemoteRanks = offsets[commSize];
|
---|
264 | remoteRanks = allocator.allocate(numRemoteRanks);
|
---|
265 | for(int i = 0; i < numRemoteRanks; ++i) {allocator.construct(remoteRanks+i, 0);}
|
---|
266 | int k = 0;
|
---|
267 | for(int p = 0; p < commSize; p++) {
|
---|
268 | for(typename std::map<int, std::set<pointTriple> >::iterator r_iter = overlapInfo[p].begin(); r_iter != overlapInfo[p].end(); ++r_iter) {
|
---|
269 | remoteRanks[k*2] = r_iter->first;
|
---|
270 | remoteRanks[k*2+1] = r_iter->second.size();
|
---|
271 | k++;
|
---|
272 | }
|
---|
273 | }
|
---|
274 | }
|
---|
275 | int numOverlaps; // The number of processes overlapping this process
|
---|
276 | MPI_Scatter(sizes, 1, MPI_INT, &numOverlaps, 1, MPI_INT, 0, comm);
|
---|
277 | int *overlapRanks = allocator.allocate(numOverlaps); // The rank and overlap size for each overlapping process
|
---|
278 | for(int i = 0; i < numOverlaps; ++i) {allocator.construct(overlapRanks+i, 0);}
|
---|
279 | MPI_Scatterv(remoteRanks, sizes, offsets, MPI_INT, overlapRanks, numOverlaps, MPI_INT, 0, comm);
|
---|
280 | point_type *sendPoints = NULL; // The points to send to each process
|
---|
281 | int numSendPoints = 0;
|
---|
282 | if (commRank == 0) {
|
---|
283 | for(int p = 0, k = 0; p < commSize; p++) {
|
---|
284 | sizes[p] = 0;
|
---|
285 | for(int r = 0; r < (int) overlapInfo[p].size(); r++) {
|
---|
286 | sizes[p] += remoteRanks[k*2+1]*2;
|
---|
287 | k++;
|
---|
288 | }
|
---|
289 | offsets[p+1] = offsets[p] + sizes[p];
|
---|
290 | }
|
---|
291 | numSendPoints = offsets[commSize];
|
---|
292 | sendPoints = point_allocator.allocate(numSendPoints*2);
|
---|
293 | for(int i = 0; i < numSendPoints*2; ++i) {point_allocator.construct(sendPoints+i, point_type());}
|
---|
294 | for(int p = 0, k = 0; p < commSize; p++) {
|
---|
295 | for(typename std::map<int, std::set<pointTriple> >::const_iterator r_iter = overlapInfo[p].begin(); r_iter != overlapInfo[p].end(); ++r_iter) {
|
---|
296 | int rank = r_iter->first;
|
---|
297 | for(typename std::set<pointTriple>::const_iterator p_iter = (overlapInfo[p][rank]).begin(); p_iter != (overlapInfo[p][rank]).end(); ++p_iter) {
|
---|
298 | sendPoints[k++] = p_iter->first;
|
---|
299 | sendPoints[k++] = p_iter->second.second;
|
---|
300 | if (debug) {std::cout << "["<<commRank<<"]Sending points " << p_iter->first << " " << p_iter->second.second << " to rank " << rank << std::endl;}
|
---|
301 | }
|
---|
302 | }
|
---|
303 | }
|
---|
304 | }
|
---|
305 | int numOverlapPoints = 0;
|
---|
306 | for(int r = 0; r < numOverlaps/2; r++) {
|
---|
307 | numOverlapPoints += overlapRanks[r*2+1];
|
---|
308 | }
|
---|
309 | point_type *overlapPoints = point_allocator.allocate(numOverlapPoints*2);
|
---|
310 | for(int i = 0; i < numOverlapPoints*2; ++i) {point_allocator.construct(overlapPoints+i, point_type());}
|
---|
311 | MPI_Scatterv(sendPoints, sizes, offsets, MPI_INT, overlapPoints, numOverlapPoints*2, MPI_INT, 0, comm);
|
---|
312 |
|
---|
313 | for(int r = 0, k = 0; r < numOverlaps/2; r++) {
|
---|
314 | int rank = overlapRanks[r*2];
|
---|
315 |
|
---|
316 | for(int p = 0; p < overlapRanks[r*2+1]; p++) {
|
---|
317 | point_type point = overlapPoints[k++];
|
---|
318 | point_type remotePoint = overlapPoints[k++];
|
---|
319 |
|
---|
320 | if (debug) {std::cout << "["<<commRank<<"]Matched up remote point " << remotePoint << "("<<point<<") to local " << renumbering[point] << std::endl;}
|
---|
321 | sendOverlap->addArrow(renumbering[point], rank, remotePoint);
|
---|
322 | recvOverlap->addArrow(rank, renumbering[point], remotePoint);
|
---|
323 | }
|
---|
324 | }
|
---|
325 |
|
---|
326 | for(int i = 0; i < numOverlapPoints; ++i) {point_allocator.destroy(overlapPoints+i);}
|
---|
327 | point_allocator.deallocate(overlapPoints, numOverlapPoints);
|
---|
328 | for(int i = 0; i < numOverlaps; ++i) {allocator.destroy(overlapRanks+i);}
|
---|
329 | allocator.deallocate(overlapRanks, numOverlaps);
|
---|
330 | for(int i = 0; i < commSize*3+2; ++i) {allocator.destroy(sizes+i);}
|
---|
331 | allocator.deallocate(sizes, commSize*3+2);
|
---|
332 | if (commRank == 0) {
|
---|
333 | for(int i = 0; i < numRemoteRanks; ++i) {allocator.destroy(remoteRanks+i);}
|
---|
334 | allocator.deallocate(remoteRanks, numRemoteRanks);
|
---|
335 | for(int i = 0; i < numRemotePoints; ++i) {pointPair_allocator.destroy(remotePoints+i);}
|
---|
336 | pointPair_allocator.deallocate(remotePoints, numRemotePoints);
|
---|
337 | for(int i = 0; i < numSendPoints; ++i) {point_allocator.destroy(sendPoints+i);}
|
---|
338 | point_allocator.deallocate(sendPoints, numSendPoints);
|
---|
339 | }
|
---|
340 | // TODO: Rewrite above to use optimized construction
|
---|
341 | sendOverlap->assemble();
|
---|
342 | recvOverlap->assemble();
|
---|
343 | sendOverlap->assemblePoints();
|
---|
344 | recvOverlap->assemblePoints();
|
---|
345 | }
|
---|
346 | };
|
---|
347 | namespace Pullback {
|
---|
348 | class SimpleCopy {
|
---|
349 | public:
|
---|
350 | // Copy the overlap section to the related processes
|
---|
351 | // This version is for Constant sections, meaning the same, single value over all points
|
---|
352 | template<typename SendOverlap, typename RecvOverlap, typename SendSection, typename RecvSection>
|
---|
353 | static void copyConstant(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<SendSection>& sendSection, const Obj<RecvSection>& recvSection) {
|
---|
354 | MPIMover<char> pMover(sendSection->comm(), sendSection->debug());
|
---|
355 | MPIMover<typename SendSection::value_type> vMover(sendSection->comm(), sendSection->debug());
|
---|
356 | std::map<int, char *> sendPoints;
|
---|
357 | std::map<int, char *> recvPoints;
|
---|
358 | typename SendSection::alloc_type::template rebind<char>::other sendAllocator;
|
---|
359 | typename RecvSection::alloc_type::template rebind<char>::other recvAllocator;
|
---|
360 |
|
---|
361 | const typename SendOverlap::baseSequence::iterator sBegin = sendOverlap->baseBegin();
|
---|
362 | const typename SendOverlap::baseSequence::iterator sEnd = sendOverlap->baseEnd();
|
---|
363 | const typename SendSection::value_type *sValues = sendSection->restrictSpace();
|
---|
364 |
|
---|
365 | for(typename SendOverlap::baseSequence::iterator r_iter = sBegin; r_iter != sEnd; ++r_iter) {
|
---|
366 | const int pSize = sendOverlap->getConeSize(*r_iter);
|
---|
367 | const typename SendOverlap::coneSequence::iterator pBegin = sendOverlap->coneBegin(*r_iter);
|
---|
368 | const typename SendOverlap::coneSequence::iterator pEnd = sendOverlap->coneEnd(*r_iter);
|
---|
369 | char *v = sendAllocator.allocate(pSize);
|
---|
370 | int k = 0;
|
---|
371 |
|
---|
372 | for(int i = 0; i < pSize; ++i) {sendAllocator.construct(v+i, 0);}
|
---|
373 | for(typename SendOverlap::coneSequence::iterator p_iter = pBegin; p_iter != pEnd; ++p_iter, ++k) {
|
---|
374 | v[k] = (char) sendSection->hasPoint(*p_iter);
|
---|
375 | }
|
---|
376 | sendPoints[*r_iter] = v;
|
---|
377 | pMover.send(*r_iter, pSize, sendPoints[*r_iter]);
|
---|
378 | vMover.send(*r_iter, 2, sValues);
|
---|
379 | }
|
---|
380 | const typename RecvOverlap::capSequence::iterator rBegin = recvOverlap->capBegin();
|
---|
381 | const typename RecvOverlap::capSequence::iterator rEnd = recvOverlap->capEnd();
|
---|
382 | const typename RecvSection::value_type *rValues = recvSection->restrictSpace();
|
---|
383 |
|
---|
384 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
385 | const int pSize = recvOverlap->getSupportSize(*r_iter);
|
---|
386 | char *v = recvAllocator.allocate(pSize);
|
---|
387 |
|
---|
388 | for(int i = 0; i < pSize; ++i) {recvAllocator.construct(v+i, 0);}
|
---|
389 | recvPoints[*r_iter] = v;
|
---|
390 | pMover.recv(*r_iter, pSize, recvPoints[*r_iter]);
|
---|
391 | vMover.recv(*r_iter, 2, rValues);
|
---|
392 | }
|
---|
393 | pMover.start();
|
---|
394 | pMover.end();
|
---|
395 | vMover.start();
|
---|
396 | vMover.end();
|
---|
397 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
398 | const typename RecvOverlap::supportSequence::iterator pBegin = recvOverlap->supportBegin(*r_iter);
|
---|
399 | const typename RecvOverlap::supportSequence::iterator pEnd = recvOverlap->supportEnd(*r_iter);
|
---|
400 | const char *v = recvPoints[*r_iter];
|
---|
401 | int k = 0;
|
---|
402 |
|
---|
403 | for(typename RecvOverlap::supportSequence::iterator s_iter = pBegin; s_iter != pEnd; ++s_iter, ++k) {
|
---|
404 | if (v[k]) {recvSection->addPoint(typename RecvSection::point_type(*r_iter, s_iter.color()));}
|
---|
405 | }
|
---|
406 | }
|
---|
407 | for(typename SendOverlap::baseSequence::iterator r_iter = sBegin; r_iter != sEnd; ++r_iter) {
|
---|
408 | sendAllocator.deallocate(sendPoints[*r_iter], sendOverlap->getConeSize(*r_iter));
|
---|
409 | }
|
---|
410 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
411 | recvAllocator.deallocate(recvPoints[*r_iter], recvOverlap->getSupportSize(*r_iter));
|
---|
412 | }
|
---|
413 | }
|
---|
414 | // Specialize to ArrowSection
|
---|
415 | template<typename SendOverlap, typename RecvOverlap, typename SendSection, typename RecvSection>
|
---|
416 | static void copyConstantArrow(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<SendSection>& sendSection, const Obj<RecvSection>& recvSection) {
|
---|
417 | MPIMover<char> pMover(sendSection->comm(), sendSection->debug());
|
---|
418 | MPIMover<typename SendSection::value_type> vMover(sendSection->comm(), sendSection->debug());
|
---|
419 | std::map<int, char *> sendPoints;
|
---|
420 | std::map<int, char *> recvPoints;
|
---|
421 | typename SendSection::alloc_type::template rebind<char>::other sendAllocator;
|
---|
422 | typename RecvSection::alloc_type::template rebind<char>::other recvAllocator;
|
---|
423 |
|
---|
424 | const Obj<typename SendOverlap::traits::baseSequence> sRanks = sendOverlap->base();
|
---|
425 | const typename SendOverlap::traits::baseSequence::iterator sEnd = sRanks->end();
|
---|
426 | const typename SendSection::value_type *sValues = sendSection->restrictSpace();
|
---|
427 |
|
---|
428 | for(typename SendOverlap::traits::baseSequence::iterator r_iter = sRanks->begin(); r_iter != sEnd; ++r_iter) {
|
---|
429 | const Obj<typename SendOverlap::coneSequence>& points = sendOverlap->cone(*r_iter);
|
---|
430 | const int pSize = sendOverlap->getConeSize(*r_iter);
|
---|
431 | const typename SendOverlap::coneSequence::iterator pBegin = points->begin();
|
---|
432 | const typename SendOverlap::coneSequence::iterator pEnd = points->end();
|
---|
433 | char *v = sendAllocator.allocate(pSize*pSize);
|
---|
434 | int k = 0;
|
---|
435 |
|
---|
436 | for(size_t i = 0; i < pSize*pSize; ++i) {sendAllocator.construct(v+i, 0);}
|
---|
437 | for(typename SendOverlap::coneSequence::iterator p_iter = pBegin; p_iter != pEnd; ++p_iter) {
|
---|
438 | for(typename SendOverlap::coneSequence::iterator q_iter = pBegin; q_iter != pEnd; ++q_iter, ++k) {
|
---|
439 | v[k] = (char) sendSection->hasPoint(typename SendSection::point_type(*p_iter,*q_iter));
|
---|
440 | }
|
---|
441 | }
|
---|
442 | sendPoints[*r_iter] = v;
|
---|
443 | pMover.send(*r_iter, pSize*pSize, sendPoints[*r_iter]);
|
---|
444 | vMover.send(*r_iter, 2, sValues);
|
---|
445 | }
|
---|
446 | const Obj<typename RecvOverlap::traits::capSequence> rRanks = recvOverlap->cap();
|
---|
447 | const typename RecvOverlap::traits::capSequence::iterator rEnd = rRanks->end();
|
---|
448 | const typename RecvSection::value_type *rValues = recvSection->restrictSpace();
|
---|
449 |
|
---|
450 | for(typename RecvOverlap::traits::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
451 | const Obj<typename RecvOverlap::traits::supportSequence>& points = recvOverlap->support(*r_iter);
|
---|
452 | const int pSize = recvOverlap->getSupportSize(*r_iter);
|
---|
453 | char *v = recvAllocator.allocate(pSize*pSize);
|
---|
454 |
|
---|
455 | for(size_t i = 0; i < pSize*pSize; ++i) {recvAllocator.construct(v+i, 0);}
|
---|
456 | recvPoints[*r_iter] = v;
|
---|
457 | pMover.recv(*r_iter, pSize*pSize, recvPoints[*r_iter]);
|
---|
458 | vMover.recv(*r_iter, 2, rValues);
|
---|
459 | }
|
---|
460 | pMover.start();
|
---|
461 | pMover.end();
|
---|
462 | vMover.start();
|
---|
463 | vMover.end();
|
---|
464 | for(typename RecvOverlap::traits::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
465 | const Obj<typename RecvOverlap::traits::supportSequence>& points = recvOverlap->support(*r_iter);
|
---|
466 | const typename RecvOverlap::traits::supportSequence::iterator pBegin = points->begin();
|
---|
467 | const typename RecvOverlap::traits::supportSequence::iterator pEnd = points->end();
|
---|
468 | const char *v = recvPoints[*r_iter];
|
---|
469 | int k = 0;
|
---|
470 |
|
---|
471 | for(typename RecvOverlap::traits::supportSequence::iterator s_iter = pBegin; s_iter != pEnd; ++s_iter) {
|
---|
472 | for(typename RecvOverlap::traits::supportSequence::iterator t_iter = pBegin; t_iter != pEnd; ++t_iter, ++k) {
|
---|
473 | if (v[k]) {recvSection->addPoint(typename RecvSection::point_type(s_iter.color(),t_iter.color()));}
|
---|
474 | }
|
---|
475 | }
|
---|
476 | }
|
---|
477 | for(typename SendOverlap::traits::baseSequence::iterator r_iter = sRanks->begin(); r_iter != sEnd; ++r_iter) {
|
---|
478 | sendAllocator.deallocate(sendPoints[*r_iter], sendOverlap->getConeSize(*r_iter)*sendOverlap->getConeSize(*r_iter));
|
---|
479 | }
|
---|
480 | for(typename RecvOverlap::traits::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
481 | recvAllocator.deallocate(recvPoints[*r_iter], recvOverlap->getSupportSize(*r_iter)*recvOverlap->getSupportSize(*r_iter));
|
---|
482 | }
|
---|
483 | }
|
---|
484 | // Copy the overlap section to the related processes
|
---|
485 | // This version is for IConstant sections, meaning the same, single value over all points
|
---|
486 | template<typename SendOverlap, typename RecvOverlap, typename SendSection, typename RecvSection>
|
---|
487 | static void copyIConstant(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<SendSection>& sendSection, const Obj<RecvSection>& recvSection) {
|
---|
488 | MPIMover<typename SendSection::point_type> pMover(sendSection->comm(), sendSection->debug());
|
---|
489 | MPIMover<typename SendSection::value_type> vMover(sendSection->comm(), sendSection->debug());
|
---|
490 | std::map<int, typename SendSection::point_type *> sendPoints;
|
---|
491 | std::map<int, typename SendSection::point_type *> recvPoints;
|
---|
492 | typename SendSection::alloc_type::template rebind<typename SendSection::point_type>::other sendAllocator;
|
---|
493 | typename RecvSection::alloc_type::template rebind<typename SendSection::point_type>::other recvAllocator;
|
---|
494 |
|
---|
495 | const Obj<typename SendOverlap::baseSequence> sRanks = sendOverlap->base();
|
---|
496 | const typename SendOverlap::baseSequence::iterator sEnd = sRanks->end();
|
---|
497 | const typename SendSection::value_type *sValues = sendSection->restrictSpace();
|
---|
498 |
|
---|
499 | for(typename SendOverlap::baseSequence::iterator r_iter = sRanks->begin(); r_iter != sEnd; ++r_iter) {
|
---|
500 | typename SendSection::point_type *v = sendAllocator.allocate(2);
|
---|
501 |
|
---|
502 | for(size_t i = 0; i < 2; ++i) {sendAllocator.construct(v+i, 0);}
|
---|
503 | v[0] = sendSection->getChart().min();
|
---|
504 | v[1] = sendSection->getChart().max();
|
---|
505 | sendPoints[*r_iter] = v;
|
---|
506 | pMover.send(*r_iter, 2, sendPoints[*r_iter]);
|
---|
507 | vMover.send(*r_iter, 2, sValues);
|
---|
508 | ///std::cout << "["<<sendOverlap->commRank()<<"]Sending chart (" << v[0] << ", " << v[1] << ") with values (" << sValues[0] << ", " << sValues[1] << ") to process " << *r_iter << std::endl;
|
---|
509 | }
|
---|
510 | const Obj<typename RecvOverlap::capSequence> rRanks = recvOverlap->cap();
|
---|
511 | const typename RecvOverlap::capSequence::iterator rEnd = rRanks->end();
|
---|
512 | const typename RecvSection::value_type *rValues = recvSection->restrictSpace();
|
---|
513 |
|
---|
514 | for(typename RecvOverlap::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
515 | typename SendSection::point_type *v = recvAllocator.allocate(2);
|
---|
516 |
|
---|
517 | for(size_t i = 0; i < 2; ++i) {recvAllocator.construct(v+i, 0);}
|
---|
518 | recvPoints[*r_iter] = v;
|
---|
519 | pMover.recv(*r_iter, 2, recvPoints[*r_iter]);
|
---|
520 | vMover.recv(*r_iter, 2, rValues);
|
---|
521 | }
|
---|
522 | pMover.start();
|
---|
523 | pMover.end();
|
---|
524 | vMover.start();
|
---|
525 | vMover.end();
|
---|
526 |
|
---|
527 | typename SendSection::point_type min = -1;
|
---|
528 | typename SendSection::point_type max = -1;
|
---|
529 |
|
---|
530 | for(typename RecvOverlap::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
531 | const typename RecvSection::point_type *v = recvPoints[*r_iter];
|
---|
532 | typename SendSection::point_type newMin = v[0];
|
---|
533 | typename SendSection::point_type newMax = v[1]-1;
|
---|
534 | //int pSize = 0;
|
---|
535 |
|
---|
536 | ///std::cout << "["<<recvOverlap->commRank()<<"]Received chart (" << v[0] << ", " << v[1] << ") from process " << *r_iter << std::endl;
|
---|
537 | #if 0
|
---|
538 | // Translate to local numbering
|
---|
539 | if (recvOverlap->support(*r_iter)->size()) {
|
---|
540 | while(!pSize) {
|
---|
541 | const Obj<typename RecvOverlap::supportSequence>& points = recvOverlap->support(*r_iter, newMin);
|
---|
542 | pSize = points->size();
|
---|
543 | if (pSize) {
|
---|
544 | newMin = *points->begin();
|
---|
545 | } else {
|
---|
546 | newMin++;
|
---|
547 | }
|
---|
548 | }
|
---|
549 | pSize = 0;
|
---|
550 | while(!pSize) {
|
---|
551 | const Obj<typename RecvOverlap::supportSequence>& points = recvOverlap->support(*r_iter, newMax);
|
---|
552 | pSize = points->size();
|
---|
553 | if (pSize) {
|
---|
554 | newMax = *points->begin();
|
---|
555 | } else {
|
---|
556 | newMax--;
|
---|
557 | }
|
---|
558 | }
|
---|
559 | }
|
---|
560 | std::cout << "["<<recvOverlap->commRank()<<"]Translated to chart (" << newMin << ", " << newMax+1 << ") from process " << *r_iter << std::endl;
|
---|
561 | #endif
|
---|
562 | // Update chart
|
---|
563 | if (min < 0) {
|
---|
564 | min = newMin;
|
---|
565 | max = newMax+1;
|
---|
566 | } else {
|
---|
567 | min = std::min(min, newMin);
|
---|
568 | max = std::max(max, (typename SendSection::point_type) (newMax+1));
|
---|
569 | }
|
---|
570 | }
|
---|
571 | if (!rRanks->size()) {min = max = 0;}
|
---|
572 | recvSection->setChart(typename RecvSection::chart_type(min, max));
|
---|
573 | for(typename SendOverlap::baseSequence::iterator r_iter = sRanks->begin(); r_iter != sEnd; ++r_iter) {
|
---|
574 | sendAllocator.deallocate(sendPoints[*r_iter], 2);
|
---|
575 | }
|
---|
576 | for(typename RecvOverlap::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
577 | recvAllocator.deallocate(recvPoints[*r_iter], 2);
|
---|
578 | }
|
---|
579 | }
|
---|
580 | // Copy the overlap section to the related processes
|
---|
581 | // This version is for different sections, possibly with different data types
|
---|
582 | // TODO: Can cache MPIMover objects (like a VecScatter)
|
---|
583 | template<typename SendOverlap, typename RecvOverlap, typename SendSection, typename RecvSection>
|
---|
584 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<SendSection>& sendSection, const Obj<RecvSection>& recvSection, const MPI_Datatype datatype = MPI_DATATYPE_NULL) {
|
---|
585 | typedef std::pair<int, typename SendSection::value_type *> allocPair;
|
---|
586 | typedef typename RecvSection::point_type recv_point_type;
|
---|
587 | const Obj<typename SendSection::atlas_type>& sendAtlas = sendSection->getAtlas();
|
---|
588 | const Obj<typename RecvSection::atlas_type>& recvAtlas = recvSection->getAtlas();
|
---|
589 | MPIMover<typename SendSection::value_type> vMover(sendSection->comm(), datatype, MPI_UNDEFINED, sendSection->debug());
|
---|
590 | std::map<int, allocPair> sendValues;
|
---|
591 | std::map<int, allocPair> recvValues;
|
---|
592 | typename SendSection::alloc_type sendAllocator;
|
---|
593 | typename RecvSection::alloc_type recvAllocator;
|
---|
594 |
|
---|
595 | copy(sendOverlap, recvOverlap, sendAtlas, recvAtlas);
|
---|
596 | const typename SendOverlap::baseSequence::iterator sBegin = sendOverlap->baseBegin();
|
---|
597 | const typename SendOverlap::baseSequence::iterator sEnd = sendOverlap->baseEnd();
|
---|
598 |
|
---|
599 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
600 | for(typename SendOverlap::baseSequence::iterator r_iter = sBegin; r_iter != sEnd; ++r_iter) {
|
---|
601 | const typename SendOverlap::coneSequence::iterator pBegin = sendOverlap->coneBegin(*r_iter);
|
---|
602 | const typename SendOverlap::coneSequence::iterator pEnd = sendOverlap->coneEnd(*r_iter);
|
---|
603 | const int numPoints = sendOverlap->getConeSize(*r_iter);
|
---|
604 | std::valarray<typename SendOverlap::source_type> sortedPoints(numPoints);
|
---|
605 | int numVals = 0, p = 0;
|
---|
606 |
|
---|
607 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
608 | for(typename SendOverlap::coneSequence::iterator c_iter = pBegin; c_iter != pEnd; ++c_iter, ++p) {
|
---|
609 | numVals += sendSection->getFiberDimension(*c_iter);
|
---|
610 | sortedPoints[p] = *c_iter;
|
---|
611 | }
|
---|
612 | typename SendSection::value_type *v = sendAllocator.allocate(numVals);
|
---|
613 | int k = 0;
|
---|
614 |
|
---|
615 | std::sort(&sortedPoints[0], &sortedPoints[numPoints]);
|
---|
616 | for(int i = 0; i < numVals; ++i) {sendAllocator.construct(v+i, 0);}
|
---|
617 | for(p = 0; p < numPoints; ++p) {
|
---|
618 | const typename SendSection::value_type *vals = sendSection->restrictPoint(sortedPoints[p]);
|
---|
619 |
|
---|
620 | for(int i = 0; i < sendSection->getFiberDimension(sortedPoints[p]); ++i, ++k) v[k] = vals[i];
|
---|
621 | }
|
---|
622 | sendValues[*r_iter] = allocPair(numVals, v);
|
---|
623 | vMover.send(*r_iter, numVals, v);
|
---|
624 | }
|
---|
625 | const typename RecvOverlap::capSequence::iterator rBegin = recvOverlap->capBegin();
|
---|
626 | const typename RecvOverlap::capSequence::iterator rEnd = recvOverlap->capEnd();
|
---|
627 |
|
---|
628 | recvSection->allocatePoint();
|
---|
629 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
630 | int maxVals = 0;
|
---|
631 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
632 | const typename RecvOverlap::supportSequence::iterator pBegin = recvOverlap->supportBegin(*r_iter);
|
---|
633 | const typename RecvOverlap::supportSequence::iterator pEnd = recvOverlap->supportEnd(*r_iter);
|
---|
634 | int numVals = 0;
|
---|
635 |
|
---|
636 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
637 | for(typename RecvOverlap::supportSequence::iterator s_iter = pBegin; s_iter != pEnd; ++s_iter) {
|
---|
638 | numVals += recvSection->getFiberDimension(recv_point_type(*r_iter, s_iter.color()));
|
---|
639 | }
|
---|
640 | typename SendSection::value_type *v = sendAllocator.allocate(numVals);
|
---|
641 |
|
---|
642 | for(int i = 0; i < numVals; ++i) {sendAllocator.construct(v+i, 0);}
|
---|
643 | recvValues[*r_iter] = allocPair(numVals, v);
|
---|
644 | vMover.recv(*r_iter, numVals, v);
|
---|
645 | maxVals = std::max(maxVals, numVals);
|
---|
646 | }
|
---|
647 | vMover.start();
|
---|
648 | vMover.end();
|
---|
649 | typename RecvSection::value_type *convertedValues = recvAllocator.allocate(maxVals);
|
---|
650 | for(int i = 0; i < maxVals; ++i) {recvAllocator.construct(convertedValues+i, 0);}
|
---|
651 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
652 | const typename RecvOverlap::supportSequence::iterator pBegin = recvOverlap->supportBegin(*r_iter);
|
---|
653 | const typename RecvOverlap::supportSequence::iterator pEnd = recvOverlap->supportEnd(*r_iter);
|
---|
654 | const int numPoints = recvOverlap->getSupportSize(*r_iter);
|
---|
655 | std::valarray<typename RecvOverlap::color_type> sortedPoints(numPoints);
|
---|
656 | typename SendSection::value_type *v = recvValues[*r_iter].second;
|
---|
657 | const int numVals = recvValues[*r_iter].first;
|
---|
658 | int k = 0, p = 0;
|
---|
659 |
|
---|
660 | for(typename RecvOverlap::supportSequence::iterator s_iter = pBegin; s_iter != pEnd; ++s_iter, ++p) {
|
---|
661 | sortedPoints[p] = s_iter.color();
|
---|
662 | }
|
---|
663 | std::sort(&sortedPoints[0], &sortedPoints[numPoints]);
|
---|
664 |
|
---|
665 | //for(typename RecvOverlap::supportSequence::iterator s_iter = points->begin(); s_iter != pEnd; ++s_iter) {
|
---|
666 | for(p = 0; p < numPoints; ++p) {
|
---|
667 | const int size = recvSection->getFiberDimension(recv_point_type(*r_iter, sortedPoints[p]));
|
---|
668 |
|
---|
669 | for(int i = 0; i < size; ++i) {convertedValues[i] = (typename RecvSection::value_type) v[k+i];}
|
---|
670 | if (size) {recvSection->updatePoint(recv_point_type(*r_iter, sortedPoints[p]), convertedValues);}
|
---|
671 | k += size;
|
---|
672 | }
|
---|
673 | assert(k == numVals);
|
---|
674 | for(int i = 0; i < numVals; ++i) {sendAllocator.destroy(v+i);}
|
---|
675 | }
|
---|
676 | for(int i = 0; i < maxVals; ++i) {recvAllocator.destroy(convertedValues+i);}
|
---|
677 | recvAllocator.deallocate(convertedValues, maxVals);
|
---|
678 | for(typename SendOverlap::baseSequence::iterator r_iter = sBegin; r_iter != sEnd; ++r_iter) {
|
---|
679 | typename SendSection::value_type *v = sendValues[*r_iter].second;
|
---|
680 | const int numVals = sendValues[*r_iter].first;
|
---|
681 |
|
---|
682 | for(int i = 0; i < numVals; ++i) {sendAllocator.destroy(v+i);}
|
---|
683 | sendAllocator.deallocate(v, numVals);
|
---|
684 | }
|
---|
685 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
686 | typename SendSection::value_type *v = recvValues[*r_iter].second;
|
---|
687 | const int numVals = recvValues[*r_iter].first;
|
---|
688 |
|
---|
689 | for(int i = 0; i < numVals; ++i) {sendAllocator.destroy(v+i);}
|
---|
690 | sendAllocator.deallocate(v, numVals);
|
---|
691 | }
|
---|
692 | //recvSection->view("After copy");
|
---|
693 | }
|
---|
694 | // Copy the overlap section to the related processes
|
---|
695 | // This version is for sections with the same type
|
---|
696 | template<typename SendOverlap, typename RecvOverlap, typename Section>
|
---|
697 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<Section>& sendSection, const Obj<Section>& recvSection, const MPI_Datatype datatype = MPI_DATATYPE_NULL) {
|
---|
698 | typedef std::pair<int, typename Section::value_type *> allocPair;
|
---|
699 | const Obj<typename Section::atlas_type>& sendAtlas = sendSection->getAtlas();
|
---|
700 | const Obj<typename Section::atlas_type>& recvAtlas = recvSection->getAtlas();
|
---|
701 | MPIMover<typename Section::value_type> vMover(sendSection->comm(), datatype, MPI_UNDEFINED, sendSection->debug());
|
---|
702 | std::map<int, allocPair> sendValues;
|
---|
703 | std::map<int, allocPair> recvValues;
|
---|
704 | typename Section::alloc_type allocator;
|
---|
705 |
|
---|
706 | ///sendAtlas->view("Send Atlas in same type copy()");
|
---|
707 | copy(sendOverlap, recvOverlap, sendAtlas, recvAtlas);
|
---|
708 | ///recvAtlas->view("Recv Atlas after same type copy()");
|
---|
709 | const Obj<typename SendOverlap::traits::baseSequence> sRanks = sendOverlap->base();
|
---|
710 | const typename SendOverlap::traits::baseSequence::iterator sEnd = sRanks->end();
|
---|
711 |
|
---|
712 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
713 | for(typename SendOverlap::traits::baseSequence::iterator r_iter = sRanks->begin(); r_iter != sEnd; ++r_iter) {
|
---|
714 | const Obj<typename SendOverlap::coneSequence>& points = sendOverlap->cone(*r_iter);
|
---|
715 | const typename SendOverlap::coneSequence::iterator pEnd = points->end();
|
---|
716 | const int numPoints = sendOverlap->getConeSize(*r_iter);
|
---|
717 | std::valarray<typename SendOverlap::source_type> sortedPoints(numPoints);
|
---|
718 | int numVals = 0, p = 0;
|
---|
719 |
|
---|
720 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
721 | for(typename SendOverlap::coneSequence::iterator c_iter = points->begin(); c_iter != pEnd; ++c_iter, ++p) {
|
---|
722 | numVals += sendSection->getFiberDimension(*c_iter);
|
---|
723 | sortedPoints[p] = *c_iter;
|
---|
724 | }
|
---|
725 | typename Section::value_type *v = allocator.allocate(numVals);
|
---|
726 | int k = 0;
|
---|
727 |
|
---|
728 | std::sort(&sortedPoints[0], &sortedPoints[numPoints]);
|
---|
729 | for(int i = 0; i < numVals; ++i) {allocator.construct(v+i, 0);}
|
---|
730 | //for(typename SendOverlap::coneSequence::iterator c_iter = points->begin(); c_iter != pEnd; ++c_iter) {
|
---|
731 | for(p = 0; p < numPoints; ++p) {
|
---|
732 | const typename Section::value_type *vals = sendSection->restrictPoint(sortedPoints[p]);
|
---|
733 | const int dim = sendSection->getFiberDimension(sortedPoints[p]);
|
---|
734 |
|
---|
735 | for(int i = 0; i < dim; ++i, ++k) v[k] = vals[i];
|
---|
736 | }
|
---|
737 | sendValues[*r_iter] = allocPair(numVals, v);
|
---|
738 | vMover.send(*r_iter, numVals, v);
|
---|
739 | }
|
---|
740 | const Obj<typename RecvOverlap::traits::capSequence> rRanks = recvOverlap->cap();
|
---|
741 | const typename RecvOverlap::traits::capSequence::iterator rEnd = rRanks->end();
|
---|
742 |
|
---|
743 | recvSection->allocatePoint();
|
---|
744 | ///recvSection->view("Recv Section after same type copy() allocation");
|
---|
745 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
746 | for(typename RecvOverlap::traits::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
747 | const Obj<typename RecvOverlap::supportSequence>& points = recvOverlap->support(*r_iter);
|
---|
748 | const typename RecvOverlap::supportSequence::iterator pEnd = points->end();
|
---|
749 | int numVals = 0;
|
---|
750 |
|
---|
751 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
752 | for(typename RecvOverlap::supportSequence::iterator s_iter = points->begin(); s_iter != pEnd; ++s_iter) {
|
---|
753 | numVals += recvSection->getFiberDimension(s_iter.color());
|
---|
754 | }
|
---|
755 | typename Section::value_type *v = allocator.allocate(numVals);
|
---|
756 |
|
---|
757 | recvValues[*r_iter] = allocPair(numVals, v);
|
---|
758 | for(int i = 0; i < numVals; ++i) {allocator.construct(v+i, 0);}
|
---|
759 | vMover.recv(*r_iter, numVals, v);
|
---|
760 | }
|
---|
761 | vMover.start();
|
---|
762 | vMover.end();
|
---|
763 | for(typename RecvOverlap::traits::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
764 | const Obj<typename RecvOverlap::supportSequence>& points = recvOverlap->support(*r_iter);
|
---|
765 | const typename RecvOverlap::supportSequence::iterator pEnd = points->end();
|
---|
766 | const int numPoints = recvOverlap->getSupportSize(*r_iter);
|
---|
767 | std::valarray<typename RecvOverlap::color_type> sortedPoints(numPoints);
|
---|
768 | typename Section::value_type *v = recvValues[*r_iter].second;
|
---|
769 | const int numVals = recvValues[*r_iter].first;
|
---|
770 | int k = 0, p = 0;
|
---|
771 |
|
---|
772 | for(typename RecvOverlap::supportSequence::iterator s_iter = points->begin(); s_iter != pEnd; ++s_iter, ++p) {
|
---|
773 | sortedPoints[p] = s_iter.color();
|
---|
774 | }
|
---|
775 | std::sort(&sortedPoints[0], &sortedPoints[numPoints]);
|
---|
776 |
|
---|
777 | //for(typename RecvOverlap::supportSequence::iterator s_iter = points->begin(); s_iter != pEnd; ++s_iter) {
|
---|
778 | for(p = 0; p < numPoints; ++p) {
|
---|
779 | const int size = recvSection->getFiberDimension(sortedPoints[p]);
|
---|
780 |
|
---|
781 | if (size) {recvSection->updatePoint(sortedPoints[p], &v[k]);}
|
---|
782 | k += size;
|
---|
783 | }
|
---|
784 | assert(k == numVals);
|
---|
785 | for(int i = 0; i < numVals; ++i) {allocator.destroy(v+i);}
|
---|
786 | allocator.deallocate(v, numVals);
|
---|
787 | }
|
---|
788 | for(typename SendOverlap::traits::baseSequence::iterator r_iter = sRanks->begin(); r_iter != sEnd; ++r_iter) {
|
---|
789 | typename Section::value_type *v = sendValues[*r_iter].second;
|
---|
790 | const int numVals = sendValues[*r_iter].first;
|
---|
791 |
|
---|
792 | for(int i = 0; i < numVals; ++i) {allocator.destroy(v+i);}
|
---|
793 | allocator.deallocate(v, numVals);
|
---|
794 | }
|
---|
795 | //recvSection->view("After copy");
|
---|
796 | }
|
---|
797 | // Specialize to ArrowSection
|
---|
798 | template<typename SendOverlap, typename RecvOverlap>
|
---|
799 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<UniformSection<MinimalArrow<int,int>,int> >& sendSection, const Obj<UniformSection<MinimalArrow<int,int>,int> >& recvSection, const MPI_Datatype datatype = MPI_DATATYPE_NULL) {
|
---|
800 | typedef UniformSection<MinimalArrow<int,int>,int> Section;
|
---|
801 | typedef std::pair<int, typename Section::value_type *> allocPair;
|
---|
802 | const Obj<typename Section::atlas_type>& sendAtlas = sendSection->getAtlas();
|
---|
803 | const Obj<typename Section::atlas_type>& recvAtlas = recvSection->getAtlas();
|
---|
804 | MPIMover<typename Section::value_type> vMover(sendSection->comm(), datatype, MPI_UNDEFINED, sendSection->debug());
|
---|
805 | std::map<int, allocPair> sendValues;
|
---|
806 | std::map<int, allocPair> recvValues;
|
---|
807 | typename Section::alloc_type allocator;
|
---|
808 |
|
---|
809 | copy(sendOverlap, recvOverlap, sendAtlas, recvAtlas);
|
---|
810 | const Obj<typename SendOverlap::traits::baseSequence> sRanks = sendOverlap->base();
|
---|
811 | const typename SendOverlap::traits::baseSequence::iterator sEnd = sRanks->end();
|
---|
812 |
|
---|
813 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
814 | for(typename SendOverlap::traits::baseSequence::iterator r_iter = sRanks->begin(); r_iter != sEnd; ++r_iter) {
|
---|
815 | const Obj<typename SendOverlap::coneSequence>& points = sendOverlap->cone(*r_iter);
|
---|
816 | const typename SendOverlap::coneSequence::iterator pBegin = points->begin();
|
---|
817 | const typename SendOverlap::coneSequence::iterator pEnd = points->end();
|
---|
818 | int numVals = 0;
|
---|
819 |
|
---|
820 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
821 | for(typename SendOverlap::coneSequence::iterator c_iter = pBegin; c_iter != pEnd; ++c_iter) {
|
---|
822 | for(typename SendOverlap::coneSequence::iterator d_iter = pBegin; d_iter != pEnd; ++d_iter) {
|
---|
823 | numVals += sendSection->getFiberDimension(typename Section::point_type(*c_iter, *d_iter));
|
---|
824 | }
|
---|
825 | }
|
---|
826 | typename Section::value_type *v = allocator.allocate(numVals);
|
---|
827 | int k = 0;
|
---|
828 |
|
---|
829 | for(int i = 0; i < numVals; ++i) {allocator.construct(v+i, 0);}
|
---|
830 | for(typename SendOverlap::coneSequence::iterator c_iter = pBegin; c_iter != pEnd; ++c_iter) {
|
---|
831 | for(typename SendOverlap::coneSequence::iterator d_iter = pBegin; d_iter != pEnd; ++d_iter) {
|
---|
832 | const typename Section::point_type arrow(*c_iter, *d_iter);
|
---|
833 | const typename Section::value_type *vals = sendSection->restrictPoint(arrow);
|
---|
834 | const int dim = sendSection->getFiberDimension(arrow);
|
---|
835 |
|
---|
836 | for(int i = 0; i < dim; ++i, ++k) v[k] = vals[i];
|
---|
837 | }
|
---|
838 | }
|
---|
839 | sendValues[*r_iter] = allocPair(numVals, v);
|
---|
840 | vMover.send(*r_iter, numVals, v);
|
---|
841 | }
|
---|
842 | const Obj<typename RecvOverlap::traits::capSequence> rRanks = recvOverlap->cap();
|
---|
843 | const typename RecvOverlap::traits::capSequence::iterator rEnd = rRanks->end();
|
---|
844 |
|
---|
845 | recvSection->allocatePoint();
|
---|
846 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
847 | for(typename RecvOverlap::traits::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
848 | const Obj<typename RecvOverlap::supportSequence>& points = recvOverlap->support(*r_iter);
|
---|
849 | const typename RecvOverlap::supportSequence::iterator pBegin = points->begin();
|
---|
850 | const typename RecvOverlap::supportSequence::iterator pEnd = points->end();
|
---|
851 | int numVals = 0;
|
---|
852 |
|
---|
853 | // TODO: This should be const_iterator, but Sifter sucks
|
---|
854 | for(typename RecvOverlap::supportSequence::iterator s_iter = pBegin; s_iter != pEnd; ++s_iter) {
|
---|
855 | for(typename RecvOverlap::supportSequence::iterator t_iter = pBegin; t_iter != pEnd; ++t_iter) {
|
---|
856 | numVals += recvSection->getFiberDimension(typename Section::point_type(s_iter.color(), t_iter.color()));
|
---|
857 | }
|
---|
858 | }
|
---|
859 | typename Section::value_type *v = allocator.allocate(numVals);
|
---|
860 |
|
---|
861 | recvValues[*r_iter] = allocPair(numVals, v);
|
---|
862 | for(int i = 0; i < numVals; ++i) {allocator.construct(v+i, 0);}
|
---|
863 | vMover.recv(*r_iter, numVals, v);
|
---|
864 | }
|
---|
865 | vMover.start();
|
---|
866 | vMover.end();
|
---|
867 | for(typename RecvOverlap::traits::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
868 | const Obj<typename RecvOverlap::supportSequence>& points = recvOverlap->support(*r_iter);
|
---|
869 | const typename RecvOverlap::supportSequence::iterator pBegin = points->begin();
|
---|
870 | const typename RecvOverlap::supportSequence::iterator pEnd = points->end();
|
---|
871 | typename Section::value_type *v = recvValues[*r_iter].second;
|
---|
872 | const int numVals = recvValues[*r_iter].first;
|
---|
873 | int k = 0;
|
---|
874 |
|
---|
875 | for(typename RecvOverlap::supportSequence::iterator s_iter = pBegin; s_iter != pEnd; ++s_iter) {
|
---|
876 | for(typename RecvOverlap::supportSequence::iterator t_iter = pBegin; t_iter != pEnd; ++t_iter) {
|
---|
877 | const typename Section::point_type arrow(s_iter.color(), t_iter.color());
|
---|
878 | const int size = recvSection->getFiberDimension(arrow);
|
---|
879 |
|
---|
880 | if (size) {recvSection->updatePoint(arrow, &v[k]);}
|
---|
881 | k += size;
|
---|
882 | }
|
---|
883 | }
|
---|
884 | for(int i = 0; i < numVals; ++i) {allocator.destroy(v+i);}
|
---|
885 | allocator.deallocate(v, numVals);
|
---|
886 | }
|
---|
887 | for(typename SendOverlap::traits::baseSequence::iterator r_iter = sRanks->begin(); r_iter != sEnd; ++r_iter) {
|
---|
888 | typename Section::value_type *v = sendValues[*r_iter].second;
|
---|
889 | const int numVals = sendValues[*r_iter].first;
|
---|
890 |
|
---|
891 | for(int i = 0; i < numVals; ++i) {allocator.destroy(v+i);}
|
---|
892 | allocator.deallocate(v, numVals);
|
---|
893 | }
|
---|
894 | //recvSection->view("After copy");
|
---|
895 | }
|
---|
896 | // Specialize to a ConstantSection
|
---|
897 | #if 0
|
---|
898 | template<typename SendOverlap, typename RecvOverlap, typename Value>
|
---|
899 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<ConstantSection<typename SendOverlap::source_type, Value> >& sendSection, const Obj<ConstantSection<typename SendOverlap::source_type, Value> >& recvSection) {
|
---|
900 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
901 | };
|
---|
902 | template<typename SendOverlap, typename RecvOverlap, typename Value>
|
---|
903 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<IConstantSection<typename SendOverlap::source_type, Value> >& sendSection, const Obj<ConstantSection<typename SendOverlap::source_type, Value> >& recvSection) {
|
---|
904 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
905 | };
|
---|
906 | #else
|
---|
907 | template<typename SendOverlap, typename RecvOverlap, typename Value>
|
---|
908 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<ConstantSection<typename SendOverlap::source_type, Value> >& sendSection, const Obj<ConstantSection<ALE::Pair<int, typename SendOverlap::source_type>, Value> >& recvSection) {
|
---|
909 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
910 | }
|
---|
911 | template<typename SendOverlap, typename RecvOverlap, typename Value>
|
---|
912 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<IConstantSection<typename SendOverlap::source_type, Value> >& sendSection, const Obj<ConstantSection<ALE::Pair<int, typename SendOverlap::source_type>, Value> >& recvSection) {
|
---|
913 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
914 | }
|
---|
915 | #endif
|
---|
916 | // Specialize to an IConstantSection
|
---|
917 | template<typename SendOverlap, typename RecvOverlap, typename Value>
|
---|
918 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<IConstantSection<typename SendOverlap::source_type, Value> >& sendSection, const Obj<IConstantSection<typename SendOverlap::source_type, Value> >& recvSection) {
|
---|
919 | // Why doesn't this work?
|
---|
920 | // This supposed to be a copy, BUT filtered through the sendOverlap
|
---|
921 | // However, an IConstant section does not allow filtration of its
|
---|
922 | // chart. Therefore, you end up with either
|
---|
923 | //
|
---|
924 | // a) Too many items in the chart, copied from the remote sendSection
|
---|
925 | // b) A chart mapped to the local numbering, which we do not want
|
---|
926 | copyIConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
927 | }
|
---|
928 | // Specialize to an BaseSection/ConstantSection pair
|
---|
929 | #if 0
|
---|
930 | template<typename SendOverlap, typename RecvOverlap, typename Sieve_>
|
---|
931 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<BaseSection<Sieve_> >& sendSection, const Obj<ConstantSection<typename SendOverlap::source_type, int> >& recvSection) {
|
---|
932 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
933 | };
|
---|
934 | #else
|
---|
935 | template<typename SendOverlap, typename RecvOverlap, typename Sieve_>
|
---|
936 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<BaseSection<Sieve_> >& sendSection, const Obj<ConstantSection<ALE::Pair<int, typename SendOverlap::source_type>, int> >& recvSection) {
|
---|
937 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
938 | }
|
---|
939 | #endif
|
---|
940 | // Specialize to an BaseSectionV/ConstantSection pair
|
---|
941 | #if 0
|
---|
942 | template<typename SendOverlap, typename RecvOverlap, typename Sieve_>
|
---|
943 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<BaseSectionV<Sieve_> >& sendSection, const Obj<ConstantSection<typename SendOverlap::source_type, int> >& recvSection) {
|
---|
944 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
945 | };
|
---|
946 | #else
|
---|
947 | template<typename SendOverlap, typename RecvOverlap, typename Sieve_>
|
---|
948 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<BaseSectionV<Sieve_> >& sendSection, const Obj<ConstantSection<ALE::Pair<int, typename SendOverlap::source_type>, int> >& recvSection) {
|
---|
949 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
950 | }
|
---|
951 | #endif
|
---|
952 | // Specialize to an LabelBaseSection/ConstantSection pair
|
---|
953 | #if 0
|
---|
954 | template<typename SendOverlap, typename RecvOverlap, typename Sieve_, typename Label_>
|
---|
955 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<LabelBaseSection<Sieve_, Label_> >& sendSection, const Obj<ConstantSection<typename SendOverlap::source_type, int> >& recvSection) {
|
---|
956 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
957 | };
|
---|
958 | #else
|
---|
959 | template<typename SendOverlap, typename RecvOverlap, typename Sieve_, typename Label_>
|
---|
960 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<LabelBaseSection<Sieve_, Label_> >& sendSection, const Obj<ConstantSection<ALE::Pair<int, typename SendOverlap::source_type>, int> >& recvSection) {
|
---|
961 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
962 | }
|
---|
963 | #endif
|
---|
964 | template<typename SendOverlap, typename RecvOverlap, typename Sieve_, typename Label_>
|
---|
965 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<LabelBaseSectionV<Sieve_, Label_> >& sendSection, const Obj<ConstantSection<ALE::Pair<int, typename SendOverlap::source_type>, int> >& recvSection) {
|
---|
966 | copyConstant(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
967 | }
|
---|
968 | // Specialize to a ConstantSection for ArrowSection
|
---|
969 | template<typename SendOverlap, typename RecvOverlap, typename Value>
|
---|
970 | static void copy(const Obj<SendOverlap>& sendOverlap, const Obj<RecvOverlap>& recvOverlap, const Obj<ConstantSection<MinimalArrow<typename SendOverlap::source_type,typename SendOverlap::source_type>, Value> >& sendSection, const Obj<ConstantSection<MinimalArrow<typename SendOverlap::source_type,typename SendOverlap::source_type>, Value> >& recvSection) {
|
---|
971 | copyConstantArrow(sendOverlap, recvOverlap, sendSection, recvSection);
|
---|
972 | }
|
---|
973 | };
|
---|
974 | class BinaryFusion {
|
---|
975 | public:
|
---|
976 | template<typename OverlapSection, typename RecvOverlap, typename Section, typename Function>
|
---|
977 | static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, const Obj<Section>& section, Function binaryOp) {
|
---|
978 | const Obj<typename RecvOverlap::traits::baseSequence> rPoints = recvOverlap->base();
|
---|
979 | const typename RecvOverlap::traits::baseSequence::iterator rEnd = rPoints->end();
|
---|
980 |
|
---|
981 | for(typename RecvOverlap::traits::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
982 | // TODO: This must become a more general iterator over colors
|
---|
983 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
984 | // Just taking the first value
|
---|
985 | const typename Section::point_type& localPoint = *p_iter;
|
---|
986 | const typename OverlapSection::point_type& remotePoint = points->begin().color();
|
---|
987 | const typename OverlapSection::value_type *overlapValues = overlapSection->restrictPoint(remotePoint);
|
---|
988 | const typename Section::value_type *localValues = section->restrictPoint(localPoint);
|
---|
989 | const int dim = section->getFiberDimension(localPoint);
|
---|
990 | // TODO: optimize allocation
|
---|
991 | typename Section::value_type *values = new typename Section::value_type[dim];
|
---|
992 |
|
---|
993 | for(int d = 0; d < dim; ++d) {
|
---|
994 | values[d] = binaryOp(overlapValues[d], localValues[d]);
|
---|
995 | }
|
---|
996 | section->updatePoint(localPoint, values);
|
---|
997 | delete [] values;
|
---|
998 | }
|
---|
999 | }
|
---|
1000 | };
|
---|
1001 | class ReplacementBinaryFusion {
|
---|
1002 | public:
|
---|
1003 | template<typename OverlapSection, typename RecvOverlap, typename Section>
|
---|
1004 | static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, const Obj<Section>& section) {
|
---|
1005 | const Obj<typename RecvOverlap::traits::baseSequence> rPoints = recvOverlap->base();
|
---|
1006 | const typename RecvOverlap::traits::baseSequence::iterator rEnd = rPoints->end();
|
---|
1007 |
|
---|
1008 | for(typename RecvOverlap::traits::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1009 | // TODO: This must become a more general iterator over colors
|
---|
1010 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1011 | // Just taking the first value
|
---|
1012 | const typename Section::point_type& localPoint = *p_iter;
|
---|
1013 | const typename OverlapSection::point_type& remotePoint = points->begin().color();
|
---|
1014 |
|
---|
1015 | section->update(localPoint, overlapSection->restrictPoint(remotePoint));
|
---|
1016 | }
|
---|
1017 | }
|
---|
1018 | };
|
---|
1019 | class AdditiveBinaryFusion {
|
---|
1020 | public:
|
---|
1021 | template<typename OverlapSection, typename RecvOverlap, typename Section>
|
---|
1022 | static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, const Obj<Section>& section) {
|
---|
1023 | typedef typename Section::point_type point_type;
|
---|
1024 | typedef typename OverlapSection::point_type overlap_point_type;
|
---|
1025 | const typename RecvOverlap::capSequence::iterator rBegin = recvOverlap->capBegin();
|
---|
1026 | const typename RecvOverlap::capSequence::iterator rEnd = recvOverlap->capEnd();
|
---|
1027 |
|
---|
1028 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
1029 | const int rank = *r_iter;
|
---|
1030 | const typename RecvOverlap::supportSequence::iterator pBegin = recvOverlap->supportBegin(*r_iter);
|
---|
1031 | const typename RecvOverlap::supportSequence::iterator pEnd = recvOverlap->supportEnd(*r_iter);
|
---|
1032 |
|
---|
1033 | for(typename RecvOverlap::supportSequence::iterator p_iter = pBegin; p_iter != pEnd; ++p_iter) {
|
---|
1034 | const point_type& localPoint = *p_iter;
|
---|
1035 | const point_type& remotePoint = p_iter.color();
|
---|
1036 |
|
---|
1037 | section->updateAddPoint(localPoint, overlapSection->restrictPoint(overlap_point_type(rank, remotePoint)));
|
---|
1038 | }
|
---|
1039 | }
|
---|
1040 | }
|
---|
1041 | };
|
---|
1042 | class InsertionBinaryFusion {
|
---|
1043 | public:
|
---|
1044 | // Insert the overlapSection values into section along recvOverlap
|
---|
1045 | template<typename OverlapSection, typename RecvOverlap, typename Section>
|
---|
1046 | static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, const Obj<Section>& section) {
|
---|
1047 | typedef typename Section::point_type point_type;
|
---|
1048 | typedef typename OverlapSection::point_type overlap_point_type;
|
---|
1049 | #if 0
|
---|
1050 | const Obj<typename RecvOverlap::baseSequence> rPoints = recvOverlap->base();
|
---|
1051 | const typename RecvOverlap::baseSequence::iterator rEnd = rPoints->end();
|
---|
1052 |
|
---|
1053 | for(typename RecvOverlap::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1054 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1055 | const point_type& localPoint = *p_iter;
|
---|
1056 | const int rank = *points->begin();
|
---|
1057 | const point_type& remotePoint = points->begin().color();
|
---|
1058 |
|
---|
1059 | if (overlapSection->hasPoint(overlap_point_type(rank, remotePoint))) {
|
---|
1060 | if (!section->hasPoint(localPoint)) {
|
---|
1061 | std::cout <<"["<<section->commRank()<<"]: Destination section does not have local point " << localPoint << " remote point " << remotePoint << " fiber dim " << overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint)) << std::endl;
|
---|
1062 | }
|
---|
1063 | section->setFiberDimension(localPoint, overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint)));
|
---|
1064 | }
|
---|
1065 | }
|
---|
1066 | if (rPoints->size()) {section->allocatePoint();}
|
---|
1067 | for(typename RecvOverlap::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1068 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1069 | const point_type& localPoint = *p_iter;
|
---|
1070 | const int rank = *points->begin();
|
---|
1071 | const point_type& remotePoint = points->begin().color();
|
---|
1072 |
|
---|
1073 | if (overlapSection->hasPoint(overlap_point_type(rank, remotePoint))) {
|
---|
1074 | section->updatePoint(localPoint, overlapSection->restrictPoint(overlap_point_type(rank, remotePoint)));
|
---|
1075 | }
|
---|
1076 | }
|
---|
1077 | #else
|
---|
1078 | const typename RecvOverlap::capSequence::iterator rBegin = recvOverlap->capBegin();
|
---|
1079 | const typename RecvOverlap::capSequence::iterator rEnd = recvOverlap->capEnd();
|
---|
1080 | bool hasPoints = false;
|
---|
1081 |
|
---|
1082 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
1083 | const int rank = *r_iter;
|
---|
1084 | const typename RecvOverlap::supportSequence::iterator pBegin = recvOverlap->supportBegin(*r_iter);
|
---|
1085 | const typename RecvOverlap::supportSequence::iterator pEnd = recvOverlap->supportEnd(*r_iter);
|
---|
1086 |
|
---|
1087 | for(typename RecvOverlap::supportSequence::iterator p_iter = pBegin; p_iter != pEnd; ++p_iter) {
|
---|
1088 | const point_type& localPoint = *p_iter;
|
---|
1089 | const point_type& remotePoint = p_iter.color();
|
---|
1090 |
|
---|
1091 | if (overlapSection->hasPoint(overlap_point_type(rank, remotePoint))) {
|
---|
1092 | if (!section->hasPoint(localPoint)) {
|
---|
1093 | std::cout <<"["<<section->commRank()<<"]: Destination section does not have local point " << localPoint << " remote point " << remotePoint << " fiber dim " << overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint)) << std::endl;
|
---|
1094 | }
|
---|
1095 | section->setFiberDimension(localPoint, overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint)));
|
---|
1096 | }
|
---|
1097 | hasPoints = true;
|
---|
1098 | }
|
---|
1099 | }
|
---|
1100 | if (hasPoints) {section->allocatePoint();}
|
---|
1101 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
1102 | const int rank = *r_iter;
|
---|
1103 | const typename RecvOverlap::supportSequence::iterator pBegin = recvOverlap->supportBegin(*r_iter);
|
---|
1104 | const typename RecvOverlap::supportSequence::iterator pEnd = recvOverlap->supportEnd(*r_iter);
|
---|
1105 |
|
---|
1106 | for(typename RecvOverlap::supportSequence::iterator p_iter = pBegin; p_iter != pEnd; ++p_iter) {
|
---|
1107 | const point_type& localPoint = *p_iter;
|
---|
1108 | const point_type& remotePoint = p_iter.color();
|
---|
1109 |
|
---|
1110 | if (overlapSection->hasPoint(overlap_point_type(rank, remotePoint))) {
|
---|
1111 | section->updatePoint(localPoint, overlapSection->restrictPoint(overlap_point_type(rank, remotePoint)));
|
---|
1112 | }
|
---|
1113 | }
|
---|
1114 | }
|
---|
1115 | #endif
|
---|
1116 | }
|
---|
1117 | // Specialize to ArrowSection
|
---|
1118 | template<typename OverlapSection, typename RecvOverlap>
|
---|
1119 | static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, const Obj<UniformSection<MinimalArrow<int,int>,int> >& section) {
|
---|
1120 | typedef UniformSection<MinimalArrow<int,int>,int> Section;
|
---|
1121 | const Obj<typename RecvOverlap::traits::baseSequence> rPoints = recvOverlap->base();
|
---|
1122 | const typename RecvOverlap::traits::baseSequence::iterator rBegin = rPoints->begin();
|
---|
1123 | const typename RecvOverlap::traits::baseSequence::iterator rEnd = rPoints->end();
|
---|
1124 |
|
---|
1125 | for(typename RecvOverlap::traits::baseSequence::iterator p_iter = rBegin; p_iter != rEnd; ++p_iter) {
|
---|
1126 | const Obj<typename RecvOverlap::coneSequence>& sources = recvOverlap->cone(*p_iter);
|
---|
1127 | const typename RecvOverlap::target_type localSource = *p_iter;
|
---|
1128 | const typename RecvOverlap::target_type remoteSource = sources->begin().color();
|
---|
1129 |
|
---|
1130 | for(typename RecvOverlap::traits::baseSequence::iterator q_iter = rBegin; q_iter != rEnd; ++q_iter) {
|
---|
1131 | const Obj<typename RecvOverlap::coneSequence>& targets = recvOverlap->cone(*q_iter);
|
---|
1132 | const typename RecvOverlap::target_type localTarget = *q_iter;
|
---|
1133 | const typename RecvOverlap::target_type remoteTarget = targets->begin().color();
|
---|
1134 | const typename Section::point_type localPoint(localSource, localTarget);
|
---|
1135 | const typename OverlapSection::point_type remotePoint(remoteSource, remoteTarget);
|
---|
1136 |
|
---|
1137 | if (overlapSection->hasPoint(remotePoint)) {section->setFiberDimension(localPoint, overlapSection->getFiberDimension(remotePoint));}
|
---|
1138 | }
|
---|
1139 | }
|
---|
1140 | if (rPoints->size()) {section->allocatePoint();}
|
---|
1141 | for(typename RecvOverlap::traits::baseSequence::iterator p_iter = rBegin; p_iter != rEnd; ++p_iter) {
|
---|
1142 | const Obj<typename RecvOverlap::coneSequence>& sources = recvOverlap->cone(*p_iter);
|
---|
1143 | const typename RecvOverlap::target_type localSource = *p_iter;
|
---|
1144 | const typename RecvOverlap::target_type remoteSource = sources->begin().color();
|
---|
1145 |
|
---|
1146 | for(typename RecvOverlap::traits::baseSequence::iterator q_iter = rBegin; q_iter != rEnd; ++q_iter) {
|
---|
1147 | const Obj<typename RecvOverlap::coneSequence>& targets = recvOverlap->cone(*q_iter);
|
---|
1148 | const typename RecvOverlap::target_type localTarget = *q_iter;
|
---|
1149 | const typename RecvOverlap::target_type remoteTarget = targets->begin().color();
|
---|
1150 | const typename Section::point_type localPoint(localSource, localTarget);
|
---|
1151 | const typename OverlapSection::point_type remotePoint(remoteSource, remoteTarget);
|
---|
1152 |
|
---|
1153 | if (overlapSection->hasPoint(remotePoint)) {section->updatePoint(localPoint, overlapSection->restrictPoint(remotePoint));}
|
---|
1154 | }
|
---|
1155 | }
|
---|
1156 | }
|
---|
1157 | // Specialize to the Sieve
|
---|
1158 | template<typename OverlapSection, typename RecvOverlap, typename Renumbering, typename Point>
|
---|
1159 | static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, Renumbering& renumbering, const Obj<Sieve<Point,Point,int> >& sieve) {
|
---|
1160 | typedef typename OverlapSection::point_type overlap_point_type;
|
---|
1161 | const Obj<typename RecvOverlap::traits::baseSequence> rPoints = recvOverlap->base();
|
---|
1162 | const typename RecvOverlap::traits::baseSequence::iterator rEnd = rPoints->end();
|
---|
1163 |
|
---|
1164 | for(typename RecvOverlap::traits::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1165 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1166 | const Point& localPoint = *p_iter;
|
---|
1167 | const int rank = *points->begin();
|
---|
1168 | const Point& remotePoint = points->begin().color();
|
---|
1169 | const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
|
---|
1170 | const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
|
---|
1171 | int c = 0;
|
---|
1172 |
|
---|
1173 | sieve->clearCone(localPoint);
|
---|
1174 | for(int i = 0; i < size; ++i, ++c) {sieve->addCone(renumbering[values[i]], localPoint, c);}
|
---|
1175 | }
|
---|
1176 | }
|
---|
1177 | // Specialize to the ISieve
|
---|
1178 | template<typename OverlapSection, typename RecvOverlap, typename Renumbering, typename Point>
|
---|
1179 | static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, Renumbering& renumbering, const Obj<IFSieve<Point> >& sieve) {
|
---|
1180 | typedef typename OverlapSection::point_type overlap_point_type;
|
---|
1181 | #if 0
|
---|
1182 | const Obj<typename RecvOverlap::baseSequence> rPoints = recvOverlap->base();
|
---|
1183 | const typename RecvOverlap::baseSequence::iterator rEnd = rPoints->end();
|
---|
1184 | int maxSize = 0;
|
---|
1185 |
|
---|
1186 | for(typename RecvOverlap::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1187 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1188 | const Point& localPoint = *p_iter;
|
---|
1189 | const int rank = *points->begin();
|
---|
1190 | const Point& remotePoint = points->begin().color();
|
---|
1191 | const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
|
---|
1192 | const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
|
---|
1193 |
|
---|
1194 | sieve->setConeSize(localPoint, size);
|
---|
1195 | ///for(int i = 0; i < size; ++i) {sieve->addSupportSize(renumbering[values[i]], 1);}
|
---|
1196 | for(int i = 0; i < size; ++i) {sieve->addSupportSize(renumbering[values[i].first], 1);}
|
---|
1197 | maxSize = std::max(maxSize, size);
|
---|
1198 | }
|
---|
1199 | sieve->allocate();
|
---|
1200 | ///typename OverlapSection::value_type *localValues = new typename OverlapSection::value_type[maxSize];
|
---|
1201 | typename OverlapSection::value_type::first_type *localValues = new typename OverlapSection::value_type::first_type[maxSize];
|
---|
1202 | typename OverlapSection::value_type::second_type *localOrientation = new typename OverlapSection::value_type::second_type[maxSize];
|
---|
1203 |
|
---|
1204 | for(typename RecvOverlap::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1205 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1206 | const Point& localPoint = *p_iter;
|
---|
1207 | const int rank = *points->begin();
|
---|
1208 | const Point& remotePoint = points->begin().color();
|
---|
1209 | const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
|
---|
1210 | const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
|
---|
1211 |
|
---|
1212 | ///for(int i = 0; i < size; ++i) {localValues[i] = renumbering[values[i]];}
|
---|
1213 | for(int i = 0; i < size; ++i) {
|
---|
1214 | localValues[i] = renumbering[values[i].first];
|
---|
1215 | localOrientation[i] = values[i].second;
|
---|
1216 | }
|
---|
1217 | sieve->setCone(localValues, localPoint);
|
---|
1218 | sieve->setConeOrientation(localOrientation, localPoint);
|
---|
1219 | }
|
---|
1220 | delete [] localValues;
|
---|
1221 | delete [] localOrientation;
|
---|
1222 | #else
|
---|
1223 | const typename RecvOverlap::capSequence::iterator rBegin = recvOverlap->capBegin();
|
---|
1224 | const typename RecvOverlap::capSequence::iterator rEnd = recvOverlap->capEnd();
|
---|
1225 | int maxSize = 0;
|
---|
1226 |
|
---|
1227 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
1228 | const int rank = *r_iter;
|
---|
1229 | const typename RecvOverlap::supportSequence::iterator pBegin = recvOverlap->supportBegin(*r_iter);
|
---|
1230 | const typename RecvOverlap::supportSequence::iterator pEnd = recvOverlap->supportEnd(*r_iter);
|
---|
1231 |
|
---|
1232 | for(typename RecvOverlap::supportSequence::iterator p_iter = pBegin; p_iter != pEnd; ++p_iter) {
|
---|
1233 | const Point& localPoint = *p_iter;
|
---|
1234 | const Point& remotePoint = p_iter.color();
|
---|
1235 | const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
|
---|
1236 | const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
|
---|
1237 |
|
---|
1238 | sieve->setConeSize(localPoint, size);
|
---|
1239 | for(int i = 0; i < size; ++i) {sieve->addSupportSize(renumbering[values[i].first], 1);}
|
---|
1240 | maxSize = std::max(maxSize, size);
|
---|
1241 | }
|
---|
1242 | }
|
---|
1243 | sieve->allocate();
|
---|
1244 | typename OverlapSection::value_type::first_type *localValues = new typename OverlapSection::value_type::first_type[maxSize];
|
---|
1245 | typename OverlapSection::value_type::second_type *localOrientation = new typename OverlapSection::value_type::second_type[maxSize];
|
---|
1246 |
|
---|
1247 | for(typename RecvOverlap::capSequence::iterator r_iter = rBegin; r_iter != rEnd; ++r_iter) {
|
---|
1248 | const int rank = *r_iter;
|
---|
1249 | const typename RecvOverlap::supportSequence::iterator pBegin = recvOverlap->supportBegin(*r_iter);
|
---|
1250 | const typename RecvOverlap::supportSequence::iterator pEnd = recvOverlap->supportEnd(*r_iter);
|
---|
1251 |
|
---|
1252 | for(typename RecvOverlap::supportSequence::iterator p_iter = pBegin; p_iter != pEnd; ++p_iter) {
|
---|
1253 | const Point& localPoint = *p_iter;
|
---|
1254 | const Point& remotePoint = p_iter.color();
|
---|
1255 | const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
|
---|
1256 | const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
|
---|
1257 |
|
---|
1258 | for(int i = 0; i < size; ++i) {
|
---|
1259 | localValues[i] = renumbering[values[i].first];
|
---|
1260 | localOrientation[i] = values[i].second;
|
---|
1261 | }
|
---|
1262 | sieve->setCone(localValues, localPoint);
|
---|
1263 | sieve->setConeOrientation(localOrientation, localPoint);
|
---|
1264 | }
|
---|
1265 | }
|
---|
1266 | delete [] localValues;
|
---|
1267 | delete [] localOrientation;
|
---|
1268 | #endif
|
---|
1269 | }
|
---|
1270 | template<typename OverlapSection, typename RecvOverlap, typename Point>
|
---|
1271 | static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, const Obj<IFSieve<Point> >& sieve) {
|
---|
1272 | typedef typename OverlapSection::point_type overlap_point_type;
|
---|
1273 | #if 0
|
---|
1274 | const Obj<typename RecvOverlap::baseSequence> rPoints = recvOverlap->base();
|
---|
1275 | const typename RecvOverlap::baseSequence::iterator rEnd = rPoints->end();
|
---|
1276 | int maxSize = 0;
|
---|
1277 |
|
---|
1278 | for(typename RecvOverlap::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1279 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1280 | const Point& localPoint = *p_iter;
|
---|
1281 | const int rank = *points->begin();
|
---|
1282 | const Point& remotePoint = points->begin().color();
|
---|
1283 | const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
|
---|
1284 | const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
|
---|
1285 |
|
---|
1286 | sieve->setConeSize(localPoint, size);
|
---|
1287 | for(int i = 0; i < size; ++i) {sieve->addSupportSize(values[i].first, 1);}
|
---|
1288 | maxSize = std::max(maxSize, size);
|
---|
1289 | }
|
---|
1290 | sieve->allocate();
|
---|
1291 | typename OverlapSection::value_type::first_type *localValues = new typename OverlapSection::value_type::first_type[maxSize];
|
---|
1292 | typename OverlapSection::value_type::second_type *localOrientation = new typename OverlapSection::value_type::second_type[maxSize];
|
---|
1293 |
|
---|
1294 | for(typename RecvOverlap::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1295 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1296 | const Point& localPoint = *p_iter;
|
---|
1297 | const int rank = *points->begin();
|
---|
1298 | const Point& remotePoint = points->begin().color();
|
---|
1299 | const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
|
---|
1300 | const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
|
---|
1301 |
|
---|
1302 | for(int i = 0; i < size; ++i) {
|
---|
1303 | localValues[i] = values[i].first;
|
---|
1304 | localOrientation[i] = values[i].second;
|
---|
1305 | }
|
---|
1306 | sieve->setCone(localValues, localPoint);
|
---|
1307 | sieve->setConeOrientation(localOrientation, localPoint);
|
---|
1308 | }
|
---|
1309 | delete [] localValues;
|
---|
1310 | delete [] localOrientation;
|
---|
1311 | #else
|
---|
1312 | const Obj<typename RecvOverlap::capSequence> rRanks = recvOverlap->cap();
|
---|
1313 | const typename RecvOverlap::capSequence::iterator rEnd = rRanks->end();
|
---|
1314 | int maxSize = 0;
|
---|
1315 |
|
---|
1316 | for(typename RecvOverlap::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
1317 | const int rank = *r_iter;
|
---|
1318 | const Obj<typename RecvOverlap::supportSequence>& points = recvOverlap->support(*r_iter);
|
---|
1319 | const typename RecvOverlap::supportSequence::iterator pBegin = points->begin();
|
---|
1320 | const typename RecvOverlap::supportSequence::iterator pEnd = points->end();
|
---|
1321 |
|
---|
1322 | for(typename RecvOverlap::supportSequence::iterator p_iter = pBegin; p_iter != pEnd; ++p_iter) {
|
---|
1323 | const Point& localPoint = *p_iter;
|
---|
1324 | const Point& remotePoint = p_iter.color();
|
---|
1325 | const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
|
---|
1326 | const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
|
---|
1327 |
|
---|
1328 | sieve->setConeSize(localPoint, size);
|
---|
1329 | for(int i = 0; i < size; ++i) {sieve->addSupportSize(values[i].first, 1);}
|
---|
1330 | maxSize = std::max(maxSize, size);
|
---|
1331 | }
|
---|
1332 | }
|
---|
1333 | sieve->allocate();
|
---|
1334 | typename OverlapSection::value_type::first_type *localValues = new typename OverlapSection::value_type::first_type[maxSize];
|
---|
1335 | typename OverlapSection::value_type::second_type *localOrientation = new typename OverlapSection::value_type::second_type[maxSize];
|
---|
1336 |
|
---|
1337 | for(typename RecvOverlap::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
|
---|
1338 | const int rank = *r_iter;
|
---|
1339 | const Obj<typename RecvOverlap::supportSequence>& points = recvOverlap->support(*r_iter);
|
---|
1340 | const typename RecvOverlap::supportSequence::iterator pBegin = points->begin();
|
---|
1341 | const typename RecvOverlap::supportSequence::iterator pEnd = points->end();
|
---|
1342 |
|
---|
1343 | for(typename RecvOverlap::supportSequence::iterator p_iter = pBegin; p_iter != pEnd; ++p_iter) {
|
---|
1344 | const Point& localPoint = *p_iter;
|
---|
1345 | const Point& remotePoint = p_iter.color();
|
---|
1346 | const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
|
---|
1347 | const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
|
---|
1348 |
|
---|
1349 | for(int i = 0; i < size; ++i) {
|
---|
1350 | localValues[i] = values[i].first;
|
---|
1351 | localOrientation[i] = values[i].second;
|
---|
1352 | }
|
---|
1353 | sieve->setCone(localValues, localPoint);
|
---|
1354 | sieve->setConeOrientation(localOrientation, localPoint);
|
---|
1355 | }
|
---|
1356 | }
|
---|
1357 | delete [] localValues;
|
---|
1358 | delete [] localOrientation;
|
---|
1359 | #endif
|
---|
1360 | }
|
---|
1361 | // Generic
|
---|
1362 | template<typename OverlapSection, typename RecvOverlap, typename Section, typename Bundle>
|
---|
1363 | static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, const Obj<Section>& section, const Obj<Bundle>& bundle) {
|
---|
1364 | typedef typename OverlapSection::point_type overlap_point_type;
|
---|
1365 | const Obj<typename RecvOverlap::baseSequence> rPoints = recvOverlap->base();
|
---|
1366 | const typename RecvOverlap::baseSequence::iterator rEnd = rPoints->end();
|
---|
1367 |
|
---|
1368 | for(typename RecvOverlap::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1369 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1370 | const typename Section::point_type& localPoint = *p_iter;
|
---|
1371 | const int rank = *points->begin();
|
---|
1372 | const typename OverlapSection::point_type& remotePoint = points->begin().color();
|
---|
1373 |
|
---|
1374 | section->setFiberDimension(localPoint, overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint)));
|
---|
1375 | }
|
---|
1376 | bundle->allocate(section);
|
---|
1377 | for(typename RecvOverlap::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1378 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1379 | const typename Section::point_type& localPoint = *p_iter;
|
---|
1380 | const int rank = *points->begin();
|
---|
1381 | const typename OverlapSection::point_type& remotePoint = points->begin().color();
|
---|
1382 |
|
---|
1383 | section->update(localPoint, overlapSection->restrictPoint(overlap_point_type(rank, remotePoint)));
|
---|
1384 | }
|
---|
1385 | }
|
---|
1386 | };
|
---|
1387 | class InterpolateMultipleFusion {
|
---|
1388 | public:
|
---|
1389 | // Interpolate the overlapSection values into section along recvOverlap
|
---|
1390 | template<typename OverlapSection, typename RecvOverlap, typename Section>
|
---|
1391 | static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, const Obj<Section>& section) {
|
---|
1392 | typedef typename Section::point_type point_type;
|
---|
1393 | typedef typename Section::value_type value_type;
|
---|
1394 | typedef typename OverlapSection::point_type overlap_point_type;
|
---|
1395 | const Obj<typename RecvOverlap::traits::baseSequence> rPoints = recvOverlap->base();
|
---|
1396 | const typename RecvOverlap::traits::baseSequence::iterator rEnd = rPoints->end();
|
---|
1397 | int maxFiberDim = -1;
|
---|
1398 |
|
---|
1399 | for(typename RecvOverlap::traits::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1400 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1401 | const typename RecvOverlap::coneSequence::iterator rpEnd = points->end();
|
---|
1402 | const point_type& localPoint = *p_iter;
|
---|
1403 | bool inOverlap = false;
|
---|
1404 | int fiberDim = -1;
|
---|
1405 |
|
---|
1406 | for(typename RecvOverlap::coneSequence::iterator rp_iter = points->begin(); rp_iter != rpEnd; ++rp_iter) {
|
---|
1407 | const int rank = *rp_iter;
|
---|
1408 | const point_type& remotePoint = rp_iter.color();
|
---|
1409 |
|
---|
1410 | if (overlapSection->hasPoint(overlap_point_type(rank, remotePoint))) {
|
---|
1411 | inOverlap = true;
|
---|
1412 | fiberDim = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
|
---|
1413 | break;
|
---|
1414 | }
|
---|
1415 | }
|
---|
1416 | if (inOverlap) {
|
---|
1417 | if (!section->hasPoint(localPoint)) {
|
---|
1418 | std::cout <<"["<<section->commRank()<<"]: Destination section does not have local point " << localPoint << " remote point " << (points->begin().color()) << " fiber dim " << fiberDim << std::endl;
|
---|
1419 | }
|
---|
1420 | section->setFiberDimension(localPoint, fiberDim);
|
---|
1421 | maxFiberDim = std::max(fiberDim, maxFiberDim);
|
---|
1422 | }
|
---|
1423 | }
|
---|
1424 | if (rPoints->size()) {section->allocatePoint();}
|
---|
1425 | value_type *interpolant = new value_type[maxFiberDim];
|
---|
1426 |
|
---|
1427 | for(typename RecvOverlap::traits::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
|
---|
1428 | const Obj<typename RecvOverlap::coneSequence>& points = recvOverlap->cone(*p_iter);
|
---|
1429 | const typename RecvOverlap::coneSequence::iterator rpEnd = points->end();
|
---|
1430 | const point_type& localPoint = *p_iter;
|
---|
1431 | bool inOverlap = false;
|
---|
1432 | int numArgs = 0;
|
---|
1433 |
|
---|
1434 | for(int d = 0; d < maxFiberDim; ++d) {interpolant[d] = 0.0;}
|
---|
1435 | for(typename RecvOverlap::coneSequence::iterator rp_iter = points->begin(); rp_iter != rpEnd; ++rp_iter) {
|
---|
1436 | const int rank = *rp_iter;
|
---|
1437 | const point_type& remotePoint = rp_iter.color();
|
---|
1438 | const overlap_point_type opoint(rank, remotePoint);
|
---|
1439 |
|
---|
1440 | if (overlapSection->hasPoint(opoint)) {
|
---|
1441 | const int fiberDim = overlapSection->getFiberDimension(opoint);
|
---|
1442 | const value_type *values = overlapSection->restrictPoint(opoint);
|
---|
1443 |
|
---|
1444 | // TODO: Include interpolation weights (stored in overlap)
|
---|
1445 | for(int d = 0; d < fiberDim; ++d) {
|
---|
1446 | interpolant[d] += values[d];
|
---|
1447 | }
|
---|
1448 | inOverlap = true;
|
---|
1449 | ++numArgs;
|
---|
1450 | }
|
---|
1451 | }
|
---|
1452 | if (inOverlap) {
|
---|
1453 | for(int d = 0; d < maxFiberDim; ++d) {interpolant[d] /= numArgs;}
|
---|
1454 | section->updatePoint(localPoint, interpolant);
|
---|
1455 | }
|
---|
1456 | }
|
---|
1457 | delete [] interpolant;
|
---|
1458 | }
|
---|
1459 | };
|
---|
1460 | }
|
---|
1461 | }
|
---|
1462 |
|
---|
1463 | #endif
|
---|