/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/parallelIO/IldgIO.h Copyright (C) 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #ifndef GRID_ILDG_IO_H #define GRID_ILDG_IO_H #include #include #include #include #include #include #include #include #ifdef HAVE_LIME extern "C" { // for linkage #include "lime.h" } namespace Grid { namespace QCD { inline void ILDGGrid(GridBase *grid, ILDGField &header) { assert(grid->_ndimension == 4); // emit error if not header.dimension.resize(4); header.boundary.resize(4); for (int d = 0; d < 4; d++) { header.dimension[d] = grid->_fdimensions[d]; // Read boundary conditions from ... ? header.boundary[d] = std::string("periodic"); } } inline void ILDGChecksum(uint32_t *buf, uint32_t buf_size_bytes, uint32_t &csum) { BinaryIO::Uint32Checksum(buf, buf_size_bytes, csum); } ////////////////////////////////////////////////////////////////////// // Utilities ; these are QCD aware ////////////////////////////////////////////////////////////////////// template inline void ILDGStatistics(GaugeField &data, ILDGField &header) { // How to convert data precision etc... header.link_trace = Grid::QCD::WilsonLoops::linkTrace(data); header.plaquette = Grid::QCD::WilsonLoops::avgPlaquette(data); // header.polyakov = } // Forcing QCD here template struct ILDGMunger { void operator()(fobj &in, sobj &out, uint32_t &csum) { for (int mu = 0; mu < 4; mu++) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { out(mu)()(i, j) = in(mu)()(i, j); } } } ILDGChecksum((uint32_t *)&in, sizeof(in), csum); }; }; template struct ILDGUnmunger { void operator()(sobj &in, fobj &out, uint32_t &csum) { for (int mu = 0; mu < 4; mu++) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { out(mu)()(i, j) = in(mu)()(i, j); } } } ILDGChecksum((uint32_t *)&out, sizeof(out), csum); }; }; //////////////////////////////////////////////////////////////////////////////// // Write and read from fstream; compute header offset for payload //////////////////////////////////////////////////////////////////////////////// enum ILDGstate {ILDGread, ILDGwrite}; class ILDGIO : public BinaryIO { FILE *File; LimeWriter *LimeW; LimeRecordHeader *LimeHeader; LimeReader *LimeR; std::string filename; public: ILDGIO(std::string file, ILDGstate RW) { filename = file; if (RW == ILDGwrite){ File = fopen(file.c_str(), "w"); // check if opened correctly LimeW = limeCreateWriter(File); } else { File = fopen(file.c_str(), "r"); // check if opened correctly LimeR = limeCreateReader(File); } } ~ILDGIO() { fclose(File); } int createHeader(std::string message, int MB, int ME, size_t PayloadSize, LimeWriter* L){ LimeRecordHeader *h; h = limeCreateHeader(MB, ME, const_cast(message.c_str()), PayloadSize); int status = limeWriteRecordHeader(h, L); if (status < 0) { std::cerr << "ILDG Header error\n"; return status; } limeDestroyHeader(h); return LIME_SUCCESS; } unsigned int writeHeader(ILDGField &header) { // write header in LIME n_uint64_t nbytes; int MB_flag = 1, ME_flag = 0; char message[] = "ildg-format"; nbytes = strlen(message); LimeHeader = limeCreateHeader(MB_flag, ME_flag, message, nbytes); limeWriteRecordHeader(LimeHeader, LimeW); limeDestroyHeader(LimeHeader); // save the xml header here // use the xml_writer to c++ streams in pugixml // and convert to char message limeWriteRecordData(message, &nbytes, LimeW); limeWriterCloseRecord(LimeW); return 0; } unsigned int readHeader(ILDGField &header) { return 0; } template uint32_t readConfiguration(Lattice > &Umu) { typedef Lattice > GaugeField; typedef LorentzColourMatrixD sobjd; typedef LorentzColourMatrixF sobjf; typedef iLorentzColourMatrix itype; typedef LorentzColourMatrix sobj; GridBase *grid = Umu._grid; ILDGField header; readHeader(header); // now just the conf, ignore the header std::string format = std::string("IEEE64BIG"); do {limeReaderNextRecord(LimeR);} while (strncmp(limeReaderType(LimeR), "ildg-binary-data",16)); n_uint64_t nbytes = limeReaderBytes(LimeR);//size of this record (configuration) ILDGtype ILDGt(true, LimeR); // this is special for double prec data, just for the moment uint32_t csum = BinaryIO::readObjectParallel< itype, sobjd >( Umu, filename, ILDGMunger(), 0, format, ILDGt); // Check configuration // todo return csum; } template uint32_t writeConfiguration(Lattice > &Umu, std::string format) { typedef Lattice > GaugeField; typedef iLorentzColourMatrix vobj; typedef typename vobj::scalar_object sobj; typedef LorentzColourMatrixD fobj; ILDGField header; // fill the header header.floating_point = format; ILDGUnmunger munge; unsigned int offset = writeHeader(header); BinaryIO::Uint32Checksum(Umu, munge, header.checksum); // Write data record header n_uint64_t PayloadSize = sizeof(fobj) * Umu._grid->_gsites; createHeader("ildg-binary-data", 0, 1, PayloadSize, LimeW); ILDGtype ILDGt(true, LimeW); uint32_t csum = BinaryIO::writeObjectParallel( Umu, filename, munge, 0, header.floating_point, ILDGt); limeWriterCloseRecord(LimeW); // Last record // the logical file name LNF // look into documentation on how to generate this string std::string LNF = "empty"; PayloadSize = sizeof(LNF); createHeader("ildg-binary-lfn", 1 , 1, PayloadSize, LimeW); limeWriteRecordData(const_cast(LNF.c_str()), &PayloadSize, LimeW); limeWriterCloseRecord(LimeW); return csum; } // format for RNG? Now just binary out }; } } //HAVE_LIME #endif #endif