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