/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./tests/IO/Test_field_array_io.cc Copyright (C) 2015 Author: Christopher Kelly Author: Peter Boyle 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 */ #include using namespace std; using namespace Grid; //This test demonstrates and checks a single-file write of an arbitrary array of fields uint64_t writeHeader(const uint32_t size, const uint32_t checksum, const std::string &format, const std::string &file){ std::ofstream fout(file,std::ios::out|std::ios::in); fout.seekp(0,std::ios::beg); fout << std::setw(10) << size << std::endl; fout << std::hex << std::setw(10) << checksum << std::endl; fout << format << std::endl; return fout.tellp(); } uint64_t readHeader(uint32_t &size, uint32_t &checksum, std::string &format, const std::string &file){ std::ifstream fin(file); std::string line; getline(fin,line); { std::stringstream ss; ss <> size; } getline(fin,line); { std::stringstream ss; ss <> std::hex >> checksum; } getline(fin,format); removeWhitespace(format); return fin.tellg(); } template void writeFieldArray(const std::string &file, const std::vector &data){ typedef typename FieldType::vector_object vobj; typedef typename FieldType::scalar_object sobj; GridBase* grid = data[0].Grid(); //assume all fields have the same Grid BinarySimpleMunger munge; //straight copy //We need a 2-pass header write, first to establish the size, the second pass writes the checksum std::string format = getFormatString(); uint64_t offset; //leave 64 bits for header if ( grid->IsBoss() ) { NerscIO::truncate(file); offset = writeHeader(data.size(), 0, format, file); } grid->Broadcast(0,(void *)&offset,sizeof(offset)); //use as a barrier std::cout << "Data offset write " << offset << std::endl; std::cout << "Data size write " << data.size() << std::endl; uint64_t field_size = uint64_t(grid->gSites()) * sizeof(sobj); std::cout << "Field size = " << field_size << " B" << std::endl; uint32_t checksum = 0; for(int i=0;i(const_cast(data[i]),file,munge,offset,format, nersc_csum,scidac_csuma,scidac_csumb); offset += field_size; checksum ^= nersc_csum + 0x9e3779b9 + (checksum<<6) + (checksum>>2); } std::cout << "Write checksum " << checksum << std::endl; if ( grid->IsBoss() ) { writeHeader(data.size(), checksum, format, file); } } template void readFieldArray(std::vector &data, const std::string &file){ typedef typename FieldType::vector_object vobj; typedef typename FieldType::scalar_object sobj; assert(data.size() > 0); GridBase* grid = data[0].Grid(); //assume all fields have the same Grid BinarySimpleUnmunger munge; //straight copy uint32_t hdr_checksum, hdr_size; std::string format; uint64_t offset = readHeader(hdr_size, hdr_checksum, format, file); std::cout << "Data offset read " << offset << std::endl; std::cout << "Data size read " << hdr_size << std::endl; assert(data.size() == hdr_size); uint64_t field_size = uint64_t(grid->gSites()) * sizeof(sobj); uint32_t checksum = 0; for(int i=0;i(data[i],file,munge,offset,format, nersc_csum,scidac_csuma,scidac_csumb); offset += field_size; checksum ^= nersc_csum + 0x9e3779b9 + (checksum<<6) + (checksum>>2); } std::cout << "Header checksum " << hdr_checksum << std::endl; std::cout << "Read checksum " << checksum << std::endl; assert( hdr_checksum == checksum ); } int main (int argc, char ** argv) { Grid_init(&argc,&argv); Coordinate latt = GridDefaultLatt(); Coordinate simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd()); Coordinate mpi_layout = GridDefaultMpi(); const int Ls=8; GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(latt, simd_layout, mpi_layout); GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); std::vector seeds4({1,2,3,4}); std::vector seeds5({5,6,7,8}); GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5); GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4); typedef DomainWallFermionD::FermionField FermionField; int nfield = 20; std::vector data(nfield, FGrid); for(int i=0;i data_r(nfield, FGrid); readFieldArray(data_r, file); for(int i=0;i