Bridge++  Version 1.5.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fieldIO_Fortran.cpp
Go to the documentation of this file.
1 
14 #include "fieldIO_Fortran.h"
15 
16 #include <fstream>
17 
18 #include "bridgeIO.h"
19 using Bridge::vout;
20 
21 const std::string FieldIO_Fortran::class_name = "FieldIO_Fortran";
22 
23 //====================================================================
24 void FieldIO_Fortran::read_file(Field *v, const std::string filename)
25 {
26  const int nin_field = v->nin();
27  const int nex_field = v->nex();
28 
29  int nin_file = m_format->nin();
30  int nex_file = m_format->nex();
31 
32  if ((nin_file == 0) || (nex_file == 0)) {
33  nin_file = nin_field;
34  nex_file = nex_field;
35  }
36 
37  const long_t Lvol = CommonParameters::Lvol();
38  const long_t size = nin_file * Lvol * nex_file;
39 
40  Field vtmp;
41 
43  vout.detailed(m_vl, "reading field data from %s", filename.c_str());
44 
45  vtmp.reset(nin_field, Lvol, nex_field);
46 
47  std::fstream infile;
48  infile.open(filename.c_str(), std::ios::in | std::ios::binary);
49  if (!infile) {
50  vout.crucial(m_vl, "Error at %s: file open failure. %s may not exist.\n", class_name.c_str(), filename.c_str());
52  }
53 
54  bool do_byteswap = false;
55 
56  // Skipping 4B data size area (for size less than 2 GB)
57  // infile.seekg(4);
58 
59  // read header: record length (bytes)
60  // assume header is 4bytes.
61  uint32_t flen;
62  infile.read((char *)&flen, sizeof(uint32_t) * 1);
63  if (!infile) {
64  vout.crucial(m_vl, "Error at %s: file read error for header bytes.\n", class_name.c_str());
66  }
67 
68  // find byteorder
69  if (flen == sizeof(double) * size) {
70  // file byteorder is equal to machine byteorder
71  vout.detailed(m_vl, "endian matched.\n");
72  } else {
73  uint32_t flen_s = flen;
74  byte_swap(&flen_s, sizeof(uint32_t), 1);
75 
76  if (flen_s == sizeof(double) * size) {
77  // file byteorder is different from machine byteorder: need swap.
78  vout.detailed(m_vl, "different endian. do swap.\n");
79  do_byteswap = true;
80  } else {
81  vout.crucial(m_vl, "Error at %s: size mismatch or format unidentified.\n", class_name.c_str());
83  }
84  }
85 
86  // read content
87  const int block_size = nin_file;
88  char buf[sizeof(double) * block_size];
89 
90  for (int j = 0; j < nex_file; ++j) {
91  for (long_t isite = 0; isite < Lvol; ++isite) {
92  // read 1 block
93  infile.read(buf, sizeof(double) * block_size);
94 
95  if (!infile) {
96  if (infile.eof()) {
97  vout.crucial(m_vl, "Error at %s: file size too small.\n", __func__);
98  } else {
99  vout.crucial(m_vl, "Error at %s: io error.\n", __func__);
100  }
101 
103  }
104 
105  if (do_byteswap) {
106  byte_swap(buf, sizeof(double), block_size);
107  }
108 
109  double *ptr = (double *)buf;
110 
111  for (int i = 0; i < nin_file; ++i) {
112  int s, t;
113  m_format->file_to_field(s, t, i, j);
114 
115  vtmp.set(s, isite, t, ptr[i]);
116  }
117  }
118  }
119 
120  // read trailer
121  uint32_t ftail;
122  infile.read((char *)&ftail, sizeof(uint32_t) * 1);
123 
124  if (flen != ftail) {
125  vout.crucial(m_vl, "Error at %s: record info mismatch.\n", __func__);
127  }
128  if (!infile) {
129  vout.crucial(m_vl, "Error at %s: file read failed.\n", __func__);
131  }
132 
133  infile.close();
134  }
135 
136  FieldIO::deliver(v, &vtmp);
137 
138  vout.detailed(m_vl, "read successful\n");
139 }
140 
141 
142 //====================================================================
143 void FieldIO_Fortran::write_file(Field *v, const std::string filename)
144 {
145  const int nin_field = v->nin();
146  const int nex_field = v->nex();
147 
148  int nin_file = m_format->nin();
149  int nex_file = m_format->nex();
150 
151  if ((nin_file == 0) || (nex_file == 0)) {
152  nin_file = nin_field;
153  nex_file = nex_field;
154  }
155 
156  const long_t Lvol = CommonParameters::Lvol();
157 
158  Field vtmp;
159  if (Communicator::is_primary()) {
160  vtmp.reset(nin_field, Lvol, nex_field);
161  }
162 
163  const size_t count = nin_file * Lvol * nex_file;
164 
165  FieldIO::gather(&vtmp, v);
166 
167  if (Communicator::is_primary()) {
168  vout.detailed(m_vl, "writing field data to %s\n", filename.c_str());
169 
170  std::ofstream outfile(filename.c_str(), std::ios::out | std::ios::binary);
171  if (!outfile) {
172  vout.crucial(m_vl, "Error at %s: file open of %s failed\n", class_name.c_str(), filename.c_str());
174  }
175 
176  const uint32_t flen = sizeof(double) * count;
177 
178  // record header: record length (bytes)
179  outfile.write((char *)&flen, sizeof(uint32_t) * 1);
180 
181  if (!outfile) {
182  vout.crucial(m_vl, "Error at %s: io error. write record header failed.\n", __func__);
184  }
185 
186  // record content
187  const int block_size = nin_file;
188  char buf[sizeof(double) * block_size];
189 
190 
191  for (int j = 0; j < nex_file; ++j) {
192  for (long_t isite = 0; isite < Lvol; ++isite) {
193  double *ptr = (double *)buf;
194 
195  for (int i = 0; i < nin_file; ++i) {
196  int s, t;
197  m_format->file_to_field(s, t, i, j);
198 
199  ptr[i] = vtmp.cmp(s, isite, t);
200  }
201 
202  outfile.write(buf, sizeof(double) * block_size);
203 
204  if (!outfile) {
205  vout.crucial(m_vl, "Error at %s: io error.\n", __func__);
207  }
208  }
209  }
210 
211  // record footer: record length (bytes)
212  outfile.write((char *)&flen, sizeof(uint32_t) * 1);
213 
214  if (!outfile) {
215  vout.crucial(m_vl, "Error at %s: write record footer failed.\n", __func__);
217  }
218 
219  outfile.close();
220  }
221 
222  vout.detailed(m_vl, "write succeeded.\n");
223 }
224 
225 
226 //====================================================================
227 // multi-record for array of fields
228 
229 void FieldIO_Fortran::read_file(std::vector<Field *>& vv, const std::string& filename)
230 {
231  if ((vv.size() == 0) || (filename == "")) return;
232 
233  const int nin_field = vv[0]->nin();
234  const int nex_field = vv[0]->nex();
235 
236  int nin_file = m_format->nin();
237  int nex_file = m_format->nex();
238 
239  if ((nin_file == 0) || (nex_file == 0)) {
240  nin_file = nin_field;
241  nex_file = nex_field;
242  }
243 
244  const long_t Lvol = CommonParameters::Lvol();
245  const long_t size = nin_file * Lvol * nex_file;
246 
247  Field vtmp;
248 
249  if (Communicator::is_primary()) {
250  vout.detailed(m_vl, "reading field data from %s", filename.c_str());
251 
252  vtmp.reset(nin_field, Lvol, nex_field);
253 
254  std::fstream infile;
255  infile.open(filename.c_str(), std::ios::in | std::ios::binary);
256  if (!infile) {
257  vout.crucial(m_vl, "Error at %s: file open failed. %s may not exist.\n", class_name.c_str(), filename.c_str());
259  }
260 
261  bool do_byteswap = false;
262 
263  for (size_t i = 0, nrec = vv.size(); i < nrec; ++i) {
264  // Skipping 4B data size area (for size less than 2 GB)
265  // infile.seekg(4);
266 
267  // read header: record length (bytes)
268  // assume header is 4bytes.
269  uint32_t flen;
270  infile.read((char *)&flen, sizeof(uint32_t) * 1);
271  if (!infile) {
272  vout.crucial(m_vl, "Error at %s: file read error for header bytes.\n", class_name.c_str());
274  }
275 
276  // find byteorder
277  if (flen == sizeof(double) * size) {
278  // file byteorder is equal to machine byteorder
279  vout.detailed(m_vl, "endian matched.\n");
280  } else {
281  uint32_t flen_s = flen;
282  byte_swap(&flen_s, sizeof(uint32_t), 1);
283 
284  if (flen_s == sizeof(double) * size) {
285  // file byteorder is different from machine byteorder: need swap.
286  vout.detailed(m_vl, "different endian. do swap.\n");
287  do_byteswap = true;
288  } else {
289  vout.crucial(m_vl, "Error at %s: size mismatch or format unidentified.\n", class_name.c_str());
291  }
292  }
293 
294  // read content
295  const int block_size = nin_file;
296  char buf[sizeof(double) * block_size];
297 
298  for (int j = 0; j < nex_file; ++j) {
299  for (long_t isite = 0; isite < Lvol; ++isite) {
300  // read 1 block
301  infile.read(buf, sizeof(double) * block_size);
302 
303  if (!infile) {
304  if (infile.eof()) {
305  vout.crucial(m_vl, "Error at %s: file size too small.\n", __func__);
306  } else {
307  vout.crucial(m_vl, "Error at %s: io error.\n", __func__);
308  }
309 
311  }
312 
313  if (do_byteswap) {
314  byte_swap(buf, sizeof(double), block_size);
315  }
316 
317  double *ptr = (double *)buf;
318 
319  for (int i = 0; i < nin_file; ++i) {
320  int s, t;
321  m_format->file_to_field(s, t, i, j);
322 
323  vtmp.set(s, isite, t, ptr[i]);
324  }
325  }
326  }
327 
328  // read trailer
329  uint32_t ftail;
330  infile.read((char *)&ftail, sizeof(uint32_t) * 1);
331 
332  if (flen != ftail) {
333  vout.crucial(m_vl, "Error at %s: record info mismatch.\n", __func__);
335  }
336  if (!infile) {
337  vout.crucial(m_vl, "Error at %s: file read failed.\n", __func__);
339  }
340 
341  FieldIO::deliver(vv[i], &vtmp);
342  }
343 
344  infile.close();
345  } else { // parallel nodes
346  for (size_t i = 0, nrec = vv.size(); i < nrec; ++i) {
347  FieldIO::deliver(vv[i], &vtmp);
348  }
349  }
350 
351  vout.detailed(m_vl, "read successful\n");
352 }
353 
354 
355 //====================================================================
356 void FieldIO_Fortran::write_file(std::vector<Field *>& vv, const std::string& filename)
357 {
358  if ((vv.size() == 0) || (filename == "")) return;
359 
360  const int nin_field = vv[0]->nin();
361  const int nex_field = vv[0]->nex();
362 
363  int nin_file = m_format->nin();
364  int nex_file = m_format->nex();
365 
366  if ((nin_file == 0) || (nex_file == 0)) {
367  nin_file = nin_field;
368  nex_file = nex_field;
369  }
370 
371  const long_t Lvol = CommonParameters::Lvol();
372  const size_t count = nin_file * Lvol * nex_file;
373 
374 
375  Field vtmp;
376  if (Communicator::is_primary()) {
377  vtmp.reset(nin_field, Lvol, nex_field);
378  }
379 
380  if (Communicator::is_primary()) {
381  vout.detailed(m_vl, "writing field data to %s\n", filename.c_str());
382 
383  std::ofstream outfile(filename.c_str(), std::ios::out | std::ios::binary);
384  if (!outfile) {
385  vout.crucial(m_vl, "Error at %s: file open of %s failed\n", class_name.c_str(), filename.c_str());
387  }
388 
389  for (size_t i = 0, nrec = vv.size(); i < nrec; ++i) {
390  FieldIO::gather(&vtmp, vv[i]);
391 
392  const uint32_t flen = sizeof(double) * count;
393 
394  // record header: record length (bytes)
395  outfile.write((char *)&flen, sizeof(uint32_t) * 1);
396 
397  if (!outfile) {
398  vout.crucial(m_vl, "Error at %s: io error. write record header failed.\n", __func__);
400  }
401 
402  // record content
403  const int block_size = nin_file;
404  char buf[sizeof(double) * block_size];
405 
406  for (int j = 0; j < nex_file; ++j) {
407  for (long_t isite = 0; isite < Lvol; ++isite) {
408  double *ptr = (double *)buf;
409 
410  for (int i = 0; i < nin_file; ++i) {
411  int s, t;
412  m_format->file_to_field(s, t, i, j);
413 
414  ptr[i] = vtmp.cmp(s, isite, t);
415  }
416 
417  outfile.write(buf, sizeof(double) * block_size);
418 
419  if (!outfile) {
420  vout.crucial(m_vl, "Error at %s: io error.\n", __func__);
422  }
423  }
424  }
425 
426  // record footer: record length (bytes)
427  outfile.write((char *)&flen, sizeof(uint32_t) * 1);
428 
429  if (!outfile) {
430  vout.crucial(m_vl, "Error at %s: io error. write record footer failed.\n", __func__);
432  }
433  }
434 
435  outfile.close();
436  } else { // parallel nodes
437  for (size_t i = 0, nrec = vv.size(); i < nrec; ++i) {
438  FieldIO::gather(&vtmp, vv[i]);
439  }
440  }
441 
442  vout.detailed(m_vl, "write succeeded.\n");
443 }
444 
445 
446 //====================================================================
447 //============================================================END=====
BridgeIO vout
Definition: bridgeIO.cpp:503
static void byte_swap(void *buf, size_t size, size_t nmemb)
< convert byte order. alternative interface.
Definition: fieldIO.h:91
void detailed(const char *format,...)
Definition: bridgeIO.cpp:216
static void abort()
terminate communicator
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:175
virtual void file_to_field(int &s, int &t, const int i, const int j) const =0
void deliver(Field *vlocal, Field *vglobal)
distribute data on primary node over parallel nodes.
Definition: fieldIO.cpp:30
virtual int nex() const =0
Container of Field-type object.
Definition: field.h:45
virtual int nin() const =0
double cmp(const int jin, const int site, const int jex) const
Definition: field.h:143
int nin() const
Definition: field.h:126
void read_file(Field *v, const std::string filename)
read data from file.
static const std::string class_name
void write_file(Field *v, const std::string filename)
write data to file.
int nex() const
Definition: field.h:128
const IO_Format::Format * m_format
Definition: fieldIO.h:62
void reset(const int Nin, const int Nvol, const int Nex, const element_type cmpl=Element_type::COMPLEX)
Definition: field.h:95
long long_t
definition of long for Bridge++
Definition: bridge_long.h:46
void crucial(const char *format,...)
Definition: bridgeIO.cpp:178
static bool is_primary()
check if the present node is primary in small communicator.
void gather(Field *vglobal, Field *vlocal)
gather data on parallel nodes to primary node.
Definition: fieldIO.cpp:119
static long_t Lvol()
Bridge::VerboseLevel m_vl
Definition: fieldIO.h:64