Bridge++  Ver. 2.0.2
fieldIO_Binary_Parallel.cpp
Go to the documentation of this file.
1 
14 // this code only makes sense in MPI environment.
15 #ifdef USE_MPI
16 
18 
19 const std::string FieldIO_Binary_Parallel::class_name = "FieldIO_Binary_Parallel";
20 
21 //====================================================================
23  : FieldIO(format),
24  m_is_initialized(false),
25  m_nvol(0), m_nin_file(0), m_nex_file(0)
26 {}
27 
28 //====================================================================
29 FieldIO_Binary_Parallel::~FieldIO_Binary_Parallel()
30 {
31  finalize();
32 }
33 
34 
35 //====================================================================
36 void FieldIO_Binary_Parallel::read_file(Field& u, const std::string& filename)
37 {
38  static const char _function_name[] = "FieldIO_Binary_Parallel::read_file";
39 
40  initialize(u);
41 
42  MPI_File fh;
43  int ret;
44 
45  // fetch data from file into buffer: buffer is in file order.
46  double *buf = new double [m_nin_file * m_nvol * m_nex_file];
47  if (!buf) {
48  vout.crucial(m_vl, "Error at %s: allocate buffer failed.\n", _function_name);
49  exit(EXIT_FAILURE);
50  }
51 
52  ret = MPI_File_open(Communicator_impl::world(), const_cast<char *>(filename.c_str()), MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
53  if (ret) {
54  vout.crucial(m_vl, "Error at %s: MPI_File_open failed.\n", _function_name);
55  exit(EXIT_FAILURE);
56  }
57 
58  ret = MPI_File_set_view(fh, 0, m_type_vector, m_type_tiled, const_cast<char *>("native"), MPI_INFO_NULL);
59  if (ret) {
60  vout.crucial(m_vl, "Error at %s: MPI_File_set_view failed.\n", _function_name);
61  exit(EXIT_FAILURE);
62  }
63 
64  ret = MPI_File_read_all(fh, (void *)buf, m_nvol * m_nex_file, m_type_vector, MPI_STATUS_IGNORE);
65  if (ret) {
66  vout.crucial(m_vl, "Error at %s: MPI_File_read_all failed.\n", _function_name);
67  exit(EXIT_FAILURE);
68  }
69 
70  ret = MPI_File_close(&fh);
71  if (ret) {
72  vout.crucial(m_vl, "Error at %s: MPI_File_close failed.\n", _function_name);
73  exit(EXIT_FAILURE);
74  }
75 
76  if (!is_bigendian()) {
77  convert_endian(buf, sizeof(double), m_nvol * m_nin_file * m_nex_file);
78  }
79 
80  // unpack buffer
81  double *p = buf;
82 
83  for (int j = 0; j < m_nex_file; ++j) {
84  for (int isite = 0; isite < m_nvol; ++isite) {
85  for (int i = 0; i < m_nin_file; ++i) {
86  int s, t;
87  m_format->file_to_field(s, t, i, j);
88 
89  u.set(s, isite, t, *p++);
90  }
91  }
92  }
93 
94  delete [] buf;
95 
96  finalize();
97 }
98 
99 
100 //====================================================================
101 void FieldIO_Binary_Parallel::write_file(Field& u, const std::string& filename)
102 {
103  static const char _function_name[] = "FieldIO_Binary_Parallel::write_file";
104 
105  initialize(u);
106 
107  double *buf = new double [m_nin_file * m_nvol * m_nex_file];
108  if (!buf) {
109  vout.crucial(m_vl, "Error at %s: allocate buffer failed.\n", _function_name);
110  exit(EXIT_FAILURE);
111  }
112 
113  // pack buffer
114  double *p = buf;
115 
116  for (int j = 0; j < m_nex_file; ++j) {
117  for (int isite = 0; isite < m_nvol; ++isite) {
118  for (int i = 0; i < m_nin_file; ++i) {
119  int s, t;
120  m_format->file_to_field(s, t, i, j);
121 
122  *p++ = u.cmp(s, isite, t);
123  }
124  }
125  }
126 
127  if (!is_bigendian()) {
128  convert_endian(buf, sizeof(double), m_nin_file * m_nvol * m_nex_file);
129  }
130 
131  MPI_File fh;
132  int ret;
133 
134  ret = MPI_File_open(Communicator_impl::world(), const_cast<char *>(filename.c_str()), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
135  if (ret) {
136  vout.crucial(m_vl, "Error at %s: MPI_File_open failed.\n", _function_name);
137  exit(EXIT_FAILURE);
138  }
139 
140  ret = MPI_File_set_view(fh, 0, m_type_vector, m_type_tiled, const_cast<char *>("native"), MPI_INFO_NULL);
141  if (ret) {
142  vout.crucial(m_vl, "Error at %s: MPI_File_set_view failed.\n", _function_name);
143  exit(EXIT_FAILURE);
144  }
145 
146  ret = MPI_File_write_all(fh, (void *)buf, m_nvol * m_nex_file, m_type_vector, MPI_STATUS_IGNORE);
147  if (ret) {
148  vout.crucial(m_vl, "Error at %s: MPI_File_write_all failed.\n", _function_name);
149  exit(EXIT_FAILURE);
150  }
151 
152  ret = MPI_File_close(&fh);
153  if (ret) {
154  vout.crucial(m_vl, "Error at %s: MPI_File_close failed.\n", _function_name);
155  exit(EXIT_FAILURE);
156  }
157 
158  delete [] buf;
159 
160  finalize();
161 }
162 
163 
164 //====================================================================
165 int FieldIO_Binary_Parallel::initialize(const Field& v)
166 {
167  static const char _function_name[] = "FieldIO_Binary_Parallel::initialize";
168 
169  // N.B. trivial layout returns 0 for nin/nex_file.
170  const int nin_file = m_format->nin() ? m_format->nin() : v.nin();
171  const int nex_file = m_format->nex() ? m_format->nex() : v.nex();
172  const int nvol = v.nvol();
173 
174  // check if layout is already generated and recyclable.
175  if (m_is_initialized &&
176  (nin_file == m_nin_file) &&
177  (nex_file == m_nex_file) &&
178  (nvol == m_nvol))
179  {
180  vout.detailed(m_vl, "%s: layout recycled.\n", _function_name);
181  return EXIT_SUCCESS;
182  }
183 
184  // first, cleanup pre-existing layout, if any.
185  clear_layout();
186 
187  // local parameters
188  m_nin_file = nin_file;
189  m_nex_file = nex_file;
190 
191  const int ndim = CommonParameters::Ndim();
192 
193  int *global_dims = new int[ndim];
194  global_dims[0] = CommonParameters::Lx();
195  global_dims[1] = CommonParameters::Ly();
196  global_dims[2] = CommonParameters::Lz();
197  global_dims[3] = CommonParameters::Lt();
198 
199  int *local_dims = new int[ndim];
200  local_dims[0] = CommonParameters::Nx();
201  local_dims[1] = CommonParameters::Ny();
202  local_dims[2] = CommonParameters::Nz();
203  local_dims[3] = CommonParameters::Nt();
204 
205  m_nvol = 1;
206  for (int i = 0; i < ndim; ++i) {
207  m_nvol *= local_dims[i];
208  }
209 
210  int *grid_pos = new int[ndim];
211  for (int i = 0; i < ndim; ++i) {
212  grid_pos[i] = Communicator::ipe(i);
213  }
214 
215  int *starts = new int[ndim];
216  for (int i = 0; i < ndim; ++i) {
217  starts[i] = local_dims[i] * grid_pos[i];
218  }
219 
220  int ret = 0;
221 
222  // MPI_Datatype m_type_vector;
223  ret = MPI_Type_contiguous(sizeof(double) * m_nin_file, MPI_BYTE, &m_type_vector);
224  if (ret) {
225  vout.crucial(m_vl, "%s: MPI_Type_Contiguous failed.\n", _function_name);
226  exit(EXIT_FAILURE);
227  }
228 
229  ret = MPI_Type_commit(&m_type_vector);
230  if (ret) {
231  vout.crucial(m_vl, "%s: MPI_Type_commit failed.\n", _function_name);
232  exit(EXIT_FAILURE);
233  }
234 
235  // MPI_Datatype m_type_tiled;
236  ret = MPI_Type_create_subarray(ndim, global_dims, local_dims, starts, MPI_ORDER_FORTRAN, m_type_vector, &m_type_tiled);
237  if (ret) {
238  vout.crucial(m_vl, "%s: MPI_Type_create_subarray failed.\n", _function_name);
239  exit(EXIT_FAILURE);
240  }
241 
242  ret = MPI_Type_commit(&m_type_tiled);
243  if (ret) {
244  vout.crucial(m_vl, "%s: MPI_Type_commit failed.\n", _function_name);
245  exit(EXIT_FAILURE);
246  }
247 
248  delete [] starts;
249  delete [] grid_pos;
250  delete [] local_dims;
251  delete [] global_dims;
252 
253  // initialization done.
254  m_is_initialized = true;
255 
256  vout.detailed(m_vl, "%s: layout initialized.\n", _function_name);
257 
258  return EXIT_SUCCESS;
259 }
260 
261 
262 //====================================================================
263 int FieldIO_Binary_Parallel::clear_layout()
264 {
265  const char _function_name[] = "FieldIO_Binary_Parallel::clear_layout";
266 
267  if (m_is_initialized) {
268  m_nin_file = 0;
269  m_nex_file = 0;
270  m_nvol = 0;
271 
272  int ret = 0;
273 
274  ret = MPI_Type_free(&m_type_vector);
275  if (ret) {
276  vout.crucial(m_vl, "%s: MPI_Type_free for type_vector failed.\n", _function_name);
277  exit(EXIT_FAILURE);
278  }
279 
280  ret = MPI_Type_free(&m_type_tiled);
281  if (ret) {
282  vout.crucial(m_vl, "%s: MPI_Type_free for type_tiled failed.\n", _function_name);
283  exit(EXIT_FAILURE);
284  }
285 
286  m_is_initialized = false;
287  }
288 
289  return EXIT_SUCCESS;
290 }
291 
292 
293 //====================================================================
294 int FieldIO_Binary_Parallel::finalize()
295 {
296  static const char _function_name[] = "FieldIO_Binary_Parallel::finalize";
297 
298  clear_layout();
299 
300  vout.detailed(m_vl, "%s via MPI I/O finalize done.\n", class_name.c_str());
301 
302  return EXIT_SUCCESS;
303 }
304 
305 
306 //====================================================================
307 #endif
308 
309 //====================================================================
310 //============================================================END=====
CommonParameters::Ny
static int Ny()
Definition: commonParameters.h:106
CommonParameters::Nz
static int Nz()
Definition: commonParameters.h:107
fieldIO_Binary_Parallel.h
CommonParameters::Ndim
static int Ndim()
Definition: commonParameters.h:117
Field::set
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:175
FieldIO_Binary_Parallel::FieldIO_Binary_Parallel
FieldIO_Binary_Parallel(const IO_Format::Format *format)
Definition: fieldIO_Binary_Parallel.h:83
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
IO_Format::Format
Definition: io_format.h:36
CommonParameters::Ly
static int Ly()
Definition: commonParameters.h:92
FieldIO::is_bigendian
static bool is_bigendian()
Definition: fieldIO.cpp:210
FieldIO_Binary::read_file
void read_file(Field &v, const std::string &filename)
read data from file. (‘const’ is added [18 Mar 2021])
Definition: fieldIO_Binary.cpp:29
FieldIO::m_vl
Bridge::VerboseLevel m_vl
Definition: fieldIO.h:64
Field::nin
int nin() const
Definition: field.h:126
CommonParameters::Nx
static int Nx()
Definition: commonParameters.h:105
CommonParameters::Lt
static int Lt()
Definition: commonParameters.h:94
FieldIO_Binary::class_name
static const std::string class_name
Definition: fieldIO_Binary.h:50
CommonParameters::Lx
static int Lx()
Definition: commonParameters.h:91
CommonParameters::Lz
static int Lz()
Definition: commonParameters.h:93
FieldIO::convert_endian
static void convert_endian(void *buf, size_t size, size_t nmemb)
check if machine byte order is big-endian.
Definition: fieldIO.cpp:231
CommonParameters::Nt
static int Nt()
Definition: commonParameters.h:108
Field::nvol
int nvol() const
Definition: field.h:127
Field::cmp
double cmp(const int jin, const int site, const int jex) const
Definition: field.h:143
FieldIO
FieldIO class for file I/O of space-time distributed data.
Definition: fieldIO.h:53
IO_Format::Format::file_to_field
virtual void file_to_field(int &s, int &t, const int i, const int j) const =0
Communicator::ipe
static int ipe(const int dir)
logical coordinate of current proc.
Definition: communicator.cpp:105
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
FieldIO_Binary::write_file
void write_file(Field &v, const std::string &filename)
write data to file. (‘const’ is added [18 Mar 2021])
Definition: fieldIO_Binary.cpp:105
FieldIO::m_format
const IO_Format::Format * m_format
Definition: fieldIO.h:62
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:512