QUDA  0.9.0
qio_field.cpp
Go to the documentation of this file.
1 #include <qio.h>
2 #include <qio_util.h>
3 #include <quda.h>
4 #include <util_quda.h>
5 
6 QIO_Layout layout;
8 int lattice_size[4];
10 
11 QIO_Reader *open_test_input(const char *filename, int volfmt, int serpar) {
12  QIO_String *xml_file_in;
13  QIO_Reader *infile;
14  QIO_Iflag iflag;
15 
16  iflag.serpar = serpar;
17  iflag.volfmt = volfmt;
18 
19  /* Create the file XML */
20  xml_file_in = QIO_string_create();
21 
22  /* Open the file for reading */
23  infile = QIO_open_read(xml_file_in, filename, &layout, NULL, &iflag);
24  if(infile == NULL){
25  printfQuda("%s(%d): QIO_open_read returns NULL.\n",__func__,this_node);
26  return NULL;
27  }
28 
29  printfQuda("%s: QIO_open_read done.\n",__func__);
30  printfQuda("%s: User file info is \"%s\"\n", __func__, QIO_string_ptr(xml_file_in));
31 
32  QIO_string_destroy(xml_file_in);
33  return infile;
34 }
35 
36 QIO_Writer *open_test_output(const char *filename, int volfmt, int serpar, int ildgstyle){
37  QIO_String *xml_file_out;
38  char xml_write_file[] = "Dummy user file XML";
39  QIO_Writer *outfile;
40  QIO_Filesystem filesys;
41  QIO_Oflag oflag;
42 
43  oflag.serpar = serpar;
44  oflag.ildgstyle = ildgstyle;
45  oflag.ildgLFN = QIO_string_create();
46  QIO_string_set(oflag.ildgLFN,"monkey");
47  oflag.mode = QIO_TRUNC;
48 
49  filesys.my_io_node = 0;
50  filesys.master_io_node = 0;
51 
52  /* Create the file XML */
53  xml_file_out = QIO_string_create();
54  QIO_string_set(xml_file_out,xml_write_file);
55 
56  /* Open the file for reading */
57  outfile = QIO_open_write(xml_file_out, filename, volfmt, &layout,
58  &filesys, &oflag);
59  if(outfile == NULL){
60  printfQuda("%s(%d): QIO_open_write returns NULL.\n",__func__,this_node);
61  return NULL;
62  }
63 
64  printfQuda("%s: QIO_open_write done.\n",__func__);
65  printfQuda("%s: User file info is \"%s\"\n", __func__, QIO_string_ptr(xml_file_out));
66 
67  QIO_string_destroy(xml_file_out);
68  return outfile;
69 }
70 
71 /* get QIO record precision */
72 QudaPrecision get_prec(QIO_Reader *infile) {
73  char dummy[100] = "";
74  QIO_RecordInfo *rec_info = QIO_create_record_info(0, NULL, NULL, 0, dummy, dummy, 0, 0, 0, 0);
75  QIO_String *xml_file = QIO_string_create();
76  int status = QIO_read_record_info(infile, rec_info, xml_file);
77  int prec = *QIO_get_precision(rec_info);
78  QIO_destroy_record_info(rec_info);
79  QIO_string_destroy(xml_file);
80 
81  printfQuda("%s: QIO_read_record_data returns status %d\n", __func__, status);
82  if (status != QIO_SUCCESS) { errorQuda("get_prec failed\n"); }
83 
85 }
86 
87 template <int len>
88 int read_field(QIO_Reader *infile, int count, void *field_in[], QudaPrecision cpu_prec)
89 {
90  QIO_String *xml_record_in;
91  QIO_RecordInfo rec_info;
92  int status;
93 
94  /* Query the precision */
95  QudaPrecision file_prec = get_prec(infile);
96  size_t rec_size = file_prec*count*len;
97 
98  /* Create the record XML */
99  xml_record_in = QIO_string_create();
100 
101  /* Read the field record and convert to cpu precision*/
103  if (file_prec == QUDA_DOUBLE_PRECISION) {
104  status = QIO_read(infile, &rec_info, xml_record_in, vputM<double,double,len>,
105  rec_size, QUDA_DOUBLE_PRECISION, field_in);
106  } else {
107  status = QIO_read(infile, &rec_info, xml_record_in, vputM<double,float,len>,
108  rec_size, QUDA_SINGLE_PRECISION, field_in);
109  }
110  } else {
111  if (file_prec == QUDA_DOUBLE_PRECISION) {
112  status = QIO_read(infile, &rec_info, xml_record_in, vputM<float,double,len>,
113  rec_size, QUDA_DOUBLE_PRECISION, field_in);
114  } else {
115  status = QIO_read(infile, &rec_info, xml_record_in, vputM<float,float,len>,
116  rec_size, QUDA_SINGLE_PRECISION, field_in);
117  }
118  }
119 
120  printfQuda("%s: QIO_read_record_data returns status %d\n", __func__, status);
121  if (status != QIO_SUCCESS) return 1;
122  return 0;
123 }
124 
125 int read_su3_field(QIO_Reader *infile, int count, void *field_in[], QudaPrecision cpu_prec)
126 {
127  return read_field<18>(infile, count, field_in, cpu_prec);
128 }
129 
130 void set_layout(const int *X) {
131  /* Lattice dimensions */
132  lattice_dim = 4;
133  int lattice_volume = 1;
134  for (int d=0; d<4; d++) {
135  lattice_size[d] = comm_dim(d)*X[d];
136  lattice_volume *= lattice_size[d];
137  }
138 
139  /* Set the mapping of coordinates to nodes */
140  if(setup_layout(lattice_size, 4, QMP_get_number_of_nodes())!=0)
141  { errorQuda("Setup layout failed\n"); }
142  printfQuda("%s layout set for %d nodes\n", __func__, QMP_get_number_of_nodes());
144 
145  /* Build the layout structure */
146  layout.node_number = node_number;
147  layout.node_index = node_index;
148  layout.get_coords = get_coords;
149  layout.num_sites = num_sites;
150  layout.latsize = lattice_size;
151  layout.latdim = lattice_dim;
152  layout.volume = lattice_volume;
153  layout.sites_on_node = sites_on_node;
154  layout.this_node = this_node;
155  layout.number_of_nodes = QMP_get_number_of_nodes();
156 }
157 
158 void read_gauge_field(const char *filename, void *gauge[], QudaPrecision precision, const int *X, int argc, char *argv[]) {
159  this_node = mynode();
160 
161  set_layout(X);
162 
163  /* Open the test file for reading */
164  QIO_Reader *infile = open_test_input(filename, QIO_UNKNOWN, QIO_PARALLEL);
165  if(infile == NULL) { errorQuda("Open file failed\n"); }
166 
167  /* Read the su3 field record */
168  printfQuda("%s: reading su3 field\n",__func__); fflush(stdout);
169  int status = read_su3_field(infile, 4, gauge, precision);
170  if(status) { errorQuda("read_su3_field failed %d\n", status); }
171 
172  /* Close the file */
173  QIO_close_read(infile);
174  printfQuda("%s: Closed file for reading\n",__func__);
175 }
176 
177 // count is the number of vectors
178 // Ninternal is the size of the "inner struct" (24 for Wilson spinor)
179 int read_field(QIO_Reader *infile, int Ninternal, int count, void *field_in[], QudaPrecision cpu_prec)
180 {
181  int status = 0;
182  switch (Ninternal) {
183  case 24:
184  status = read_field<24>(infile, count, field_in, cpu_prec);
185  break;
186  case 96:
187  status = read_field<96>(infile, count, field_in, cpu_prec);
188  break;
189  case 128:
190  status = read_field<128>(infile, count, field_in, cpu_prec);
191  break;
192  default:
193  errorQuda("Undefined %d", Ninternal);
194  }
195  return status;
196 }
197 
198 void read_spinor_field(const char *filename, void *V[], QudaPrecision precision, const int *X,
199  int nColor, int nSpin, int Nvec, int argc, char *argv[]) {
200  this_node = mynode();
201 
202  set_layout(X);
203 
204  /* Open the test file for reading */
205  QIO_Reader *infile = open_test_input(filename, QIO_UNKNOWN, QIO_PARALLEL);
206  if(infile == NULL) { errorQuda("Open file failed\n"); }
207 
208  /* Read the spinor field record */
209  printfQuda("%s: reading %d vector fields\n", __func__, Nvec); fflush(stdout);
210  int status = read_field(infile, 2*nSpin*nColor, Nvec, V, precision);
211  if(status) { errorQuda("read_spinor_fields failed %d\n", status); }
212 
213  /* Close the file */
214  QIO_close_read(infile);
215  printfQuda("%s: Closed file for reading\n",__func__);
216 }
217 
218 template <int len>
219 int write_field(QIO_Writer *outfile, int count, void *field_out[], QudaPrecision file_prec,
220  QudaPrecision cpu_prec, int nSpin, int nColor, const char *type)
221 {
222  QIO_String *xml_record_out;
223  char xml_write_field[] = "Dummy user record XML for SU(N) field";
224  QIO_RecordInfo *rec_info;
225  int status;
226 
227  // Create the record info for the field
228  if (file_prec != QUDA_DOUBLE_PRECISION && file_prec != QUDA_SINGLE_PRECISION)
229  errorQuda("Error, file_prec=%d not supported", file_prec);
230 
231  const char *precision = (file_prec == QUDA_DOUBLE_PRECISION) ? "D" : "F";
232 
233  int *lower = new int[count];
234  int *upper = new int[count];
235 
236  for (int d=0; d<count; d++) {
237  lower[d] = 0;
238  upper[d] = lattice_size[d];
239  }
240 
241  rec_info = QIO_create_record_info(QIO_FIELD, lower, upper, count, const_cast<char*>(type),
242  const_cast<char*>(precision), nColor, nSpin, file_prec*len, count);
243 
244  delete []upper;
245  delete []lower;
246 
247 
248  /* Create the record XML */
249  xml_record_out = QIO_string_create();
250  // Create the record XML for the field
251  xml_record_out = QIO_string_create();
252  QIO_string_set(xml_record_out,xml_write_field);
253 
254  /* Write the field record converting to desired file precision*/
255  size_t rec_size = file_prec*count*len;
257  if (file_prec == QUDA_DOUBLE_PRECISION) {
258  status = QIO_write(outfile, rec_info, xml_record_out, vgetM<double,double,len>,
259  rec_size, QUDA_DOUBLE_PRECISION, field_out);
260  } else {
261  status = QIO_write(outfile, rec_info, xml_record_out, vgetM<double,float,len>,
262  rec_size, QUDA_SINGLE_PRECISION, field_out);
263  }
264  } else {
265  if (file_prec == QUDA_DOUBLE_PRECISION) {
266  status = QIO_write(outfile, rec_info, xml_record_out, vgetM<float,double,len>,
267  rec_size, QUDA_DOUBLE_PRECISION, field_out);
268  } else {
269  status = QIO_write(outfile, rec_info, xml_record_out, vgetM<float,float,len>,
270  rec_size, QUDA_SINGLE_PRECISION, field_out);
271  }
272  }
273 
274  printfQuda("%s: QIO_write_record_data returns status %d\n", __func__, status);
275  QIO_destroy_record_info(rec_info);
276  QIO_string_destroy(xml_record_out);
277 
278  if (status != QIO_SUCCESS) return 1;
279  return 0;
280 }
281 
282 // count is the number of vectors
283 // Ninternal is the size of the "inner struct" (24 for Wilson spinor)
284 int write_field(QIO_Writer *outfile, int Ninternal, int count, void *field_out[],
286  int nSpin, int nColor, const char *type)
287 {
288  int status = 0;
289  switch (Ninternal) {
290  case 24:
291  status = write_field<24>(outfile, count, field_out, file_prec, cpu_prec, nSpin, nColor, type);
292  break;
293  case 96:
294  status = write_field<96>(outfile, count, field_out, file_prec, cpu_prec, nSpin, nColor, type);
295  break;
296  case 128:
297  status = write_field<128>(outfile, count, field_out, file_prec, cpu_prec, nSpin, nColor, type);
298  break;
299  default:
300  errorQuda("Undefined %d", Ninternal);
301  }
302  return status;
303 }
304 
305 void write_spinor_field(const char *filename, void *V[], QudaPrecision precision, const int *X,
306  int nColor, int nSpin, int Nvec, int argc, char *argv[]) {
307  this_node = mynode();
308 
309  set_layout(X);
310 
311  QudaPrecision file_prec = precision;
312 
313  char type[128];
314  sprintf(type, "QUDA_%sNs%dNc%d_ColorSpinorField", (file_prec == QUDA_DOUBLE_PRECISION) ? "D" : "F", nSpin, nColor);
315 
316  /* Open the test file for reading */
317  QIO_Writer *outfile = open_test_output(filename, QIO_SINGLEFILE, QIO_PARALLEL, QIO_ILDGNO);
318  if(outfile == NULL) { printfQuda("Open file failed\n"); exit(0); }
319 
320  /* Read the spinor field record */
321  printfQuda("%s: writing %d vector fields\n", __func__, Nvec); fflush(stdout);
322  int status = write_field(outfile, 2*nSpin*nColor, Nvec, V, precision, precision, nSpin, nColor, type);
323  if(status) { errorQuda("write_spinor_fields failed %d\n", status); }
324 
325  /* Close the file */
326  QIO_close_write(outfile);
327  printfQuda("%s: Closed file for writing\n",__func__);
328 }
enum QudaPrecision_s QudaPrecision
int this_node
Definition: qio_field.cpp:9
int fflush(FILE *)
void read_gauge_field(const char *filename, void *gauge[], QudaPrecision precision, const int *X, int argc, char *argv[])
Definition: qio_field.cpp:158
#define errorQuda(...)
Definition: util_quda.h:90
int comm_dim(int dim)
QIO_Writer * open_test_output(const char *filename, int volfmt, int serpar, int ildgstyle)
Definition: qio_field.cpp:36
int node_number(const int x[])
Definition: layout_hyper.c:205
void exit(int) __attribute__((noreturn))
QIO_Reader * open_test_input(const char *filename, int volfmt, int serpar)
Definition: qio_field.cpp:11
int node_index(const int x[])
Definition: layout_hyper.c:215
QudaPrecision cpu_prec
Definition: covdev_test.cpp:33
int num_sites(int node)
Definition: layout_hyper.c:283
static int sites_on_node
Definition: layout_hyper.c:56
QIO_Layout layout
Definition: qio_field.cpp:6
const int nColor
Definition: covdev_test.cpp:77
int V
Definition: test_util.cpp:28
int write_field(QIO_Writer *outfile, int count, void *field_out[], QudaPrecision file_prec, QudaPrecision cpu_prec, int nSpin, int nColor, const char *type)
Definition: qio_field.cpp:219
int read_su3_field(QIO_Reader *infile, int count, void *field_in[], QudaPrecision cpu_prec)
Definition: qio_field.cpp:125
void read_spinor_field(const char *filename, void *V[], QudaPrecision precision, const int *X, int nColor, int nSpin, int Nvec, int argc, char *argv[])
Definition: qio_field.cpp:198
Main header file for the QUDA library.
int sprintf(char *, const char *,...) __attribute__((__format__(__printf__
#define printfQuda(...)
Definition: util_quda.h:84
void get_coords(int x[], int node, int index)
Definition: layout_hyper.c:232
void write_spinor_field(const char *filename, void *V[], QudaPrecision precision, const int *X, int nColor, int nSpin, int Nvec, int argc, char *argv[])
Definition: qio_field.cpp:305
int lattice_dim
Definition: qio_field.cpp:7
int lattice_size[4]
Definition: qio_field.cpp:8
const void size_t count
static __inline__ size_t size_t d
void set_layout(const int *X)
Definition: qio_field.cpp:130
int read_field(QIO_Reader *infile, int count, void *field_in[], QudaPrecision cpu_prec)
Definition: qio_field.cpp:88
QudaPrecision prec
Definition: test_util.cpp:1615
int setup_layout(int len[], int nd, int numnodes)
Definition: layout_hyper.c:150
QudaPrecision get_prec(QIO_Reader *infile)
Definition: qio_field.cpp:72