#pragma once #include #include #include #include #include #include "gsl/gsl" #include "MpiSubarray.hpp" #include "Util.hpp" #include "state.hpp" struct FileIO { struct HeaderInfo { Size GlobalSize; std::size_t HeaderLength; }; static auto ReadHeader(const std::string& path) { // read the header into a buf (20 should be sufficient) MPI_File fh; MPI_File_open(MPI_COMM_SELF, path.c_str(), MPI_MODE_RDONLY | MPI_MODE_UNIQUE_OPEN, MPI_INFO_NULL, &fh); constexpr auto HeaderBufSize = 20; std::array buf; MPI_File_read_all(fh, buf.data(), buf.size(), MPI_CHAR, MPI_STATUS_IGNORE); MPI_File_close(&fh); // make stream out of buf std::istringstream input; input.rdbuf()->pubsetbuf(buf.data(), buf.size()); // parse the stream std::size_t noCols{}; std::size_t noRows{}; input >> noCols >> noRows; if (noCols < 1 || noRows < 1) { std::cerr << "File header corrupt\n"; MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } std::string dummy; // skip line break std::getline(input, dummy); const auto& headerLength = input.tellg(); return HeaderInfo{ {noCols, noRows}, static_cast( headerLength) // should fit (is max HeaderBuf size) }; } // TODO: is not an IO concern 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}; } // should return a Tile?? static void ReadTileData(const std::string& path, std::size_t headerLength, Size srcSize, Size gridSize, std::size_t rank, gsl::span buf) { constexpr auto LF = 1; // linefeed chars const auto& tileSize = GetTileSize(srcSize, gridSize); const auto& tileX = rank % gridSize.Cols; const auto& tileY = rank / gridSize.Cols; const auto& tileType = MpiSubarray({{srcSize.Rows, tileSize.Rows, 0}, {srcSize.Cols + LF, tileSize.Cols, 0}}); const auto& bufType = MpiSubarray({{tileSize.Rows + 2, tileSize.Rows, 1}, {tileSize.Cols + 2, tileSize.Cols, 1}}); // read MPI_File file; MPI_File_open(MPI_COMM_WORLD, path.c_str(), MPI_MODE_RDONLY | MPI_MODE_UNIQUE_OPEN, MPI_INFO_NULL, &file); const auto displ = headerLength + (srcSize.Cols + LF) * tileSize.Rows * tileY + tileSize.Cols * tileX; MPI_File_set_view(file, displ, MPI_CHAR, tileType.type(), "native", MPI_INFO_NULL); MPI_File_read_all(file, buf.data(), 1, bufType.type(), MPI_STATUS_IGNORE); } };