Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#pragma once
#include <cstddef>
#include <fstream>
#include <string>
#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<State> buf, std::size_t bufStride) {
std::size_t writeOffset{0};
for (size_t i{0}; i < count; ++i) {
input.read(reinterpret_cast<char*>(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<State> 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);
}
};