51 template <
unsigned Dim>
53 unsigned int numFields,
const char* typestr) {
55 initialize(base, config, typestr, numFields);
63 template <
unsigned Dim>
65 const char* typestr) {
67 initialize(base, 0, typestr, numFields);
75 template <
unsigned Dim>
78 initialize(base, config, 0, 0);
86 template <
unsigned Dim>
89 initialize(base, 0, 0, 0);
95 template <
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();
141 template <
unsigned Dim>
148 delete [] VnodeTally;
159 template <
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];
178 template <
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 ");
195 template <
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());
222 template <
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 ");
256 template <
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());
302 template <
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));
372 template <
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 '");
413 template <
unsigned Dim>
416 template <
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);
446 template <
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");
492 template <
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);
678 template <
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);
711 template <
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);
759 template <
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);
798 template <
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);
848 template <
unsigned Dim>
854 for (; local != f.
end_iv(); ++local) {
858 if (domain.
touches(readDomain)) {
861 expected += newdomain.
size();
872 template <
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);
Message & put(const T &val)
void getMessage(Message &m, T &t)
bool read_NDIndex(FILE *, NDIndex< Dim > &)
bool touches(const NDIndex< Dim > &) const
bool make_globalID(FieldLayout< Dim > &)
bool write_NDIndex(FILE *, const NDIndex< Dim > &)
Message * receive_block(int &node, int &tag)
DiscField(const char *fname, const char *config, unsigned int numFields, const char *typestr=0)
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
int next_tag(int t, int s=1000)
iterator_dv begin_rdv(const GuardCellSizes< Dim > &gc=gc0())
ac_id_vnodes::iterator iterator_iv
Message & get(const T &cval)
clearpage the user may choose between constant or variable radius This model includes fringe fields begin
Inform & endl(Inform &inf)
void initialize(const char *base, const char *config, const char *typestr, unsigned int numFields)
if write to the Free Software Temple MA USA Also add information on how to contact you by electronic and paper mail If the program is make it output a short notice like this when it starts in an interactive mode
static Communicate * Comm
container_t::iterator iterator
void query(int &numRecords, int &numFields, std::vector< int > &size) const
bool parse_config(const char *, bool)
std::pair< NDIndex< Dim >, int > value_type
bool send(Message *, int node, int tag, bool delmsg=true)
rep_type::iterator iterator
NDIndex< Dim > chunk_domain(const NDIndex< Dim > &currblock, int chunkelems, int &msdim, bool iscompressed)
int compute_expected(const FieldLayout< Dim > &, const NDIndex< Dim > &)
iterator_dv end_rdv(const GuardCellSizes< Dim > &gc=gc0())
FILE * open_df_file(const std::string &fnm, const std::string &mode)
ac_id_vnodes::const_iterator const_iterator_iv
void putMessage(Message &m, const T &t)
const NDIndex< Dim > & getDomain() const
int open_df_file_fd(const std::string &fnm, const std::string &suf, int flags)
static void abort(const char *=0)
int read_layout(int record, int sf)