Bridge++  Ver. 2.0.2
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 //============================================================END=====
FieldIO_Fortran::read_file
void read_file(Field &v, const std::string &filename)
read data from file. (‘const’ is added [18 Mar 2021])
Definition: fieldIO_Fortran.cpp:24
bridgeIO.h
CommonParameters::Lvol
static long_t Lvol()
Definition: commonParameters.h:95
Field::set
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:175
IO_Format::Format::nin
virtual int nin() const =0
Bridge::BridgeIO::detailed
void detailed(const char *format,...)
Definition: bridgeIO.cpp:219
Field::nex
int nex() const
Definition: field.h:128
FieldIO::m_vl
Bridge::VerboseLevel m_vl
Definition: fieldIO.h:64
FieldIO::gather
void gather(Field *vglobal, Field *vlocal)
gather data on parallel nodes to primary node.
Definition: fieldIO.cpp:121
Field::nin
int nin() const
Definition: field.h:126
fieldIO_Fortran.h
FieldIO::deliver
void deliver(Field *vlocal, Field *vglobal)
distribute data on primary node over parallel nodes.
Definition: fieldIO.cpp:30
Communicator::abort
static void abort()
terminate communicator
Definition: communicator.cpp:36
Field::reset
void reset(const int Nin, const int Nvol, const int Nex, const element_type cmpl=Element_type::COMPLEX)
Definition: field.h:95
FieldIO_Fortran::write_file
void write_file(Field &v, const std::string &filename)
write data to file. (‘const’ is added [18 Mar 2021])
Definition: fieldIO_Fortran.cpp:143
Field::cmp
double cmp(const int jin, const int site, const int jex) const
Definition: field.h:143
Communicator::is_primary
static bool is_primary()
check if the present node is primary in small communicator.
Definition: communicator.cpp:60
IO_Format::Format::file_to_field
virtual void file_to_field(int &s, int &t, const int i, const int j) const =0
Bridge::BridgeIO::crucial
void crucial(const char *format,...)
Definition: bridgeIO.cpp:180
FieldIO_Fortran::class_name
static const std::string class_name
Definition: fieldIO_Fortran.h:55
Field
Container of Field-type object.
Definition: field.h:46
IO_Format::Format::nex
virtual int nex() const =0
FieldIO::m_format
const IO_Format::Format * m_format
Definition: fieldIO.h:62
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:512