Bridge++  Ver. 2.0.2
fieldIO_NERSC.cpp
Go to the documentation of this file.
1 
14 #include "fieldIO_NERSC.h"
15 
16 #include <fstream>
17 #include <strings.h>
18 
19 #include "bridgeIO.h"
20 using Bridge::vout;
21 
22 //typedef unsigned short int n_uint16_t;
23 //typedef unsigned int n_uint32_t;
24 //typedef unsigned long int n_uint64_t;
25 
26 const std::string FieldIO_NERSC::class_name = "FieldIO_NERSC";
27 
28 //====================================================================
29 void FieldIO_NERSC::read_file(Field& v, const std::string& filename)
30 {
31  const int nin_field = v.nin();
32  const 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  // temporary buffer: allocated only at I/O node.
43  Field vtmp;
44 
46  vout.detailed(m_vl, "reading field data from %s\n", filename.c_str());
47 
48  const long_t Lvol = CommonParameters::Lvol();
49  vtmp.reset(nin_field, Lvol, nex_field);
50 
51  const bool do_swap = (is_bigendian() == false);
52  if (do_swap) {
53  vout.detailed(m_vl, "host endian is little: byte swap performed.\n");
54  }
55 
56 
57  // read header and get header size
58  std::ifstream infile_header(filename.c_str());
59  if (!infile_header) {
60  vout.crucial(m_vl, "Error at %s: file open failed, %s may not exist.\n", class_name.c_str(), filename.c_str());
61  exit(EXIT_FAILURE);
62  }
63  // assumes the header size is smaller than this value
64  // N.B. w/o this kind of limit, whole configuration might be dumped
65  // to stdout
66  const size_t max_header_size = 10000; // 25 lines x 400 bytes
67 
68  std::string line;
69  getline(infile_header, line);
70  if (line != "BEGIN_HEADER") {
71  vout.crucial(m_vl, "Error at %s: invalid header\n", class_name.c_str());
72  vout.crucial(m_vl, " a bad configuration %s\n", filename.c_str());
73  exit(EXIT_FAILURE);
74  }
75  vout.general(m_vl, "%s: %s\n", class_name.c_str(), line.c_str());
76  while (line.find("END_HEADER") == std::string::npos)
77  {
78  if (infile_header.eof() ||
79  (max_header_size < infile_header.tellg())) {
81  "%s: the header is too large, maybe END_HEADER is missing\n",
82  class_name.c_str());
83  vout.crucial(m_vl, " filename: %s\n", filename.c_str());
84  vout.crucial(m_vl, " max_header_size = %zu\n", max_header_size);
85  exit(EXIT_FAILURE);
86  }
87  getline(infile_header, line);
88  vout.general(m_vl, "%s: %s\n", class_name.c_str(), line.c_str());
89  }
90  size_t offset = infile_header.tellg();
91  vout.general("%s: offset=%zu\n", class_name.c_str(), offset);
92  infile_header.close();
93 
94  const int block_size = nin_file;
95  char buf[sizeof(double) * block_size];
96 
97  std::ifstream infile(filename.c_str(), std::ios::in | std::ios::binary);
98  if (!infile) {
99  vout.crucial(m_vl, "Error at %s: file open failed, %s may not exist.\n", class_name.c_str(), filename.c_str());
100  exit(EXIT_FAILURE);
101  }
102  infile.seekg(offset);
103 
104  for (int j = 0; j < nex_file; ++j) {
105  for (long_t isite = 0; isite < Lvol; ++isite) {
106  // read 1 block
107  infile.read(buf, sizeof(double) * block_size);
108 
109  if (!infile) {
110  if (infile.eof()) { // short file
111  vout.crucial(m_vl, "Error at %s: file size of %s is too small.\n", class_name.c_str(), __func__);
112  } else {
113  vout.crucial(m_vl, "Error at %s: io error of %s.\n", class_name.c_str(), __func__);
114  }
115 
116  exit(EXIT_FAILURE);
117  }
118 
119  if (do_swap) {
120  byte_swap(buf, sizeof(double), block_size);
121  }
122 
123  double *ptr = (double *)buf;
124 
125  for (int i = 0; i < nin_file; ++i) {
126  int s, t;
127  m_format->file_to_field(s, t, i, j);
128 
129  vtmp.set(s, isite, t, ptr[i]);
130  }
131  }
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_NERSC::write_file(Field& v, const std::string& filename)
145 {
146  vout.crucial(m_vl, "%s: write_file is not ready\n", class_name.c_str());
147  exit(EXIT_FAILURE);
148 
149  /*
150  Todo:
151  see https://arxiv.org/pdf/1202.4813.pdf for the NERSC format
152 (here is the 3x3 format from 1202.4813)
153 BEGIN_HEADER
154 HDR_VERSION = 1.0
155 DATATYPE = 4D_SU3_GAUGE_3x3
156 DIMENSION_1 = %(NX)i
157 DIMENSION_2 = %(NY)i
158 DIMENSION_3 = %(NZ)i
159 DIMENSION_4 = %(NT)i
160 CHECKSUM = %( checksum)s
161 LINK_TRACE = %( linktrace)f
162 PLAQUETTE = %( plaquette)f
163 CREATOR = %( creator)s
164 ARCHIVE_DATE = %( archive_date)s
165 ENSEMBLE_LABEL = %( label)s
166 FLOATING_POINT = %( precision)s
167 ENSEMBLE_ID = %( ensemble_id)s
168 SEQUENCE_NUMBER = %( sequence_number)i
169 BETA = %(beta)f
170 MASS = %(mass)f
171 END_HEADER
172 
173 The definition of CHECKSUM and LINK_TRACE are not explicitly given.
174 
175 Here is the implementation in GRID for reference (see Grid/parallelIO/* )
176  * CHECKSUM: global sum as uint32
177  * LINK_TRACE: sum of the trace of all link variable, divided by (V4 * 4dim * 3color)
178  * PLAQUETTE: average of all possible plaquette, normalized to [-1:1]
179 In reading,
180  * always checks: CHECKSUM
181  * checks for gauge field: LINK_TRACE, PLAQUETTE
182  */
183 
184  /*
185  const int nin_field = v->nin();
186  const int nex_field = v->nex();
187 
188  int nin_file = m_format->nin();
189  int nex_file = m_format->nex();
190 
191  if ((nin_file == 0) || (nex_file == 0)) {
192  nin_file = nin_field;
193  nex_file = nex_field;
194  }
195 
196  const long_t Lvol = CommonParameters::Lvol();
197 
198  Field vtmp;
199  if (Communicator::is_primary()) {
200  vtmp.reset(nin_field, Lvol, nex_field);
201  }
202 
203  FieldIO::gather(&vtmp, v);
204 
205  if (Communicator::is_primary()) {
206  vout.detailed(m_vl, "writing field data to %s\n", filename.c_str());
207 
208  const bool do_swap = (is_bigendian() == false);
209  if (do_swap) {
210  vout.detailed(m_vl, "host endian is little: byte swap performed.\n");
211  }
212 
213  const int block_size = nin_file;
214  char buf[sizeof(double) * block_size];
215 
216  std::ofstream outfile(filename.c_str(), std::ios::out | std::ios::binary);
217  if (!outfile) {
218  vout.crucial(m_vl, "Error at %s: file open of %s failed\n", class_name.c_str(), filename.c_str());
219  exit(EXIT_FAILURE);
220  }
221 
222  for (int j = 0; j < nex_file; ++j) {
223  for (long_t isite = 0; isite < Lvol; ++isite) {
224  double *ptr = (double *)buf;
225 
226  for (int i = 0; i < nin_file; ++i) {
227  int s, t;
228  m_format->file_to_field(s, t, i, j);
229 
230  ptr[i] = vtmp.cmp(s, isite, t);
231  }
232 
233  if (do_swap) {
234  byte_swap(buf, sizeof(double), block_size);
235  }
236 
237  outfile.write(buf, sizeof(double) * block_size);
238 
239  if (!outfile) { // error
240  vout.crucial(m_vl, "Error at %s: io error of %s.\n", class_name.c_str(), __func__);
241  exit(EXIT_FAILURE);
242  }
243  }
244  }
245 
246  outfile.close();
247  }
248 
249  vout.detailed(m_vl, "write succeeded.\n");
250  */
251 }
252 
253 
254 //====================================================================
255 //============================================================END=====
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
fieldIO_NERSC.h
Bridge::BridgeIO::detailed
void detailed(const char *format,...)
Definition: bridgeIO.cpp:219
Field::nex
int nex() const
Definition: field.h:128
FieldIO::is_bigendian
static bool is_bigendian()
Definition: fieldIO.cpp:210
FieldIO::m_vl
Bridge::VerboseLevel m_vl
Definition: fieldIO.h:64
Field::nin
int nin() const
Definition: field.h:126
FieldIO_NERSC::read_file
void read_file(Field &v, const std::string &filename)
read data from file. (‘const’ is added [18 Mar 2021])
Definition: fieldIO_NERSC.cpp:29
FieldIO::deliver
void deliver(Field *vlocal, Field *vglobal)
distribute data on primary node over parallel nodes.
Definition: fieldIO.cpp:30
Field::reset
void reset(const int Nin, const int Nvol, const int Nex, const element_type cmpl=Element_type::COMPLEX)
Definition: field.h:95
Communicator::is_primary
static bool is_primary()
check if the present node is primary in small communicator.
Definition: communicator.cpp:60
FieldIO_NERSC::class_name
static const std::string class_name
Definition: fieldIO_NERSC.h:47
IO_Format::Format::file_to_field
virtual void file_to_field(int &s, int &t, const int i, const int j) const =0
FieldIO_NERSC::write_file
void write_file(Field &v, const std::string &filename)
write data to file. (‘const’ is added [18 Mar 2021])
Definition: fieldIO_NERSC.cpp:144
Bridge::BridgeIO::crucial
void crucial(const char *format,...)
Definition: bridgeIO.cpp:180
Field
Container of Field-type object.
Definition: field.h:46
IO_Format::Format::nex
virtual int nex() const =0
Bridge::BridgeIO::general
void general(const char *format,...)
Definition: bridgeIO.cpp:200
FieldIO::m_format
const IO_Format::Format * m_format
Definition: fieldIO.h:62
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:512