Grid 0.7.0
NerscIO.h
Go to the documentation of this file.
1/*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/parallelIO/NerscIO.h
6
7 Copyright (C) 2015
8
9 Author: Matt Spraggs <matthew.spraggs@gmail.com>
10 Author: Peter Boyle <paboyle@ph.ed.ac.uk>
11 Author: paboyle <paboyle@ph.ed.ac.uk>
12 Author: Jamie Hudspith <renwick.james.hudspth@gmail.com>
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License along
25 with this program; if not, write to the Free Software Foundation, Inc.,
26 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27
28 See the full license in the file "LICENSE" in the top level distribution directory
29*************************************************************************************/
30/* END LEGAL */
31#ifndef GRID_NERSC_IO_H
32#define GRID_NERSC_IO_H
33
34#include <string>
35
37
38using namespace Grid;
39
41// Write and read from fstream; comput header offset for payload
43class NerscIO : public BinaryIO {
44public:
46
47 // Enable/disable exiting if the plaquette in the header does not match the value computed (default true)
48 static bool & exitOnReadPlaquetteMismatch(){ static bool v=true; return v; }
49
50 static inline void truncate(std::string file){
51 std::ofstream fout(file,std::ios::out);
52 }
53
54 static inline unsigned int writeHeader(FieldMetaData &field,std::string file)
55 {
56 std::ofstream fout(file,std::ios::out|std::ios::in);
57 fout.seekp(0,std::ios::beg);
58 dump_meta_data(field, fout);
59 field.data_start = fout.tellp();
60 return field.data_start;
61 }
62
63 // for the header-reader
64 static inline int readHeader(std::string file,GridBase *grid, FieldMetaData &field)
65 {
66 std::map<std::string,std::string> header;
67 std::string line;
68
70 // read the header
72 std::ifstream fin(file);
73
74 getline(fin,line); // read one line and insist is
75
76 removeWhitespace(line);
77 std::cout << GridLogMessage << "* " << line << std::endl;
78
79 assert(line==std::string("BEGIN_HEADER"));
80
81 do {
82 getline(fin,line); // read one line
83 std::cout << GridLogMessage << "* "<<line<< std::endl;
84 int eq = line.find("=");
85 if(eq >0) {
86 std::string key=line.substr(0,eq);
87 std::string val=line.substr(eq+1);
90
91 header[key] = val;
92 }
93 } while( line.find("END_HEADER") == std::string::npos );
94
95 field.data_start = fin.tellg();
96
98 // chomp the values
100 field.hdr_version = header["HDR_VERSION"];
101 field.data_type = header["DATATYPE"];
102 field.storage_format = header["STORAGE_FORMAT"];
103
104 field.dimension[0] = std::stol(header["DIMENSION_1"]);
105 field.dimension[1] = std::stol(header["DIMENSION_2"]);
106 field.dimension[2] = std::stol(header["DIMENSION_3"]);
107 field.dimension[3] = std::stol(header["DIMENSION_4"]);
108
109 assert(grid->_ndimension == 4);
110 for(int d=0;d<4;d++){
111 assert(grid->_fdimensions[d]==field.dimension[d]);
112 }
113
114 field.link_trace = std::stod(header["LINK_TRACE"]);
115 field.plaquette = std::stod(header["PLAQUETTE"]);
116
117 field.boundary[0] = header["BOUNDARY_1"];
118 field.boundary[1] = header["BOUNDARY_2"];
119 field.boundary[2] = header["BOUNDARY_3"];
120 field.boundary[3] = header["BOUNDARY_4"];
121
122 field.checksum = std::stoul(header["CHECKSUM"],0,16);
123 field.ensemble_id = header["ENSEMBLE_ID"];
124 field.ensemble_label = header["ENSEMBLE_LABEL"];
125 field.sequence_number = std::stol(header["SEQUENCE_NUMBER"]);
126 field.creator = header["CREATOR"];
127 field.creator_hardware = header["CREATOR_HARDWARE"];
128 field.creation_date = header["CREATION_DATE"];
129 field.archive_date = header["ARCHIVE_DATE"];
130 field.floating_point = header["FLOATING_POINT"];
131
132 return field.data_start;
133 }
134
136 // Now the meat: the object readers
138
139 template<class GaugeStats=PeriodicGaugeStatistics>
140 static inline void readConfiguration(GaugeField &Umu,
142 std::string file,
143 GaugeStats GaugeStatisticsCalculator=GaugeStats())
144 {
145
146 GridBase *grid = Umu.Grid();
147 uint64_t offset = readHeader(file,Umu.Grid(),header);
148
149 FieldMetaData clone(header);
150
151 std::string format(header.floating_point);
152
153 const int ieee32big = (format == std::string("IEEE32BIG"));
154 const int ieee32 = (format == std::string("IEEE32"));
155 const int ieee64big = (format == std::string("IEEE64BIG"));
156 const int ieee64 = (format == std::string("IEEE64") || \
157 format == std::string("IEEE64LITTLE"));
158
159 uint32_t nersc_csum,scidac_csuma,scidac_csumb;
160 // depending on datatype, set up munger;
161 // munger is a function of <floating point, Real, data_type>
162 const std::string stNC = std::to_string( Nc ) ;
163 if ( header.data_type == std::string("4D_SU"+stNC+"_GAUGE") ) {
164 if ( ieee32 || ieee32big ) {
167 nersc_csum,scidac_csuma,scidac_csumb);
168 }
169 if ( ieee64 || ieee64big ) {
172 nersc_csum,scidac_csuma,scidac_csumb);
173 }
174 } else if ( header.data_type == std::string("4D_SU"+stNC+"_GAUGE_"+stNC+"x"+stNC) ) {
175 if ( ieee32 || ieee32big ) {
178 nersc_csum,scidac_csuma,scidac_csumb);
179 }
180 if ( ieee64 || ieee64big ) {
183 nersc_csum,scidac_csuma,scidac_csumb);
184 }
185 } else {
186 assert(0);
187 }
188
189 GaugeStats Stats; Stats(Umu,clone);
190
191 std::cout<<GridLogMessage <<"NERSC Configuration "<<file<<" checksum "<<std::hex<<nersc_csum<< std::dec
192 <<" header "<<std::hex<<header.checksum<<std::dec <<std::endl;
193 std::cout<<GridLogMessage <<"NERSC Configuration "<<file<<" plaquette "<<clone.plaquette
194 <<" header "<<header.plaquette<<std::endl;
195 std::cout<<GridLogMessage <<"NERSC Configuration "<<file<<" link_trace "<<clone.link_trace
196 <<" header "<<header.link_trace<<std::endl;
197
198 if ( fabs(clone.plaquette -header.plaquette ) >= 1.0e-5 ) {
199 std::cout << " Plaquette mismatch "<<std::endl;
200 }
201 if ( nersc_csum != header.checksum ) {
202 std::cerr << " checksum mismatch " << std::endl;
203 std::cerr << " plaqs " << clone.plaquette << " " << header.plaquette << std::endl;
204 std::cerr << " trace " << clone.link_trace<< " " << header.link_trace<< std::endl;
205 std::cerr << " nersc_csum " <<std::hex<< nersc_csum << " " << header.checksum<< std::dec<< std::endl;
206 exit(0);
207 }
208 if(exitOnReadPlaquetteMismatch()) assert(fabs(clone.plaquette -header.plaquette ) < 1.0e-5 );
209 assert(fabs(clone.link_trace-header.link_trace) < 1.0e-6 );
210 assert(nersc_csum == header.checksum );
211
212 std::cout<<GridLogMessage <<"NERSC Configuration "<<file<< " and plaquette, link trace, and checksum agree"<<std::endl;
213 }
214
215 // Preferred interface
216 template<class GaugeStats=PeriodicGaugeStatistics>
218 std::string file,
219 std::string ens_label = std::string("DWF"),
220 std::string ens_id = std::string("UKQCD"),
221 unsigned int sequence_number = 1)
222 {
223 writeConfiguration(Umu,file,0,1,ens_label,ens_id,sequence_number);
224 }
225 template<class GaugeStats=PeriodicGaugeStatistics>
227 std::string file,
228 int two_row,
229 int bits32,
230 std::string ens_label = std::string("DWF"),
231 std::string ens_id = std::string("UKQCD"),
232 unsigned int sequence_number = 1)
233 {
234 typedef vLorentzColourMatrixD vobj;
235 typedef typename vobj::scalar_object sobj;
236
238 header.sequence_number = sequence_number;
239 header.ensemble_id = ens_id;
240 header.ensemble_label = ens_label;
241 header.hdr_version = "1.0" ;
242
243 typedef LorentzColourMatrixD fobj3D;
244 typedef LorentzColour2x3D fobj2D;
245
246 GridBase *grid = Umu.Grid();
247
248 GridMetaData(grid,header);
249 assert(header.nd==4);
250 GaugeStats Stats; Stats(Umu,header);
252
253 uint64_t offset;
254
255 // Sod it -- always write NcxNc double
256 header.floating_point = std::string("IEEE64BIG");
257 const std::string stNC = std::to_string( Nc ) ;
258 if( two_row ) {
259 header.data_type = std::string("4D_SU" + stNC + "_GAUGE" );
260 } else {
261 header.data_type = std::string("4D_SU" + stNC + "_GAUGE_" + stNC + "x" + stNC );
262 }
263 if ( grid->IsBoss() ) {
264 truncate(file);
265 offset = writeHeader(header,file);
266 }
267 grid->Broadcast(0,(void *)&offset,sizeof(offset));
268
269 uint32_t nersc_csum,scidac_csuma,scidac_csumb;
270 if( two_row ) {
272 BinaryIO::writeLatticeObject<vobj,fobj2D>(Umu,file,munge,offset,header.floating_point,
273 nersc_csum,scidac_csuma,scidac_csumb);
274 } else {
276 BinaryIO::writeLatticeObject<vobj,fobj3D>(Umu,file,munge,offset,header.floating_point,
277 nersc_csum,scidac_csuma,scidac_csumb);
278 }
279 header.checksum = nersc_csum;
280 if ( grid->IsBoss() ) {
281 writeHeader(header,file);
282 }
283
284 std::cout<<GridLogMessage <<"Written NERSC Configuration on "<< file << " checksum "
285 <<std::hex<<header.checksum
286 <<std::dec<<" plaq "<< header.plaquette <<std::endl;
287
288 }
289
290 // RNG state
292 static inline void writeRNGState(GridSerialRNG &serial,GridParallelRNG &parallel,std::string file)
293 {
294 typedef typename GridParallelRNG::RngStateType RngStateType;
295
296 // Following should become arguments
298 header.sequence_number = 1;
299 header.ensemble_id = "UKQCD";
300 header.ensemble_label = "DWF";
301
302 GridBase *grid = parallel.Grid();
303
304 GridMetaData(grid,header);
305 assert(header.nd==4);
306 header.link_trace=0.0;
307 header.plaquette=0.0;
309
310 uint64_t offset;
311#ifdef RNG_RANLUX
312 header.floating_point = std::string("UINT64");
313 header.data_type = std::string("RANLUX48");
314#endif
315#ifdef RNG_MT19937
316 header.floating_point = std::string("UINT32");
317 header.data_type = std::string("MT19937");
318#endif
319#ifdef RNG_SITMO
320 header.floating_point = std::string("UINT64");
321 header.data_type = std::string("SITMO");
322#endif
323
324 if ( grid->IsBoss() ) {
325 truncate(file);
326 offset = writeHeader(header,file);
327 }
328 grid->Broadcast(0,(void *)&offset,sizeof(offset));
329
330 uint32_t nersc_csum,scidac_csuma,scidac_csumb;
331 BinaryIO::writeRNG(serial,parallel,file,offset,nersc_csum,scidac_csuma,scidac_csumb);
332 header.checksum = nersc_csum;
333 if ( grid->IsBoss() ) {
334 offset = writeHeader(header,file);
335 }
336
337 std::cout<<GridLogMessage
338 <<"Written NERSC RNG STATE "<<file<< " checksum "
339 <<std::hex<<header.checksum
340 <<std::dec<<std::endl;
341
342 }
343
344 static inline void readRNGState(GridSerialRNG &serial,GridParallelRNG & parallel,FieldMetaData& header,std::string file)
345 {
346 typedef typename GridParallelRNG::RngStateType RngStateType;
347
348 GridBase *grid = parallel.Grid();
349
350 uint64_t offset = readHeader(file,grid,header);
351
352 FieldMetaData clone(header);
353
354 std::string format(header.floating_point);
355 std::string data_type(header.data_type);
356
357#ifdef RNG_RANLUX
358 assert(format == std::string("UINT64"));
359 assert(data_type == std::string("RANLUX48"));
360#endif
361#ifdef RNG_MT19937
362 assert(format == std::string("UINT32"));
363 assert(data_type == std::string("MT19937"));
364#endif
365#ifdef RNG_SITMO
366 assert(format == std::string("UINT64"));
367 assert(data_type == std::string("SITMO"));
368#endif
369
370 // depending on datatype, set up munger;
371 // munger is a function of <floating point, Real, data_type>
372 uint32_t nersc_csum,scidac_csuma,scidac_csumb;
373 BinaryIO::readRNG(serial,parallel,file,offset,nersc_csum,scidac_csuma,scidac_csumb);
374
375 if ( nersc_csum != header.checksum ) {
376 std::cerr << "checksum mismatch "<<std::hex<< nersc_csum <<" "<<header.checksum<<std::dec<<std::endl;
377 exit(0);
378 }
379 assert(nersc_csum == header.checksum );
380
381 std::cout<<GridLogMessage <<"Read NERSC RNG file "<<file<< " format "<< data_type <<std::endl;
382 }
383};
384
386
387#endif
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
iLorentzColour2x3< ComplexD > LorentzColour2x3D
Definition MetaData.h:351
void MachineCharacteristics(FieldMetaData &header)
Definition MetaData.h:122
#define dump_meta_data(field, s)
Definition MetaData.h:144
void GridMetaData(GridBase *grid, FieldMetaData &header)
Definition MetaData.h:107
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
iLorentzColourMatrix< vComplexD > vLorentzColourMatrixD
Definition QCD.h:179
static constexpr int Nc
Definition QCD.h:50
iLorentzColourMatrix< ComplexD > LorentzColourMatrixD
Definition QCD.h:175
#define header
static void readRNG(GridSerialRNG &serial_rng, GridParallelRNG &parallel_rng, std::string file, uint64_t offset, uint32_t &nersc_csum, uint32_t &scidac_csuma, uint32_t &scidac_csumb)
Definition BinaryIO.h:647
static void writeRNG(GridSerialRNG &serial_rng, GridParallelRNG &parallel_rng, std::string file, uint64_t offset, uint32_t &nersc_csum, uint32_t &scidac_csuma, uint32_t &scidac_csumb)
Definition BinaryIO.h:714
static void writeLatticeObject(Lattice< vobj > &Umu, std::string file, munger munge, uint64_t offset, const std::string &format, uint32_t &nersc_csum, uint32_t &scidac_csuma, uint32_t &scidac_csumb, int control=BINARYIO_LEXICOGRAPHIC)
Definition BinaryIO.h:580
static void readLatticeObject(Lattice< vobj > &Umu, std::string file, munger munge, uint64_t offset, const std::string &format, uint32_t &nersc_csum, uint32_t &scidac_csuma, uint32_t &scidac_csumb, int control=BINARYIO_LEXICOGRAPHIC)
Definition BinaryIO.h:541
void Broadcast(int root, void *data, int bytes)
Coordinate _fdimensions
GridBase * Grid(void) const
GridBase * Grid(void) const
Lattice< vLorentzColourMatrixD > GaugeField
Definition NerscIO.h:45
static void readRNGState(GridSerialRNG &serial, GridParallelRNG &parallel, FieldMetaData &header, std::string file)
Definition NerscIO.h:344
static void readConfiguration(GaugeField &Umu, FieldMetaData &header, std::string file, GaugeStats GaugeStatisticsCalculator=GaugeStats())
Definition NerscIO.h:140
static void writeConfiguration(Lattice< vLorentzColourMatrixD > &Umu, std::string file, int two_row, int bits32, std::string ens_label=std::string("DWF"), std::string ens_id=std::string("UKQCD"), unsigned int sequence_number=1)
Definition NerscIO.h:226
static void writeRNGState(GridSerialRNG &serial, GridParallelRNG &parallel, std::string file)
Definition NerscIO.h:292
static bool & exitOnReadPlaquetteMismatch()
Definition NerscIO.h:48
static void writeConfiguration(Lattice< vLorentzColourMatrixD > &Umu, std::string file, std::string ens_label=std::string("DWF"), std::string ens_id=std::string("UKQCD"), unsigned int sequence_number=1)
Definition NerscIO.h:217
static int readHeader(std::string file, GridBase *grid, FieldMetaData &field)
Definition NerscIO.h:64
static unsigned int writeHeader(FieldMetaData &field, std::string file)
Definition NerscIO.h:54
static void truncate(std::string file)
Definition NerscIO.h:50
void removeWhitespace(std::string &key)
Definition BinaryIO.h:71