80template <
unsigned Dim>
90 unsigned int maxLength=0;
92 for (
unsigned int d=0; d<
Dim; ++d) {
96 unsigned int length = domain[d].length();
97 if ( maxLength < length ) {
123template<
class RandomIterator,
class T>
125FindMedian(
int nprocs,RandomIterator
begin, RandomIterator
end,
T)
136 int lprocs = nprocs/2;
137 RandomIterator rp, median;
152 T w2 = (w*lprocs)/nprocs;
156 for (rp=
begin; (rp!=
end)&&(!found); ++rp) {
161 if ( (w-w2) > (*rp/
T(2)) )
164 median = (rp+1 !=
end) ? rp+1 : rp;
193 int l1 = data.
size(1);
194 int l2 = data.
size(2);
195 if ( (l1>0) && (l2>0) )
196 for (
int j2=0; j2<l2; ++j2)
197 for (
int j1=0; j1<l1; ++j1)
198 r += data.
offset(i,j1,j2);
202 int l0 = data.
size(0);
203 int l2 = data.
size(2);
204 if ( (l0>0) && (l2>0) )
205 for (
int j2=0; j2<l2; ++j2)
206 for (
int j0=0; j0<l0; ++j0)
207 r += data.
offset(j0,i,j2);
211 int l0 = data.
size(0);
212 int l1 = data.
size(1);
213 if ( (l0>0) && (l1>0) )
214 for (
int j1=0; j1<l1; ++j1)
215 for (
int j0=0; j0<l0; ++j0)
216 r += data.
offset(j0,j1,i);
231 int length = data.
size(1);
232 for (
int j=0; j<length; ++j)
237 int length = data.
size(0);
238 for (
int j=0; j<length; ++j)
261template<
unsigned Dim>
268 int length = data.
size(cutAxis);
269 for (
int i=0; i<length; ++i)
270 reduced[i] = PerpReduce(data,i,cutAxis);
285template<
class IndexIterator,
unsigned Dim>
287SendReduce(IndexIterator domainsBegin, IndexIterator domainsEnd,
292 std::vector<double*> reducedBuffer;
293 std::vector<Index> domainBuffer;
298 for (dp=domainsBegin, di=0; dp!=domainsEnd; ++dp, ++di)
303 int cutAxis = FindCutAxis(*dp, weights.
getLayout());
307 if ( (*dp).touches( (*lf_p).second->getOwned() ) )
311 (*dp).
intersect( (*lf_p).second->getOwned() );
313 int length = intersection[cutAxis].length();
314 double *reduced =
new double[length];
317 LocalReduce(reduced,cutAxis,(*lf_p).second->begin(intersection));
319 reducedBuffer.push_back(reduced);
320 domainBuffer.push_back(intersection[cutAxis]);
324 int nrdomains = reducedBuffer.size();
331 mess->
put(nrdomains);
335 for (
int i=0; i<nrdomains; ++i, ++dbp, ++rbp)
349 domainBuffer.erase( domainBuffer.begin(), domainBuffer.end() );
350 reducedBuffer.erase( reducedBuffer.begin(), reducedBuffer.end() );
363template<
unsigned Dim>
366 int reduce_tag,
int nprocs,
367 int& cutLoc,
int& cutAxis)
372 cutAxis = FindCutAxis(domain, weights.
getLayout());
374 int i, length = domain[cutAxis].length();
375 int offset = domain[cutAxis].first();
376 std::vector<double> reduced(length);
377 std::vector<double> subReduced(length);
378 for (i=0; i<length; ++i)
386 bool* found_touch =
new bool[nodes];
387 for (i=0; i<nodes; ++i) found_touch[i] =
false;
391 lf_p != lf_end && !(found_touch[mynode]); ++lf_p) {
393 if ( (*lf_p).second->getOwned().touches(domain) )
394 found_touch[mynode] =
true;
402 for (rf_p = range.first; rf_p != range.second ; ++rf_p) {
403 int owner = (*((*rf_p).second)).getNode();
404 found_touch[owner] =
true;
407 for (i=0; i<nodes; ++i)
408 if (found_touch[i]) expected++;
409 delete [] found_touch;
412 while ( --expected >= 0 )
419 int received_domains = 0;
420 mess->
get(received_domains);
421 while ( --received_domains>=0 )
428 int rfirst = rdomain.
first() - offset;
429 mess->
get(subReduced[rfirst]);
431 int rlast = rdomain.
last() - offset;
432 for (
int i=rfirst; i<=rlast; ++i)
433 reduced[i] += subReduced[i];
441 FindMedian(nprocs,reduced.begin(),reduced.begin()+length,
double())
442 -reduced.begin() + domain[cutAxis].first();
474template<
unsigned Dim>
477 std::vector< int >& nprocs,
484 int nDomains = domains.size();
485 std::vector< NDIndex<Dim> > cutDomains(nDomains*2);
486 std::vector<int> cutProcs(std::vector<int>::size_type(nDomains*2));
490 for (
int expected = 0; expected < nDomains; ++expected)
496 int cutLocation = 0, cutAxis = 0;
499 mess->
get(cutLocation);
515 left[ cutAxis ] =
Index( domain[cutAxis].first(), cutLocation-1 );
516 right[ cutAxis ] =
Index( cutLocation, domain[cutAxis].last() );
518 int procs = nprocs[whichDomain];
519 cutProcs[ whichDomain*2 ] = procs/2;
520 cutProcs[ whichDomain*2+1 ] = procs - procs/2;
527 PAssert_EQ(cutProcs.size(), cutDomains.size());
528 for (
unsigned int i=0; i<cutProcs.size(); ++i)
530 if ( cutProcs[i] != 0 )
532 domains.push_back(cutDomains[i]);
533 nprocs.push_back(cutProcs[i]);
549template<
unsigned Dim>
552 std::vector< int >& nprocs,
563 SendReduce(domains.begin(),domains.end(),weights,reduce_tag);
568 if ( mynode < domains.size() )
572 ReceiveReduce(domains[mynode],weights,reduce_tag,
573 nprocs[mynode],cutLoc,cutAxis);
579 ReceiveCuts(domains,nprocs,bcast_tag);
584template<
unsigned Dim>
589 std::vector< NDIndex<Dim> > domains;
590 std::vector<int> procs;
599 domains.reserve(nprocs);
600 procs.reserve(nprocs);
603 procs.push_back( nprocs );
612 CutEach(domains,procs,weights);
616 for (
unsigned int i=0; i<procs.size(); ++i)
617 if (mprocs<procs[i]) mprocs = procs[i];
623 typename std::vector< NDIndex<Dim> >
::iterator i;
625 bool degenerated =
false;
627 for(i = domains.begin();i!=domains.end();++i)
629 for(
unsigned int d = 0;d<
Dim;++d)
630 if((*i)[d].first() == (*i)[d].last())
640 return domains.begin()[myproc];
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
void BcastCuts(int cutLoc, int cutAxis, int bcast_tag)
NDIndex< Dim > CalcBinaryRepartition(FieldLayout< Dim > &layout, BareField< double, Dim > &weights)
void putMessage(Message &m, const T &t)
void getMessage(Message &m, T &t)
#define F_REDUCE_PERP_TAG
std::string::iterator iterator
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
Layout_t & getLayout() const
touch_range_dv touch_range_rdv(const NDIndex< Dim > &domain, const GuardCellSizes< Dim > &gc=gc0()) const
const NDIndex< Dim > & getDomain() const
std::pair< touch_iterator_dv, touch_iterator_dv > touch_range_dv
e_dim_tag getRequestedDistribution(unsigned int d) const
e_dim_tag getDistribution(unsigned int d) const
int size(unsigned d) const
bool send(Message *, int node, int tag, bool delmsg=true)
Message * receive_block(int &node, int &tag)
virtual int broadcast_all(Message *, int)
Message & setCopy(const bool c)
Message & put(const T &val)
Message & setDelete(const bool c)
Message & get(const T &cval)
int next_tag(int t, int s=1000)
static Communicate * Comm