QDP++
qdp_qdpio.cc
Go to the documentation of this file.
1//
5
6#include "qdp.h"
7
8namespace QDP
9{
10
11 //-----------------------------------------
12 static int get_node_number(const int coord[])
13 {
14 multi1d<int> crd(Nd);
15 crd = coord; // an array copy
16 int node = Layout::nodeNumber(crd);
17 return node;
18 }
19
20 static int get_node_index(const int coord[])
21 {
22 multi1d<int> crd(Nd);
23 crd = coord; // an array copy
24 int linear = Layout::linearSiteIndex(crd);
25 return linear;
26 }
27
28 static void get_coords(int coord[], int node, int linear)
29 {
30 multi1d<int> crd = Layout::siteCoords(node, linear);
31 for(int i=0; i < Nd; ++i)
32 coord[i] = crd[i];
33 }
34
35 static int get_sites_on_node(int node)
36 {
37 return Layout::sitesOnNode();
38 }
39
40 // Setting up the QIO Filesystem
43 {
44 return 0;
45 }
46
47
49
54 int io_node(int node)
55 {
56 // If no io grid is defined, each node is its own I/O node
57
58 if( ! Layout::isIOGridDefined() ) {
59 return node;
60 }
61
62 // A grid is defined. A shortcut for when there is only 1
63 if ( Layout::numIONodeGrid() == 1 ) {
64 return master_io_node();
65 }
66
67 // Compute my I/O node. Block lat size into I/O grid
68 const multi1d<int>& proc_size = Layout::logicalSize();
69 const multi1d<int>& io_geom = Layout::getIONodeGrid();
70
71 multi1d<int> block_sizes(Nd);
72 for(int mu=0; mu < Nd; mu++) {
73 block_sizes[mu] = proc_size[mu]/io_geom[mu];
74
75 // Pick up slack if CPU dimension not divisible
76 // Last block will stretch beyond processor grid, but this is OK
77 // since no node outside the proc grid will be asked for
78 if( proc_size[mu] % io_geom[mu] != 0 ) block_sizes[mu]++;
79 }
80
81 // My node coords -- always in the processor grid
83
84 // Coords of I/O node, basically the origin of the block the
85 // current node is in
86 multi1d<int> io_node_coords(Nd);
87 for(int mu=0; mu < Nd; mu++) {
88 // Integer division: will truncate to origin of block.
89 io_node_coords[mu] = node_coords[mu] / block_sizes[mu];
90 io_node_coords[mu] *= block_sizes[mu];
91 }
92
93 // Now just convert the io_node_coords to a node number and we're done
94 return Layout::getNodeNumberFrom(io_node_coords);
95 }
96
98
99 int io_node_multifile(int node)
100 {
101 return node;
102 }
103
104 //-----------------------------------------------------------------------------
105 // QDP QIO support
107
109 const std::string& path,
111 {open(xml,path,serpar);}
112
114 const std::string& path,
116 {
117 QIO_Layout layout;
118
119 int latsize[Nd];
120
121 for(int m=0; m < Nd; ++m)
122 latsize[m] = Layout::lattSize()[m];
123
125 layout.node_index = &get_node_index;
126 layout.get_coords = &get_coords;
128 layout.latsize = latsize;
129 layout.latdim = Nd;
130 layout.volume = Layout::vol();
132 layout.this_node = Layout::nodeNumber();
134
136 fs.my_io_node = &io_node;
138
139 // Initialize string objects
140 QIO_String *xml_c = QIO_string_create();
141
142 QIO_Iflag iflag;
143 if( serpar == QDPIO_PARALLEL ) {
144 iflag.serpar = QIO_PARALLEL;
145 }
146 else {
147 iflag.serpar = QIO_SERIAL;
148 }
149
150 iflag.volfmt = QIO_UNKNOWN;
151
152 // Call QIO read
153 // At this moment, serpar (which is an enum in QDP++) is ignored here.
154 if ((qio_in = QIO_open_read(xml_c, path.c_str(), &layout, &fs, &iflag)) == NULL)
155 {
156 iostate = QDPIO_badbit; // not helpful
157
158 QDPIO::cerr << "QDPFileReader: failed to open file " << path << std::endl;
159 QDP_abort(1); // just bail, otherwise xml stuff below fails.
160 }
161 else
162 {
163 iostate = QDPIO_goodbit;
164 }
165
166 // Use string to initialize XMLReader
167 std::istringstream ss;
169 {
170 std::string foo = QIO_string_ptr(xml_c);
171 ss.str(foo);
172 }
173 file_xml.open(ss);
174
175 QIO_string_destroy(xml_c);
176
177 iop=true;
178 }
179
180
182 {
183 if (is_open())
184 {
185 //int status = QIO_close_read(qio_in);
186 QIO_close_read(qio_in);
187 }
188
189 iop = false;
190 iostate = QDPIO_badbit;
191 }
192
193 bool QDPFileReader::is_open() {return iop;}
194
195 bool QDPFileReader::eof() const {return false;}
196
197 bool QDPFileReader::bad() const {return iostate;}
198
200 {
201 iostate = state;
202 }
203
205
208 {
209 qsw.close();
210 }
211
214 {
215 return qsw.is_open();
216 }
217
218 // Reads a record header only (state of reader left intact
219 // so subsequent read to get header and data still works)
220
222 {
223 QIO_RecordInfo rec_info;
224 QIO_String* xml_c = QIO_string_create();
225 int status;
226
227 status = QIO_read_record_info(qio_in, &rec_info, xml_c);
228 if( status != QIO_SUCCESS) {
229 QDPIO::cerr << "Failed to read the Record Info" << std::endl;
230 QDP_abort(1);
231 }
232
233 std::istringstream ss;
234 if (Layout::primaryNode()) {
235 std::string foo = QIO_string_ptr(xml_c);
236 ss.str(foo);
237 }
238 rec_xml.open(ss);
239
240 QIO_string_destroy(xml_c);
241 }
242
243
244 // Reads a BinaryBufferReader object
250 {
251 QIO_RecordInfo rec_info;
252 QIO_String* xml_c = QIO_string_create();
253 int status;
254
255 status = QIO_read_record_info(qio_in, &rec_info, xml_c);
256 if( status != QIO_SUCCESS) {
257 QDPIO::cerr << "Failed to read the Record Info" << std::endl;
258 QDP_abort(1);
259 }
260
261 QDPIO::cout << "BinaryBufferRead" << std::endl;
262 std::string from_disk;
263 from_disk.resize(QIO_get_datacount(&rec_info));
264 status = QIO_read_record_data(qio_in,
266 from_disk.size()*sizeof(char),
267 sizeof(char),
268 (void *)&(from_disk[0]));
269 if (status != QIO_SUCCESS) {
270 QDPIO::cerr << "Failed to read data" << std::endl;
272 QDP_abort(1);
273 }
274 QDPIO::cout << "QIO_read_finished" << std::endl;
275
276 // Cast appropriately
277// for(int i=0; i < from_disk.size(); i++) {
278 s1.open(from_disk);
279// }
280
281 std::istringstream ss;
282 if (Layout::primaryNode()) {
283 std::string foo = QIO_string_ptr(xml_c);
284 ss.str(foo);
285 }
286 rec_xml.open(ss);
287
288 QIO_string_destroy(xml_c);
289 }
290
291
292 //-----------------------------------------------------------------------------
293 // QDP QIO support (writers)
295
297 const std::string& path,
298 QDP_volfmt_t qdp_volfmt,
299 QDP_serialparallel_t qdp_serpar,
300 QDP_filemode_t qdp_mode)
301 {
302 open(xml,path,qdp_volfmt,qdp_serpar,qdp_mode, std::string());
303 }
304
306 const std::string& path,
307 QDP_volfmt_t qdp_volfmt,
308 QDP_serialparallel_t qdp_serpar,
309 QDP_filemode_t qdp_mode,
310 const std::string& data_LFN)
311 {
312 open(xml,path,qdp_volfmt,qdp_serpar,qdp_mode, data_LFN);
313 }
314
315 // filemode not specified
317 const std::string& path,
318 QDP_volfmt_t qdp_volfmt,
319 QDP_serialparallel_t qdp_serpar)
320 {
321 open(file_xml,path,qdp_volfmt,qdp_serpar,QDPIO_OPEN, std::string());
322 }
323
325 const std::string& path,
326 QDP_volfmt_t qdp_volfmt,
327 QDP_serialparallel_t qdp_serpar,
328 const std::string& data_LFN)
329 {
330 open(file_xml,path,qdp_volfmt,qdp_serpar,QDPIO_OPEN, data_LFN);
331 }
332
333
334 // filemode not specified
336 const std::string& path,
337 QDP_volfmt_t qdp_volfmt,
338 QDP_serialparallel_t qdp_serpar)
339 {
340 open(xml,path,qdp_volfmt,qdp_serpar,QDPIO_OPEN, std::string());
341 }
342
343 // filemode not specified
345 const std::string& path,
346 QDP_volfmt_t qdp_volfmt,
347 QDP_serialparallel_t qdp_serpar,
348 const std::string& data_LFN)
349 {
350 open(xml,path,qdp_volfmt,qdp_serpar,QDPIO_OPEN, data_LFN);
351 }
352
354 const std::string& path,
355 QDP_volfmt_t qdp_volfmt,
356 QDP_serialparallel_t qdp_serpar,
357 QDP_filemode_t qdp_mode,
358 const std::string& data_LFN)
359 {
360
361 QIO_Layout layout;
362 int latsize[Nd];
363
364 for(int m=0; m < Nd; ++m)
365 latsize[m] = Layout::lattSize()[m];
366
368 layout.node_index = &get_node_index;
369 layout.get_coords = &get_coords;
371 layout.latsize = latsize;
372 layout.latdim = Nd;
373 layout.volume = Layout::vol();
375 layout.this_node = Layout::nodeNumber();
377
378 // Copy metadata string into simple qio string container
379 QIO_String* xml_c = QIO_string_create();
380 QIO_string_set(xml_c, file_xml.str().c_str());
381
382 if (xml_c == NULL)
383 {
384 QDPIO::cerr << "QDPFileWriter - error in creating QIO string" << std::endl;
385 iostate = QDPIO_badbit;
386 }
387 else
388 {
389 iostate = QDPIO_goodbit;
390 }
391
393 fs.my_io_node = &io_node;
395
396 // Wrappers over simple ints
397 int volfmt;
398 switch(qdp_volfmt)
399 {
400 case QDPIO_SINGLEFILE:
401 volfmt = QIO_SINGLEFILE;
402 break;
403
404 case QDPIO_MULTIFILE:
405 volfmt = QIO_MULTIFILE;
407 break;
408
409 case QDPIO_PARTFILE:
410 volfmt = QIO_PARTFILE;
411
412 break;
413
414 default:
415 QDPIO::cerr << "Unknown value for qdp_volfmt " << qdp_volfmt << std::endl;
416 QDP_abort(1);
417 return;
418 }
419
420 // Wrappers over simple ints
421 int mode;
422 switch(qdp_mode)
423 {
424 case QDPIO_CREATE:
425 mode = QIO_CREAT;
426 break;
427
428 case QDPIO_OPEN:
429 mode = QIO_TRUNC;
430 break;
431
432 case QDPIO_APPEND:
433 mode = QIO_APPEND;
434 break;
435
436 default:
437 QDPIO::cerr << "Unknown value for qdp_mode " << qdp_mode << std::endl;
438 QDP_abort(1);
439 return;
440 }
441
442 // QIO write
443 // For now, serpar (which is an enum in QDP) is ignored here
444 QIO_Oflag oflag;
445 if( qdp_serpar == QDPIO_SERIAL ) {
446 oflag.serpar = QIO_SERIAL;
447 }
448 else {
449 oflag.serpar = QIO_PARALLEL;
450 }
451 oflag.mode = mode;
452 oflag.ildgstyle = QIO_ILDGLAT;
453 if( data_LFN.length() == 0 ) {
454 oflag.ildgLFN = NULL;
455 }
456 else {
457 oflag.ildgLFN = QIO_string_create();
458 QIO_string_set(oflag.ildgLFN, data_LFN.c_str());
459 }
460
461
462 // This is the QIO Way - older way
463 if ((qio_out = QIO_open_write(xml_c, path.c_str(),
464 volfmt,
465 &layout,
466 &fs, &oflag)) == NULL )
467 {
468 iostate = QDPIO_badbit; // not helpful
469
470 QDPIO::cerr << "QDPFileWriter: failed to open file " << path << std::endl;
471 QDP_abort(1); // just bail. Not sure I want this. This is not stream semantics
472 }
473 else
474 {
475 iostate = QDPIO_goodbit;
476 }
477
478
479 // Free memory -- this is OK< as it should'of been copied
481 // Cleanup
482 QIO_string_destroy(xml_c);
483
484 iop=true;
485 }
486
488 {
489 if (is_open())
490 {
491 // int status = QIO_close_write(qio_out);
492 QIO_close_write(qio_out);
493 }
494
495 iop = false;
496 iostate = QDPIO_badbit;
497 }
498
499 bool QDPFileWriter::is_open() {return iop;}
500
501 bool QDPFileWriter::bad() const {return iostate;}
502
504 {
505 iostate = state;
506 }
507
509
510
512 {
513 qsw.close();
514 }
515
516
518 {
519 return qsw.is_open();
520 }
521
522
524
529 {
530 std::string ss = s1.str();
531 char *typestr=(char *)"char";
532 char *signtype=(char *)"U";
533
534 QIO_RecordInfo* info = QIO_create_record_info(QIO_GLOBAL, NULL, NULL, 0,
535 typestr,
536 signtype,
537 0, 0,
538 sizeof(char), ss.size());
539
540
541 // Copy metadata string into simple qio string container
542 QIO_String* xml_c = QIO_string_create();
543 if (xml_c == NULL)
544 {
545 QDPIO::cerr << "QDPFileWriter::write - error in creating XML string" << std::endl;
546 QDP_abort(1);
547 }
548
550 QIO_string_set(xml_c, rec_xml.str().c_str());
551
552 // Big call to qio
553 if (QIO_write(get(), info, xml_c,
555 ss.size()*sizeof(char),
556 sizeof(char),
557 (void *)ss.c_str()) != QIO_SUCCESS)
558 {
559 QDPIO::cerr << "QDPFileWriter: error in write" << std::endl;
561 QDP_abort(1);
562 }
563
564 // Cleanup
565 QIO_string_destroy(xml_c);
567 }
568
569
570} // namespace QDP;
Binary buffer input class.
Definition qdp_io.h:905
void open(const std::string &s)
Construct from a string.
Definition qdp_io.cc:924
Binary buffer output class.
Definition qdp_io.h:1390
std::string str() const
Return entire buffer as a string.
Definition qdp_io.cc:1372
bool bad() const
Query whether an unrecoverable error has occurred.
Definition qdp_qdpio.cc:197
void close()
Closes the last file opened.
Definition qdp_qdpio.cc:181
void open(XMLReader &xml, const std::string &path, QDP_serialparallel_t qdp_serpar)
Opens a file for reading.
Definition qdp_qdpio.cc:113
~QDPFileReader()
Closes the last file opened.
Definition qdp_qdpio.cc:204
bool is_open()
Queries whether a file is open.
Definition qdp_qdpio.cc:193
void read(XMLReader &xml)
Reads a record header only.
Definition qdp_qdpio.cc:221
bool eof() const
Query whether the end-of-file has been reached.
Definition qdp_qdpio.cc:195
void clear(QDP_iostate_t state=QDPIO_goodbit)
Sets a new value for the IO status, ignoring the existing value.
Definition qdp_qdpio.cc:199
QDPFileReader()
Partial constructor.
Definition qdp_qdpio.cc:106
QIO writer class.
Definition qdp_qdpio.h:509
bool bad() const
Query whether an unrecoverable error has occurred.
Definition qdp_qdpio.cc:501
QDPFileWriter()
Partial constructor.
Definition qdp_qdpio.cc:294
~QDPFileWriter()
Closes the last file opened.
Definition qdp_qdpio.cc:508
void write(XMLBufferWriter &xml, const QDPType< T, C > &s1)
Write a QDP object.
Definition qdp_qdpio.h:633
void clear(QDP_iostate_t state=QDPIO_goodbit)
Sets a new value for the control state ignoring the existing value.
Definition qdp_qdpio.cc:503
void close()
Closes the last file opened.
Definition qdp_qdpio.cc:487
void open(XMLBufferWriter &xml, const std::string &path, QDP_volfmt_t qdp_volfmt, QDP_serialparallel_t qdp_serpar)
Opens a file for writing and writes the file metadata.
Definition qdp_qdpio.cc:316
bool is_open()
Queries whether a file is open.
Definition qdp_qdpio.cc:499
QIO_Writer * get() const
Definition qdp_qdpio.h:714
Writes XML metadata to a buffer.
Definition qdp_xmlio.h:1024
std::string str() const
Return entire buffer as a string.
XML reader class.
Definition qdp_xmlio.h:44
void open(const std::string &filename)
Opens and reads an XML file.
Definition qdp_xmlio.cc:45
Container for a multi-dimensional 1D array.
Definition qdp_multi.h:25
const int Nd
Definition qdp_params.h:24
void QDPOScalarFactoryPut(char *buf, size_t linear, int count, void *arg)
Function for moving data.
Definition qdp_qdpio.h:834
QDP_serialparallel_t
File access mode.
Definition qdp_qdpio.h:27
bool is_open(QDPFileReader &qsw)
Is a QDPFileReader open.
Definition qdp_qdpio.cc:213
void close(QDPFileReader &qsw)
Close a QDPFileReader.
Definition qdp_qdpio.cc:207
QDP_filemode_t
File open mode.
Definition qdp_qdpio.h:42
void QDPOScalarFactoryGet(char *buf, size_t linear, int count, void *arg)
Function for moving data.
Definition qdp_qdpio.h:1051
QDP_volfmt_t
File format.
Definition qdp_qdpio.h:34
QDP_iostate_t
QDPIO state.
Definition qdp_qdpio.h:50
@ QDPIO_PARALLEL
Definition qdp_qdpio.h:29
@ QDPIO_SERIAL
Definition qdp_qdpio.h:28
@ QDPIO_CREATE
Definition qdp_qdpio.h:43
@ QDPIO_OPEN
Definition qdp_qdpio.h:44
@ QDPIO_APPEND
Definition qdp_qdpio.h:45
@ QDPIO_PARTFILE
Definition qdp_qdpio.h:37
@ QDPIO_SINGLEFILE
Definition qdp_qdpio.h:35
@ QDPIO_MULTIFILE
Definition qdp_qdpio.h:36
@ QDPIO_goodbit
Definition qdp_qdpio.h:51
@ QDPIO_badbit
Definition qdp_qdpio.h:54
int nodeNumber()
Returns the node number of this node.
const multi1d< int > & logicalSize()
Returns the logical size of this machine.
int linearSiteIndex(int site)
The linearized site index for the corresponding lexicographic site.
int sitesOnNode()
Subgrid lattice volume.
multi1d< int > siteCoords(int node, int index) QDP_CONST
Reconstruct the lattice coordinate from the node and site number.
int getNodeNumberFrom(const multi1d< int > &node_coord)
Returns the node number given some logical node coordinate.
int numNodes()
Returns the number of nodes.
const multi1d< int > & lattSize()
Virtual grid (problem grid) lattice size.
bool isIOGridDefined(void) QDP_CONST
check if I/O grid is defined
int numIONodeGrid(void) QDP_CONST
number of I/O nodes
multi1d< int > getLogicalCoordFrom(int node)
Returns the logical node coordinates given some node number.
int vol()
Total lattice volume.
bool primaryNode()
Returns whether this is the primary node.
const multi1d< int > & getIONodeGrid() QDP_CONST
Get the I/O Node grid.
StandardOutputStream cout
Definition qdp_stdio.cc:21
StandardOutputStream cerr
Definition qdp_stdio.cc:22
Yet another random number generator.
static void get_coords(int coord[], int node, int linear)
Definition qdp_qdpio.cc:28
int io_node(int node)
io_node(node) returns the I/O node for node 'node'
Definition qdp_qdpio.cc:54
static int get_node_number(const int coord[])
Definition qdp_qdpio.cc:12
int io_node_multifile(int node)
io_node for multifile...
Definition qdp_qdpio.cc:99
static int get_node_index(const int coord[])
Definition qdp_qdpio.cc:20
void QDP_abort(int status)
Panic button.
static int get_sites_on_node(int node)
Definition qdp_qdpio.cc:35
int master_io_node(void)
Master IO node is always IO node 0.
Definition qdp_qdpio.cc:42
Primary include file for QDP.
#define QIO_MULTIFILE
#define QIO_GLOBAL
#define QIO_TRUNC
int QIO_read_record_data(QIO_Reader *in, void(*put)(char *buf, size_t index, int count, void *arg), size_t datum_size, int word_size, void *arg)
#define QIO_SERIAL
#define QIO_ILDGLAT
#define QIO_PARTFILE
QIO_Writer * QIO_open_write(QIO_String *xml_file, const char *filename, int volfmt, QIO_Layout *layout, QIO_Filesystem *fs, QIO_Oflag *oflag)
#define QIO_APPEND
#define QIO_SUCCESS
QIO_Reader * QIO_open_read(QIO_String *xml_file, const char *filename, QIO_Layout *layout, QIO_Filesystem *fs, QIO_Iflag *iflag)
int QIO_close_write(QIO_Writer *out)
#define QIO_PARALLEL
int QIO_write(QIO_Writer *out, QIO_RecordInfo *record_info, QIO_String *xml_record, void(*get)(char *buf, size_t index, int count, void *arg), size_t datum_size, int word_size, void *arg)
#define QIO_SINGLEFILE
int QIO_close_read(QIO_Reader *in)
#define QIO_CREAT
#define QIO_UNKNOWN
int QIO_read_record_info(QIO_Reader *in, QIO_RecordInfo *record_info, QIO_String *xml_record)
void QIO_string_set(QIO_String *qs, const char *const string)
char * QIO_string_ptr(QIO_String *qs)
QIO_String * QIO_string_create(void)
void QIO_string_destroy(QIO_String *qs)
int QIO_get_datacount(QIO_RecordInfo *record_info)
QIO_RecordInfo * QIO_create_record_info(int recordtype, int lower[], int upper[], int n, char *datatype, char *precision, int colors, int spins, int typesize, int datacount)
void QIO_destroy_record_info(QIO_RecordInfo *record_info)
DML_master_io_node_t master_io_node
DML_io_node_t my_io_node
size_t volume
size_t sites_on_node
int number_of_nodes
void(* get_coords)(int coords[], int node, int index)
int * latsize
int(* node_number)(const int coords[])
int(* num_sites)(int node)
int(* node_index)(const int coords[])
QIO_String * ildgLFN