#ifndef Benchmark_IO_hpp_ #define Benchmark_IO_hpp_ #include #ifdef HAVE_LIME #define MSG std::cout << GridLogMessage #define SEP \ "=============================================================================" namespace Grid { template using WriterFn = std::function ; template using ReaderFn = std::function; // AP 06/10/2020: Standard C version in case one is suspicious of the C++ API // // template // void stdWrite(const std::string filestem, Field &vec) // { // std::string rankStr = std::to_string(vec.Grid()->ThisRank()); // std::FILE *file = std::fopen((filestem + "." + rankStr + ".bin").c_str(), "wb"); // size_t size; // uint32_t crc; // GridStopWatch ioWatch, crcWatch; // size = vec.Grid()->lSites()*sizeof(typename Field::scalar_object); // autoView(vec_v, vec, CpuRead); // crcWatch.Start(); // crc = GridChecksum::crc32(vec_v.cpu_ptr, size); // std::fwrite(&crc, sizeof(uint32_t), 1, file); // crcWatch.Stop(); // MSG << "Std I/O write: Data CRC32 " << std::hex << crc << std::dec << std::endl; // ioWatch.Start(); // std::fwrite(vec_v.cpu_ptr, sizeof(typename Field::scalar_object), vec.Grid()->lSites(), file); // ioWatch.Stop(); // std::fclose(file); // size *= vec.Grid()->ProcessorCount(); // MSG << "Std I/O write: Wrote " << size << " bytes in " << ioWatch.Elapsed() // << ", performance " << size/1024./1024./(ioWatch.useconds()/1.e6) // << " MB/s" << std::endl; // MSG << "Std I/O write: checksum overhead " << crcWatch.Elapsed() << std::endl; // } // // template // void stdRead(Field &vec, const std::string filestem) // { // std::string rankStr = std::to_string(vec.Grid()->ThisRank()); // std::FILE *file = std::fopen((filestem + "." + rankStr + ".bin").c_str(), "rb"); // size_t size; // uint32_t crcRead, crcData; // GridStopWatch ioWatch, crcWatch; // size = vec.Grid()->lSites()*sizeof(typename Field::scalar_object); // crcWatch.Start(); // std::fread(&crcRead, sizeof(uint32_t), 1, file); // crcWatch.Stop(); // { // autoView(vec_v, vec, CpuWrite); // ioWatch.Start(); // std::fread(vec_v.cpu_ptr, sizeof(typename Field::scalar_object), vec.Grid()->lSites(), file); // ioWatch.Stop(); // std::fclose(file); // } // { // autoView(vec_v, vec, CpuRead); // crcWatch.Start(); // crcData = GridChecksum::crc32(vec_v.cpu_ptr, size); // crcWatch.Stop(); // } // MSG << "Std I/O read: Data CRC32 " << std::hex << crcData << std::dec << std::endl; // assert(crcData == crcRead); // size *= vec.Grid()->ProcessorCount(); // MSG << "Std I/O read: Read " << size << " bytes in " << ioWatch.Elapsed() // << ", performance " << size/1024./1024./(ioWatch.useconds()/1.e6) // << " MB/s" << std::endl; // MSG << "Std I/O read: checksum overhead " << crcWatch.Elapsed() << std::endl; // } template void stdWrite(const std::string filestem, Field &vec) { std::string rankStr = std::to_string(vec.Grid()->ThisRank()); std::ofstream file(filestem + "." + rankStr + ".bin", std::ios::out | std::ios::binary); size_t size, sizec; uint32_t crc; GridStopWatch ioWatch, crcWatch; size = vec.Grid()->lSites()*sizeof(typename Field::scalar_object); sizec = size/sizeof(char); // just in case of... autoView(vec_v, vec, CpuRead); crcWatch.Start(); crc = GridChecksum::crc32(vec_v.cpu_ptr, size); file.write(reinterpret_cast(&crc), sizeof(uint32_t)/sizeof(char)); crcWatch.Stop(); MSG << "Std I/O write: Data CRC32 " << std::hex << crc << std::dec << std::endl; ioWatch.Start(); file.write(reinterpret_cast(vec_v.cpu_ptr), sizec); file.flush(); ioWatch.Stop(); size *= vec.Grid()->ProcessorCount(); MSG << "Std I/O write: Wrote " << size << " bytes in " << ioWatch.Elapsed() << ", " << size/1024./1024./(ioWatch.useconds()/1.e6) << " MB/s" << std::endl; MSG << "Std I/O write: checksum overhead " << crcWatch.Elapsed() << std::endl; } template void stdRead(Field &vec, const std::string filestem) { std::string rankStr = std::to_string(vec.Grid()->ThisRank()); std::ifstream file(filestem + "." + rankStr + ".bin", std::ios::in | std::ios::binary); size_t size, sizec; uint32_t crcRead, crcData; GridStopWatch ioWatch, crcWatch; size = vec.Grid()->lSites()*sizeof(typename Field::scalar_object); sizec = size/sizeof(char); // just in case of... crcWatch.Start(); file.read(reinterpret_cast(&crcRead), sizeof(uint32_t)/sizeof(char)); crcWatch.Stop(); { autoView(vec_v, vec, CpuWrite); ioWatch.Start(); file.read(reinterpret_cast(vec_v.cpu_ptr), sizec); ioWatch.Stop(); } { autoView(vec_v, vec, CpuRead); crcWatch.Start(); crcData = GridChecksum::crc32(vec_v.cpu_ptr, size); crcWatch.Stop(); } MSG << "Std I/O read: Data CRC32 " << std::hex << crcData << std::dec << std::endl; assert(crcData == crcRead); size *= vec.Grid()->ProcessorCount(); MSG << "Std I/O read: Read " << size << " bytes in " << ioWatch.Elapsed() << ", " << size/1024./1024./(ioWatch.useconds()/1.e6) << " MB/s" << std::endl; MSG << "Std I/O read: checksum overhead " << crcWatch.Elapsed() << std::endl; } template void limeWrite(const std::string filestem, Field &vec) { emptyUserRecord record; ScidacWriter binWriter(vec.Grid()->IsBoss()); binWriter.open(filestem + ".lime.bin"); binWriter.writeScidacFieldRecord(vec, record); binWriter.close(); } template void limeRead(Field &vec, const std::string filestem) { emptyUserRecord record; ScidacReader binReader; binReader.open(filestem + ".lime.bin"); binReader.readScidacFieldRecord(vec, record); binReader.close(); } inline void makeGrid(std::shared_ptr &gPt, const std::shared_ptr &gBasePt, const unsigned int Ls = 1, const bool rb = false) { if (rb) { if (Ls > 1) { gPt.reset(SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, gBasePt.get())); } else { gPt.reset(SpaceTimeGrid::makeFourDimRedBlackGrid(gBasePt.get())); } } else { if (Ls > 1) { gPt.reset(SpaceTimeGrid::makeFiveDimGrid(Ls, gBasePt.get())); } else { gPt = gBasePt; } } } template void writeBenchmark(const Coordinate &latt, const std::string filename, const WriterFn &write, const unsigned int Ls = 1, const bool rb = false) { auto mpi = GridDefaultMpi(); auto simd = GridDefaultSimd(latt.size(), Field::vector_type::Nsimd()); std::shared_ptr gBasePt(SpaceTimeGrid::makeFourDimGrid(latt, simd, mpi)); std::shared_ptr gPt; makeGrid(gPt, gBasePt, Ls, rb); GridBase *g = gPt.get(); GridParallelRNG rng(g); Field vec(g); random(rng, vec); write(filename, vec); } template void readBenchmark(const Coordinate &latt, const std::string filename, const ReaderFn &read, const unsigned int Ls = 1, const bool rb = false) { auto mpi = GridDefaultMpi(); auto simd = GridDefaultSimd(latt.size(), Field::vector_type::Nsimd()); std::shared_ptr gBasePt(SpaceTimeGrid::makeFourDimGrid(latt, simd, mpi)); std::shared_ptr gPt; makeGrid(gPt, gBasePt, Ls, rb); GridBase *g = gPt.get(); Field vec(g); read(vec, filename); } } #endif //LIME #endif // Benchmark_IO_hpp_