diff --git a/Grid/parallelIO/BinaryIO.h b/Grid/parallelIO/BinaryIO.h index 17f2bc13e..d586472a2 100644 --- a/Grid/parallelIO/BinaryIO.h +++ b/Grid/parallelIO/BinaryIO.h @@ -262,6 +262,16 @@ class BinaryIO { static const int BINARYIO_READ = 0x02; static const int BINARYIO_WRITE = 0x01; + // Single point of control for the aggregated path. Setting + // GRID_BINARYIO_NOAGGREGATE falls back to plain lexicographic I/O. + static int DefaultControl(void) + { + static int ctrl = getenv("GRID_BINARYIO_NOAGGREGATE") + ? BINARYIO_LEXICOGRAPHIC + : BINARYIO_LEXICOGRAPHIC|BINARYIO_AGGREGATE; + return ctrl; + } + #ifdef USE_MPI_IO ///////////////////////////////////////////////////////////////////////////// // Aggregation: self controlled transposition onto an I/O friendly layout. @@ -989,7 +999,7 @@ class BinaryIO { uint32_t &nersc_csum, uint32_t &scidac_csuma, uint32_t &scidac_csumb, - int control=BINARYIO_LEXICOGRAPHIC|BINARYIO_AGGREGATE + int control=DefaultControl() ) { typedef typename vobj::scalar_object sobj; @@ -1028,7 +1038,7 @@ class BinaryIO { uint32_t &nersc_csum, uint32_t &scidac_csuma, uint32_t &scidac_csumb, - int control=BINARYIO_LEXICOGRAPHIC|BINARYIO_AGGREGATE) + int control=DefaultControl()) { typedef typename vobj::scalar_object sobj; typedef typename vobj::Realified::scalar_type word; word w=0; @@ -1115,7 +1125,7 @@ class BinaryIO { std::cout << GridLogMessage << "RNG read I/O on file " << file << std::endl; std::vector iodata(lsites); - IOobject(w,grid,iodata,file,offset,format,BINARYIO_READ|BINARYIO_LEXICOGRAPHIC|BINARYIO_AGGREGATE, + IOobject(w,grid,iodata,file,offset,format,BINARYIO_READ|DefaultControl(), nersc_csum,scidac_csuma,scidac_csumb); timer.Start(); @@ -1194,7 +1204,7 @@ class BinaryIO { }); timer.Stop(); - IOobject(w,grid,iodata,file,offset,format,BINARYIO_WRITE|BINARYIO_LEXICOGRAPHIC|BINARYIO_AGGREGATE, + IOobject(w,grid,iodata,file,offset,format,BINARYIO_WRITE|DefaultControl(), nersc_csum,scidac_csuma,scidac_csumb); iodata.resize(1); { diff --git a/Grid/parallelIO/MetaData.h b/Grid/parallelIO/MetaData.h index 1fc3fe31d..284a9c7f1 100644 --- a/Grid/parallelIO/MetaData.h +++ b/Grid/parallelIO/MetaData.h @@ -180,7 +180,7 @@ template class GaugeStatistics { public: - void operator()(Lattice & data,FieldMetaData &header) + void operator()(typename Impl::Field & data,FieldMetaData &header) { header.link_trace = WilsonLoops::linkTrace(data); header.plaquette = WilsonLoops::avgPlaquette(data); @@ -188,13 +188,24 @@ public: }; typedef GaugeStatistics PeriodicGaugeStatistics; typedef GaugeStatistics ConjugateGaugeStatistics; +typedef GaugeStatistics lexPeriodicGaugeStatistics; +typedef GaugeStatistics lexConjugateGaugeStatistics; template<> inline void PrepareMetaData(Lattice & field, FieldMetaData &header) { GridBase *grid = field.Grid(); std::string format = getFormatString(); header.floating_point = format; header.checksum = 0x0; // Nersc checksum unused in ILDG, Scidac - GridMetaData(grid,header); + GridMetaData(grid,header); + MachineCharacteristics(header); +} +template<> inline void PrepareMetaData(Lattice & field, FieldMetaData &header) +{ + GridBase *grid = field.Grid(); + std::string format = getFormatString(); + header.floating_point = format; + header.checksum = 0x0; // Nersc checksum unused in ILDG, Scidac + GridMetaData(grid,header); MachineCharacteristics(header); } diff --git a/Grid/parallelIO/NerscIO.h b/Grid/parallelIO/NerscIO.h index 5b2066cc7..7545552d1 100644 --- a/Grid/parallelIO/NerscIO.h +++ b/Grid/parallelIO/NerscIO.h @@ -136,12 +136,14 @@ public: // Now the meat: the object readers ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - template - static inline void readConfiguration(GaugeField &Umu, - FieldMetaData& header, - std::string file, - GaugeStats GaugeStatisticsCalculator=GaugeStats()) + template + static inline void readConfigurationInternal(GaugeFieldType &Umu, + FieldMetaData& header, + std::string file, + GaugeStats GaugeStatisticsCalculator) { + typedef typename GaugeFieldType::vector_object vobj; + typedef typename GaugeFieldType::scalar_object sobj; GridBase *grid = Umu.Grid(); uint64_t offset = readHeader(file,Umu.Grid(),header); @@ -162,24 +164,24 @@ public: const std::string stNC = std::to_string( Nc ) ; if ( header.data_type == std::string("4D_SU"+stNC+"_GAUGE") ) { if ( ieee32 || ieee32big ) { - BinaryIO::readLatticeObject - (Umu,file,Gauge3x2munger(), offset,format, + BinaryIO::readLatticeObject + (Umu,file,Gauge3x2munger(), offset,format, nersc_csum,scidac_csuma,scidac_csumb); } if ( ieee64 || ieee64big ) { - BinaryIO::readLatticeObject - (Umu,file,Gauge3x2munger(),offset,format, + BinaryIO::readLatticeObject + (Umu,file,Gauge3x2munger(),offset,format, nersc_csum,scidac_csuma,scidac_csumb); } } else if ( header.data_type == std::string("4D_SU"+stNC+"_GAUGE_"+stNC+"x"+stNC) ) { if ( ieee32 || ieee32big ) { - BinaryIO::readLatticeObject - (Umu,file,GaugeSimpleMunger(),offset,format, + BinaryIO::readLatticeObject + (Umu,file,GaugeSimpleMunger(),offset,format, nersc_csum,scidac_csuma,scidac_csumb); } if ( ieee64 || ieee64big ) { - BinaryIO::readLatticeObject - (Umu,file,GaugeSimpleMunger(),offset,format, + BinaryIO::readLatticeObject + (Umu,file,GaugeSimpleMunger(),offset,format, nersc_csum,scidac_csuma,scidac_csumb); } } else { @@ -198,12 +200,11 @@ public: if ( fabs(clone.plaquette -header.plaquette ) >= 1.0e-5 ) { std::cout << " Plaquette mismatch "< + static inline void readConfiguration(Lattice &Umu, + FieldMetaData& header, + std::string file, + GaugeStats GaugeStatisticsCalculator=GaugeStats()) + { + readConfigurationInternal(Umu,header,file,GaugeStatisticsCalculator); + } + template + static inline void readConfiguration(Lattice &Umu, + FieldMetaData& header, + std::string file, + GaugeStats GaugeStatisticsCalculator=GaugeStats()) + { + readConfigurationInternal(Umu,header,file,GaugeStatisticsCalculator); + } + // Preferred interface template static inline void writeConfiguration(Lattice &Umu, @@ -220,7 +241,16 @@ public: std::string ens_id = std::string("UKQCD"), unsigned int sequence_number = 1) { - writeConfiguration(Umu,file,0,1,ens_label,ens_id,sequence_number); + writeConfigurationInternal,GaugeStats>(Umu,file,0,1,ens_label,ens_id,sequence_number); + } + template + static inline void writeConfiguration(Lattice &Umu, + std::string file, + std::string ens_label = std::string("DWF"), + std::string ens_id = std::string("UKQCD"), + unsigned int sequence_number = 1) + { + writeConfigurationInternal,GaugeStats>(Umu,file,0,1,ens_label,ens_id,sequence_number); } template static inline void writeConfiguration(Lattice &Umu, @@ -231,7 +261,29 @@ public: std::string ens_id = std::string("UKQCD"), unsigned int sequence_number = 1) { - typedef vLorentzColourMatrixD vobj; + writeConfigurationInternal,GaugeStats>(Umu,file,two_row,bits32,ens_label,ens_id,sequence_number); + } + template + static inline void writeConfiguration(Lattice &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) + { + writeConfigurationInternal,GaugeStats>(Umu,file,two_row,bits32,ens_label,ens_id,sequence_number); + } + template + static inline void writeConfigurationInternal(GaugeFieldType &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) + { + typedef typename GaugeFieldType::vector_object vobj; typedef typename vobj::scalar_object sobj; FieldMetaData header; @@ -277,9 +329,12 @@ public: nersc_csum,scidac_csuma,scidac_csumb); } header.checksum = nersc_csum; - if ( grid->IsBoss() ) { + if ( grid->IsBoss() ) { writeHeader(header,file); } + // The header is written twice; the checksum is only known after the data. + // Other ranks must not proceed to read it until the rewrite has landed. + grid->Barrier(); std::cout<IsBoss() ) { + if ( grid->IsBoss() ) { offset = writeHeader(header,file); } + // As for the gauge field: the checksum is only known after the data, so + // the header is rewritten. Hold the other ranks until that has landed. + grid->Barrier(); - std::cout<