Newer
Older
#pragma once
#include <cstddef>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
#include "gsl/gsl"
#include "Util.hpp"
#include "state.hpp"
struct FileIO {
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<char, HeaderBufSize> 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();
{noCols, noRows},
static_cast<std::size_t>(
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};
}
static void ReadTileData(const std::string& path, std::size_t headerLength,
Size srcSize, Size gridSize, std::size_t rank,
gsl::span<State> 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_File_read_all(file, buf.data(), 1, bufType.type(),
MPI_STATUS_IGNORE);