Actual source code: ParallelMapping.hh
petsc-3.4.5 2014-06-29
1: #ifndef included_ALE_ParallelMapping_hh
2: #define included_ALE_ParallelMapping_hh
4: #ifndef included_ALE_BasicCommunication_hh
5: #include <sieve/BasicCommunication.hh>
6: #endif
8: #ifndef included_ALE_IField_hh
9: #include <sieve/IField.hh>
10: #endif
12: #ifndef included_ALE_Sections_hh
13: #include <sieve/Sections.hh>
14: #endif
16: #include <functional>
17: #include <valarray>
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: };
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: };
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;
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 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;
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()];
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];
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: };
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;
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
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);
313: for(int r = 0, k = 0; r < numOverlaps/2; r++) {
314: int rank = overlapRanks[r*2];
316: for(int p = 0; p < overlapRanks[r*2+1]; p++) {
317: point_type point = overlapPoints[k++];
318: point_type remotePoint = overlapPoints[k++];
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: }
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;
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();
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;
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();
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);
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;
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;
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();
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;
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();
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);
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;
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;
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();
499: for(typename SendOverlap::baseSequence::iterator r_iter = sRanks->begin(); r_iter != sEnd; ++r_iter) {
500: typename SendSection::point_type *v = sendAllocator.allocate(2);
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();
514: for(typename RecvOverlap::capSequence::iterator r_iter = rRanks->begin(); r_iter != rEnd; ++r_iter) {
515: typename SendSection::point_type *v = recvAllocator.allocate(2);
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();
527: typename SendSection::point_type min = -1;
528: typename SendSection::point_type max = -1;
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;
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;
595: copy(sendOverlap, recvOverlap, sendAtlas, recvAtlas);
596: const typename SendOverlap::baseSequence::iterator sBegin = sendOverlap->baseBegin();
597: const typename SendOverlap::baseSequence::iterator sEnd = sendOverlap->baseEnd();
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;
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;
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]);
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();
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;
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);
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;
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]);
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]));
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;
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;
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;
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();
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;
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;
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]);
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();
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;
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);
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;
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]);
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]);
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;
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;
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();
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;
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;
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);
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();
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;
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);
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;
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);
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;
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();
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];
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();
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();
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();
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);
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();
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();
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();
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();
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;
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);
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();
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);
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();
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();
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();
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);
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();
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);
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();
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;
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;
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));
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];
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));
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;
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);
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));
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];
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);
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));
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;
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));
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];
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));
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;
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();
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));
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];
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();
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));
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();
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();
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();
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;
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;
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();
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];
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;
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);
1440: if (overlapSection->hasPoint(opoint)) {
1441: const int fiberDim = overlapSection->getFiberDimension(opoint);
1442: const value_type *values = overlapSection->restrictPoint(opoint);
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: }
1463: #endif