80 template <
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 ) {
123 template<
class RandomIterator,
class T>
124 static RandomIterator
125 FindMedian(
int nprocs,RandomIterator begin, RandomIterator end,
T)
136 int lprocs = nprocs/2;
137 RandomIterator rp, median;
138 for (rp=begin; rp!=end; ++rp)
146 median = begin + ((end-begin)*lprocs)/nprocs;
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)
261 template<
unsigned Dim>
268 int length = data.
size(cutAxis);
269 for (
int i=0; i<length; ++i)
270 reduced[i] = PerpReduce(data,i,cutAxis);
285 template<
class IndexIterator,
unsigned Dim>
287 SendReduce(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)
346 DEBUGMSG(
"Comm->Send to Node " << di <<
", tag=" << tag <<
endl);
350 domainBuffer.erase( domainBuffer.begin(), domainBuffer.end() );
351 reducedBuffer.erase( reducedBuffer.begin(), reducedBuffer.end() );
364 template<
unsigned Dim>
367 int reduce_tag,
int nprocs,
368 int& cutLoc,
int& cutAxis)
373 cutAxis = FindCutAxis(domain, weights.
getLayout());
375 int i, length = domain[cutAxis].length();
376 int offset = domain[cutAxis].first();
377 std::vector<double> reduced(length);
378 std::vector<double> subReduced(length);
379 for (i=0; i<length; ++i)
387 bool* found_touch =
new bool[nodes];
388 for (i=0; i<nodes; ++i) found_touch[i] =
false;
392 lf_p != lf_end && !(found_touch[mynode]); ++lf_p) {
394 if ( (*lf_p).second->getOwned().touches(domain) )
395 found_touch[mynode] =
true;
403 for (rf_p = range.first; rf_p != range.second ; ++rf_p) {
404 int owner = (*((*rf_p).second)).getNode();
405 found_touch[owner] =
true;
408 for (i=0; i<nodes; ++i)
409 if (found_touch[i]) expected++;
410 delete [] found_touch;
412 DEBUGMSG(
"ReceiveReduce, msgs expected=" << expected <<
endl);
414 while ( --expected >= 0 )
420 DEBUGMSG(
"ReceiveReduce: Comm->Receive from Node " << any_node <<
", tag=" << reduce_tag <<
endl);
422 int received_domains = 0;
423 mess->
get(received_domains);
424 while ( --received_domains>=0 )
431 int rfirst = rdomain.
first() - offset;
432 mess->
get(subReduced[rfirst]);
434 int rlast = rdomain.
last() - offset;
435 for (
int i=rfirst; i<=rlast; ++i)
436 reduced[i] += subReduced[i];
444 FindMedian(nprocs,reduced.begin(),reduced.begin()+length,double())
445 -reduced.begin() + domain[cutAxis].first();
464 DEBUGMSG(
"Broadcast cutLoc=" << cutLoc <<
", cutAxis=" << cutAxis <<
endl);
478 template<
unsigned Dim>
481 std::vector< int >& nprocs,
488 int nDomains = domains.size();
489 std::vector< NDIndex<Dim> > cutDomains(nDomains*2);
490 std::vector<int> cutProcs(std::vector<int>::size_type(nDomains*2));
494 for (
int expected = 0; expected < nDomains; ++expected)
500 int cutLocation = 0, cutAxis = 0;
503 DEBUGMSG(
"ReceiveCuts: received bcast " << expected <<
endl);
504 mess->
get(cutLocation);
520 left[ cutAxis ] =
Index( domain[cutAxis].first(), cutLocation-1 );
521 right[ cutAxis ] =
Index( cutLocation, domain[cutAxis].last() );
523 int procs = nprocs[whichDomain];
524 cutProcs[ whichDomain*2 ] = procs/2;
525 cutProcs[ whichDomain*2+1 ] = procs - procs/2;
532 PAssert_EQ(cutProcs.size(), cutDomains.size());
533 for (
unsigned int i=0; i<cutProcs.size(); ++i)
535 if ( cutProcs[i] != 0 )
537 domains.push_back(cutDomains[i]);
538 nprocs.push_back(cutProcs[i]);
554 template<
unsigned Dim>
557 std::vector< int >& nprocs,
569 SendReduce(domains.begin(),domains.end(),weights,reduce_tag);
575 if ( mynode < domains.size() )
580 ReceiveReduce(domains[mynode],weights,reduce_tag,
581 nprocs[mynode],cutLoc,cutAxis);
591 ReceiveCuts(domains,nprocs,bcast_tag);
597 template<
unsigned Dim>
602 std::vector< NDIndex<Dim> > domains;
603 std::vector<int> procs;
612 domains.reserve(nprocs);
613 procs.reserve(nprocs);
616 procs.push_back( nprocs );
626 CutEach(domains,procs,weights);
631 for (
unsigned int i=0; i<procs.size(); ++i)
632 if (mprocs<procs[i]) mprocs = procs[i];
638 typename std::vector< NDIndex<Dim> >
::iterator i;
640 bool degenerated =
false;
642 for(i = domains.begin();i!=domains.end();++i)
644 for(
unsigned int d = 0;d<
Dim;++d)
645 if((*i)[d].first() == (*i)[d].last())
655 return domains.begin()[myproc];
Layout_t & getLayout() const
ac_id_larray::iterator iterator_if
touch_range_dv touch_range_rdv(const NDIndex< Dim > &domain, const GuardCellSizes< Dim > &gc=gc0()) const
void BcastCuts(int cutLoc, int cutAxis, int bcast_tag)
int next_tag(int t, int s=1000)
e_dim_tag getRequestedDistribution(unsigned int d) const
int size(unsigned d) const
#define F_REDUCE_PERP_TAG
Message & get(const T &cval)
Message & put(const T &val)
NDIndex< Dim > CalcBinaryRepartition(FieldLayout< Dim > &, BareField< double, Dim > &)
void getMessage(Message &m, T &t)
e_dim_tag getDistribution(unsigned int d) const
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
std::string::iterator iterator
void putMessage(Message &m, const T &t)
Message * receive_block(int &node, int &tag)
Message & setDelete(const bool c)
static Communicate * Comm
Message & setCopy(const bool c)
bool send(Message *, int node, int tag, bool delmsg=true)
std::pair< touch_iterator_dv, touch_iterator_dv > touch_range_dv
const NDIndex< Dim > & getDomain() const
virtual int broadcast_all(Message *, int)
Inform & endl(Inform &inf)