#pragma once #include #include #include #include "gsl/gsl" #include "Util.hpp" #include "state.hpp" struct FileIO { static auto ReadHeader(std::istream& input) { std::size_t noCols{}; std::size_t noRows{}; input >> noCols >> noRows; if (noCols < 1 || noRows < 1) throw std::logic_error("File header corrupt"); std::string dummy; // skip line break std::getline(input, dummy); const auto& headerSize = input.tellg(); return Size{noCols, noRows}; } static auto GetTileSize(Size globalSize, Size gridSize) { const auto& tileSizeCols = globalSize.Cols / gridSize.Cols; const auto& tileSizeRows = globalSize.Rows / gridSize.Rows; return Size{tileSizeCols, tileSizeRows}; } static void StridedRead(std::istream& input, std::size_t inputChunkLength, std::size_t count, std::size_t inputStride, gsl::span buf, std::size_t bufStride) { std::size_t writeOffset{0}; for (size_t i{0}; i < count; ++i) { input.read(reinterpret_cast(buf.data()) + writeOffset, inputChunkLength); input.seekg(inputStride - inputChunkLength, std::ios::cur); writeOffset += bufStride; } } static void ReadTile(std::istream& input, Size srcSize, Size gridSize, std::size_t rank, gsl::span buf, std::size_t bufStride) { constexpr auto LF = 1; // linefeed chars const auto& tileSize = GetTileSize(srcSize, gridSize); const auto& tileX = rank % gridSize.Cols; const auto& tileY = rank / gridSize.Cols; // seek to the begin of the tile const auto& displacement = (srcSize.Cols + LF) * (tileSize.Rows * tileY) + (tileSize.Cols * tileX); input.seekg(displacement, std::ios::cur); const auto& tileStride = srcSize.Cols + LF; StridedRead(input, tileSize.Cols, tileSize.Rows, tileStride, buf, bufStride); } };