52 vnodesPerDirection_m = 0;
56 for (
unsigned int dl=0; dl <
Dim; ++dl) RequestedLayout[dl] =
PARALLEL;
75 vnodesPerDirection_m = 0;
79 for (
unsigned int dl=0; dl <
Dim; ++dl) RequestedLayout[dl] =
PARALLEL;
91 if (vnodesPerDirection_m != 0)
92 delete [] vnodesPerDirection_m;
107template<
unsigned Dim>
113 setup(domain, p, vnodes);
117template<
unsigned Dim>
124 "Number of arguments does not match dimension of FieldLayout!!");
126 setup(ndi,&p1,vnodes);
129template<
unsigned Dim>
137 "Number of arguments does not match dimension of FieldLayout!!");
144 setup(ndi,par,vnodes);
146template<
unsigned Dim>
153 "Number of arguments does not match dimension of FieldLayout!!");
162 setup(ndi,par,vnodes);
164template<
unsigned Dim>
174 "Number of arguments does not match dimension of FieldLayout!!");
185 setup(ndi,par,vnodes);
187template<
unsigned Dim>
196 "Number of arguments does not match dimension of FieldLayout!!");
209 setup(ndi,par,vnodes);
211template<
unsigned Dim>
220 "Number of arguments does not match dimension of FieldLayout!!");
235 setup(ndi,par,vnodes);
245template<
unsigned Dim>
248 e_dim_tag *p,
unsigned* vnodesPerDirection,
249 bool recurse,
int vnodes) {
253 unsigned vnodesProduct = 1;
254 for (
unsigned int d=0; d<
Dim; d++) vnodesProduct *= vnodesPerDirection[d];
255 if (vnodes == -1) vnodes = vnodesProduct;
257 if ((
unsigned int) vnodes != vnodesProduct) {
258 ERRORMSG(
"FieldLayout constructor: "
259 <<
"(vnodes != vnodesPerDirection[0]*vnodesPerDirection[1]*"
260 <<
"...*vnodesPerDirection[" <<
Dim-1 <<
"])"
261 <<
" ; vnodesPerDirection[0]*vnodesPerDirection[1]*"
262 <<
"...*vnodesPerDirection[" <<
Dim-1 <<
"] = "
263 << vnodesProduct <<
" ; vnodes = " << vnodes <<
endl);
265 setup(domain, p, vnodesPerDirection,recurse,vnodes);
268template<
unsigned Dim>
271 unsigned vnodes1,
bool recurse,
int vnodes) {
276 "Number of arguments does not match dimension of FieldLayout!!");
278 setup(ndi,&p1,&vnodes1,recurse,vnodes);
281template<
unsigned Dim>
285 unsigned vnodes1,
unsigned vnodes2,
286 bool recurse,
int vnodes) {
289 "Number of arguments does not match dimension of FieldLayout!!");
296 unsigned vnodesPerDirection[
Dim];
297 vnodesPerDirection[0] = vnodes1;
298 vnodesPerDirection[1] = vnodes2;
299 setup(ndi,par,vnodesPerDirection,recurse,vnodes);
301template<
unsigned Dim>
305 unsigned vnodes1,
unsigned vnodes2,
307 bool recurse,
int vnodes) {
310 "Number of arguments does not match dimension of FieldLayout!!");
319 unsigned vnodesPerDirection[
Dim];
320 vnodesPerDirection[0] = vnodes1;
321 vnodesPerDirection[1] = vnodes2;
322 vnodesPerDirection[2] = vnodes3;
323 setup(ndi,par,vnodesPerDirection,recurse,vnodes);
325template<
unsigned Dim>
331 unsigned vnodes1,
unsigned vnodes2,
332 unsigned vnodes3,
unsigned vnodes4,
333 bool recurse,
int vnodes) {
336 "Number of arguments does not match dimension of FieldLayout!!");
347 unsigned vnodesPerDirection[
Dim];
348 vnodesPerDirection[0] = vnodes1;
349 vnodesPerDirection[1] = vnodes2;
350 vnodesPerDirection[2] = vnodes3;
351 vnodesPerDirection[3] = vnodes4;
352 setup(ndi,par,vnodesPerDirection,recurse,vnodes);
354template<
unsigned Dim>
360 unsigned vnodes1,
unsigned vnodes2,
361 unsigned vnodes3,
unsigned vnodes4,
363 bool recurse,
int vnodes) {
366 "Number of arguments does not match dimension of FieldLayout!!");
379 unsigned vnodesPerDirection[
Dim];
380 vnodesPerDirection[0] = vnodes1;
381 vnodesPerDirection[1] = vnodes2;
382 vnodesPerDirection[2] = vnodes3;
383 vnodesPerDirection[3] = vnodes4;
384 vnodesPerDirection[4] = vnodes5;
385 setup(ndi,par,vnodesPerDirection,recurse,vnodes);
387template<
unsigned Dim>
393 unsigned vnodes1,
unsigned vnodes2,
394 unsigned vnodes3,
unsigned vnodes4,
395 unsigned vnodes5,
unsigned vnodes6,
396 bool recurse,
int vnodes) {
399 "Number of arguments does not match dimension of FieldLayout!!");
414 unsigned vnodesPerDirection[
Dim];
415 vnodesPerDirection[0] = vnodes1;
416 vnodesPerDirection[1] = vnodes2;
417 vnodesPerDirection[2] = vnodes3;
418 vnodesPerDirection[3] = vnodes4;
419 vnodesPerDirection[4] = vnodes5;
420 vnodesPerDirection[5] = vnodes6;
421 setup(ndi,par,vnodesPerDirection,recurse,vnodes);
434template<
unsigned Dim>
439 const int *nbegin,
const int *nend)
450 int vnodes = (nend - nbegin);
452 "A user-specified FieldLayout must have at least one vnode.");
453 PInsist(vnodes == (domend - dombegin),
454 "A user-specified FieldLayout must have equal length node and domain lists");
458 for (d = 0; d <
Dim; ++d)
462 vnodesPerDirection_m = 0;
467 Remotes_ac.insert( vntype(gc0(), remote_ac) );
475 for (i = 0; i < vnodes; ++i) {
477 for (j = (i+1); j < vnodes; ++j) {
478 PInsist(! (dombegin[i].touches(dombegin[j])),
479 "A user-specified FieldLayout cannot have overlapping domains.");
484 "A user-specified FieldLayout must have legal node assignments.");
487 coverage += dombegin[i].
size();
493 bool nosplit = (dombegin[i].
size() < 2);
499 remote_ac->
insert(v2(dombegin[i], vnode), nosplit);
504 "A user-specified FieldLayout must completely cover the domain.");
521template<
unsigned Dim>
536 if (vnodes <= 0) vnodes = nprocs;
543 int parallel_count = 0;
544 unsigned int flagdim = 0;
545 long totparelems = 1;
546 for (flagdim=0; flagdim <
Dim; ++flagdim) {
548 RequestedLayout[flagdim] =
PARALLEL;
550 RequestedLayout[flagdim] = userflags[flagdim];
551 if (RequestedLayout[flagdim] ==
PARALLEL) {
553 totparelems *= domain[flagdim].length();
557 PInsist(parallel_count>0,
"At least one dimension of a FieldLayout must be PARALLEL!");
562 if (totparelems < vnodes) {
565 vnodes = totparelems;
577 domains_c[0] = domain;
581 int v1,v2,rm,vtot,vl,vr;
583 vnodesPerDirection_m = 0;
584 for (v=vnodes,rm=0;v>1;v/=2) { rm += (v % 2); }
594 for (v=1; v<vnodes; v*=2) {
600 for (i=0, j=0; i<v; ++i, j+=2)
602 domains_c[i].split( copy_c[j] , copy_c[j+1] , d );
604 std::copy(copy_c,copy_c+v*2, domains_c);
609 if (++d ==
Dim) d = 0;
626 for (v=1; v<2*vnodes; ++v) {
628 for (v2=v,v1=1;v2>1;v2/=2) { v1 = 2*v1+(v2%2); }
644 leftDomain=domains_c[vl];
647 for (
unsigned int dd=0;dd<
Dim;++dd) {
649 if ((len = leftDomain[dd].length()) > lmax) {
655 domains_c[vl].
split( domains_c[vl] , domains_c[vr] , d ,
a);
668 Remotes_ac.insert( vtype(gc0(),remote_ac) );
669 for (v=0; v<vnodes; ++v)
671 int p = (v*nprocs)/vnodes;
672 bool nosplit = (domains_c[v].
size() < 2);
681 remote_ac->
insert(v2(domains_c[v], vnode), nosplit);
713template<
unsigned Dim>
716 e_dim_tag *userflags,
unsigned* vnodesPerDirection,
717 bool recurse,
int vnodes)
725 if (vnodes <= 0)
ERRORMSG(
"FieldLayout::setup(): vnodes <= 0 "
726 <<
"for a vnodes-per-direction product "
727 <<
"specification; not allowed." <<
endl);
731 unsigned int d, d2, vl;
733 int parallel_count = 0;
734 unsigned int flagdim = 0;
735 for (flagdim=0; flagdim <
Dim; ++flagdim) {
737 RequestedLayout[flagdim] =
PARALLEL;
739 RequestedLayout[flagdim] = userflags[flagdim];
742 parallel_count += (RequestedLayout[flagdim] ==
PARALLEL);
745 if (RequestedLayout[flagdim] ==
SERIAL) {
746 bool chk = vnodesPerDirection[flagdim] == 1;
747 PInsist(chk,
"SERIAL layout specified, yet vnodesPerDirection is not 1!");
752 PInsist(parallel_count>0,
"At least one dimension of a FieldLayout must be PARALLEL!");
755 vnodesPerDirection_m =
new unsigned[
Dim];
756 for (d=0; d<
Dim; d++) vnodesPerDirection_m[d] = vnodesPerDirection[d];
767 unsigned elementsPerVnode[
Dim];
768 unsigned nLargerVnodes[
Dim];
769 for (d=0; d<
Dim; d++) {
770 elementsPerVnode[d] = domain[d].length()/vnodesPerDirection[d];
771 nLargerVnodes[d] = domain[d].length() % vnodesPerDirection[d];
783 for (d=0; d<
Dim; d++) stride[d] = domain[d].stride();
786 for (d=0; d<
Dim; d++) {
787 base[d] =
new int[vnodesPerDirection[d]];
788 bound[d] =
new int[vnodesPerDirection[d]];
791 for (d=0; d<
Dim; d++) {
793 length = elementsPerVnode[d];
794 if (nLargerVnodes[d] > 0) length += 1;
795 base[d][0] = domain[d].first();
796 bound[d][0] = base[d][0] + (length-1)*stride[d];
798 for (vl=1; vl < vnodesPerDirection[d]; vl++) {
799 base[d][vl] = bound[d][vl-1] + stride[d];
800 length = elementsPerVnode[d];
801 if (vl < nLargerVnodes[d]) length += 1;
802 bound[d][vl] = base[d][vl] +(length-1)*stride[d];
808 for (v=0; v<vnodes; v++) {
809 for (d=0; d<
Dim; d++) {
812 for (d2=0; d2<d; d2++) denom *= vnodesPerDirection[d2];
813 int vnodeLevel = (v/denom) % vnodesPerDirection[d];
815 domains_c[v][d] =
Index(base[d][vnodeLevel],bound[d][vnodeLevel],
826 int *vnodeProcs =
new int[vnodes];
827 int *sizes =
new int[
Dim];
828 for (v=0; (
unsigned int) v<
Dim; ++v)
829 sizes[v] = vnodesPerDirection[v];
836 for ( v=0; v<vnodes; ++v )
837 vnodeProcs[v] = (v*nprocs)/vnodes;
844 Remotes_ac.insert(v1(gc0(),remote_ac) );
845 for (v=0; v<vnodes; ++v) {
846 int p = vnodeProcs[v];
863 if (domains_c[v].size() <= 1) {
865 remote_ac->
insert(v1(domains_c[v], vnode),
true);
868 remote_ac->
insert(v1(domains_c[v], vnode),
false);
874 delete [] vnodeProcs;
876 for (d=0; d<
Dim; d++) {
889template<
unsigned Dim>
898 return(vnodesPerDirection_m[dir]);
905template<
unsigned Dim>
917 Remotes_ac.insert(v1(gc,gr) );
927 gr->
insert(v2(domain,(*v_i).second) );
932template<
unsigned Dim>
958 int count = idx_end - idx_begin;
959 bcast_mess->
put(count);
962 while (indxmsg != idx_end)
973 while ((--node_count)>=0)
981 recv_mess->
get(count);
984 while (count-- > 0) {
999 remote_ac->
insert(v1(p, vnode),
true);
1002 remote_ac->
insert(v1(p, vnode),
false);
1016template<
unsigned Dim>
1033 for (
const Vnode<Dim>* p=idx_begin; p!=idx_end; ++p) {
1036 new Vnode<Dim>((*p).getDomain(),mynode,(*p).getVnode())));
1042 int count = idx_end - idx_begin;
1043 bcast_mess->
put(count);
1046 while (indxmsg != idx_end)
1057 while ((--node_count)>=0)
1065 recv_mess->
get(count);
1068 while (count-- > 0) {
1102template<
unsigned Dim>
1114 if (vnodesPerDirection_m != 0) {
1116 for (
unsigned int d=0; d<
Dim; d++) {
1123 for (p=begin_if(); p!=endp; ++p) {
1146template<
unsigned Dim>
1158 if (vnodesPerDirection_m != 0) {
1160 for (
unsigned int d=0; d<
Dim; d++) {
1167 for (p=begin_if(); p!=endp; ++p) {
1185template<
unsigned Dim>
1195 FILE *f = fopen(filename,
"w");
1197 ERRORMSG(
"Could not create FieldLayout data file '" << filename);
1203 fprintf(f,
"dim = %d\n",
Dim);
1204 fprintf(f,
"vnodes = %d\n", numVnodes());
1207 fprintf(f,
"domain =");
1208 for (d=0; d <
Dim; ++d)
1209 fprintf(f,
" %d %d %d",
1210 Domain[d].first(), Domain[d].last(), Domain[d].stride());
1213 if (vnodesPerDirection_m != 0) {
1214 fprintf(f,
"vnodesperdir =");
1215 for (d=0; d <
Dim; ++d)
1216 fprintf(f,
" %d", vnodesPerDirection_m[d]);
1220 for (
iterator_iv localv = begin_iv(); localv != end_iv(); ++localv) {
1223 for (d=0; d <
Dim; ++d)
1224 fprintf(f,
" %d %d %d", vn->
getDomain()[d].first(),
1229 for (
iterator_dv remotev = begin_rdv(); remotev != end_rdv(); ++remotev) {
1232 for (d=0; d <
Dim; ++d)
1233 fprintf(f,
" %d %d %d", vn->
getDomain()[d].first(),
1258template<
unsigned Dim>
1269 unsigned *vnodesPerDir = 0;
1283 for ( ; ok == 1 && metaline != f.
end(); ++metaline) {
1285 int numtokens = (*metaline).second.first;
1286 std::string *tokens = (*metaline).second.second;
1289 if (tokens[0] ==
"dim") {
1291 ERRORMSG(
"Repeated 'dim' line in FieldLayout data file '");
1295 fdim = atoi(tokens[1].c_str());
1297 ERRORMSG(
"Mismatched dimension in FieldLayout data file '");
1301 }
else if (tokens[0] ==
"vnodes") {
1302 if (fvnodes != 0 || vnlist != 0) {
1303 ERRORMSG(
"Repeated 'vnodes' line in FieldLayout data file '");
1307 fvnodes = atoi(tokens[1].c_str());
1309 ERRORMSG(
"Incorrect 'vnodes' line in FieldLayout data file '");
1315 }
else if (tokens[0] ==
"pnodes") {
1317 ERRORMSG(
"Repeated 'pnodes' line in FieldLayout data file '");
1321 fpnodes = atoi(tokens[1].c_str());
1323 ERRORMSG(
"Incorrect 'pnodes' line in FieldLayout data file '");
1327 }
else if (tokens[0] ==
"vnodesperdir") {
1328 if (vnodesPerDir != 0) {
1329 ERRORMSG(
"Repeated 'vnodesperdir' line in FieldLayout data file '");
1333 if (numtokens - 1 !=
Dim) {
1334 ERRORMSG(
"Incorrect 'vnodesperdir' line in FieldLayout data file '");
1338 vnodesPerDir =
new unsigned[
Dim];
1339 for (
unsigned int d=0; d <
Dim; ++d) {
1340 vnodesPerDir[d] = atoi(tokens[d+1].c_str());
1341 if (vnodesPerDir[d] < 1) {
1342 ERRORMSG(
"Illegal vnode per direction value for dim=" << d);
1343 ERRORMSG(
" in FieldLayout data file '" << filename <<
"'."<<
endl);
1347 }
else if (tokens[0] ==
"domain") {
1349 if ((numtokens-1) % 3 != 0 || (numtokens-1) / 3 !=
Dim) {
1350 ERRORMSG(
"Incorrect 'domain' line in FieldLayout data file '");
1354 for (
unsigned int d=0, dindx=1; d <
Dim; ++d) {
1355 fdomain[d] =
Index(atoi(tokens[dindx].c_str()),
1356 atoi(tokens[dindx + 1].c_str()),
1357 atoi(tokens[dindx + 2].c_str()));
1360 }
else if (tokens[0] ==
"block") {
1364 if (numtokens % 3 != 0 || numtokens / 3 != (
Dim+1)) {
1365 ERRORMSG(
"Incorrect 'block' line in FieldLayout data file '");
1368 }
else if (vnlist == 0) {
1369 ERRORMSG(
"In FieldLayout data file '" << filename <<
": You must ");
1370 ERRORMSG(
"give the number vnodes before any block lines." <<
endl);
1373 int vnum = atoi(tokens[1].c_str());
1374 int pnum = atoi(tokens[2].c_str());
1375 if (pnum < 0 || pnum >= fpnodes) {
1376 ERRORMSG(
"Illegal pnode number in 'block' line ");
1381 for (
unsigned int d=0, dindx=3; d <
Dim; ++d) {
1382 vdom[d] =
Index(atoi(tokens[dindx].c_str()),
1383 atoi(tokens[dindx + 1].c_str()),
1384 atoi(tokens[dindx + 2].c_str()));
1390 vnlist[vnodesread++] =
Vnode<Dim>(vdom, pnum, vnum);
1393 ERRORMSG(
"Unrecognized '" << tokens[0] <<
"' line in FieldLayout ");
1400 if (ok != 0 && (fvnodes < 1 || fdim !=
Dim || vnodesread != fvnodes)) {
1401 ERRORMSG(
"Inconsistent FieldLayout data in file '" << filename);
1407 if ( ok != 0 && getNumUsers() > 0 && !(fdomain == Domain) ) {
1408 ERRORMSG(
"You cannot change the global domain of a FieldLayout which");
1421 int vnpdok = (vnodesPerDir != 0 ? 1 : 0);
1424 msg->
put(vnodesPerDir, vnodesPerDir +
Dim);
1425 for (
int v=0; v < fvnodes; ++v) {
1426 msg->
put(vnlist[v]);
1448 vnodesPerDir =
new unsigned[
Dim];
1451 if ((vnodesread = fvnodes) > 0) {
1453 for (
int v=0; v < fvnodes; ++v) {
1468 if (ok != 1 || fvnodes < 1) {
1469 if (vnodesPerDir != 0)
1470 delete [] vnodesPerDir;
1481 int localvnodes = 0;
1482 for (
int v=0; v < fvnodes; ++v) {
1485 if (v > localvnodes) {
1488 vnlist[localvnodes] = vnlist[v];
1496 if (vnodesPerDirection_m != 0)
1497 delete [] vnodesPerDirection_m;
1498 vnodesPerDirection_m = vnodesPerDir;
1501 Repartition(vnlist, vnlist + localvnodes);
1512template<
unsigned Dim>
1517 for (d=0; d <
Dim; ++d)
1518 MinWidth[d] = getDomain()[d].length();
1523 for (d=0; d <
Dim; ++d) {
1524 if ((
unsigned int) dom[d].length() < MinWidth[d])
1525 MinWidth[d] = dom[d].length();
1533 for (d=0; d <
Dim; ++d) {
1534 if ((
unsigned int) dom[d].length() < MinWidth[d])
1535 MinWidth[d] = dom[d].length();
1552template<
unsigned Dim>
1562 if ( guarded == Remotes_ac.end() )
1569template<
unsigned Dim>
1578template<
unsigned Dim>
1583 for (
iterator_iv localv = begin_iv(); localv != end_iv(); ++localv) {
1595template<
unsigned Dim>
1603 out <<
"Domain = " << Domain <<
"\n";
1604 out <<
"FieldLayoutUsers = " << size_if() <<
"\n";
1607 if (vnodesPerDirection_m != 0) {
1608 out <<
"vnodesPerDirection_m[] =";
1609 for (
unsigned int d=0; d<
Dim; d++)
1610 out <<
" " << vnodesPerDirection_m[d];
1615 out <<
"Total number of vnodes = " << numVnodes() <<
std::endl;
1616 out <<
"Local Vnodes = " << Local_ac.size() <<
"\n";
1622 out <<
" vnode " << icount++ <<
": " << *((*v_i).second) <<
std::endl;
1626 out <<
"Remote Vnodes = " << v_ac->
size() <<
"\n";
1629 out <<
" vnode " << icount++ <<
" : " << *((*dv_i).second) <<
std::endl;
void vnodeRecursiveBisection(int dim, const int *sizes, int nprocs, int *procs)
void putMessage(Message &m, const T &t)
#define F_REPARTITION_BCAST_TAG
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
NDIndex< Dim > AddGuardCells(const NDIndex< Dim > &idx, const GuardCellSizes< Dim > &g)
Inform & endl(Inform &inf)
Message & getMessage(Message &m)
bool split(NDIndex< Dim > &l, NDIndex< Dim > &r, unsigned d, double a) const
void insert(const value_type &d, bool noSplit=false)
bool write(const char *filename)
void new_gc_layout(const GuardCellSizes< Dim > &)
void Repartition(const NDIndex< Dim > *, const NDIndex< Dim > *)
bool read(const char *filename)
NDIndex< Dim > getLocalNDIndex()
ac_gc_domain_vnodes Remotes_ac
void checkout(FieldLayoutUser &f)
unsigned getVnodesPerDirection(unsigned dir)
ac_gc_domain_vnodes::iterator iterator_gdv
ac_id_vnodes::const_iterator const_iterator_iv
static GuardCellSizes< Dim > gc0()
e_dim_tag RequestedLayout[Dim]
unsigned * vnodesPerDirection_m
DomainMap< NDIndex< Dim >, RefCountedP< Vnode< Dim > >, Touches< Dim >, Contains< Dim >, Split< Dim > > ac_domain_vnodes
void initialize(const Index &i1, e_dim_tag p1=PARALLEL, int vnodes=-1)
void setup(const NDIndex< Dim > &, e_dim_tag *, int)
iterator_user iterator_if
void checkin(FieldLayoutUser &f, const GuardCellSizes< Dim > &gc=gc0())
ac_id_vnodes::iterator iterator_iv
virtual void Repartition(UserList *)=0
const NDIndex< Dim > & getDomain() const
Message & getMessage(Message &m)
virtual int broadcast_others(Message *, int, bool delmsg=true)
Message * receive_block(int &node, int &tag)
Message & get_iter(OutputIterator o)
Message & put(const T &val)
Message & get(const T &cval)
int next_tag(int t, int s=1000)
container_t::iterator iterator
static Communicate * Comm
std::pair< GuardCellSizes< Dim >, my_auto_ptr< ac_domain_vnodes > > value_type
std::pair< iterator, bool > insert(const value_type &x)