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 "Utility/DiscField.h"
00028 #include "Utility/DiscConfig.h"
00029 #include "Utility/DiscMeta.h"
00030 #include "Field/BrickIterator.h"
00031 #include "Message/Tags.h"
00032 #include "Profile/Profiler.h"
00033 #include "Utility/PAssert.h"
00034 #include "Utility/IpplStats.h"
00035 #include <string.h>
00036 #include <errno.h>
00037
00038
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 template <unsigned Dim>
00053 DiscField<Dim>::DiscField(const char* base, const char* config,
00054 unsigned int numFields, const char* typestr) {
00055 TAU_TYPE_STRING(taustr, CT(*this) +
00056 " void (char *, char *, unsigned int, char *)" );
00057 TAU_PROFILE("DiscField::DiscField()", taustr,
00058 TAU_UTILITY | TAU_FIELD | TAU_IO);
00059 initialize(base, config, typestr, numFields);
00060 }
00061
00062
00064
00065
00066
00067 template <unsigned Dim>
00068 DiscField<Dim>::DiscField(const char* base, unsigned int numFields,
00069 const char* typestr) {
00070 TAU_TYPE_STRING(taustr,CT(*this) + " void (char *, unsigned int, char *)" );
00071 TAU_PROFILE("DiscField::DiscField()", taustr,
00072 TAU_UTILITY | TAU_FIELD | TAU_IO);
00073 initialize(base, 0, typestr, numFields);
00074 }
00075
00076
00078
00079
00080
00081 template <unsigned Dim>
00082 DiscField<Dim>::DiscField(const char* base, const char* config) {
00083 TAU_TYPE_STRING(taustr, CT(*this) + " void (char *, char *)" );
00084 TAU_PROFILE("DiscField::DiscField()", taustr,
00085 TAU_UTILITY | TAU_FIELD | TAU_IO);
00086 initialize(base, config, 0, 0);
00087 }
00088
00089
00091
00092
00093
00094 template <unsigned Dim>
00095 DiscField<Dim>::DiscField(const char* base) {
00096 TAU_TYPE_STRING(taustr, CT(*this) + " void (char * )" );
00097 TAU_PROFILE("DiscField::DiscField()", taustr,
00098 TAU_UTILITY | TAU_FIELD | TAU_IO);
00099 initialize(base, 0, 0, 0);
00100 }
00101
00102
00104
00105 template <unsigned Dim>
00106 void DiscField<Dim>::initialize(const char *base, const char *config,
00107 const char *typestr, unsigned int numFields) {
00108 TAU_TYPE_STRING(taustr, CT(*this) +
00109 " void (char *, char *, char *, unsigned int )" );
00110 TAU_PROFILE("DiscField::initialize()", taustr,
00111 TAU_UTILITY | TAU_FIELD | TAU_IO);
00112
00113
00114 BaseFile = base;
00115 DiscType = "";
00116 if (typestr != 0)
00117 TypeString = typestr;
00118 else
00119 TypeString = "unknown";
00120
00121
00122 DataDimension = Dim;
00123 CurrentOffset = 0;
00124 NumRecords = 0;
00125 NumWritten = 0;
00126 NumVnodes = 0;
00127 VnodeTally = 0;
00128
00129 #ifdef IPPL_DIRECTIO
00130 openedDirectIO = false;
00131 #endif
00132
00133
00134
00135 NumFields = numFields;
00136 WritingFile = (NumFields > 0);
00137 if (WritingFile)
00138 NeedStartRecord = 1;
00139 else
00140 NeedStartRecord = -1;
00141
00142
00143 for (unsigned int i=0; i < NumFields; ++i)
00144 ValidField.push_back(false);
00145
00146
00147 ConfigOK = parse_config(config, WritingFile);
00148
00149
00150
00151
00152 if (ConfigOK && !WritingFile)
00153 ConfigOK = read_meta();
00154 }
00155
00156
00158
00159 template <unsigned Dim>
00160 DiscField<Dim>::~DiscField() {
00161 TAU_TYPE_STRING(taustr, CT(*this) + " void ()" );
00162 TAU_PROFILE("DiscField::~DiscField()", taustr,
00163 TAU_UTILITY | TAU_FIELD | TAU_IO);
00164
00165
00166 if (NumVnodes != 0)
00167 delete [] NumVnodes;
00168 if (VnodeTally != 0)
00169 delete [] VnodeTally;
00170
00171
00172 if (Config != 0)
00173 delete Config;
00174 }
00175
00176
00178
00179
00180 template <unsigned Dim>
00181 void DiscField<Dim>::query(int& numRecords, int& numFields,
00182 vector<int>& size) const {
00183 TAU_TYPE_STRING(taustr, CT(*this) + " void (int, int, vector<int> )" );
00184 TAU_PROFILE("DiscField::query()", taustr,
00185 TAU_UTILITY | TAU_FIELD | TAU_IO);
00186 numRecords = NumRecords;
00187 numFields = NumFields;
00188 if (numFiles() > 0 && myBox0() == Ippl::myNode()) {
00189 size = NumVnodes[0];
00190 for (int i=1; i < numFiles(); ++i) {
00191 for (int j=0; j < NumVnodes[i].size(); ++j)
00192 size[j] += NumVnodes[i][j];
00193 }
00194 }
00195 }
00196
00197
00199
00200
00201 template <unsigned Dim>
00202 FILE* DiscField<Dim>::open_df_file(const string& fnm, const string& mode) {
00203 TAU_TYPE_STRING(taustr, CT(*this) + " FILE * (string, string)" );
00204 TAU_PROFILE("DiscField::open_df_file()", taustr,
00205 TAU_UTILITY | TAU_FIELD | TAU_IO);
00206 FILE *f = fopen(fnm.c_str(), mode.c_str());
00207 if (f == 0) {
00208 ERRORMSG("DiscField: Could not open file '" << fnm.c_str());
00209 ERRORMSG("' for mode '" << mode.c_str() << "' on node ");
00210 ERRORMSG(Ippl::myNode() << "." << endl);
00211 Ippl::abort("Exiting due to DiscField error.");
00212 }
00213 return f;
00214 }
00215
00216
00218
00219
00220 template <unsigned Dim>
00221 int DiscField<Dim>::open_df_file_fd(const string& fnm, const string& suf,
00222 int origflags) {
00223
00224
00225 string fnamebuf("");
00226 if (fnm.length() > 0)
00227 fnamebuf += fnm;
00228 if (suf.length() > 0)
00229 fnamebuf += suf;
00230
00231
00232 int flags = origflags;
00233 #ifdef IPPL_DIRECTIO
00234 openedDirectIO = false;
00235 if (IpplInfo::useDirectIO) {
00236 flags |= O_DIRECT;
00237 openedDirectIO = true;
00238 }
00239 #endif
00240
00241
00242 int f = ::open(fnamebuf.c_str(), flags, 0644);
00243 if (f < 0) {
00244
00245 #ifdef IPPL_DIRECTIO
00246 f = ::open(fnamebuf.c_str(), origflags, 0644);
00247 openedDirectIO = (f >= 0);
00248 #endif
00249
00250
00251 if (f < 0) {
00252 ERRORMSG("DiscField: Could not open file '" << fnamebuf.c_str());
00253 ERRORMSG("' on node " << Ippl::myNode() << ", f = " << f << "."<<endl);
00254 return (-1);
00255 }
00256 }
00257
00258
00259
00260 #ifdef IPPL_DIRECTIO
00261 if (openedDirectIO) {
00262 if (::fcntl(f, F_DIOINFO, &dioinfo) != 0) {
00263 ERRORMSG("DiscField: Could not get dio info for '"<< fnamebuf.c_str());
00264 ERRORMSG("' using direct io on node ");
00265 ERRORMSG(Ippl::myNode() << "." << endl);
00266 close(f);
00267 return (-1);
00268 }
00269
00270 DFDBG(string dbgmsgname("DF:open_df_file_fd"));
00271 DFDBG(Inform dbgmsg(dbgmsgname.c_str(), INFORM_ALL_NODES));
00272 DFDBG(dbgmsg << "Opened file '" << fnamebuf.c_str() << "' with direct-io");
00273 DFDBG(dbgmsg << ", dioinfo = (miniosz="<<dioinfo.d_miniosz<<", maxiosz=");
00274 DFDBG(dbgmsg << dioinfo.d_maxiosz << ", mem=" << dioinfo.d_mem << ")");
00275 DFDBG(dbgmsg << endl);
00276 }
00277 #endif
00278
00279 return f;
00280 }
00281
00282
00284
00285 template <unsigned Dim>
00286 FILE* DiscField<Dim>::open_df_file(const string& fnm, const string& suf,
00287 const string& mode) {
00288 TAU_TYPE_STRING(taustr, CT(*this) +
00289 " FILE * (string, string, string)" );
00290 TAU_PROFILE("DiscField::open_df_file()", taustr,
00291 TAU_UTILITY | TAU_FIELD | TAU_IO);
00292
00293 string fnamebuf("");
00294 if (fnm.length() > 0)
00295 fnamebuf += fnm;
00296 if (suf.length() > 0)
00297 fnamebuf += suf;
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 FILE *f = fopen(fnamebuf.c_str(), mode.c_str());
00310
00311 if (f == 0) {
00312 ERRORMSG("DiscField: Could not open file '" << fnamebuf);
00313 ERRORMSG("' for mode '" << mode.c_str() << "' on node ");
00314 ERRORMSG(Ippl::myNode() << "." << endl);
00315 Ippl::abort("Exiting due to DiscField error.");
00316 }
00317 return f;
00318 }
00319
00320
00322
00323 template <unsigned Dim>
00324 bool DiscField<Dim>::create_files() {
00325 TAU_TYPE_STRING(taustr, CT(*this) + " bool ()" );
00326 TAU_PROFILE("DiscField::create_files()", taustr,
00327 TAU_UTILITY | TAU_FIELD | TAU_IO);
00328
00329 FILE *f;
00330 string om("w");
00331 string suff[4];
00332 suff[0] = ".meta";
00333 suff[1] = ".layout";
00334 suff[2] = ".offset";
00335 suff[3] = ".data";
00336
00337 unsigned int nfiles = 3;
00338
00339
00340 for (unsigned int i=0; i < nfiles; ++i) {
00341 string fname(Config->getFilename(0) + suff[i]);
00342 if ((f = open_df_file(fname, om)) == 0) {
00343 ERRORMSG("DiscField: Could not create file '" << fname.c_str());
00344 ERRORMSG("'." << endl);
00345 Ippl::abort("Exiting due to DiscField error.");
00346 }
00347 fclose(f);
00348 }
00349
00350
00351 int fd = open_df_file_fd(Config->getFilename(0), suff[3],
00352 O_RDWR|O_CREAT|O_TRUNC);
00353 if (fd < 0) {
00354 string fname(Config->getFilename(0) + suff[3]);
00355 ERRORMSG("DiscField: Could not create data file '"<<fname.c_str());
00356 ERRORMSG("'. errno = " << errno << endl);
00357 Ippl::abort("Exiting due to DiscField error.");
00358 } else {
00359 close(fd);
00360 }
00361
00362 return true;
00363 }
00364
00365
00367
00368
00369
00370
00371 template <unsigned Dim>
00372 bool DiscField<Dim>::make_globalID(FieldLayout<Dim>& layout) {
00373 TAU_TYPE_STRING(taustr, CT(*this) + " bool (" + CT(layout) + " )" );
00374 TAU_PROFILE("DiscField::make_globalID()", taustr,
00375 TAU_UTILITY | TAU_FIELD | TAU_IO);
00376
00377
00378 if (Size.size() != 0 && !(Size == layout.getDomain()))
00379 return false;
00380 else
00381 Size = layout.getDomain();
00382
00383
00384 globalID.erase(globalID.begin(), globalID.end());
00385
00386
00387
00388 typedef typename GlobalIDList_t::value_type vtype;
00389 typename FieldLayout<Dim>::iterator_iv local;
00390 for (local = layout.begin_iv() ; local != layout.end_iv(); ++local) {
00391
00392 NDIndex<Dim>& domain = (NDIndex<Dim>&) (*local).second.get()->getDomain();
00393 int node = (*local).second.get()->getNode();
00394 int nodesmp = Config->getNodeSMPIndex(node);
00395
00396
00397 bool foundsmp = (nodesmp == mySMP());
00398 int checksmp = 0;
00399 while (!foundsmp && checksmp < Config->getNumOtherSMP()) {
00400 foundsmp = (nodesmp == Config->getOtherSMP(checksmp));
00401 checksmp++;
00402 }
00403
00404
00405 if (foundsmp) {
00406
00407
00408 globalID.insert(vtype(domain, node));
00409 }
00410 }
00411
00412
00413
00414 typename FieldLayout<Dim>::iterator_dv remote;
00415 for (remote = layout.begin_rdv() ; remote != layout.end_rdv(); ++remote) {
00416
00417 NDIndex<Dim>& domain = (NDIndex<Dim>&) (*remote).first;
00418 int node = (*remote).second->getNode();
00419 int nodesmp = Config->getNodeSMPIndex(node);
00420
00421
00422 bool foundsmp = (nodesmp == mySMP());
00423 int checksmp = 0;
00424 while (!foundsmp && checksmp < Config->getNumOtherSMP()) {
00425 foundsmp = (nodesmp == Config->getOtherSMP(checksmp));
00426 checksmp++;
00427 }
00428
00429
00430 if (foundsmp) {
00431
00432
00433 globalID.insert(vtype(domain, node));
00434 }
00435 }
00436
00437 return true;
00438 }
00439
00440
00442
00443
00444 template <unsigned Dim>
00445 bool DiscField<Dim>::parse_config(const char *fname, bool writing) {
00446 TAU_TYPE_STRING(taustr, CT(*this) + " bool (char *, bool)" );
00447 TAU_PROFILE("DiscField::parse_config()", taustr,
00448 TAU_UTILITY | TAU_FIELD | TAU_IO);
00449
00450
00451
00452 Config = new DiscConfig(fname, BaseFile.c_str(), writing);
00453
00454
00455 if (Config->ok()) {
00456
00457 if (numFiles() > 0 && myBox0() == Ippl::myNode()) {
00458 NumVnodes = new vector<int>[numFiles()];
00459 VnodeTally = new vector<int>[numFiles()];
00460 }
00461
00462
00463 if (writing && Ippl::myNode() == myBox0() && NumFields > 0) {
00464 if (!create_files())
00465 return false;
00466 }
00467
00468
00469 if (writing) {
00470 ADDIPPLSTAT(incDiscFilesetWrites,numFiles());
00471 } else {
00472 ADDIPPLSTAT(incDiscFilesetReads,numFiles());
00473 }
00474 } else {
00475 ERRORMSG("DiscField: A problem occurred reading the config file '");
00476 ERRORMSG(fname << "'." << endl);
00477 Ippl::abort("Exiting due to DiscField error.");
00478 }
00479
00480 return Config->ok();
00481 }
00482
00483
00485
00486 template <unsigned Dim>
00487 void DiscField<Dim>::printDebug() { printDebug(cout); }
00488
00489 template <unsigned Dim>
00490 void DiscField<Dim>::printDebug(ostream& outmsg) {
00491 TAU_TYPE_STRING(taustr, CT(*this) + " void (ostream )" );
00492 TAU_PROFILE("DiscField::printDebug()", taustr,
00493 TAU_UTILITY | TAU_FIELD | TAU_IO);
00494
00495 Inform msg("DiscField", outmsg, INFORM_ALL_NODES);
00496
00497 msg << "BaseFile = " << BaseFile << endl;
00498 msg << "Field Type = " << TypeString << endl;
00499 msg << "NumRecords = " << NumRecords << endl;
00500 msg << "NumFields = " << NumFields << endl;
00501
00502 msg << "Configuration file information:" << endl;
00503 Config->printDebug(msg);
00504
00505 msg << endl;
00506 }
00507
00508
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 template <unsigned Dim>
00523 bool DiscField<Dim>::write_meta() {
00524 TAU_TYPE_STRING(taustr, CT(*this) + " bool ()" );
00525 TAU_PROFILE("DiscField::write_meta()", taustr,
00526 TAU_UTILITY | TAU_FIELD | TAU_IO);
00527
00528 unsigned int r, d;
00529
00530
00531 if (numFiles() == 0)
00532 return true;
00533
00534
00535 FILE *outputMeta = open_df_file(Config->getFilename(0),".meta",string("w"));
00536 if (outputMeta == 0)
00537 return false;
00538
00539
00540 fprintf(outputMeta, "Type = %s\n", TypeString.c_str());
00541 fprintf(outputMeta, "Dim = %d\n", Dim);
00542 for (d=0; d < Dim; ++d)
00543 fprintf(outputMeta, "Domain = %d %d %d\n",
00544 Size[d].first(), Size[d].last(), Size[d].stride());
00545 fprintf(outputMeta, "Fields = %d\n", NumFields);
00546 fprintf(outputMeta, "Records = %d\n", NumRecords);
00547 fprintf(outputMeta, "SMPs = %d\n", fileSMPs());
00548
00549
00550
00551 fprintf(outputMeta, "VnodesInRecord = ");
00552 for (r=0; r < NumRecords; ++r)
00553 fprintf(outputMeta, " %d", NumVnodes[0][r]);
00554 fprintf(outputMeta, "\n");
00555
00556 fprintf(outputMeta, "VnodeTally= ");
00557 for (r=0; r < NumRecords; ++r)
00558 fprintf(outputMeta, " %d", VnodeTally[0][r]);
00559 fprintf(outputMeta, "\n");
00560
00561
00562 fclose(outputMeta);
00563 return true;
00564 }
00565
00566
00568
00569
00570
00571 template <unsigned Dim>
00572 bool DiscField<Dim>::read_meta() {
00573 TAU_TYPE_STRING(taustr, CT(*this) + " bool ()" );
00574 TAU_PROFILE("DiscField::read_meta()", taustr,
00575 TAU_UTILITY | TAU_FIELD | TAU_IO);
00576 unsigned int r;
00577 bool iserror = false;
00578 int tag = Ippl::Comm->next_tag(DF_READ_META_TAG, DF_TAG_CYCLE);
00579
00580 DFDBG(string dbgmsgname("DF:read_meta:"));
00581 DFDBG(dbgmsgname += Config->getConfigFile());
00582 DFDBG(Inform dbgmsg(dbgmsgname.c_str(), INFORM_ALL_NODES));
00583 DFDBG(dbgmsg << "Starting to read meta info: mySMP=" << mySMP());
00584 DFDBG(dbgmsg << ", mybox0=" << myBox0() << ", numfiles=" << numFiles());
00585 DFDBG(dbgmsg << endl);
00586
00587
00588
00589 if (Ippl::myNode() == myBox0()) {
00590
00591 for (int sf=0; sf < numFiles(); ++sf) {
00592
00593 string filename = Config->getFilename(sf) + ".meta";
00594 DiscMeta outputMeta(filename.c_str());
00595 if (outputMeta.size() == 0) {
00596 ERRORMSG("DiscField: The meta file '" << filename << "' is empty ");
00597 ERRORMSG("or does not exist." << endl);
00598 Ippl::abort("Exiting due to DiscField error.");
00599 return false;
00600 }
00601
00602
00603 unsigned int dimread = 0;
00604 TypeString = "unknown";
00605 DataDimension = Dim;
00606 NumFields = 0;
00607 NumRecords = 0;
00608 NumVnodes[sf].erase(NumVnodes[sf].begin(), NumVnodes[sf].end());
00609 VnodeTally[sf].erase(VnodeTally[sf].begin(), VnodeTally[sf].end());
00610
00611
00612 DiscMeta::iterator metaline, metaend = outputMeta.end();
00613 for (metaline = outputMeta.begin(); metaline != metaend; ++metaline) {
00614
00615 int linesread = (*metaline).first;
00616 int numtokens = (*metaline).second.first;
00617 string *tokens = (*metaline).second.second;
00618
00619
00620 if (tokens[0] == "Type") {
00621 if (numtokens > 1)
00622 TypeString = tokens[1];
00623 }
00624 else if (tokens[0] == "Dim" && numtokens == 2) {
00625 DataDimension = atoi(tokens[1].c_str());
00626 if (DataDimension < 1) {
00627 ERRORMSG("DiscField: The meta file '" << filename << "' ");
00628 ERRORMSG("contains a value for dimension < 1, '");
00629 ERRORMSG(tokens[1] << "'." << endl);
00630 Ippl::abort("Exiting due to DiscField error.");
00631 iserror = true;
00632 }
00633 }
00634 else if (tokens[0] == "Fields" && numtokens == 2) {
00635 NumFields = atoi(tokens[1].c_str());
00636 if (NumFields < 1) {
00637 ERRORMSG("DiscField: The meta file '" << filename << "' ");
00638 ERRORMSG("contains a value for Fields < 1, '");
00639 ERRORMSG(tokens[1] << "'." << endl);
00640 Ippl::abort("Exiting due to DiscField error.");
00641 iserror = true;
00642 }
00643 }
00644 else if (tokens[0] == "Records" && numtokens == 2) {
00645 NumRecords = atoi(tokens[1].c_str());
00646 }
00647 else if (tokens[0] == "SMPs" && numtokens == 2) {
00648 int checkfileSMPs = atoi(tokens[1].c_str());
00649 if (fileSMPs() != checkfileSMPs) {
00650 ERRORMSG("DiscField: The meta file '" << filename << "' ");
00651 ERRORMSG("contains a value for the number of filesets that\n");
00652 ERRORMSG("does not match the number of filesets in the config\n");
00653 ERRORMSG("file: metafile filesets = " << tokens[1] << ", ");
00654 ERRORMSG("config filesets = " << fileSMPs() << "." << endl);
00655 Ippl::abort("Exiting due to DiscField error.");
00656 iserror = true;
00657 }
00658 }
00659 else if (tokens[0] == "Domain" && numtokens == 4) {
00660 if (dimread < Dim) {
00661 Size[dimread] = Index(atoi(tokens[1].c_str()),
00662 atoi(tokens[2].c_str()),
00663 atoi(tokens[3].c_str()));
00664 }
00665 dimread++;
00666 }
00667 else if (tokens[0] == "VnodesInRecord") {
00668 for (r=1; r < numtokens; ++r)
00669 NumVnodes[sf].push_back(atoi(tokens[r].c_str()));
00670 }
00671 else if (tokens[0] == "VnodeTally") {
00672 for (r=1; r < numtokens; ++r)
00673 VnodeTally[sf].push_back(atoi(tokens[r].c_str()));
00674 }
00675 else {
00676
00677 ERRORMSG("DiscField: Format error on line " << linesread);
00678 ERRORMSG(" in meta file '" << filename << "'." << endl);
00679 Ippl::abort("Exiting due to DiscField error.");
00680 iserror = true;
00681 }
00682
00683 DFDBG(dbgmsg << "On box0: finished line with tokens[0]='"<<tokens[0]);
00684 DFDBG(dbgmsg << "' ... iserror = " << iserror << endl);
00685
00686 if (iserror)
00687 break;
00688 }
00689
00690
00691 if (DataDimension != dimread) {
00692 ERRORMSG("DiscField: Dim != # Domain lines in meta file '");
00693 ERRORMSG(filename << "'. (" << DataDimension << " != " << dimread);
00694 ERRORMSG(")" << endl);
00695 Ippl::abort("Exiting due to DiscField error.");
00696 iserror = true;
00697 }
00698 if (NumRecords != NumVnodes[sf].size()) {
00699 ERRORMSG("DiscField: Records != VnodesInRecord items in meta file '");
00700 ERRORMSG(filename << "'. (" << NumRecords << " != ");
00701 ERRORMSG(NumVnodes[sf].size() << ")" << endl);
00702 Ippl::abort("Exiting due to DiscField error.");
00703 iserror = true;
00704 }
00705 if (NumRecords != VnodeTally[sf].size()) {
00706 ERRORMSG("DiscField: Records != VnodeTally items in meta file '");
00707 ERRORMSG(filename << "'. (" << NumRecords << " != ");
00708 ERRORMSG(VnodeTally[sf].size() << ")" << endl);
00709 Ippl::abort("Exiting due to DiscField error.");
00710 iserror = true;
00711 }
00712
00713
00714 if (iserror)
00715 break;
00716 }
00717
00718 DFDBG(dbgmsg << "Summary of meta info:" << endl);
00719 DFDBG(dbgmsg << " iserror = " << iserror << endl);
00720 DFDBG(dbgmsg << " DataDimension = " << DataDimension << endl);
00721 DFDBG(dbgmsg << " NumFields = " << NumFields << endl);
00722 DFDBG(dbgmsg << " NumRecords = " << NumRecords << endl);
00723 DFDBG(dbgmsg << " Size = " << Size << endl);
00724 DFDBG(dbgmsg << " TypeString = " << TypeString << endl);
00725
00726
00727 int numinform = Config->getNumOtherSMP();
00728 DFDBG(dbgmsg << "Preparing messages to send to other nodes ..." << endl);
00729 DFDBG(dbgmsg << " Must send data to my SMP nodes, and to ");
00730 DFDBG(dbgmsg << numinform << " other SMP's." << endl);
00731 for (int s=0; s <= numinform; ++s) {
00732 int smp = mySMP();
00733 if (s != numinform)
00734 smp = Config->getOtherSMP(s);
00735 DFDBG(dbgmsg << " Preparing messages for SMP " << smp << " with ");
00736 DFDBG(dbgmsg << Config->getNumSMPNodes(smp) << " nodes." << endl);
00737 for (int n=0; n < Config->getNumSMPNodes(smp); ++n) {
00738 int node = Config->getSMPNode(smp, n);
00739 if (node != Ippl::myNode()) {
00740
00741 Message *msg = new Message;
00742 int errint = iserror;
00743 msg->put(errint);
00744 msg->put(DataDimension);
00745 msg->put(NumFields);
00746 msg->put(NumRecords);
00747 ::putMessage(*msg, Size);
00748 ::putMessage(*msg, TypeString);
00749
00750
00751 DFDBG(dbgmsg << " Sending meta info to node " << node);
00752 DFDBG(dbgmsg << " with tag " << tag << ", on SMP " << smp << endl);
00753 Ippl::Comm->send(msg, node, tag);
00754 } else {
00755 DFDBG(dbgmsg << " Skipping send to node " << node);
00756 DFDBG(dbgmsg << " since it is my node." << endl);
00757 }
00758 }
00759 }
00760
00761 } else {
00762
00763
00764 int node = myBox0();
00765 DFDBG(dbgmsg << "Waiting for meta info from node " << node);
00766 DFDBG(dbgmsg << " with tag " << tag << endl);
00767 Message *msg = Ippl::Comm->receive_block(node, tag);
00768 PAssert(msg != 0);
00769
00770
00771 DFDBG(dbgmsg << "Summary of received meta info:" << endl);
00772 int errint;
00773 msg->get(errint);
00774 iserror = (errint != 0);
00775 DFDBG(dbgmsg << " iserror = " << iserror << endl);
00776 msg->get(DataDimension);
00777 DFDBG(dbgmsg << " DataDimension = " << DataDimension << endl);
00778 msg->get(NumFields);
00779 DFDBG(dbgmsg << " NumFields = " << NumFields << endl);
00780 msg->get(NumRecords);
00781 DFDBG(dbgmsg << " NumRecords = " << NumRecords << endl);
00782 ::getMessage(*msg, Size);
00783 DFDBG(dbgmsg << " Size = " << Size << endl);
00784 ::getMessage(*msg, TypeString);
00785 DFDBG(dbgmsg << " TypeString = " << TypeString << endl);
00786
00787
00788 delete msg;
00789 }
00790
00791 return (!iserror);
00792 }
00793
00794
00796
00797 template <unsigned Dim>
00798 bool DiscField<Dim>::read_NDIndex(FILE *f, NDIndex<Dim> &ndi) {
00799
00800 int ndidata[6*Dim];
00801
00802
00803
00804
00805
00806
00807
00808 if (fread(ndidata, sizeof(int), 6*Dim, f) != 6*Dim) {
00809 ERRORMSG("DiscField: Error reading NDIndex line from data file." << endl);
00810 Ippl::abort("Exiting due to DiscField error.");
00811 return false;
00812 }
00813
00814
00815 int *dptr = ndidata + 1;
00816 for (int d=0; d < Dim; ++d) {
00817 int first = *dptr;
00818 int stride = *(dptr + 1);
00819 int length = *(dptr + 2);
00820 ndi[d] = Index(first, first + (length - 1)*stride, stride);
00821 dptr += 6;
00822 }
00823
00824 return true;
00825 }
00826
00827
00829
00830 template <unsigned Dim>
00831 bool DiscField<Dim>::write_NDIndex(FILE *f, const NDIndex<Dim> &ndi) {
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854 int ndidata[6*Dim];
00855 int *dptr = ndidata;
00856 for (int d=0; d < Dim; ++d) {
00857 *dptr++ = 0;
00858 *dptr++ = ndi[d].first();
00859 *dptr++ = ndi[d].stride();
00860 *dptr++ = ndi[d].length();
00861 *dptr++ = 0;
00862 *dptr++ = 0;
00863 }
00864
00865
00866 return (fwrite(ndidata, sizeof(int), 6*Dim, f) == 6*Dim);
00867 }
00868
00869
00871
00872
00873
00874
00875
00876
00877
00878 template <unsigned Dim>
00879 bool DiscField<Dim>::write_layout() {
00880 TAU_TYPE_STRING(taustr, CT(*this) + " bool ()" );
00881 TAU_PROFILE("DiscField::write_layout()", taustr,
00882 TAU_UTILITY | TAU_FIELD | TAU_IO);
00883
00884
00885 if (numFiles() == 0)
00886 return true;
00887
00888
00889 FILE *outputLayout = open_df_file(Config->getFilename(0), ".layout",
00890 string("a"));
00891
00892
00893 int numvnodes = globalID.size();
00894 if (fwrite(&numvnodes, sizeof(int), 1, outputLayout) != 1) {
00895 ERRORMSG("Error writing .layout file in DiscField::write_layout." << endl);
00896 Ippl::abort("Exiting due to DiscField error.");
00897 fclose(outputLayout);
00898 return false;
00899 }
00900
00901
00902 typename GlobalIDList_t::iterator id, idend = globalID.end();
00903 for (id = globalID.begin(); id != idend; ++id) {
00904 if (!write_NDIndex(outputLayout, (*id).first)) {
00905 ERRORMSG("Error writing record " << NumRecords-1 << " to .layout file.");
00906 Ippl::abort("Exiting due to DiscField error.");
00907 fclose(outputLayout);
00908 return false;
00909 }
00910 }
00911
00912
00913 fclose(outputLayout);
00914 return true;
00915 }
00916
00917
00919
00920 template <unsigned Dim>
00921 int DiscField<Dim>::read_layout(int record, int sf) {
00922 TAU_TYPE_STRING(taustr, CT(*this) + " int (int, int, int &)" );
00923 TAU_PROFILE("DiscField::read_layout()", taustr,
00924 TAU_UTILITY | TAU_FIELD | TAU_IO);
00925
00926 DFDBG(string dbgmsgname("DF:read_layout:"));
00927 DFDBG(dbgmsgname += Config->getConfigFile());
00928 DFDBG(Inform dbgmsg(dbgmsgname.c_str(), INFORM_ALL_NODES));
00929 DFDBG(dbgmsg << "Starting to read layout info for record " << record);
00930 DFDBG(dbgmsg << ", file " << sf << ": mySMP=" << mySMP() << ", mybox0=");
00931 DFDBG(dbgmsg << myBox0() << ", numfiles=" << numFiles() << endl);
00932
00933
00934 string filename = Config->getFilename(sf) + ".layout";
00935 FILE *outputLayout = open_df_file(Config->getFilename(sf),
00936 ".layout", string("r"));
00937 if (outputLayout == 0)
00938 return (-1);
00939
00940 DFDBG(dbgmsg << "On box0: sf=" << sf << ", opened file '");
00941 DFDBG(dbgmsg << filename << "' ..." << endl);
00942
00943
00944 Offset_t seekpos = record*sizeof(int) +
00945 VnodeTally[sf][record]*6*Dim*sizeof(int);
00946 DFDBG(dbgmsg << " Seeking to position ");
00947 DFDBG(dbgmsg << static_cast<long>(seekpos) << endl);
00948
00949 if (fseek(outputLayout, seekpos, SEEK_SET) != 0) {
00950 ERRORMSG("Error seeking to position " << static_cast<long>(seekpos));
00951 ERRORMSG(" in file '" << filename << "' for DiscField::read_layout.");
00952 ERRORMSG(endl);
00953 Ippl::abort("Exiting due to DiscField error.");
00954 fclose(outputLayout);
00955 return (-1);
00956 }
00957
00958
00959 int numvnodes = 0;
00960 if (fread(&numvnodes, sizeof(int), 1, outputLayout) != 1) {
00961 ERRORMSG("Error reading file '" << filename);
00962 ERRORMSG("' in DiscField::read_layout.");
00963 ERRORMSG(endl);
00964 Ippl::abort("Exiting due to DiscField error.");
00965 fclose(outputLayout);
00966 return (-1);
00967 }
00968
00969
00970
00971
00972
00973
00974 fclose(outputLayout);
00975 return numvnodes;
00976 }
00977
00978
00980
00981
00982
00983
00984
00985 template <unsigned Dim>
00986 int DiscField<Dim>::compute_expected(const FieldLayout<Dim> &f,
00987 const NDIndex<Dim> &readDomain) {
00988 int expected = 0;
00989
00990 DFDBG(string dbgmsgname("DF:compute_expected"));
00991 DFDBG(Inform dbgmsg(dbgmsgname.c_str(), INFORM_ALL_NODES));
00992 DFDBG(dbgmsg << "Computing expected size for node " << Ippl::myNode());
00993 DFDBG(dbgmsg <<endl);
00994
00995 typename FieldLayout<Dim>::const_iterator_iv local = f.begin_iv();
00996 for (; local != f.end_iv(); ++local) {
00997
00998
00999 NDIndex<Dim>& domain = (NDIndex<Dim>&)(*local).second.get()->getDomain();
01000 if (domain.touches(readDomain)) {
01001 NDIndex<Dim> newdomain = domain.intersect(readDomain);
01002 DFDBG(dbgmsg << "Intersection of " << domain << " and " << readDomain);
01003 DFDBG(dbgmsg << " = " << newdomain << endl);
01004
01005 expected += newdomain.size();
01006 } else {
01007 DFDBG(dbgmsg << "No intersection of " << domain << " and ");
01008 DFDBG(dbgmsg << readDomain << endl);
01009 }
01010
01011 DFDBG(dbgmsg << " Size for local domain " << domain << " = ");
01012 DFDBG(dbgmsg << domain.size() << ", readDomain = " << readDomain);
01013 DFDBG(dbgmsg << ", new expected for node " << Ippl::myNode() << " ");
01014 DFDBG(dbgmsg << expected << endl);
01015 }
01016
01017 return expected;
01018 }
01019
01020
01022
01023
01024 template <unsigned Dim>
01025 NDIndex<Dim> DiscField<Dim>::chunk_domain(const NDIndex<Dim> &currblock,
01026 int chunkelems,
01027 int &msdim,
01028 bool iscompressed)
01029 {
01030 TAU_TYPE_STRING(taustr, CT(*this) + " NDIndex (NDIndex, int, int &, bool)");
01031 TAU_PROFILE("DiscField::chunk_domain()", taustr,
01032 TAU_UTILITY | TAU_FIELD | TAU_IO);
01033
01034
01035 NDIndex<Dim> sliceblock;
01036 for (int i=0; i < Dim; ++i)
01037 sliceblock[i] = Index(currblock[i].length());
01038
01039
01040 int currsize = currblock.size();
01041 if (chunkelems < 1 || iscompressed)
01042 chunkelems = currsize;
01043
01044
01045
01046 for (int d=(Dim-1); d >= 0; --d) {
01047
01048 int axislen = currblock[d].length();
01049 currsize /= axislen;
01050
01051
01052 int numslices = chunkelems / currsize;
01053 if (numslices > axislen)
01054 numslices = axislen;
01055
01056
01057 if (numslices > 0) {
01058 sliceblock[d] = Index(numslices);
01059 msdim = d;
01060 break;
01061 } else {
01062
01063 sliceblock[d] = Index(1);
01064 }
01065 }
01066
01067
01068
01069 return sliceblock;
01070 }
01071
01072
01073
01074
01075
01076
01077