QUDA  1.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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 {
13  QIO_Iflag iflag;
14 
15  iflag.serpar = serpar;
16  iflag.volfmt = volfmt;
17 
18  /* Create the file XML */
19  QIO_String *xml_file_in = QIO_string_create();
20 
21  /* Open the file for reading */
22  QIO_Reader *infile = QIO_open_read(xml_file_in, filename, &layout, NULL, &iflag);
23  if (infile == NULL) {
24  printfQuda("%s(%d): QIO_open_read returns NULL.\n", __func__, this_node);
25  return NULL;
26  }
27 
28  printfQuda("%s: QIO_open_read done.\n",__func__);
29  printfQuda("%s: User file info is \"%s\"\n", __func__, QIO_string_ptr(xml_file_in));
30 
31  QIO_string_destroy(xml_file_in);
32  return infile;
33 }
34 
35 QIO_Writer *open_test_output(const char *filename, int volfmt, int serpar, int ildgstyle)
36 {
37  char xml_write_file[] = "Dummy user file XML";
38  QIO_Filesystem filesys;
39  QIO_Oflag oflag;
40 
41  oflag.serpar = serpar;
42  oflag.ildgstyle = ildgstyle;
43  oflag.ildgLFN = QIO_string_create();
44  QIO_string_set(oflag.ildgLFN,"monkey");
45  oflag.mode = QIO_TRUNC;
46 
47  filesys.my_io_node = 0;
48  filesys.master_io_node = 0;
49 
50  /* Create the file XML */
51  QIO_String *xml_file_out = QIO_string_create();
52  QIO_string_set(xml_file_out,xml_write_file);
53 
54  /* Open the file for reading */
55  QIO_Writer *outfile = QIO_open_write(xml_file_out, filename, volfmt, &layout, &filesys, &oflag);
56  if (outfile == NULL) {
57  printfQuda("%s(%d): QIO_open_write returns NULL.\n", __func__, this_node);
58  return NULL;
59  }
60 
61  printfQuda("%s: QIO_open_write done.\n",__func__);
62  printfQuda("%s: User file info is \"%s\"\n", __func__, QIO_string_ptr(xml_file_out));
63 
64  QIO_string_destroy(xml_file_out);
65  return outfile;
66 }
67 
68 /* get QIO record precision */
69 QudaPrecision get_prec(QIO_Reader *infile)
70 {
71  char dummy[100] = "";
72  QIO_RecordInfo *rec_info = QIO_create_record_info(0, NULL, NULL, 0, dummy, dummy, 0, 0, 0, 0);
73  QIO_String *xml_file = QIO_string_create();
74  int status = QIO_read_record_info(infile, rec_info, xml_file);
75  int prec = *QIO_get_precision(rec_info);
76  QIO_destroy_record_info(rec_info);
77  QIO_string_destroy(xml_file);
78 
79  printfQuda("%s: QIO_read_record_data returns status %d\n", __func__, status);
80  if (status != QIO_SUCCESS) { errorQuda("get_prec failed\n"); }
81 
82  return (prec == 70) ? QUDA_SINGLE_PRECISION : QUDA_DOUBLE_PRECISION;
83 }
84 
85 template <int len>
86 int read_field(QIO_Reader *infile, int count, void *field_in[], QudaPrecision cpu_prec)
87 {
88  QIO_String *xml_record_in;
89  QIO_RecordInfo rec_info;
90  int status;
91 
92  /* Query the precision */
93  QudaPrecision file_prec = get_prec(infile);
94  size_t rec_size = file_prec*count*len;
95 
96  /* Create the record XML */
97  xml_record_in = QIO_string_create();
98 
99  /* Read the field record and convert to cpu precision*/
100  if (cpu_prec == QUDA_DOUBLE_PRECISION) {
101  if (file_prec == QUDA_DOUBLE_PRECISION) {
102  status = QIO_read(infile, &rec_info, xml_record_in, vputM<double,double,len>,
103  rec_size, QUDA_DOUBLE_PRECISION, field_in);
104  } else {
105  status = QIO_read(infile, &rec_info, xml_record_in, vputM<double,float,len>,
106  rec_size, QUDA_SINGLE_PRECISION, field_in);
107  }
108  } else {
109  if (file_prec == QUDA_DOUBLE_PRECISION) {
110  status = QIO_read(infile, &rec_info, xml_record_in, vputM<float,double,len>,
111  rec_size, QUDA_DOUBLE_PRECISION, field_in);
112  } else {
113  status = QIO_read(infile, &rec_info, xml_record_in, vputM<float,float,len>,
114  rec_size, QUDA_SINGLE_PRECISION, field_in);
115  }
116  }
117 
118  QIO_string_destroy(xml_record_in);
119  printfQuda("%s: QIO_read_record_data returns status %d\n", __func__, status);
120  if (status != QIO_SUCCESS) return 1;
121  return 0;
122 }
123 
124 int read_su3_field(QIO_Reader *infile, int count, void *field_in[], QudaPrecision cpu_prec)
125 {
126  return read_field<18>(infile, count, field_in, cpu_prec);
127 }
128 
129 void set_layout(const int *X)
130 {
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) { errorQuda("Setup layout failed\n"); }
141  printfQuda("%s layout set for %d nodes\n", __func__, QMP_get_number_of_nodes());
143 
144  /* Build the layout structure */
145  layout.node_number = node_number;
146  layout.node_index = node_index;
147  layout.get_coords = get_coords;
148  layout.num_sites = num_sites;
149  layout.latsize = lattice_size;
150  layout.latdim = lattice_dim;
151  layout.volume = lattice_volume;
152  layout.sites_on_node = sites_on_node;
153  layout.this_node = this_node;
154  layout.number_of_nodes = QMP_get_number_of_nodes();
155 }
156 
157 void read_gauge_field(const char *filename, void *gauge[], QudaPrecision precision, const int *X, int argc, char *argv[])
158 {
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, int nColor, int nSpin,
199  int Nvec, int argc, char *argv[])
200 {
201  this_node = mynode();
202 
203  set_layout(X);
204 
205  /* Open the test file for reading */
206  QIO_Reader *infile = open_test_input(filename, QIO_UNKNOWN, QIO_PARALLEL);
207  if (infile == NULL) { errorQuda("Open file failed\n"); }
208 
209  /* Read the spinor field record */
210  printfQuda("%s: reading %d vector fields\n", __func__, Nvec); fflush(stdout);
211  int status = read_field(infile, 2*nSpin*nColor, Nvec, V, precision);
212  if (status) { errorQuda("read_spinor_fields failed %d\n", status); }
213 
214  /* Close the file */
215  QIO_close_read(infile);
216  printfQuda("%s: Closed file for reading\n",__func__);
217 }
218 
219 template <int len>
220 int write_field(QIO_Writer *outfile, int count, void *field_out[], QudaPrecision file_prec,
221  QudaPrecision cpu_prec, int nSpin, int nColor, const char *type)
222 {
223  char xml_write_field[] = "Dummy user record XML for SU(N) field";
224  int status;
225 
226  // Create the record info for the field
227  if (file_prec != QUDA_DOUBLE_PRECISION && file_prec != QUDA_SINGLE_PRECISION)
228  errorQuda("Error, file_prec=%d not supported", file_prec);
229 
230  const char *precision = (file_prec == QUDA_DOUBLE_PRECISION) ? "D" : "F";
231 
232  // presently assumes 4-d
233  const int nDim = 4;
234  int lower[nDim] = {0, 0, 0, 0};
235  int upper[nDim] = {lattice_size[0], lattice_size[1], lattice_size[2], lattice_size[3]};
236 
237  QIO_RecordInfo *rec_info = QIO_create_record_info(QIO_FIELD, lower, upper, nDim, const_cast<char *>(type),
238  const_cast<char *>(precision), nColor, nSpin, file_prec * len, count);
239 
240  // Create the record XML for the field
241  QIO_String *xml_record_out = QIO_string_create();
242  QIO_string_set(xml_record_out,xml_write_field);
243 
244  /* Write the field record converting to desired file precision*/
245  size_t rec_size = file_prec*count*len;
246  if (cpu_prec == QUDA_DOUBLE_PRECISION) {
247  if (file_prec == QUDA_DOUBLE_PRECISION) {
248  status = QIO_write(outfile, rec_info, xml_record_out, vgetM<double,double,len>,
249  rec_size, QUDA_DOUBLE_PRECISION, field_out);
250  } else {
251  status = QIO_write(outfile, rec_info, xml_record_out, vgetM<double,float,len>,
252  rec_size, QUDA_SINGLE_PRECISION, field_out);
253  }
254  } else {
255  if (file_prec == QUDA_DOUBLE_PRECISION) {
256  status = QIO_write(outfile, rec_info, xml_record_out, vgetM<float,double,len>,
257  rec_size, QUDA_DOUBLE_PRECISION, field_out);
258  } else {
259  status = QIO_write(outfile, rec_info, xml_record_out, vgetM<float,float,len>,
260  rec_size, QUDA_SINGLE_PRECISION, field_out);
261  }
262  }
263 
264  printfQuda("%s: QIO_write_record_data returns status %d\n", __func__, status);
265  QIO_destroy_record_info(rec_info);
266  QIO_string_destroy(xml_record_out);
267 
268  if (status != QIO_SUCCESS) return 1;
269  return 0;
270 }
271 
272 int write_su3_field(QIO_Writer *outfile, int count, void *field_out[],
273  QudaPrecision file_prec, QudaPrecision cpu_prec, const char* type)
274 {
275  return write_field<18>(outfile, count, field_out, file_prec, cpu_prec, 1, 9, type);
276 }
277 
278 void write_gauge_field(const char *filename, void *gauge[], QudaPrecision precision, const int *X, int argc, char *argv[])
279 {
280  this_node = mynode();
281 
282  set_layout(X);
283 
284  QudaPrecision file_prec = precision;
285 
286  char type[128];
287  sprintf(type, "QUDA_%sNc%d_GaugeField", (file_prec == QUDA_DOUBLE_PRECISION) ? "D" : "F", 3);
288 
289  /* Open the test file for writing */
290  QIO_Writer *outfile = open_test_output(filename, QIO_SINGLEFILE, QIO_PARALLEL, QIO_ILDGNO);
291  if (outfile == NULL) { errorQuda("Open file failed\n"); }
292 
293  /* Write the gauge field record */
294  printfQuda("%s: writing the gauge field\n", __func__); fflush(stdout);
295  int status = write_su3_field(outfile, 4, gauge, precision, precision, type);
296  if (status) { errorQuda("write_gauge_field failed %d\n", status); }
297 
298  /* Close the file */
299  QIO_close_write(outfile);
300  printfQuda("%s: Closed file for writing\n", __func__);
301 }
302 
303 // count is the number of vectors
304 // Ninternal is the size of the "inner struct" (24 for Wilson spinor)
305 int write_field(QIO_Writer *outfile, int Ninternal, int count, void *field_out[],
307  int nSpin, int nColor, const char *type)
308 {
309  int status = 0;
310  switch (Ninternal) {
311  case 24:
312  status = write_field<24>(outfile, count, field_out, file_prec, cpu_prec, nSpin, nColor, type);
313  break;
314  case 96:
315  status = write_field<96>(outfile, count, field_out, file_prec, cpu_prec, nSpin, nColor, type);
316  break;
317  case 128:
318  status = write_field<128>(outfile, count, field_out, file_prec, cpu_prec, nSpin, nColor, type);
319  break;
320  default:
321  errorQuda("Undefined %d", Ninternal);
322  }
323  return status;
324 }
325 
326 void write_spinor_field(const char *filename, void *V[], QudaPrecision precision, const int *X, int nColor, int nSpin,
327  int Nvec, int argc, char *argv[])
328 {
329  this_node = mynode();
330 
331  set_layout(X);
332 
333  QudaPrecision file_prec = precision;
334 
335  char type[128];
336  sprintf(type, "QUDA_%sNs%dNc%d_ColorSpinorField", (file_prec == QUDA_DOUBLE_PRECISION) ? "D" : "F", nSpin, nColor);
337 
338  /* Open the test file for reading */
339  QIO_Writer *outfile = open_test_output(filename, QIO_SINGLEFILE, QIO_PARALLEL, QIO_ILDGNO);
340  if (outfile == NULL) { errorQuda("Open file failed\n"); }
341 
342  /* Read the spinor field record */
343  printfQuda("%s: writing %d vector fields\n", __func__, Nvec); fflush(stdout);
344  int status = write_field(outfile, 2*nSpin*nColor, Nvec, V, precision, precision, nSpin, nColor, type);
345  if (status) { errorQuda("write_spinor_fields failed %d\n", status); }
346 
347  /* Close the file */
348  QIO_close_write(outfile);
349  printfQuda("%s: Closed file for writing\n",__func__);
350 }
enum QudaPrecision_s QudaPrecision
int this_node
Definition: qio_field.cpp:9
void read_gauge_field(const char *filename, void *gauge[], QudaPrecision precision, const int *X, int argc, char *argv[])
Definition: qio_field.cpp:157
#define errorQuda(...)
Definition: util_quda.h:121
int write_su3_field(QIO_Writer *outfile, int count, void *field_out[], QudaPrecision file_prec, QudaPrecision cpu_prec, const char *type)
Definition: qio_field.cpp:272
int comm_dim(int dim)
QIO_Writer * open_test_output(const char *filename, int volfmt, int serpar, int ildgstyle)
Definition: qio_field.cpp:35
int node_number(const int x[])
Definition: layout_hyper.c:214
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:224
int num_sites(int node)
Definition: layout_hyper.c:292
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:75
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:220
int read_su3_field(QIO_Reader *infile, int count, void *field_in[], QudaPrecision cpu_prec)
Definition: qio_field.cpp:124
int X[4]
Definition: covdev_test.cpp:70
int V
Definition: test_util.cpp:27
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
void write_gauge_field(const char *filename, void *gauge[], QudaPrecision precision, const int *X, int argc, char *argv[])
Definition: qio_field.cpp:278
Main header file for the QUDA library.
#define printfQuda(...)
Definition: util_quda.h:115
void get_coords(int x[], int node, int index)
Definition: layout_hyper.c:241
QudaPrecision & cpu_prec
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:326
int lattice_dim
Definition: qio_field.cpp:7
int lattice_size[4]
Definition: qio_field.cpp:8
__device__ unsigned int count[QUDA_MAX_MULTI_REDUCE]
Definition: cub_helper.cuh:90
void set_layout(const int *X)
Definition: qio_field.cpp:129
int read_field(QIO_Reader *infile, int count, void *field_in[], QudaPrecision cpu_prec)
Definition: qio_field.cpp:86
QudaPrecision prec
Definition: test_util.cpp:1608
int setup_layout(int len[], int nd, int numnodes)
Definition: layout_hyper.c:150
QudaPrecision get_prec(QIO_Reader *infile)
Definition: qio_field.cpp:69