Newer
Older
#include "Configuration.hpp"
#include "FileIO.hpp"
#include "MpiEnvironment.hpp"
#include "Util.hpp"
#include "state.hpp"
class Tile {
const MpiEnvironment& _env;
const Configuration& _cfg;
const HeaderInfo _header;
const Size _tileSize;
std::vector<State> _memoryA;
std::vector<State> _memoryB;
gsl::multi_span<State, -1, -1> _model;
gsl::multi_span<State, -1, -1> _nextModel;
Tile(const Configuration& cfg, const MpiEnvironment& env)
: _env(env), _cfg(cfg),
_header(FileIO::ReadHeader(cfg.InputFilePath)), //
_tileSize(FileIO::GetTileSize(_header.GlobalSize, cfg.Grid)) {
if ((_header.GlobalSize.Cols % _tileSize.Cols) != 0 ||
(_header.GlobalSize.Rows % _tileSize.Rows) != 0) {
std::cerr
<< "Wireworld size is not even divisible by the grid size.\n";
MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
}
const auto bufsize = (_tileSize.Cols + 2) * (_tileSize.Rows + 2);
_memoryA.resize(bufsize);
_memoryB.resize(bufsize);
_model =
gsl::as_multi_span(_memoryA.data(), gsl::dim(_tileSize.Rows + 2),
gsl::dim(_tileSize.Cols + 2));
_nextModel =
gsl::as_multi_span(_memoryB.data(), gsl::dim(_tileSize.Rows + 2),
gsl::dim(_tileSize.Cols + 2));
FileIO::Tile(cfg.InputFilePath, _header, cfg.Grid, _env.worldRank(),
gsl::span<State>(_model))
.Read();
if (env.worldRank() == 0)
std::cout << "Tilesitze: cols:" << _tileSize.Cols
<< ", rows: " << _tileSize.Rows << "\n";
public:
auto& model() { return _model; }
auto& model() const { return _model; }
auto& nextModel() { return _nextModel; }
auto tileSize() const { return _tileSize; }
static auto Read(const Configuration& cfg, const MpiEnvironment& env) {
return Tile{cfg, env};
}
void write() const {
const auto& path = _cfg.OutputFilePath;
FileIO::WriteHeader(_header, path, _env);
FileIO::Tile(path, _header, _cfg.Grid, _env.worldRank(),
gsl::span<State>(_model))
.Write();
}
};
std::ostream& operator<<(std::ostream& out, const Tile& t) {
out << '+';
std::fill_n(std::ostream_iterator<char>(out), length, '-');
out << "+\n";
};
hline(out, t.tileSize().Cols);
for (std::size_t x{1}; x <= t.tileSize().Rows; ++x) {
out << '|';
for (std::size_t y{1}; y <= t.tileSize().Cols; ++y) {
out << to_integral(t.model()[x][y]);
}
out << "|\n";
}
hline(out, t.tileSize().Cols);
return out;
}