00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "FieldLayout/FieldLayout.h"
00028 #include "FieldLayout/VRB.h"
00029 #include "Message/Communicate.h"
00030 #include "Message/Message.h"
00031 #include "Utility/DiscMeta.h"
00032 #include "Utility/IpplInfo.h"
00033 #include "Utility/IpplStats.h"
00034 #include "Utility/PAssert.h"
00035 #include "Profile/Profiler.h"
00036
00037 #include <stdlib.h>
00038
00039
00041
00042
00043 template<unsigned Dim>
00044 FieldLayout<Dim>::FieldLayout() {
00045 TAU_TYPE_STRING(taustr, "void ()");
00046 TAU_PROFILE("FieldLayout::FieldLayout()", taustr, TAU_LAYOUT);
00047
00048
00049
00050
00051
00052 vnodesPerDirection_m = 0;
00053
00054
00055
00056 for (int dl=0; dl < Dim; ++dl) RequestedLayout[dl] = PARALLEL;
00057 }
00058
00059
00061
00062
00063
00064
00065
00066 template<unsigned Dim>
00067 FieldLayout<Dim>::FieldLayout(const char *filename) {
00068 TAU_TYPE_STRING(taustr, "void (const char *)");
00069 TAU_PROFILE("FieldLayout::FieldLayout()", taustr, TAU_LAYOUT);
00070
00071
00072
00073
00074
00075 vnodesPerDirection_m = 0;
00076
00077
00078
00079 for (int dl=0; dl < Dim; ++dl) RequestedLayout[dl] = PARALLEL;
00080
00081
00082 read(filename);
00083 }
00084
00085
00087
00088
00089 template<unsigned Dim>
00090 FieldLayout<Dim>::~FieldLayout() {
00091 if (vnodesPerDirection_m != 0)
00092 delete [] vnodesPerDirection_m;
00093 }
00094
00095
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 template<unsigned Dim>
00108 void
00109 FieldLayout<Dim>::initialize(const NDIndex<Dim>& domain,
00110 e_dim_tag *p, int vnodes) {
00111 TAU_TYPE_STRING(taustr, "void (" + CT(domain) + ", e_dim_tag*, int)");
00112 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00113 setup(domain, p, vnodes);
00114 }
00115
00116
00117 template<unsigned Dim>
00118 void
00119 FieldLayout<Dim>::initialize(const Index& i1, e_dim_tag p1, int vnodes) {
00120 TAU_TYPE_STRING(taustr, "void (Index, e_dim_tag, int)");
00121 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00122
00123 PInsist(Dim==1,
00124 "Number of arguments does not match dimension of FieldLayout!!");
00125 NDIndex<Dim> ndi(i1);
00126 setup(ndi,&p1,vnodes);
00127 }
00128
00129 template<unsigned Dim>
00130 void
00131 FieldLayout<Dim>::initialize(const Index& i1, const Index& i2,
00132 e_dim_tag p1, e_dim_tag p2, int vnodes) {
00133 TAU_TYPE_STRING(taustr, "void (Index, Index, e_dim_tag, e_dim_tag, int)");
00134 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00135
00136 PInsist(Dim==2,
00137 "Number of arguments does not match dimension of FieldLayout!!");
00138 e_dim_tag par[Dim];
00139 par[0] = p1;
00140 par[1] = p2;
00141 NDIndex<Dim> ndi;
00142 ndi[0] = i1;
00143 ndi[1] = i2;
00144 setup(ndi,par,vnodes);
00145 }
00146 template<unsigned Dim>
00147 void
00148 FieldLayout<Dim>::initialize(const Index& i1, const Index& i2, const Index& i3,
00149 e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
00150 int vnodes) {
00151 TAU_TYPE_STRING(taustr, string("void (Index, Index, Index,") +
00152 string(" e_dim_tag, e_dim_tag, e_dim_tag, int)"));
00153 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00154
00155 PInsist(Dim==3,
00156 "Number of arguments does not match dimension of FieldLayout!!");
00157 e_dim_tag par[Dim];
00158 par[0] = p1;
00159 par[1] = p2;
00160 par[2] = p3;
00161 NDIndex<Dim> ndi;
00162 ndi[0] = i1;
00163 ndi[1] = i2;
00164 ndi[2] = i3;
00165 setup(ndi,par,vnodes);
00166 }
00167 template<unsigned Dim>
00168 void
00169 FieldLayout<Dim>::initialize(const Index& i1, const Index& i2, const Index& i3,
00170 const Index& i4,
00171 e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
00172 e_dim_tag p4,
00173 int vnodes) {
00174 TAU_TYPE_STRING(taustr, string("void (Index, Index, Index, Index,") +
00175 string(" e_dim_tag, e_dim_tag, e_dim_tag, e_dim_tag, int)"));
00176 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00177
00178 PInsist(Dim==4,
00179 "Number of arguments does not match dimension of FieldLayout!!");
00180 e_dim_tag par[Dim];
00181 par[0] = p1;
00182 par[1] = p2;
00183 par[2] = p3;
00184 par[3] = p4;
00185 NDIndex<Dim> ndi;
00186 ndi[0] = i1;
00187 ndi[1] = i2;
00188 ndi[2] = i3;
00189 ndi[3] = i4;
00190 setup(ndi,par,vnodes);
00191 }
00192 template<unsigned Dim>
00193 void
00194 FieldLayout<Dim>::initialize(const Index& i1, const Index& i2, const Index& i3,
00195 const Index& i4, const Index& i5,
00196 e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
00197 e_dim_tag p4, e_dim_tag p5,
00198 int vnodes) {
00199 TAU_TYPE_STRING(taustr, string("void (Index, Index, Index, Index, Index,") +
00200 string(" e_dim_tag, e_dim_tag, e_dim_tag, e_dim_tag,") +
00201 string(" e_dim_tag, int)"));
00202 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00203
00204 PInsist(Dim==5,
00205 "Number of arguments does not match dimension of FieldLayout!!");
00206 e_dim_tag par[Dim];
00207 par[0] = p1;
00208 par[1] = p2;
00209 par[2] = p3;
00210 par[3] = p4;
00211 par[4] = p5;
00212 NDIndex<Dim> ndi;
00213 ndi[0] = i1;
00214 ndi[1] = i2;
00215 ndi[2] = i3;
00216 ndi[3] = i4;
00217 ndi[4] = i5;
00218 setup(ndi,par,vnodes);
00219 }
00220 template<unsigned Dim>
00221 void
00222 FieldLayout<Dim>::initialize(const Index& i1, const Index& i2, const Index& i3,
00223 const Index& i4, const Index& i5, const Index& i6,
00224 e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
00225 e_dim_tag p4, e_dim_tag p5, e_dim_tag p6,
00226 int vnodes) {
00227 TAU_TYPE_STRING(taustr, string("void (Index, Index, Index, Index, Index,") +
00228 string(" Index, e_dim_tag, e_dim_tag, e_dim_tag,") +
00229 string(" e_dim_tag, e_dim_tag, e_dim_tag, int)"));
00230 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00231
00232 PInsist(Dim==6,
00233 "Number of arguments does not match dimension of FieldLayout!!");
00234 e_dim_tag par[Dim];
00235 par[0] = p1;
00236 par[1] = p2;
00237 par[2] = p3;
00238 par[3] = p4;
00239 par[4] = p5;
00240 par[5] = p6;
00241 NDIndex<Dim> ndi;
00242 ndi[0] = i1;
00243 ndi[1] = i2;
00244 ndi[2] = i3;
00245 ndi[3] = i4;
00246 ndi[4] = i5;
00247 ndi[5] = i6;
00248 setup(ndi,par,vnodes);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258 template<unsigned Dim>
00259 void
00260 FieldLayout<Dim>::initialize(const NDIndex<Dim>& domain,
00261 e_dim_tag *p, unsigned* vnodesPerDirection,
00262 bool recurse, int vnodes) {
00263 TAU_TYPE_STRING(taustr, "void (" + CT(domain) +
00264 ", e_dim_tag*, unsigned*, bool, int)");
00265 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00266
00267
00268 unsigned vnodesProduct = 1;
00269 for (int d=0; d<Dim; d++) vnodesProduct *= vnodesPerDirection[d];
00270 if (vnodes == -1) vnodes = vnodesProduct;
00271
00272 if (vnodes != vnodesProduct) {
00273 ERRORMSG("FieldLayout constructor: "
00274 << "(vnodes != vnodesPerDirection[0]*vnodesPerDirection[1]*"
00275 << "...*vnodesPerDirection[" << Dim-1 << "])"
00276 << " ; vnodesPerDirection[0]*vnodesPerDirection[1]*"
00277 << "...*vnodesPerDirection[" << Dim-1 << "] = "
00278 << vnodesProduct << " ; vnodes = " << vnodes << endl);
00279 }
00280 setup(domain, p, vnodesPerDirection,recurse,vnodes);
00281 }
00282
00283 template<unsigned Dim>
00284 void
00285 FieldLayout<Dim>::initialize(const Index& i1, e_dim_tag p1,
00286 unsigned vnodes1, bool recurse, int vnodes) {
00287 TAU_TYPE_STRING(taustr, "void (Index, e_dim_tag, unsigned, bool, int)");
00288 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00289
00290 PInsist(Dim==1,
00291 "Number of arguments does not match dimension of FieldLayout!!");
00292 NDIndex<Dim> ndi(i1);
00293 setup(ndi,&p1,&vnodes1,recurse,vnodes);
00294 }
00295
00296 template<unsigned Dim>
00297 void
00298 FieldLayout<Dim>::initialize(const Index& i1, const Index& i2,
00299 e_dim_tag p1, e_dim_tag p2,
00300 unsigned vnodes1, unsigned vnodes2,
00301 bool recurse, int vnodes) {
00302 TAU_TYPE_STRING(taustr, string("void (Index, Index, e_dim_tag, e_dim_tag,") +
00303 string(" unsigned, unsigned, bool, int)"));
00304 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00305
00306 PInsist(Dim==2,
00307 "Number of arguments does not match dimension of FieldLayout!!");
00308 e_dim_tag par[Dim];
00309 par[0] = p1;
00310 par[1] = p2;
00311 NDIndex<Dim> ndi;
00312 ndi[0] = i1;
00313 ndi[1] = i2;
00314 unsigned vnodesPerDirection[Dim];
00315 vnodesPerDirection[0] = vnodes1;
00316 vnodesPerDirection[1] = vnodes2;
00317 setup(ndi,par,vnodesPerDirection,recurse,vnodes);
00318 }
00319 template<unsigned Dim>
00320 void
00321 FieldLayout<Dim>::initialize(const Index& i1, const Index& i2, const Index& i3,
00322 e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
00323 unsigned vnodes1, unsigned vnodes2,
00324 unsigned vnodes3,
00325 bool recurse, int vnodes) {
00326 TAU_TYPE_STRING(taustr, string("void (Index, Index, Index, e_dim_tag,") +
00327 string(" e_dim_tag, e_dim_tag, unsigned, unsigned,") +
00328 string(" unsigned, bool, int)"));
00329 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00330
00331 PInsist(Dim==3,
00332 "Number of arguments does not match dimension of FieldLayout!!");
00333 e_dim_tag par[Dim];
00334 par[0] = p1;
00335 par[1] = p2;
00336 par[2] = p3;
00337 NDIndex<Dim> ndi;
00338 ndi[0] = i1;
00339 ndi[1] = i2;
00340 ndi[2] = i3;
00341 unsigned vnodesPerDirection[Dim];
00342 vnodesPerDirection[0] = vnodes1;
00343 vnodesPerDirection[1] = vnodes2;
00344 vnodesPerDirection[2] = vnodes3;
00345 setup(ndi,par,vnodesPerDirection,recurse,vnodes);
00346 }
00347 template<unsigned Dim>
00348 void
00349 FieldLayout<Dim>::initialize(const Index& i1, const Index& i2, const Index& i3,
00350 const Index& i4,
00351 e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
00352 e_dim_tag p4,
00353 unsigned vnodes1, unsigned vnodes2,
00354 unsigned vnodes3, unsigned vnodes4,
00355 bool recurse, int vnodes) {
00356 TAU_TYPE_STRING(taustr, string("void (Index, Index, Index, Index,") +
00357 string(" e_dim_tag, e_dim_tag, e_dim_tag, e_dim_tag,") +
00358 string(" unsigned, unsigned, unsigned, unsigned, bool,") +
00359 string(" int)"));
00360 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00361
00362 PInsist(Dim==4,
00363 "Number of arguments does not match dimension of FieldLayout!!");
00364 e_dim_tag par[Dim];
00365 par[0] = p1;
00366 par[1] = p2;
00367 par[2] = p3;
00368 par[3] = p4;
00369 NDIndex<Dim> ndi;
00370 ndi[0] = i1;
00371 ndi[1] = i2;
00372 ndi[2] = i3;
00373 ndi[3] = i4;
00374 unsigned vnodesPerDirection[Dim];
00375 vnodesPerDirection[0] = vnodes1;
00376 vnodesPerDirection[1] = vnodes2;
00377 vnodesPerDirection[2] = vnodes3;
00378 vnodesPerDirection[3] = vnodes4;
00379 setup(ndi,par,vnodesPerDirection,recurse,vnodes);
00380 }
00381 template<unsigned Dim>
00382 void
00383 FieldLayout<Dim>::initialize(const Index& i1, const Index& i2, const Index& i3,
00384 const Index& i4, const Index& i5,
00385 e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
00386 e_dim_tag p4, e_dim_tag p5,
00387 unsigned vnodes1, unsigned vnodes2,
00388 unsigned vnodes3, unsigned vnodes4,
00389 unsigned vnodes5,
00390 bool recurse, int vnodes) {
00391 TAU_TYPE_STRING(taustr, string("void (Index, Index, Index, Index, Index,") +
00392 string(" e_dim_tag, e_dim_tag, e_dim_tag, e_dim_tag,") +
00393 string(" e_dim_tag, unsigned, unsigned, unsigned,") +
00394 string(" unsigned, unsigned, bool, int)"));
00395 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00396
00397 PInsist(Dim==5,
00398 "Number of arguments does not match dimension of FieldLayout!!");
00399 e_dim_tag par[Dim];
00400 par[0] = p1;
00401 par[1] = p2;
00402 par[2] = p3;
00403 par[3] = p4;
00404 par[4] = p5;
00405 NDIndex<Dim> ndi;
00406 ndi[0] = i1;
00407 ndi[1] = i2;
00408 ndi[2] = i3;
00409 ndi[3] = i4;
00410 ndi[4] = i5;
00411 unsigned vnodesPerDirection[Dim];
00412 vnodesPerDirection[0] = vnodes1;
00413 vnodesPerDirection[1] = vnodes2;
00414 vnodesPerDirection[2] = vnodes3;
00415 vnodesPerDirection[3] = vnodes4;
00416 vnodesPerDirection[4] = vnodes5;
00417 setup(ndi,par,vnodesPerDirection,recurse,vnodes);
00418 }
00419 template<unsigned Dim>
00420 void
00421 FieldLayout<Dim>::initialize(const Index& i1, const Index& i2, const Index& i3,
00422 const Index& i4, const Index& i5, const Index& i6,
00423 e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
00424 e_dim_tag p4, e_dim_tag p5, e_dim_tag p6,
00425 unsigned vnodes1, unsigned vnodes2,
00426 unsigned vnodes3, unsigned vnodes4,
00427 unsigned vnodes5, unsigned vnodes6,
00428 bool recurse, int vnodes) {
00429 TAU_TYPE_STRING(taustr, string("void (Index, Index, Index, Index, Index,") +
00430 string(" Index, e_dim_tag, e_dim_tag, e_dim_tag,") +
00431 string(" e_dim_tag, e_dim_tag, e_dim_tag, unsigned,") +
00432 string(" unsigned, unsigned, unsigned, unsigned,") +
00433 string(" unsigned, bool, int)"));
00434 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00435
00436 PInsist(Dim==6,
00437 "Number of arguments does not match dimension of FieldLayout!!");
00438 e_dim_tag par[Dim];
00439 par[0] = p1;
00440 par[1] = p2;
00441 par[2] = p3;
00442 par[3] = p4;
00443 par[4] = p5;
00444 par[5] = p6;
00445 NDIndex<Dim> ndi;
00446 ndi[0] = i1;
00447 ndi[1] = i2;
00448 ndi[2] = i3;
00449 ndi[3] = i4;
00450 ndi[4] = i5;
00451 ndi[5] = i6;
00452 unsigned vnodesPerDirection[Dim];
00453 vnodesPerDirection[0] = vnodes1;
00454 vnodesPerDirection[1] = vnodes2;
00455 vnodesPerDirection[2] = vnodes3;
00456 vnodesPerDirection[3] = vnodes4;
00457 vnodesPerDirection[4] = vnodes5;
00458 vnodesPerDirection[5] = vnodes6;
00459 setup(ndi,par,vnodesPerDirection,recurse,vnodes);
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 template<unsigned Dim>
00473 void
00474 FieldLayout<Dim>::initialize(const NDIndex<Dim> &domain,
00475 const NDIndex<Dim> *dombegin,
00476 const NDIndex<Dim> *domend,
00477 const int *nbegin, const int *nend)
00478 {
00479 TAU_TYPE_STRING(taustr, string("void (NDIndex, NDIndex *, NDIndex *,") +
00480 string(" int *, int *)"));
00481 TAU_PROFILE("FieldLayout::initialize()", taustr, TAU_LAYOUT);
00482
00483
00484 int i, j, d;
00485
00486
00487 Domain = domain;
00488
00489
00490 int vnodes = (nend - nbegin);
00491 PInsist(vnodes > 0,
00492 "A user-specified FieldLayout must have at least one vnode.");
00493 PInsist(vnodes == (domend - dombegin),
00494 "A user-specified FieldLayout must have equal length node and domain lists");
00495
00496
00497
00498 for (d = 0; d < Dim; ++d)
00499 RequestedLayout[d] = PARALLEL;
00500
00501
00502 vnodesPerDirection_m = 0;
00503
00504
00505 ac_domain_vnodes *remote_ac = new ac_domain_vnodes(domain);
00506 typedef typename ac_gc_domain_vnodes::value_type vntype;
00507 Remotes_ac.insert( vntype(gc0(), remote_ac) );
00508
00509
00510
00511
00512
00513
00514 int coverage = 0;
00515 for (i = 0; i < vnodes; ++i) {
00516
00517 for (j = (i+1); j < vnodes; ++j) {
00518 PInsist(! (dombegin[i].touches(dombegin[j])),
00519 "A user-specified FieldLayout cannot have overlapping domains.");
00520 }
00521
00522
00523 PInsist(nbegin[i] >= 0 && nbegin[i] < Ippl::getNodes(),
00524 "A user-specified FieldLayout must have legal node assignments.");
00525
00526
00527 coverage += dombegin[i].size();
00528
00529
00530 Vnode<Dim> *vnode = new Vnode<Dim>(dombegin[i], nbegin[i], i);
00531 typedef typename ac_id_vnodes::value_type v1;
00532 typedef typename ac_domain_vnodes::value_type v2;
00533 bool nosplit = (dombegin[i].size() < 2);
00534
00535
00536 if (nbegin[i] == Ippl::myNode())
00537 Local_ac.insert(v1(Unique::get(), vnode));
00538 else
00539 remote_ac->insert(v2(dombegin[i], vnode), nosplit);
00540 }
00541
00542
00543 PInsist(coverage == domain.size(),
00544 "A user-specified FieldLayout must completely cover the domain.");
00545
00546
00547 calcWidths();
00548 }
00549
00550
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 template<unsigned Dim>
00562 void
00563 FieldLayout<Dim>::setup(const NDIndex<Dim>& domain,
00564 e_dim_tag *userflags, int vnodes)
00565 {
00566 TAU_TYPE_STRING(taustr, "void (" + CT(domain) + ", e_dim_tag, int)");
00567 TAU_PROFILE("FieldLayout::setup()", taustr, TAU_LAYOUT);
00568
00569
00570
00571
00572 int nprocs = Ippl::getNodes();
00573 int myproc = Ippl::myNode();
00574
00575
00576 if (vnodes <= 0) vnodes = nprocs;
00577
00578 Inform dbgmsg("FieldLayout::setup", INFORM_ALL_NODES);
00579
00580
00581
00582
00583 int parallel_count = 0, flagdim = 0;
00584 long totparelems = 1;
00585 for (flagdim=0; flagdim < Dim; ++flagdim) {
00586 if (userflags == 0)
00587 RequestedLayout[flagdim] = PARALLEL;
00588 else
00589 RequestedLayout[flagdim] = userflags[flagdim];
00590 if (RequestedLayout[flagdim] == PARALLEL) {
00591 parallel_count++;
00592 totparelems *= domain[flagdim].length();
00593 }
00594 }
00595
00596
00597 PInsist(parallel_count>0,"At least one dimension of a FieldLayout must be PARALLEL!");
00598
00599
00600
00601
00602 if (totparelems < vnodes) {
00603
00604
00605 vnodes = totparelems;
00606 }
00607
00608 e_dim_tag *flags = RequestedLayout;
00609
00610
00611 Domain = domain;
00612 NDIndex<Dim> *domains_c = new NDIndex<Dim>[vnodes];
00613 NDIndex<Dim> *copy_c = new NDIndex<Dim>[vnodes];
00614 NDIndex<Dim> leftDomain ;
00615
00616
00617 domains_c[0] = domain;
00618 int v;
00619 int d=0;
00620
00621 int v1,v2,rm,vtot,vl,vr,dd;
00622 double a,lmax,len;
00623 vnodesPerDirection_m = 0;
00624 for (v=vnodes,rm=0;v>1;v/=2) { rm += (v % 2); }
00625 if (rm == 0) {
00626
00627
00628
00629
00630
00631
00632
00633
00634 for (v=1; v<vnodes; v*=2) {
00635
00636 while(flags[d] != PARALLEL) if(++d == Dim) d = 0;
00637
00638
00639 int i,j;
00640 for (i=0, j=0; i<v; ++i, j+=2)
00641
00642 domains_c[i].split( copy_c[j] , copy_c[j+1] , d );
00643
00644 copy(copy_c,copy_c+v*2, domains_c);
00645
00646
00647
00648
00649 if (++d == Dim) d = 0;
00650 }
00651
00652 } else {
00653
00654 vtot = 1;
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 for (v=1; v<2*vnodes; ++v) {
00667
00668 for (v2=v,v1=1;v2>1;v2/=2) { v1 = 2*v1+(v2%2); }
00669 vl = 0; vr = vnodes;
00670 while (v1>1) {
00671 if ((v1%2)==1) {
00672 vl=vl+(vr-vl)/2;
00673 } else {
00674 vr=vl+(vr-vl)/2;
00675 }
00676 v1/=2;
00677 }
00678 v2=vl+(vr-vl)/2;
00679
00680 if (v2>vl) {
00681 a = v2-vl;
00682 a /= vr-vl;
00683 vr=v2;
00684 leftDomain=domains_c[vl];
00685 lmax=0;
00686 d=-1;
00687 for (dd=0;dd<Dim;++dd) {
00688 if ( flags[dd] == PARALLEL ) {
00689 if ((len = leftDomain[dd].length()) > lmax) {
00690 lmax = len;
00691 d = dd;
00692 }
00693 }
00694 }
00695 domains_c[vl].split( domains_c[vl] , domains_c[vr] , d , a);
00696 ++vtot;
00697 }
00698 }
00699 v=vtot;
00700 }
00701
00702
00703 PAssert( v == vnodes );
00704
00705
00706
00707 ac_domain_vnodes *remote_ac = new ac_domain_vnodes( domain );
00708 typedef typename ac_gc_domain_vnodes::value_type vtype;
00709 Remotes_ac.insert( vtype(gc0(),remote_ac) );
00710 for (v=0; v<vnodes; ++v)
00711 {
00712 int p = (v*nprocs)/vnodes;
00713 bool nosplit = (domains_c[v].size() < 2);
00714
00715
00716 Vnode<Dim> *vnode = new Vnode<Dim>(domains_c[v], p, v);
00717 typedef typename ac_id_vnodes::value_type v1;
00718 typedef typename ac_domain_vnodes::value_type v2;
00719 if ( p==myproc )
00720 Local_ac.insert(v1(Unique::get(),vnode));
00721 else
00722 remote_ac->insert(v2(domains_c[v], vnode), nosplit);
00723 }
00724
00725
00726 delete [] domains_c;
00727 delete [] copy_c;
00728
00729
00730 calcWidths();
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 template<unsigned Dim>
00755 void
00756 FieldLayout<Dim>::setup(const NDIndex<Dim>& domain,
00757 e_dim_tag *userflags, unsigned* vnodesPerDirection,
00758 bool recurse, int vnodes)
00759 {
00760 TAU_TYPE_STRING(taustr, "void (" + CT(domain) +
00761 ", e_dim_tag, unsigned, int)");
00762 TAU_PROFILE("FieldLayout::setup()", taustr, TAU_LAYOUT);
00763
00764
00765 int nprocs = Ippl::getNodes();
00766 int myproc = Ippl::myNode();
00767
00768
00769 if (vnodes <= 0) ERRORMSG("FieldLayout::setup(): vnodes <= 0 "
00770 << "for a vnodes-per-direction product "
00771 << "specification; not allowed." << endl);
00772
00773
00774 int v, d, vl, d2;
00775
00776 int parallel_count = 0, flagdim = 0;
00777 for (flagdim=0; flagdim < Dim; ++flagdim) {
00778 if (userflags == 0)
00779 RequestedLayout[flagdim] = PARALLEL;
00780 else
00781 RequestedLayout[flagdim] = userflags[flagdim];
00782
00783
00784 parallel_count += (RequestedLayout[flagdim] == PARALLEL);
00785
00786
00787 if (RequestedLayout[flagdim] == SERIAL) {
00788 bool chk = vnodesPerDirection[flagdim] == 1;
00789 PInsist(chk,"SERIAL layout specified, yet vnodesPerDirection is not 1!");
00790 }
00791 }
00792
00793
00794 PInsist(parallel_count>0,"At least one dimension of a FieldLayout must be PARALLEL!");
00795
00796
00797 vnodesPerDirection_m = new unsigned[Dim];
00798 for (d=0; d<Dim; d++) vnodesPerDirection_m[d] = vnodesPerDirection[d];
00799
00800
00801 Domain = domain;
00802
00803
00804 NDIndex<Dim> *domains_c = new NDIndex<Dim>[vnodes];
00805
00806
00807
00808
00809 unsigned elementsPerVnode[Dim];
00810 unsigned nLargerVnodes[Dim];
00811 for (d=0; d<Dim; d++) {
00812 elementsPerVnode[d] = domain[d].length()/vnodesPerDirection[d];
00813 nLargerVnodes[d] = domain[d].length() % vnodesPerDirection[d];
00814 }
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 int stride[Dim];
00825 for (d=0; d<Dim; d++) stride[d] = domain[d].stride();
00826 int* base[Dim];
00827 int* bound[Dim];
00828 for (d=0; d<Dim; d++) {
00829 base[d] = new int[vnodesPerDirection[d]];
00830 bound[d] = new int[vnodesPerDirection[d]];
00831 }
00832 int length;
00833 for (d=0; d<Dim; d++) {
00834
00835 length = elementsPerVnode[d];
00836 if (nLargerVnodes[d] > 0) length += 1;
00837 base[d][0] = domain[d].first();
00838 bound[d][0] = base[d][0] + (length-1)*stride[d];
00839
00840 for (vl=1; vl < vnodesPerDirection[d]; vl++) {
00841 base[d][vl] = bound[d][vl-1] + stride[d];
00842 length = elementsPerVnode[d];
00843 if (vl < nLargerVnodes[d]) length += 1;
00844 bound[d][vl] = base[d][vl] +(length-1)*stride[d];
00845 }
00846 }
00847
00848
00849
00850 for (v=0; v<vnodes; v++) {
00851 for (d=0; d<Dim; d++) {
00852
00853 unsigned denom = 1;
00854 for (d2=0; d2<d; d2++) denom *= vnodesPerDirection[d2];
00855 int vnodeLevel = (v/denom) % vnodesPerDirection[d];
00856
00857 domains_c[v][d] = Index(base[d][vnodeLevel],bound[d][vnodeLevel],
00858 stride[d]);
00859 denom = 1;
00860 }
00861 }
00862
00863
00864
00865
00866
00867
00868 int *vnodeProcs = new int[vnodes];
00869 int *sizes = new int[Dim];
00870 for (v=0; v<Dim; ++v)
00871 sizes[v] = vnodesPerDirection[v];
00872
00873
00874
00875 if ( recurse )
00876 vnodeRecursiveBisection(Dim,sizes,nprocs,vnodeProcs);
00877 else
00878 for ( v=0; v<vnodes; ++v )
00879 vnodeProcs[v] = (v*nprocs)/vnodes;
00880
00881
00882
00883
00884 ac_domain_vnodes *remote_ac = new ac_domain_vnodes( domain );
00885 typedef typename ac_gc_domain_vnodes::value_type v1;
00886 Remotes_ac.insert(v1(gc0(),remote_ac) );
00887 for (v=0; v<vnodes; ++v) {
00888 int p = vnodeProcs[v];
00889
00890 Vnode<Dim> *vnode = new Vnode<Dim>(domains_c[v], p, v);
00891 typedef typename ac_id_vnodes::value_type v2;
00892 if ( p==myproc )
00893 Local_ac.insert(v2(Unique::get(),vnode) );
00894 else
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905 if (domains_c[v].size() <= 1) {
00906 typedef typename ac_domain_vnodes::value_type v1;
00907 remote_ac->insert(v1(domains_c[v], vnode), true);
00908 } else {
00909 typedef typename ac_domain_vnodes::value_type v1;
00910 remote_ac->insert(v1(domains_c[v], vnode), false);
00911 }
00912 }
00913
00914
00915 delete [] domains_c;
00916 delete [] vnodeProcs;
00917 delete [] sizes;
00918 for (d=0; d<Dim; d++) {
00919 delete [] base[d];
00920 delete [] bound[d];
00921 }
00922
00923
00924 calcWidths();
00925 }
00926
00927
00928
00929
00930
00931 template<unsigned Dim>
00932 unsigned FieldLayout<Dim>::
00933 getVnodesPerDirection(unsigned dir) {
00934
00935
00936
00937
00938 PAssert(vnodesPerDirection_m != 0);
00939
00940 return(vnodesPerDirection_m[dir]);
00941 }
00942
00943
00944
00945
00946
00947 template<unsigned Dim>
00948 void FieldLayout<Dim>::new_gc_layout(const GuardCellSizes<Dim>& gc)
00949 {
00950 TAU_TYPE_STRING(taustr, "void (" + CT(gc) + " )");
00951 TAU_PROFILE("FieldLayout::new_gc_layout()", taustr, TAU_LAYOUT);
00952
00953
00954 NDIndex<Dim> guarded_domain( AddGuardCells(Domain,gc) );
00955
00956 ac_domain_vnodes *gr = new ac_domain_vnodes(guarded_domain);
00957
00958 typedef typename ac_gc_domain_vnodes::value_type v1;
00959 Remotes_ac.insert(v1(gc,gr) );
00960
00961 ac_domain_vnodes &v0 = *Remotes_ac[ gc0() ];
00962
00963 for (iterator_dv v_i = v0.begin(); v_i != v0.end(); ++v_i)
00964 {
00965
00966 NDIndex<Dim> domain(AddGuardCells((*v_i).first,gc));
00967
00968 typedef typename ac_domain_vnodes::value_type v2;
00969 gr->insert(v2(domain,(*v_i).second) );
00970 }
00971 }
00972
00973
00974 template<unsigned Dim>
00975 FieldLayout<Dim>::FieldLayout(const NDIndex<Dim>& domain,
00976 const NDIndex<Dim>* idx_begin,
00977 const NDIndex<Dim>* idx_end)
00978 : Domain(domain)
00979 {
00980 TAU_TYPE_STRING(taustr, "void (" + CT(domain) + ", " + CT(idx_begin)
00981 + CT(idx_end) + " )");
00982 TAU_PROFILE("FieldLayout::FieldLayout()", taustr, TAU_LAYOUT);
00983
00984
00985
00986
00987
00988
00989 for (int dl=0; dl < Dim; ++dl) RequestedLayout[dl] = PARALLEL;
00990
00991
00992 vnodesPerDirection_m = 0;
00993 int mynode = Ippl::Comm->myNode();
00994 for (const NDIndex<Dim>* p=idx_begin; p!=idx_end; ++p)
00995 {
00996 typedef typename ac_id_vnodes::value_type v1;
00997 Local_ac.insert(v1(Unique::get(), new Vnode<Dim>(*p,mynode)));
00998 }
00999
01000
01001
01002 Message* bcast_mess = new Message;
01003 int count = idx_end - idx_begin;
01004 bcast_mess->put(count);
01005
01006 const NDIndex<Dim>* indxmsg = idx_begin;
01007 while (indxmsg != idx_end)
01008 (indxmsg++)->putMessage(*bcast_mess);
01009
01010 int tag = Ippl::Comm->next_tag( F_REPARTITION_BCAST_TAG , F_TAG_CYCLE );
01011 int node_count = Ippl::Comm->broadcast_others(bcast_mess,tag);
01012
01013 ac_domain_vnodes *remote_ac = new ac_domain_vnodes( Domain );
01014 typedef typename ac_gc_domain_vnodes::value_type v1;
01015 Remotes_ac.insert(v1(gc0(),remote_ac) );
01016
01017
01018 while ((--node_count)>=0)
01019 {
01020
01021 int other_node = COMM_ANY_NODE;
01022 Message *recv_mess = Ippl::Comm->receive_block(other_node,tag);
01023 PAssert(recv_mess != 0);
01024
01025 int count;
01026 recv_mess->get(count);
01027
01028 NDIndex<Dim> p;
01029 while (count-- > 0) {
01030 p.getMessage(*recv_mess);
01031 Vnode<Dim> *vnode = new Vnode<Dim>(p, other_node);
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 if (p.size() <= 1) {
01043 typedef typename ac_domain_vnodes::value_type v1;
01044 remote_ac->insert(v1(p, vnode), true);
01045 } else {
01046 typedef typename ac_domain_vnodes::value_type v1;
01047 remote_ac->insert(v1(p, vnode), false);
01048 }
01049 }
01050 }
01051
01052
01053 calcWidths();
01054 }
01055
01056
01057
01058
01059
01060 template<unsigned Dim>
01061 FieldLayout<Dim>::FieldLayout(const NDIndex<Dim>& domain,
01062 const Vnode<Dim>* idx_begin,
01063 const Vnode<Dim>* idx_end)
01064 : Domain(domain)
01065 {
01066 TAU_TYPE_STRING(taustr, "void (" + CT(domain) + ", " + CT(idx_begin)
01067 + CT(idx_end) + " )");
01068 TAU_PROFILE("FieldLayout::FieldLayout()", taustr, TAU_LAYOUT);
01069
01070
01071
01072
01073
01074
01075 for (int dl=0; dl < Dim; ++dl) RequestedLayout[dl] = PARALLEL;
01076
01077
01078 vnodesPerDirection_m = 0;
01079 int mynode = Ippl::Comm->myNode();
01080 for (const Vnode<Dim>* p=idx_begin; p!=idx_end; ++p) {
01081 typedef typename ac_id_vnodes::value_type v1;
01082 Local_ac.insert(v1(Unique::get(),
01083 new Vnode<Dim>((*p).getDomain(),mynode,(*p).getVnode())));
01084 }
01085
01086
01087
01088 Message* bcast_mess = new Message;
01089 int count = idx_end - idx_begin;
01090 bcast_mess->put(count);
01091
01092 const Vnode<Dim>* indxmsg = idx_begin;
01093 while (indxmsg != idx_end)
01094 (indxmsg++)->putMessage(*bcast_mess);
01095
01096 int tag = Ippl::Comm->next_tag( F_REPARTITION_BCAST_TAG , F_TAG_CYCLE );
01097 int node_count = Ippl::Comm->broadcast_others(bcast_mess,tag);
01098
01099 ac_domain_vnodes *remote_ac = new ac_domain_vnodes( Domain );
01100 typedef typename ac_gc_domain_vnodes::value_type v1;
01101 Remotes_ac.insert(v1(gc0(),remote_ac) );
01102
01103
01104 while ((--node_count)>=0)
01105 {
01106
01107 int other_node = COMM_ANY_NODE;
01108 Message *recv_mess = Ippl::Comm->receive_block(other_node,tag);
01109 PAssert(recv_mess != 0);
01110
01111 int count;
01112 recv_mess->get(count);
01113
01114 Vnode<Dim> p;
01115 while (count-- > 0) {
01116 p.getMessage(*recv_mess);
01117 Vnode<Dim> *vnode =
01118 new Vnode<Dim>(p.getDomain(), other_node, p.getVnode());
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129 if (p.getDomain().size() <= 1) {
01130 typedef typename ac_domain_vnodes::value_type v1;
01131 remote_ac->insert(v1(p.getDomain(), vnode), true);
01132 } else {
01133 typedef typename ac_domain_vnodes::value_type v1;
01134 remote_ac->insert(v1(p.getDomain(), vnode), false);
01135 }
01136 }
01137 }
01138
01139
01140 calcWidths();
01141 }
01142
01143
01144
01145
01146
01147
01148
01149 template<unsigned Dim>
01150 void
01151 FieldLayout<Dim>::Repartition(const NDIndex<Dim>* idxBegin,
01152 const NDIndex<Dim>* idxEnd)
01153 {
01154 TAU_TYPE_STRING(taustr, "void (" + CT(idxBegin) + ", " + CT(idxEnd) + " )");
01155 TAU_PROFILE("FieldLayout::Repartition()", taustr, TAU_LAYOUT);
01156
01157
01158 FieldLayout<Dim> tempLayout(Domain,idxBegin,idxEnd);
01159
01160
01161 if (vnodesPerDirection_m != 0) {
01162 tempLayout.vnodesPerDirection_m = new unsigned[Dim];
01163 for (int d=0; d<Dim; d++) {
01164 tempLayout.vnodesPerDirection_m[d] = vnodesPerDirection_m[d];
01165 }
01166 }
01167
01168
01169 iterator_if p, endp=end_if();
01170 for (p=begin_if(); p!=endp; ++p) {
01171 FieldLayoutUser *user = (FieldLayoutUser *)((*p).second);
01172 user->Repartition(&tempLayout);
01173 }
01174
01175
01176 Local_ac = tempLayout.Local_ac;
01177 Remotes_ac = tempLayout.Remotes_ac;
01178
01179
01180 calcWidths();
01181
01182
01183 }
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193 template<unsigned Dim>
01194 void
01195 FieldLayout<Dim>::Repartition(const Vnode<Dim>* idxBegin,
01196 const Vnode<Dim>* idxEnd)
01197 {
01198 TAU_TYPE_STRING(taustr, "void (" + CT(idxBegin) + ", " + CT(idxEnd) + " )");
01199 TAU_PROFILE("FieldLayout::Repartition()", taustr, TAU_LAYOUT);
01200
01201
01202 FieldLayout<Dim> tempLayout(Domain,idxBegin,idxEnd);
01203
01204
01205 if (vnodesPerDirection_m != 0) {
01206 tempLayout.vnodesPerDirection_m = new unsigned[Dim];
01207 for (int d=0; d<Dim; d++) {
01208 tempLayout.vnodesPerDirection_m[d] = vnodesPerDirection_m[d];
01209 }
01210 }
01211
01212
01213 iterator_if p, endp=end_if();
01214 for (p=begin_if(); p!=endp; ++p) {
01215 FieldLayoutUser *user = (FieldLayoutUser *)((*p).second);
01216 user->Repartition(&tempLayout);
01217 }
01218
01219
01220 Local_ac = tempLayout.Local_ac;
01221 Remotes_ac = tempLayout.Remotes_ac;
01222
01223
01224 calcWidths();
01225 }
01226
01227
01228
01229
01230
01231
01232 template<unsigned Dim>
01233 bool FieldLayout<Dim>::write(const char *filename) {
01234 TAU_TYPE_STRING(taustr, "bool (const char *)");
01235 TAU_PROFILE("FieldLayout::write()", taustr, TAU_LAYOUT);
01236
01237 int d;
01238
01239
01240 if (Ippl::myNode() == 0) {
01241
01242 FILE *f = fopen(filename, "w");
01243 if (f == 0) {
01244 ERRORMSG("Could not create FieldLayout data file '" << filename);
01245 ERRORMSG("'." << endl);
01246 return false;
01247 }
01248
01249
01250 fprintf(f, "dim = %d\n", Dim);
01251 fprintf(f, "vnodes = %d\n", numVnodes());
01252 fprintf(f, "pnodes = %d\n", Ippl::getNodes());
01253
01254 fprintf(f, "domain =");
01255 for (d=0; d < Dim; ++d)
01256 fprintf(f, " %d %d %d",
01257 Domain[d].first(), Domain[d].last(), Domain[d].stride());
01258 fprintf(f, "\n");
01259
01260 if (vnodesPerDirection_m != 0) {
01261 fprintf(f, "vnodesperdir =");
01262 for (d=0; d < Dim; ++d)
01263 fprintf(f, " %d", vnodesPerDirection_m[d]);
01264 fprintf(f, "\n");
01265 }
01266
01267 for (iterator_iv localv = begin_iv(); localv != end_iv(); ++localv) {
01268 Vnode<Dim> *vn = (*localv).second.get();
01269 fprintf(f, "block = %d %d", vn->getVnode(), vn->getNode());
01270 for (d=0; d < Dim; ++d)
01271 fprintf(f, " %d %d %d", vn->getDomain()[d].first(),
01272 vn->getDomain()[d].last(), vn->getDomain()[d].stride());
01273 fprintf(f, "\n");
01274 }
01275
01276 for (iterator_dv remotev = begin_rdv(); remotev != end_rdv(); ++remotev) {
01277 Vnode<Dim> *vn = (*remotev).second;
01278 fprintf(f, "block = %d %d", vn->getVnode(), vn->getNode());
01279 for (d=0; d < Dim; ++d)
01280 fprintf(f, " %d %d %d", vn->getDomain()[d].first(),
01281 vn->getDomain()[d].last(), vn->getDomain()[d].stride());
01282 fprintf(f, "\n");
01283 }
01284
01285 fclose(f);
01286 }
01287
01288 return true;
01289 }
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305 template<unsigned Dim>
01306 bool FieldLayout<Dim>::read(const char *filename) {
01307 TAU_TYPE_STRING(taustr, "bool (const char *)");
01308 TAU_PROFILE("FieldLayout::read()", taustr, TAU_LAYOUT);
01309
01310
01311 int tag = Ippl::Comm->next_tag(F_LAYOUT_IO_TAG, F_TAG_CYCLE);
01312
01313
01314 NDIndex<Dim> fdomain;
01315 Vnode<Dim> *vnlist = 0;
01316 unsigned *vnodesPerDir = 0;
01317 int fdim = 0;
01318 int fvnodes = 0;
01319 int fpnodes = 0;
01320 int vnodesread = 0;
01321 int ok = 1;
01322
01323
01324 if (Ippl::myNode() == 0) {
01325
01326 DiscMeta f(filename);
01327
01328
01329 DiscMeta::iterator metaline = f.begin();
01330 for ( ; ok == 1 && metaline != f.end(); ++metaline) {
01331
01332 int numtokens = (*metaline).second.first;
01333 string *tokens = (*metaline).second.second;
01334
01335
01336 if (tokens[0] == "dim") {
01337 if (fdim != 0) {
01338 ERRORMSG("Repeated 'dim' line in FieldLayout data file '");
01339 ERRORMSG(filename << "'." << endl);
01340 ok = 0;
01341 }
01342 fdim = atoi(tokens[1].c_str());
01343 if (fdim != Dim) {
01344 ERRORMSG("Mismatched dimension in FieldLayout data file '");
01345 ERRORMSG(filename << "'." << endl);
01346 ok = 0;
01347 }
01348 } else if (tokens[0] == "vnodes") {
01349 if (fvnodes != 0 || vnlist != 0) {
01350 ERRORMSG("Repeated 'vnodes' line in FieldLayout data file '");
01351 ERRORMSG(filename << "'." << endl);
01352 ok = 0;
01353 }
01354 fvnodes = atoi(tokens[1].c_str());
01355 if (fvnodes < 1) {
01356 ERRORMSG("Incorrect 'vnodes' line in FieldLayout data file '");
01357 ERRORMSG(filename << "'." << endl);
01358 ok = 0;
01359 } else {
01360 vnlist = new Vnode<Dim>[fvnodes];
01361 }
01362 } else if (tokens[0] == "pnodes") {
01363 if (fpnodes != 0) {
01364 ERRORMSG("Repeated 'pnodes' line in FieldLayout data file '");
01365 ERRORMSG(filename << "'." << endl);
01366 ok = 0;
01367 }
01368 fpnodes = atoi(tokens[1].c_str());
01369 if (fpnodes < 1) {
01370 ERRORMSG("Incorrect 'pnodes' line in FieldLayout data file '");
01371 ERRORMSG(filename << "'." << endl);
01372 ok = 0;
01373 }
01374 } else if (tokens[0] == "vnodesperdir") {
01375 if (vnodesPerDir != 0) {
01376 ERRORMSG("Repeated 'vnodesperdir' line in FieldLayout data file '");
01377 ERRORMSG(filename << "'." << endl);
01378 ok = 0;
01379 }
01380 if (numtokens - 1 != Dim) {
01381 ERRORMSG("Incorrect 'vnodesperdir' line in FieldLayout data file '");
01382 ERRORMSG(filename << "'." << endl);
01383 ok = 0;
01384 }
01385 vnodesPerDir = new unsigned[Dim];
01386 for (int d=0; d < Dim; ++d) {
01387 vnodesPerDir[d] = atoi(tokens[d+1].c_str());
01388 if (vnodesPerDir[d] < 1) {
01389 ERRORMSG("Illegal vnode per direction value for dim=" << d);
01390 ERRORMSG(" in FieldLayout data file '" << filename << "'."<<endl);
01391 ok = 0;
01392 }
01393 }
01394 } else if (tokens[0] == "domain") {
01395
01396 if ((numtokens-1) % 3 != 0 || (numtokens-1) / 3 != Dim) {
01397 ERRORMSG("Incorrect 'domain' line in FieldLayout data file '");
01398 ERRORMSG(filename << "'." << endl);
01399 ok = 0;
01400 }
01401 for (int d=0, dindx=1; d < Dim; ++d) {
01402 fdomain[d] = Index(atoi(tokens[dindx].c_str()),
01403 atoi(tokens[dindx + 1].c_str()),
01404 atoi(tokens[dindx + 2].c_str()));
01405 dindx += 3;
01406 }
01407 } else if (tokens[0] == "block") {
01408
01409
01410
01411 if (numtokens % 3 != 0 || numtokens / 3 != (Dim+1)) {
01412 ERRORMSG("Incorrect 'block' line in FieldLayout data file '");
01413 ERRORMSG(filename << "'." << endl);
01414 ok = 0;
01415 } else if (vnlist == 0) {
01416 ERRORMSG("In FieldLayout data file '" << filename << ": You must ");
01417 ERRORMSG("give the number vnodes before any block lines." << endl);
01418 ok = 0;
01419 } else {
01420 int vnum = atoi(tokens[1].c_str());
01421 int pnum = atoi(tokens[2].c_str());
01422 if (pnum < 0 || pnum >= fpnodes) {
01423 ERRORMSG("Illegal pnode number in 'block' line ");
01424 ERRORMSG("of file '" << filename << "'." << endl);
01425 ok = 0;
01426 }
01427 NDIndex<Dim> vdom;
01428 for (int d=0, dindx=3; d < Dim; ++d) {
01429 vdom[d] = Index(atoi(tokens[dindx].c_str()),
01430 atoi(tokens[dindx + 1].c_str()),
01431 atoi(tokens[dindx + 2].c_str()));
01432 dindx += 3;
01433 }
01434
01435
01436
01437 vnlist[vnodesread++] = Vnode<Dim>(vdom, pnum, vnum);
01438 }
01439 } else {
01440 ERRORMSG("Unrecognized '" << tokens[0] << "' line in FieldLayout ");
01441 ERRORMSG(" data file '" << filename << "'." << endl);
01442 ok = 0;
01443 }
01444 }
01445
01446
01447 if (ok != 0 && (fvnodes < 1 || fdim != Dim || vnodesread != fvnodes)) {
01448 ERRORMSG("Inconsistent FieldLayout data in file '" << filename);
01449 ERRORMSG("'." << endl);
01450 ok = 0;
01451 }
01452
01453
01454 if ( ok != 0 && getNumUsers() > 0 && !(fdomain == Domain) ) {
01455 ERRORMSG("You cannot change the global domain of a FieldLayout which");
01456 ERRORMSG(" has users." << endl);
01457 ok = 0;
01458 }
01459
01460
01461 if (Ippl::getNodes() > 1) {
01462 Message *msg = new Message;
01463 msg->put(ok);
01464 if (ok != 0) {
01465 msg->put(fvnodes);
01466 msg->put(fpnodes);
01467 msg->put(fdomain);
01468 int vnpdok = (vnodesPerDir != 0 ? 1 : 0);
01469 msg->put(vnpdok);
01470 if (vnpdok != 0)
01471 msg->put(vnodesPerDir, vnodesPerDir + Dim);
01472 for (int v=0; v < fvnodes; ++v) {
01473 msg->put(vnlist[v]);
01474 }
01475 }
01476
01477 Ippl::Comm->broadcast_others(msg, tag);
01478 }
01479 } else {
01480
01481
01482 int node = 0;
01483 Message *msg = Ippl::Comm->receive_block(node, tag);
01484 PAssert(msg);
01485
01486
01487 msg->get(ok);
01488 if (ok != 0) {
01489 msg->get(fvnodes);
01490 msg->get(fpnodes);
01491 msg->get(fdomain);
01492 int vnpdok;
01493 msg->get(vnpdok);
01494 if (vnpdok != 0) {
01495 vnodesPerDir = new unsigned[Dim];
01496 msg->get_iter(vnodesPerDir);
01497 }
01498 if ((vnodesread = fvnodes) > 0) {
01499 vnlist = new Vnode<Dim>[fvnodes];
01500 for (int v=0; v < fvnodes; ++v) {
01501 Vnode<Dim> vn;
01502 msg->get(vn);
01503 vnlist[v] = vn;
01504 }
01505 }
01506 }
01507
01508
01509 delete msg;
01510 }
01511
01512
01513
01514
01515 if (ok != 1 || fvnodes < 1) {
01516 if (vnodesPerDir != 0)
01517 delete [] vnodesPerDir;
01518 if (vnlist != 0)
01519 delete [] vnlist;
01520 return false;
01521 }
01522
01523
01524 Domain = fdomain;
01525
01526
01527
01528 int localvnodes = 0;
01529 for (int v=0; v < fvnodes; ++v) {
01530 int node = vnlist[v].getNode() % Ippl::getNodes();
01531 if (node == Ippl::myNode()) {
01532 if (v > localvnodes) {
01533
01534 Vnode<Dim> tempv(vnlist[localvnodes]);
01535 vnlist[localvnodes] = vnlist[v];
01536 vnlist[v] = tempv;
01537 }
01538 localvnodes++;
01539 }
01540 }
01541
01542
01543 if (vnodesPerDirection_m != 0)
01544 delete [] vnodesPerDirection_m;
01545 vnodesPerDirection_m = vnodesPerDir;
01546
01547
01548 Repartition(vnlist, vnlist + localvnodes);
01549
01550
01551 delete [] vnlist;
01552 return true;
01553 }
01554
01555
01556
01557
01558
01559 template<unsigned Dim>
01560 void FieldLayout<Dim>::calcWidths() {
01561 unsigned int d;
01562
01563
01564 for (d=0; d < Dim; ++d)
01565 MinWidth[d] = getDomain()[d].length();
01566
01567
01568 for (const_iterator_iv v_i = begin_iv() ; v_i != end_iv(); ++v_i) {
01569 const NDIndex<Dim> &dom = (*v_i).second->getDomain();
01570 for (d=0; d < Dim; ++d) {
01571 if (dom[d].length() < MinWidth[d])
01572 MinWidth[d] = dom[d].length();
01573 }
01574 }
01575
01576
01577 ac_domain_vnodes *v_ac = Remotes_ac[ gc0() ].get();
01578 for (iterator_dv dv_i = v_ac->begin(); dv_i != v_ac->end(); ++ dv_i) {
01579 const NDIndex<Dim> &dom = (*dv_i).first;
01580 for (d=0; d < Dim; ++d) {
01581 if (dom[d].length() < MinWidth[d])
01582 MinWidth[d] = dom[d].length();
01583 }
01584 }
01585
01586
01587
01588
01589
01590
01591
01592
01593 }
01594
01595
01596
01597
01598
01599 template<unsigned Dim>
01600 void
01601 FieldLayout<Dim>::checkin(FieldLayoutUser& f,
01602 const GuardCellSizes<Dim>& gc)
01603 {
01604 TAU_TYPE_STRING(taustr, "void (FieldLayoutUser, " + CT(gc) + " )");
01605 TAU_PROFILE("FieldLayout::checkin()", taustr, TAU_LAYOUT);
01606
01607 checkinUser(f);
01608 iterator_gdv guarded = Remotes_ac.find(gc);
01609 if ( guarded == Remotes_ac.end() )
01610 new_gc_layout(gc);
01611 }
01612
01613
01614
01615
01616 template<unsigned Dim>
01617 void
01618 FieldLayout<Dim>::checkout(FieldLayoutUser& f)
01619 {
01620 TAU_PROFILE("FieldLayout::checkout()", "void (FieldLayoutUser)", TAU_LAYOUT);
01621
01622 checkoutUser(f);
01623 }
01624
01625 template<unsigned Dim>
01626 NDIndex<Dim> FieldLayout<Dim>::getLocalNDIndex()
01627 {
01628
01629 NDIndex<Dim> theId;
01630 for (iterator_iv localv = begin_iv(); localv != end_iv(); ++localv) {
01631 Vnode<Dim> *vn = (*localv).second.get();
01632 if(vn->getNode() == Ippl::myNode())
01633 theId = vn->getDomain();
01634 }
01635 return theId;
01636 }
01637
01638
01639
01640
01641
01642 template<unsigned Dim>
01643 void FieldLayout<Dim>::write(ostream& out) const
01644 {
01645 TAU_PROFILE("FieldLayout::write()", "void (ostream)", TAU_LAYOUT);
01646
01647 int icount;
01648
01649
01650 out << "Domain = " << Domain << "\n";
01651 out << "FieldLayoutUsers = " << size_if() << "\n";
01652
01653
01654 if (vnodesPerDirection_m != 0) {
01655 out << "vnodesPerDirection_m[] =";
01656 for (int d=0; d<Dim; d++)
01657 out << " " << vnodesPerDirection_m[d];
01658 out << endl;
01659 }
01660
01661
01662 out << "Total number of vnodes = " << numVnodes() << endl;
01663 out << "Local Vnodes = " << Local_ac.size() << "\n";
01664 icount = 0;
01665
01666
01667
01668 for(const_iterator_iv v_i = begin_iv() ; v_i != end_iv(); ++v_i)
01669 out << " vnode " << icount++ << ": " << *((*v_i).second) << endl;
01670
01671
01672 ac_domain_vnodes *v_ac = Remotes_ac[ gc0() ].get();
01673 out << "Remote Vnodes = " << v_ac->size() << "\n";
01674 icount = 0;
01675 for (iterator_dv dv_i = v_ac->begin(); dv_i != v_ac->end(); ++ dv_i)
01676 out << " vnode " << icount++ << " : " << *((*dv_i).second) << endl;
01677 }
01678
01679
01680
01681
01682
01683
01684