Bridge++  Ver. 1.3.x
fieldIO_LIME.cpp
Go to the documentation of this file.
1 
14 #include "fieldIO_LIME.h"
15 
16 #include <iostream>
17 #include <fstream>
18 #include <string.h>
19 
20 #include "communicator.h"
21 
22 #include "bridgeIO.h"
23 using Bridge::vout;
24 
25 #include "io_format_gauge.h"
26 
27 #if USE_ILDG_METADATA
28 #include "ildg_metadata.h"
29 #endif
30 
31 #ifdef USE_LIMELIB
32 
33 //typedef unsigned short int n_uint16_t;
34 //typedef unsigned int n_uint32_t;
35 //typedef unsigned long int n_uint64_t;
36 
37 #ifdef off_t
38 #undef off_t
39 #endif
40 #define off_t n_uint64_t
41 
42 static const off_t block_size = 64;
43 
44 const std::string FieldIO_LIME::class_name = "FieldIO_LIME";
45 
46 //================================================================
47 #if USE_ILDG_METADATA
48 
49 void FieldIO_LIME::check_metadata(const ILDG_Format::Params *params)
50 {
51  // check if config is as expected.
52  int Lx = CommonParameters::Lx();
53  int Ly = CommonParameters::Ly();
54  int Lz = CommonParameters::Lz();
55  int Lt = CommonParameters::Lt();
56 
57  if (!((params->Lx == Lx) &&
58  (params->Ly == Ly) &&
59  (params->Lz == Lz) &&
60  (params->Lt == Lt))) {
61  vout.crucial(m_vl, "lattice size mismatch. config=(%d,%d,%d,%d), expected=(%d,%d,%d,%d).\n",
62  params->Lx, params->Ly, params->Lz, params->Lt,
63  Lx, Ly, Lz, Lt);
64  exit(EXIT_FAILURE);
65  }
66 
67  if (params->prec == 32) {
68  vout.detailed(m_vl, "ildg-format: single precision: extend to double\n");
69  } else {
70  vout.detailed(m_vl, "ildg-format: double precision\n");
71  }
72 }
73 
74 
75 void FieldIO_LIME::load_metadata(LimeReader *reader, ILDG_Format::Params *params)
76 {
77  off_t nbytes = limeReaderBytes(reader);
78 
79  vout.detailed(m_vl, "limeReaderBytes: %lu bytes to read.\n", nbytes);
80 
81  off_t nbytes_alloc = nbytes + ((nbytes % block_size) ? (block_size - (nbytes % block_size)) : 0);
82 
83  char *buf = (char *)malloc(nbytes_alloc);
84  if (buf == 0) {
85  vout.crucial(m_vl, "malloc failed.");
86  exit(EXIT_FAILURE);
87  }
88  vout.detailed(m_vl, "allocated %lu bytes\n", nbytes_alloc);
89 
90  int status = limeReaderReadData(buf, &nbytes, reader);
91  if (status != LIME_SUCCESS) {
92  vout.crucial(m_vl, "limeReaderReadData failed.");
93  exit(EXIT_FAILURE);
94  }
95 
96  // dump Metadata
97  vout.detailed(m_vl, "%s\n", buf);
98 
99  // process ILDG Metadata
100  ILDG_Format::Metadata md;
101  md.read_from_buffer(buf).extract(params);
102 
103  free(buf);
104 }
105 #endif
106 
107 void FieldIO_LIME::load_lfn(LimeReader *reader)
108 {
109  off_t nbytes = limeReaderBytes(reader);
110 
111  vout.detailed(m_vl, "limeReaderBytes: %lu bytes to read.\n", nbytes);
112 
113  off_t nbytes_alloc = (nbytes + 1) + (block_size - ((nbytes + 1) % block_size));
114 
115  char *buf = (char *)malloc(nbytes_alloc);
116  if (!buf) {
117  vout.crucial(m_vl, "malloc failed.");
118  exit(EXIT_FAILURE);
119  }
120 
121  vout.detailed(m_vl, "allocated %lu bytes\n", nbytes_alloc);
122 
123  int status = limeReaderReadData(buf, &nbytes, reader);
124  if (status != LIME_SUCCESS) {
125  vout.crucial(m_vl, "limeReaderReadData failed.");
126  exit(EXIT_FAILURE);
127  }
128 
129  vout.detailed(m_vl, "limeReaderReadData: %lu bytes read.\n", nbytes);
130 
131  buf[nbytes] = '\0';
132 
133  vout.detailed(m_vl, "ildg-data-lfn: %s\n", buf);
134 
135  free(buf);
136 }
137 
138 
139 void FieldIO_LIME::load_data(LimeReader *reader, Field *v)
140 {
141  off_t word_size = 8; //XXX assume 64bit precision
142 
143  off_t nbytes = limeReaderBytes(reader);
144 
145  vout.detailed(m_vl, "ildg-binary-data: limeReaderBytes: %lu bytes to read.\n", nbytes);
146 
147  // allocate memory for whole config data.
148  char *buf = (char *)malloc(nbytes);
149  if (!buf) {
150  vout.crucial(m_vl, "%s: malloc failed.", __func__);
151  exit(EXIT_FAILURE);
152  }
153 
154  int status = limeReaderReadData(buf, &nbytes, reader);
155  if (status != LIME_SUCCESS) {
156  vout.crucial(m_vl, "%s: malloc failed.", __func__);
157  exit(EXIT_FAILURE);
158  }
159 
160  // adjust byteorder
161  if (!FieldIO::is_bigendian()) {
162  byte_swap(buf, word_size, nbytes / word_size);
163  }
164 
165  // reorder and store
166  int nin_file = m_format->nin();
167  int nex_file = m_format->nex();
168 
169  if ((nin_file == 0) || (nex_file == 0)) {
170  nin_file = v->nin();
171  nex_file = v->nex();
172  }
173 
174  int lvol = v->nvol();
175 
176  double *p = (double *)buf;
177 
178  for (int j = 0; j < nex_file; ++j) {
179  for (int isite = 0; isite < lvol; ++isite) {
180  for (int i = 0; i < nin_file; ++i) {
181  int s, t;
182  m_format->file_to_field(s, t, i, j);
183  v->set(s, isite, t, *p++);
184  }
185  }
186  }
187 
188  free(buf);
189 }
190 
191 
192 void FieldIO_LIME::process_file(Field *v, string filename)
193 {
194  FILE *fp = fopen(filename.c_str(), "r");
195 
196  if (!fp) {
197  vout.crucial(m_vl, "%s: fopen failed.", __func__);
198  }
199 
200  LimeReader *reader = limeCreateReader(fp);
201  if (!reader) {
202  vout.crucial(m_vl, "%s: limeCreateReader failed.", __func__);
203  }
204 
205 #if USE_ILDG_METADATA
206  ILDG_Format::Params params;
207 #endif
208 
209  // scan file for records.
210  for ( ; ; ) {
211  int status = limeReaderNextRecord(reader);
212  if (status != LIME_SUCCESS) break;
213 
214  const char *t = limeReaderType(reader);
215 
216  if (strcmp(t, "ildg-format") == 0) {
217 #if USE_ILDG_METADATA
218  load_metadata(reader, &params);
219  check_metadata(&params);
220 #endif
221  } else if (strcmp(t, "ildg-binary-data") == 0) {
222  load_data(reader, v);
223  } else if (strcmp(t, "ildg-data-lfn") == 0) {
224  load_lfn(reader);
225  } else {
226  vout.crucial(m_vl, "%s: known record %s.\n", __func__, t);
227  }
228  } // end loop over records.
229 
230  limeDestroyReader(reader);
231 
232  fclose(fp);
233 }
234 
235 
236 void FieldIO_LIME::read_file(Field *v, string filename)
237 {
238  int nin_field = v->nin();
239  int nex_field = v->nex();
240 
241  int Lvol = CommonParameters::Lvol();
242 
243  Field vtmp;
244 
245  if (Communicator::is_primary()) {
246  vout.detailed(m_vl, "reading gauge configuration from %s", filename.c_str());
247 
248  vtmp.reset(nin_field, Lvol, nex_field);
249 
250  process_file(&vtmp, filename);
251  }
252 
253  FieldIO::deliver(v, &vtmp);
254 
255  vout.detailed(m_vl, "read successful\n");
256 }
257 
258 
259 //================================================================
260 #if USE_ILDG_METADATA
261 
262 void FieldIO_LIME::store_metadata(LimeWriter *writer)
263 {
264  // first, write metadata record.
265  vout.detailed(m_vl, "%s: write metadata.\n", __func__);
266 
267  ILDG_Format::Params params;
268  params.Lx = CommonParameters::Lx();
269  params.Ly = CommonParameters::Ly();
270  params.Lz = CommonParameters::Lz();
271  params.Lt = CommonParameters::Lt();
272  params.type = 0;
273  params.prec = 8 * sizeof(double);
274 
275  ILDG_Format::Metadata md;
276  md.store(&params);
277 
278  const int buf_size = 4 * 1024;
279  char *buf = (char *)malloc(buf_size);
280 
281  md.write_to_buffer(buf, buf_size);
282 
283  off_t nbytes = strlen(buf);
284 
285  LimeRecordHeader *h = limeCreateHeader(1 /* MB */, 0 /* ME */, const_cast<char *>("ildg-format"), nbytes);
286  limeWriteRecordHeader(h, writer);
287  limeDestroyHeader(h);
288 
289  limeWriteRecordData(buf, &nbytes, writer);
290 
291  free(buf);
292 }
293 #endif
294 
295 void FieldIO_LIME::store_data(LimeWriter *writer, Field *v,
296  bool mark_begin, bool mark_end)
297 {
298  // second, write binary data.
299  vout.detailed(m_vl, "%s: write binary data.\n", __func__);
300 
301 // off_t nbytes = sizeof(Field::element_type) * u->size();
302  off_t nbytes = sizeof(double) * v->size();
303 
304  LimeRecordHeader *h = limeCreateHeader(
305  mark_begin ? 1 : 0 /* MB */,
306  mark_end ? 1 : 0 /* ME */,
307  const_cast<char *>("ildg-binary-data"), nbytes);
308  limeWriteRecordHeader(h, writer);
309  limeDestroyHeader(h);
310 
311  char *buf = (char *)malloc(nbytes);
312  if (!buf) {
313  vout.crucial(m_vl, "%s: malloc failed.\n", __func__);
314  exit(EXIT_FAILURE);
315  }
316 
317  // reorder and pack to buffer
318 
319  int nin_field = v->nin();
320  int nex_field = v->nex();
321 
322  int nin_file = m_format->nin();
323  int nex_file = m_format->nex();
324 
325  if ((nin_file == 0) || (nex_file == 0)) {
326  nin_file = nin_field;
327  nex_file = nex_field;
328  }
329 
330  int lvol = CommonParameters::Lvol();
331 
332 // Field::element_type *p = (Field::element_type *)buf;
333  double *p = (double *)buf;
334 
335  for (int j = 0; j < nex_file; ++j) {
336  for (int isite = 0; isite < lvol; ++isite) {
337  for (int i = 0; i < nin_file; ++i) {
338  int s, t;
339  m_format->file_to_field(s, t, i, j);
340  *p++ = v->cmp(s, isite, t);
341  }
342  }
343  }
344 
345  // adjust byteorder
346  if (!FieldIO::is_bigendian()) {
347 // byte_swap(buf, sizeof(Field::element_type), u->size());
348  byte_swap(buf, sizeof(double), v->size());
349  }
350 
351  // store
352  limeWriteRecordData(buf, &nbytes, writer);
353 
354  vout.detailed(m_vl, "write succeeded.\n");
355 
356  free(buf); // added by s.motoki[12.06.05].
357 }
358 
359 
360 void FieldIO_LIME::store_lfn(LimeWriter *writer, string lfn_string)
361 {
362  off_t nbytes = lfn_string.size();
363 
364  LimeRecordHeader *h = limeCreateHeader(1 /* MB */, 1 /* ME */, const_cast<char *>("ildg-data-lfn"), nbytes);
365 
366  limeWriteRecordHeader(h, writer);
367  limeDestroyHeader(h);
368 
369  // store
370  limeWriteRecordData(const_cast<char *>(lfn_string.c_str()), &nbytes, writer);
371 
372  vout.detailed(m_vl, "write succeeded.\n");
373 }
374 
375 
376 void FieldIO_LIME::write_file(Field *v, string filename)
377 {
378  int nin_field = v->nin();
379  int nex_field = v->nex();
380 
381  int nin_file = m_format->nin();
382  int nex_file = m_format->nex();
383 
384  if ((nin_file == 0) || (nex_file == 0)) {
385  nin_file = nin_field;
386  nex_file = nex_field;
387  }
388 
389  int Lvol = CommonParameters::Lvol();
390 
391  Field vtmp;
392  if (Communicator::is_primary()) {
393  vtmp.reset(nin_field, Lvol, nex_field);
394  }
395 
396  // gather data
397  FieldIO::gather(&vtmp, v);
398 
399  // reorder
400 
401  // dump to file.
402  if (Communicator::is_primary()) {
403  vout.detailed(m_vl, "writing gauge configuration to %s\n", filename.c_str());
404 
405  FILE *fp = fopen(filename.c_str(), "w");
406  if (!fp) {
407  vout.crucial(m_vl, "cannot open file for write\n");
408  exit(EXIT_FAILURE);
409  }
410 
411  LimeWriter *writer = limeCreateWriter(fp);
412  if (!writer) {
413  vout.crucial(m_vl, "cannot create limeWriter\n");
414  exit(EXIT_FAILURE);
415  }
416 
417  // first, write metadata
418 #ifdef USE_ILDG_METADATA
419  store_metadata(writer);
420 #endif
421 
422  // second, write binary data.
423  store_data(writer, &vtmp, true, true);
424 
425  // if any, write lfn.
426 // store_lfn(writer, "lfn://");
427 
428  limeDestroyWriter(writer);
429 
430  fclose(fp);
431  }
432 
433  vout.detailed(m_vl, "write succeeded.\n");
434 
435  // cleanup.
436 }
437 
438 
439 void FieldIO_LIME::read_file(std::vector<Field *>& vv, const string& filename)
440 {
441  if (vv.size() == 0) return;
442 
443  int nin_field = vv[0]->nin();
444  int nex_field = vv[0]->nex();
445 
446  int Lvol = CommonParameters::Lvol();
447 
448  Field vtmp;
449 
450  if (Communicator::is_primary()) {
451  vout.detailed(m_vl, "reading gauge configuration from %s", filename.c_str());
452 
453  vtmp.reset(nin_field, Lvol, nex_field);
454 
455  FILE *fp = fopen(filename.c_str(), "r");
456  if (!fp) {
457  vout.crucial(m_vl, "%s: fopen failed.", __func__);
458  }
459 
460  LimeReader *reader = limeCreateReader(fp);
461  if (!reader) {
462  vout.crucial(m_vl, "%s: limeCreateReader failed.", __func__);
463  }
464 
465  // primary node reads file and deliver data to the other nodes.
466 
467  int idx = 0; // idx-th field
468 
469  // scan file for records.
470  for ( ; ; ) {
471  int status = limeReaderNextRecord(reader);
472  if (status != LIME_SUCCESS) break;
473 
474  const char *t = limeReaderType(reader);
475 
476  if (strcmp(t, "ildg-format") == 0) {
477 #if USE_ILDG_METADATA
478  ILDG_Format::Params params;
479  load_metadata(reader, &params);
480  check_metadata(&params);
481 #endif
482  } else if (strcmp(t, "ildg-binary-data") == 0) {
483  load_data(reader, &vtmp);
484 
485  FieldIO::deliver(vv[idx++], &vtmp);
486  } else if (strcmp(t, "ildg-data-lfn") == 0) {
487  load_lfn(reader);
488  } else {
489  vout.crucial(m_vl, "%s: known record %s.\n", __func__, t);
490  }
491  } // end loop over records.
492 
493  limeDestroyReader(reader);
494 
495  fclose(fp);
496  } else {
497  // other nodes wait for data to be delivered from primary node.
498  for (int i = 0, n = vv.size(); i < n; ++i) {
499  FieldIO::deliver(vv[i], &vtmp);
500  }
501  }
502 
503  vout.detailed(m_vl, "read successful\n");
504 }
505 
506 
507 void FieldIO_LIME::write_file(std::vector<Field *>& vv, const string& filename)
508 {
509  if (vv.size() == 0) return;
510 
511  int nin_field = vv[0]->nin();
512  int nex_field = vv[0]->nex();
513 
514  int nin_file = m_format->nin();
515  int nex_file = m_format->nex();
516 
517  if ((nin_file == 0) || (nex_file == 0)) {
518  nin_file = nin_field;
519  nex_file = nex_field;
520  }
521 
522  int Lvol = CommonParameters::Lvol();
523 
524  Field vtmp;
525  if (Communicator::is_primary()) {
526  vtmp.reset(nin_field, Lvol, nex_field);
527  }
528 
529  FILE *fp = NULL; // only on primary node.
530  LimeWriter *writer = NULL;
531 
532  // dump to file.
533  if (Communicator::is_primary()) {
534  vout.detailed(m_vl, "writing gauge configuration to %s\n", filename.c_str());
535 
536  fp = fopen(filename.c_str(), "w");
537  if (!fp) {
538  vout.crucial(m_vl, "cannot open file for write\n");
539  exit(EXIT_FAILURE);
540  }
541 
542  writer = limeCreateWriter(fp);
543  if (!writer) {
544  vout.crucial(m_vl, "cannot create limeWriter\n");
545  exit(EXIT_FAILURE);
546  }
547 
548  // first, write metadata
549 #ifdef USE_ILDG_METADATA
550  store_metadata(writer);
551 #endif
552  }
553 
554  for (int i = 0, n = vv.size(); i < n; ++i) {
555  // gather data
556  FieldIO::gather(&vtmp, vv[i]);
557 
558  if (Communicator::is_primary()) {
559  // reorder
560 
561  // second, write binary data.
562  store_data(writer, &vtmp, (i == 0), (i == n - 1));
563  }
564  }
565 
566  if (Communicator::is_primary()) {
567  // if any, write lfn.
568 // store_lfn(writer, "lfn://");
569 
570  limeDestroyWriter(writer);
571 
572  fclose(fp);
573  }
574 
575  vout.detailed(m_vl, "write succeeded.\n");
576 
577  // cleanup.
578 }
579 
580 
581 #else /* USE_LIMELIB */
582 
583 void FieldIO_LIME::read_file(Field *v, string filename) {}
584 void FieldIO_LIME::write_file(Field *v, string filename) {}
585 #endif /* USE_LIMELIB */
586 
587 //================================================================
Index_lex idx
Definition: fieldIO.h:59
BridgeIO vout
Definition: bridgeIO.cpp:278
static void byte_swap(void *buf, size_t size, size_t nmemb)
< convert byte order. alternative interface.
Definition: fieldIO.h:91
static const std::string class_name
Definition: fieldIO.h:56
void detailed(const char *format,...)
Definition: bridgeIO.cpp:82
virtual void file_to_field(int &s, int &t, const int i, const int j) const =0
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:155
virtual int nex() const =0
void deliver(Field *vlocal, Field *vglobal)
distribute data on primary node over parallel nodes.
Definition: fieldIO.cpp:30
Container of Field-type object.
Definition: field.h:39
int nvol() const
Definition: field.h:116
double cmp(const int jin, const int site, const int jex) const
Definition: field.h:123
void read_file(Field *v, std::string filename)
read data from file.
static int Lvol()
static bool is_bigendian()
Definition: fieldIO.cpp:203
int nin() const
Definition: field.h:115
void write_file(Field *v, std::string filename)
write data to file.
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:48
virtual int nin() const =0
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
int size() const
Definition: field.h:121