Bridge++  Ver. 1.2.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fieldIO_Fortran.cpp
Go to the documentation of this file.
1 
10 // This class is to read binary file generated by Fortran code.
11 // If the endian of the system differs from file format,
12 // byte_swap must be called.
13 
14 #include "fieldIO_Fortran.h"
15 
16 #include <iostream>
17 #include <fstream>
18 
19 #include "commonParameters.h"
20 #include "communicator.h"
21 #include "bridgeIO.h"
22 using Bridge::vout;
23 
24 #include "field.h"
25 
26 const std::string FieldIO_Fortran::class_name = "FieldIO_Fortran";
27 
28 //====================================================================
29 void FieldIO_Fortran::read_file(Field *v, std::string filename)
30 {
31  int nin_field = v->nin();
32  int nex_field = v->nex();
33 
34  int nin_file = m_format->nin();
35  int nex_file = m_format->nex();
36 
37  if ((nin_file == 0) || (nex_file == 0)) {
38  nin_file = nin_field;
39  nex_file = nex_field;
40  }
41 
42  int Lvol = CommonParameters::Lvol();
43 
44  int size = nin_file * Lvol * nex_file;
45 
46  Field vtmp;
47 
49  vout.detailed(m_vl, "reading field data from %s", filename.c_str());
50 
51  vtmp.reset(nin_field, Lvol, nex_field);
52 
53  std::fstream infile;
54  infile.open(filename.c_str(), std::ios::in | std::ios::binary);
55  if (!infile) {
56  vout.crucial(m_vl, "file open failure: %s may not exist.\n", filename.c_str());
57  abort();
58  }
59 
60  bool do_byteswap = false;
61 
62  // Skipping 4B data size area (for size less than 2 GB)
63  // infile.seekg(4);
64 
65  // read header: record length (bytes)
66  // assume header is 4bytes.
67  uint32_t flen;
68  infile.read((char *)&flen, sizeof(uint32_t) * 1);
69  if (!infile) {
70  vout.crucial(m_vl, "file read error for header bytes.\n");
71  abort();
72  }
73 
74  // find byteorder
75  if (flen == sizeof(double) * size) {
76  // file byteorder is equal to machine byteorder
77  vout.detailed(m_vl, "endian matched.\n");
78  } else {
79  uint32_t flen_s = flen;
80  byte_swap(&flen_s, sizeof(uint32_t), 1);
81 
82  if (flen_s == sizeof(double) * size) {
83  // file byteorder is different from machine byteorder: need swap.
84  vout.detailed(m_vl, "different endian. do swap.\n");
85  do_byteswap = true;
86  } else {
87  vout.crucial(m_vl, "size mismatch or format unidentified.\n");
88  abort();
89  }
90  }
91 
92  // read content
93  const int block_size = nin_file;
94  char buf[sizeof(double) * block_size];
95 
96  for (int j = 0; j < nex_file; ++j) {
97  for (int isite = 0; isite < Lvol; ++isite) {
98  // read 1 block
99  infile.read(buf, sizeof(double) * block_size);
100 
101  if (!infile) {
102  if (infile.eof()) {
103  vout.crucial(m_vl, "%s: file size too small.\n", __func__);
104  abort();
105  } else {
106  vout.crucial(m_vl, "%s: io error.\n", __func__);
107  }
108  }
109 
110  if (do_byteswap) {
111  byte_swap(buf, sizeof(double), block_size);
112  }
113 
114  double *ptr = (double *)buf;
115 
116  for (int i = 0; i < nin_file; ++i) {
117  int s, t;
118  m_format->file_to_field(s, t, i, j);
119 
120  vtmp.set(s, isite, t, ptr[i]);
121  }
122  }
123  }
124 
125  // read trailer
126  uint32_t ftail;
127  infile.read((char *)&ftail, sizeof(uint32_t) * 1);
128 
129  if (flen != ftail) {
130  vout.crucial(m_vl, "record info mismatch.\n");
131  abort();
132  }
133  if (!infile) {
134  vout.crucial(m_vl, "file read failed.\n");
135  abort();
136  }
137 
138  infile.close();
139  }
140 
141  FieldIO::deliver(v, &vtmp);
142 
143  vout.detailed(m_vl, "read successful\n");
144 }
145 
146 
147 //====================================================================
148 void FieldIO_Fortran::write_file(Field *v, std::string filename)
149 {
150  int nin_field = v->nin();
151  int nex_field = v->nex();
152 
153  int nin_file = m_format->nin();
154  int nex_file = m_format->nex();
155 
156  if ((nin_file == 0) || (nex_file == 0)) {
157  nin_file = nin_field;
158  nex_file = nex_field;
159  }
160 
161  int Lvol = CommonParameters::Lvol();
162 
163  Field vtmp;
164  if (Communicator::is_primary()) {
165  vtmp.reset(nin_field, Lvol, nex_field);
166  }
167 
168  size_t count = nin_file * Lvol * nex_file;
169 
170  FieldIO::gather(&vtmp, v);
171 
172  if (Communicator::is_primary()) {
173  vout.detailed(m_vl, "writing field data to %s\n", filename.c_str());
174 
175  std::ofstream outfile(filename.c_str(), std::ios::out | std::ios::binary);
176  if (!outfile) {
177  vout.crucial(m_vl, "file open failed: %s\n", filename.c_str());
178  abort();
179  }
180 
181  uint32_t flen = sizeof(double) * count;
182 
183  // record header: record length (bytes)
184  outfile.write((char *)&flen, sizeof(uint32_t) * 1);
185 
186  if (!outfile) {
187  vout.crucial(m_vl, "%s: io error. write record header failed.\n", __func__);
188  abort();
189  }
190 
191  // record content
192  const int block_size = nin_file;
193  char buf[sizeof(double) * block_size];
194 
195 
196  for (int j = 0; j < nex_file; ++j) {
197  for (int isite = 0; isite < Lvol; ++isite) {
198  double *ptr = (double *)buf;
199 
200  for (int i = 0; i < nin_file; ++i) {
201  int s, t;
202  m_format->file_to_field(s, t, i, j);
203 
204  ptr[i] = vtmp.cmp(s, isite, t);
205  }
206 
207  outfile.write(buf, sizeof(double) * block_size);
208 
209  if (!outfile) {
210  vout.crucial(m_vl, "%s: io error.\n", __func__);
211  abort();
212  }
213  }
214  }
215 
216  // record footer: record length (bytes)
217  outfile.write((char *)&flen, sizeof(uint32_t) * 1);
218 
219  if (!outfile) {
220  vout.crucial(m_vl, "%s: io error. write record footer failed.\n", __func__);
221  abort();
222  }
223 
224  outfile.close();
225  }
226 
227  vout.detailed(m_vl, "write succeeded.\n");
228 }
229 
230 
231 //====================================================================
232 //============================================================END=====
BridgeIO vout
Definition: bridgeIO.cpp:207
static void byte_swap(void *buf, size_t size, size_t nmemb)
&lt; convert byte order. alternative interface.
Definition: fieldIO.h:76
void detailed(const char *format,...)
Definition: bridgeIO.cpp:50
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:128
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:29
virtual int nex() const =0
Container of Field-type object.
Definition: field.h:37
virtual int nin() const =0
double cmp(const int jin, const int site, const int jex) const
Definition: field.h:108
static int Lvol()
void read_file(Field *v, std::string filename)
read data from file.
int nin() const
Definition: field.h:100
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:82
int nex() const
Definition: field.h:102
const IO_Format::Format * m_format
Definition: fieldIO.h:57
void crucial(const char *format,...)
Definition: bridgeIO.cpp:26
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:115
Bridge::VerboseLevel m_vl
Definition: fieldIO.h:59