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