51template <
unsigned Dim>
53 unsigned int numFields,
const char* typestr) {
55 initialize(base, config, typestr, numFields);
63template <
unsigned Dim>
65 const char* typestr) {
67 initialize(base, 0, typestr, numFields);
75template <
unsigned Dim>
78 initialize(base, config, 0, 0);
86template <
unsigned Dim>
89 initialize(base, 0, 0, 0);
95template <
unsigned Dim>
97 const char *typestr,
unsigned int numFields) {
103 TypeString = typestr;
105 TypeString =
"unknown";
117 NumFields = numFields;
118 WritingFile = (NumFields > 0);
122 NeedStartRecord = -1;
125 for (
unsigned int i=0; i < NumFields; ++i)
126 ValidField.push_back(
false);
129 ConfigOK = parse_config(config, WritingFile);
134 if (ConfigOK && !WritingFile)
135 ConfigOK = read_meta();
141template <
unsigned Dim>
148 delete [] VnodeTally;
159template <
unsigned Dim>
161 std::vector<int>& size)
const {
163 numRecords = NumRecords;
164 numFields = NumFields;
167 for (
int i=1; i < numFiles(); ++i) {
168 for (
int j=0; j < NumVnodes[i].size(); ++j)
169 size[j] += NumVnodes[i][j];
178template <
unsigned Dim>
181 FILE *f = fopen(fnm.c_str(), mode.c_str());
183 ERRORMSG(
"DiscField: Could not open file '" << fnm.c_str());
184 ERRORMSG(
"' for mode '" << mode.c_str() <<
"' on node ");
195template <
unsigned Dim>
200 std::string fnamebuf(
"");
201 if (fnm.length() > 0)
203 if (suf.length() > 0)
207 int flags = origflags;
210 int f = ::open(fnamebuf.c_str(), flags, 0644);
212 ERRORMSG(
"DiscField: Could not open file '" << fnamebuf.c_str());
222template <
unsigned Dim>
224 const std::string& mode) {
226 std::string fnamebuf(
"");
227 if (fnm.length() > 0)
229 if (suf.length() > 0)
242 FILE *f = fopen(fnamebuf.c_str(), mode.c_str());
245 ERRORMSG(
"DiscField: Could not open file '" << fnamebuf);
246 ERRORMSG(
"' for mode '" << mode.c_str() <<
"' on node ");
256template <
unsigned Dim>
268 unsigned int nfiles = 3;
271 for (
unsigned int i=0; i < nfiles; ++i) {
272 std::string fname(Config->getFilename(0) + suff[i]);
273 if ((f = open_df_file(fname, om)) == 0) {
274 ERRORMSG(
"DiscField: Could not create file '" << fname.c_str());
282 int fd = open_df_file_fd(Config->getFilename(0), suff[3],
283 O_RDWR|O_CREAT|O_TRUNC);
285 std::string fname(Config->getFilename(0) + suff[3]);
286 ERRORMSG(
"DiscField: Could not create data file '"<<fname.c_str());
302template <
unsigned Dim>
306 if (Size.size() != 0 && !(Size == layout.
getDomain()))
312 globalID.erase(globalID.begin(), globalID.end());
318 for (local = layout.
begin_iv() ; local != layout.
end_iv(); ++local) {
321 int node = (*local).second.get()->getNode();
322 unsigned int nodesmp = Config->getNodeSMPIndex(node);
325 bool foundsmp = (nodesmp == mySMP());
326 unsigned int checksmp = 0;
327 while (!foundsmp && checksmp < Config->getNumOtherSMP()) {
328 foundsmp = (nodesmp == Config->getOtherSMP(checksmp));
336 globalID.insert(vtype(domain, node));
346 int node = (*remote).second->getNode();
347 unsigned int nodesmp = Config->getNodeSMPIndex(node);
350 bool foundsmp = (nodesmp == mySMP());
351 unsigned int checksmp = 0;
352 while (!foundsmp && checksmp < Config->getNumOtherSMP()) {
353 foundsmp = (nodesmp == Config->getOtherSMP(checksmp));
361 globalID.insert(vtype(domain, node));
372template <
unsigned Dim>
377 Config =
new DiscConfig(fname, BaseFile.c_str(), writing);
382 if (numFiles() > 0 && myBox0() == (
unsigned int)
Ippl::myNode()) {
383 NumVnodes =
new std::vector<int>[numFiles()];
384 VnodeTally =
new std::vector<int>[numFiles()];
402 ERRORMSG(
"DiscField: A problem occurred reading the config file '");
413template <
unsigned Dim>
416template <
unsigned Dim>
421 msg <<
"BaseFile = " << BaseFile <<
endl;
422 msg <<
"Field Type = " << TypeString <<
endl;
423 msg <<
"NumRecords = " << NumRecords <<
endl;
424 msg <<
"NumFields = " << NumFields <<
endl;
426 msg <<
"Configuration file information:" <<
endl;
427 Config->printDebug(msg);
446template <
unsigned Dim>
456 FILE *outputMeta = open_df_file(Config->getFilename(0),
".meta",std::string(
"w"));
461 fprintf(outputMeta,
"Type = %s\n", TypeString.c_str());
462 fprintf(outputMeta,
"Dim = %u\n",
Dim);
463 for (d=0; d <
Dim; ++d)
464 fprintf(outputMeta,
"Domain = %d %d %d\n",
465 Size[d].first(), Size[d].last(), Size[d].stride());
466 fprintf(outputMeta,
"Fields = %u\n", NumFields);
467 fprintf(outputMeta,
"Records = %u\n", NumRecords);
468 fprintf(outputMeta,
"SMPs = %u\n", fileSMPs());
472 fprintf(outputMeta,
"VnodesInRecord = ");
473 for (r=0; r < NumRecords; ++r)
474 fprintf(outputMeta,
" %d", NumVnodes[0][r]);
475 fprintf(outputMeta,
"\n");
477 fprintf(outputMeta,
"VnodeTally= ");
478 for (r=0; r < NumRecords; ++r)
479 fprintf(outputMeta,
" %d", VnodeTally[0][r]);
480 fprintf(outputMeta,
"\n");
492template <
unsigned Dim>
495 bool iserror =
false;
502 for (
unsigned int sf=0; sf < numFiles(); ++sf) {
504 std::string filename = Config->getFilename(sf) +
".meta";
505 DiscMeta outputMeta(filename.c_str());
506 if (outputMeta.
size() == 0) {
507 ERRORMSG(
"DiscField: The meta file '" << filename <<
"' is empty ");
514 unsigned int dimread = 0;
515 TypeString =
"unknown";
519 NumVnodes[sf].erase(NumVnodes[sf].
begin(), NumVnodes[sf].
end());
520 VnodeTally[sf].erase(VnodeTally[sf].
begin(), VnodeTally[sf].
end());
524 for (metaline = outputMeta.
begin(); metaline != metaend; ++metaline) {
526 int linesread = (*metaline).first;
527 int numtokens = (*metaline).second.first;
528 std::string *tokens = (*metaline).second.second;
531 if (tokens[0] ==
"Type") {
533 TypeString = tokens[1];
535 else if (tokens[0] ==
"Dim" && numtokens == 2) {
536 DataDimension = atoi(tokens[1].c_str());
537 if (DataDimension < 1) {
538 ERRORMSG(
"DiscField: The meta file '" << filename <<
"' ");
539 ERRORMSG(
"contains a value for dimension < 1, '");
545 else if (tokens[0] ==
"Fields" && numtokens == 2) {
546 NumFields = atoi(tokens[1].c_str());
548 ERRORMSG(
"DiscField: The meta file '" << filename <<
"' ");
549 ERRORMSG(
"contains a value for Fields < 1, '");
555 else if (tokens[0] ==
"Records" && numtokens == 2) {
556 NumRecords = atoi(tokens[1].c_str());
558 else if (tokens[0] ==
"SMPs" && numtokens == 2) {
559 unsigned int checkfileSMPs = atoi(tokens[1].c_str());
560 if (fileSMPs() != checkfileSMPs) {
561 ERRORMSG(
"DiscField: The meta file '" << filename <<
"' ");
562 ERRORMSG(
"contains a value for the number of filesets that\n");
563 ERRORMSG(
"does not match the number of filesets in the config\n");
564 ERRORMSG(
"file: metafile filesets = " << tokens[1] <<
", ");
565 ERRORMSG(
"config filesets = " << fileSMPs() <<
"." <<
endl);
570 else if (tokens[0] ==
"Domain" && numtokens == 4) {
572 Size[dimread] =
Index(atoi(tokens[1].c_str()),
573 atoi(tokens[2].c_str()),
574 atoi(tokens[3].c_str()));
578 else if (tokens[0] ==
"VnodesInRecord") {
579 for (
int r=1; r < numtokens; ++r)
580 NumVnodes[sf].push_back(atoi(tokens[r].c_str()));
582 else if (tokens[0] ==
"VnodeTally") {
583 for (
int r=1; r < numtokens; ++r)
584 VnodeTally[sf].push_back(atoi(tokens[r].c_str()));
588 ERRORMSG(
"DiscField: Format error on line " << linesread);
589 ERRORMSG(
" in meta file '" << filename <<
"'." <<
endl);
599 if (DataDimension != dimread) {
600 ERRORMSG(
"DiscField: Dim != # Domain lines in meta file '");
601 ERRORMSG(filename <<
"'. (" << DataDimension <<
" != " << dimread);
606 if (NumRecords != NumVnodes[sf].size()) {
607 ERRORMSG(
"DiscField: Records != VnodesInRecord items in meta file '");
608 ERRORMSG(filename <<
"'. (" << NumRecords <<
" != ");
613 if (NumRecords != VnodeTally[sf].size()) {
614 ERRORMSG(
"DiscField: Records != VnodeTally items in meta file '");
615 ERRORMSG(filename <<
"'. (" << NumRecords <<
" != ");
627 int numinform = Config->getNumOtherSMP();
628 for (
int s=0; s <= numinform; ++s) {
631 smp = Config->getOtherSMP(s);
632 for (
unsigned int n=0;
n < Config->getNumSMPNodes(smp); ++
n) {
633 int node = Config->getSMPNode(smp,
n);
637 int errint = iserror;
639 msg->
put(DataDimension);
641 msg->
put(NumRecords);
661 iserror = (errint != 0);
662 msg->
get(DataDimension);
664 msg->
get(NumRecords);
678template <
unsigned Dim>
689 if (fread(ndidata,
sizeof(
int), 6*
Dim, f) != 6*
Dim) {
690 ERRORMSG(
"DiscField: Error reading NDIndex line from data file." <<
endl);
696 int *dptr = ndidata + 1;
697 for (
unsigned int d=0; d <
Dim; ++d) {
699 int stride = *(dptr + 1);
700 int length = *(dptr + 2);
701 ndi[d] =
Index(first, first + (length - 1)*stride, stride);
711template <
unsigned Dim>
737 for (
unsigned int d=0; d <
Dim; ++d) {
739 *dptr++ = ndi[d].first();
740 *dptr++ = ndi[d].stride();
741 *dptr++ = ndi[d].length();
747 return (fwrite(ndidata,
sizeof(
int), 6*
Dim, f) == 6*
Dim);
759template <
unsigned Dim>
767 FILE *outputLayout = open_df_file(Config->getFilename(0),
".layout",
771 int numvnodes = globalID.size();
772 if (fwrite(&numvnodes,
sizeof(
int), 1, outputLayout) != 1) {
773 ERRORMSG(
"Error writing .layout file in DiscField::write_layout." <<
endl);
775 fclose(outputLayout);
781 for (
id = globalID.begin();
id != idend; ++
id) {
782 if (!write_NDIndex(outputLayout, (*id).first)) {
783 ERRORMSG(
"Error writing record " << NumRecords-1 <<
" to .layout file.");
785 fclose(outputLayout);
791 fclose(outputLayout);
798template <
unsigned Dim>
802 std::string filename = Config->getFilename(sf) +
".layout";
803 FILE *outputLayout = open_df_file(Config->getFilename(sf),
804 ".layout", std::string(
"r"));
805 if (outputLayout == 0)
809 Offset_t seekpos = record*
sizeof(int) +
810 VnodeTally[sf][record]*6*
Dim*
sizeof(
int);
812 if (fseek(outputLayout, seekpos, SEEK_SET) != 0) {
813 ERRORMSG(
"Error seeking to position " <<
static_cast<long>(seekpos));
814 ERRORMSG(
" in file '" << filename <<
"' for DiscField::read_layout.");
817 fclose(outputLayout);
823 if (fread(&numvnodes,
sizeof(
int), 1, outputLayout) != 1) {
824 ERRORMSG(
"Error reading file '" << filename);
825 ERRORMSG(
"' in DiscField::read_layout.");
828 fclose(outputLayout);
837 fclose(outputLayout);
848template <
unsigned Dim>
854 for (; local != f.
end_iv(); ++local) {
858 if (domain.
touches(readDomain)) {
861 expected += newdomain.
size();
872template <
unsigned Dim>
881 for (
unsigned int i=0; i <
Dim; ++i)
882 sliceblock[i] =
Index(currblock[i].length());
885 int currsize = currblock.
size();
886 if (chunkelems < 1 || iscompressed)
887 chunkelems = currsize;
891 for (
int d=(
Dim-1); d >= 0; --d) {
893 int axislen = currblock[d].length();
897 int numslices = chunkelems / currsize;
898 if (numslices > axislen)
903 sliceblock[d] =
Index(numslices);
908 sliceblock[d] =
Index(1);
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
void putMessage(Message &m, const T &t)
void getMessage(Message &m, T &t)
Inform & endl(Inform &inf)
bool touches(const NDIndex< Dim > &) const
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
iterator_dv begin_rdv(const GuardCellSizes< Dim > &gc=gc0())
iterator_dv end_rdv(const GuardCellSizes< Dim > &gc=gc0())
ac_id_vnodes::const_iterator const_iterator_iv
const NDIndex< Dim > & getDomain() const
ac_id_vnodes::iterator iterator_iv
bool send(Message *, int node, int tag, bool delmsg=true)
Message * receive_block(int &node, int &tag)
Message & put(const T &val)
Message & get(const T &cval)
int next_tag(int t, int s=1000)
bool make_globalID(FieldLayout< Dim > &)
int compute_expected(const FieldLayout< Dim > &, const NDIndex< Dim > &)
void query(int &numRecords, int &numFields, std::vector< int > &size) const
DiscField(const char *fname, const char *config, unsigned int numFields, const char *typestr=0)
void initialize(const char *base, const char *config, const char *typestr, unsigned int numFields)
NDIndex< Dim > chunk_domain(const NDIndex< Dim > &currblock, int chunkelems, int &msdim, bool iscompressed)
int read_layout(int record, int sf)
bool parse_config(const char *, bool)
bool write_NDIndex(FILE *, const NDIndex< Dim > &)
int open_df_file_fd(const std::string &fnm, const std::string &suf, int flags)
bool read_NDIndex(FILE *, NDIndex< Dim > &)
FILE * open_df_file(const std::string &fnm, const std::string &mode)
unsigned int size() const
container_t::iterator iterator
static void abort(const char *=0)
static Communicate * Comm
rep_type::iterator iterator
std::pair< NDIndex< Dim >, int > value_type