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