not crashing
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
|
||||
#include "game_of_life.h"
|
||||
|
||||
GameOfLife::GameOfLife(const Matrix& grid, MPIGridSize mpiProcs)
|
||||
GameOfLife::GameOfLife(const SuperGrid &grid, MPIGridSize mpiProcs)
|
||||
: grid_(grid), mpiProcs_(mpiProcs) {}
|
||||
|
||||
void GameOfLife::step() {
|
||||
Matrix next = Matrix::zeros(grid_.rows(), grid_.cols());
|
||||
SuperGrid next = SuperGrid::zeros(grid_.rows(), grid_.cols());
|
||||
const int rows = grid_.rows();
|
||||
const int cols = grid_.cols();
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
@@ -25,9 +24,9 @@ int GameOfLife::countLiveNeighbors(int row, int col) const {
|
||||
for (int i = -1; i <= 1; ++i) {
|
||||
for (int j = -1; j <= 1; ++j) {
|
||||
if (i == 0 && j == 0)
|
||||
continue; // Skip the cell itself
|
||||
int nextRow = (row + i + rows) % rows; // Wrap around
|
||||
int nextCol = (col + j + cols) % cols; // Wrap around
|
||||
continue; // Skip the cell itself
|
||||
int nextRow = (row + i + rows) % rows; // Wrap around
|
||||
int nextCol = (col + j + cols) % cols; // Wrap around
|
||||
if (grid_(nextRow, nextCol) == 1) {
|
||||
count++;
|
||||
}
|
||||
@@ -47,10 +46,6 @@ int GameOfLife::updateCell(int currentState, int numLiveNeighbors) const {
|
||||
}
|
||||
}
|
||||
|
||||
Matrix GameOfLife::getGrid() const {
|
||||
return grid_;
|
||||
}
|
||||
Matrix GameOfLife::getGrid() const { return grid_.get_matrix(); }
|
||||
|
||||
MPIGridSize GameOfLife::mpiProcs() const {
|
||||
return mpiProcs_;
|
||||
}
|
||||
MPIGridSize GameOfLife::mpiProcs() const { return mpiProcs_; }
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
#ifndef GAME_OF_LIFE_H
|
||||
#define GAME_OF_LIFE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <mpi.h>
|
||||
#include <vector>
|
||||
|
||||
#include "common.h"
|
||||
#include "matrix.h"
|
||||
#include "super_grid.h"
|
||||
|
||||
class GameOfLife {
|
||||
public:
|
||||
GameOfLife(const Matrix& grid, MPIGridSize mpiProcs);
|
||||
public:
|
||||
GameOfLife(const SuperGrid &grid, MPIGridSize mpiProcs);
|
||||
|
||||
void step();
|
||||
|
||||
@@ -21,12 +22,12 @@ class GameOfLife {
|
||||
|
||||
MPIGridSize mpiProcs() const;
|
||||
|
||||
private:
|
||||
private:
|
||||
int countLiveNeighbors(int row, int col) const;
|
||||
|
||||
int updateCell(int currentState, int numLiveNeighbors) const;
|
||||
|
||||
Matrix grid_;
|
||||
SuperGrid grid_;
|
||||
MPIGridSize mpiProcs_;
|
||||
int myRank_ = 0;
|
||||
|
||||
@@ -35,4 +36,4 @@ class GameOfLife {
|
||||
friend class GameOfLifeTest;
|
||||
};
|
||||
|
||||
#endif // GAME_OF_LIFE_H
|
||||
#endif // GAME_OF_LIFE_H
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <mpi.h>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
#include "game_of_life.h"
|
||||
#include "patterns.h"
|
||||
#include "matrix_io.h"
|
||||
#include "utils.h"
|
||||
#include "common.h"
|
||||
#include "game_of_life.h"
|
||||
#include "matrix_io.h"
|
||||
#include "patterns.h"
|
||||
#include "super_grid.h"
|
||||
#include "utils.h"
|
||||
|
||||
/**
|
||||
* Main function to run the simulation of the game of life
|
||||
@@ -19,12 +20,12 @@ void gameOfLife(MPIGridSize mpiProcs) {
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
|
||||
|
||||
// Create a grid that results in some interesting patterns
|
||||
const Matrix grid = Pattern(20, 40, mpiProcs)
|
||||
.glider(10, 17)
|
||||
.beeHive(7, 10)
|
||||
.octagon(6, 27)
|
||||
.octagon(12, 0)
|
||||
.getGrid();
|
||||
const SuperGrid grid = Pattern(20, 40, mpiProcs)
|
||||
.glider(10, 17)
|
||||
.beeHive(7, 10)
|
||||
.octagon(6, 27)
|
||||
.octagon(12, 0)
|
||||
.getGrid();
|
||||
|
||||
GameOfLife game(grid, mpiProcs);
|
||||
|
||||
@@ -40,7 +41,7 @@ void gameOfLife(MPIGridSize mpiProcs) {
|
||||
std::cout << "Final state" << std::endl;
|
||||
print(game);
|
||||
|
||||
storeAnimation("output", grid, 150, mpiProcs);
|
||||
storeAnimation("output", grid.get_matrix(), 150, mpiProcs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,7 +49,7 @@ void gameOfLife(MPIGridSize mpiProcs) {
|
||||
* Initializes MPI, checks command line arguments, and starts the game of life
|
||||
* simulation.
|
||||
*/
|
||||
int main(int argc, char* argv[]) {
|
||||
int main(int argc, char *argv[]) {
|
||||
MPI_Init(&argc, &argv);
|
||||
if (argc != 3) {
|
||||
std::cout << "Specify number of processes in x and y as arguments\n";
|
||||
@@ -70,11 +71,11 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
try {
|
||||
gameOfLife({np0, np1});
|
||||
} catch (const std::exception& e) {
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
MPI_Abort(MPI_COMM_WORLD, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
MPI_Finalize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@ test:
|
||||
mpicxx $(SOURCE_FILES) test.cpp -g -o game_of_life_test ${COMPILER_FLAGS}
|
||||
mpirun -np 16 --oversubscribe ./game_of_life_test
|
||||
|
||||
tests:
|
||||
mpicxx $(SOURCE_FILES) test.cpp -g -o game_of_life_test ${COMPILER_FLAGS}
|
||||
mpirun -np 1 --oversubscribe ./game_of_life_test
|
||||
|
||||
runserial:
|
||||
mpirun -np 1 ./$(PROGRAM_NAME) 1 1
|
||||
|
||||
@@ -30,4 +34,4 @@ run: release
|
||||
mpirun -np 16 --oversubscribe ./$(PROGRAM_NAME) 4 4
|
||||
|
||||
ani: animate.py
|
||||
python3 animate.py
|
||||
python3 animate.py
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "patterns.h"
|
||||
|
||||
Pattern::Pattern(int rows, int cols, MPIGridSize mpiProcs)
|
||||
: mpiProcs_(mpiProcs), grid_(Matrix::zeros(rows / np0(), cols / np1())) {
|
||||
: mpiProcs_(mpiProcs), grid_(SuperGrid::zeros(rows / np0(), cols / np1())) {
|
||||
if (rows <= 0 || cols <= 0) {
|
||||
throw std::invalid_argument("Rows and columns must be positive");
|
||||
}
|
||||
@@ -87,7 +87,7 @@ Pattern Pattern::octagon(int row, int col) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix Pattern::getGrid() const { return grid_; }
|
||||
SuperGrid Pattern::getGrid() const { return grid_; }
|
||||
|
||||
Pattern Pattern::setCell(int globalRow, int globalCol) {
|
||||
if (globalRow < 0 || globalCol < 0 || globalRow >= numRowsTotal() ||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#ifndef PATTERNS_H
|
||||
#define PATTERNS_H
|
||||
|
||||
#include <memory>
|
||||
#include <array>
|
||||
#include <mpi.h>
|
||||
#include "matrix.h"
|
||||
#include "common.h"
|
||||
#include "matrix.h"
|
||||
#include "super_grid.h"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <mpi.h>
|
||||
|
||||
/**
|
||||
* Class to create some patterns for the Game of Life.
|
||||
@@ -20,10 +21,10 @@
|
||||
* Pattern pattern(20, 40, comm).glider(10, 17).getGrid();
|
||||
*/
|
||||
class Pattern {
|
||||
public:
|
||||
public:
|
||||
Pattern(int rows, int cols, MPIGridSize mpiProcs);
|
||||
|
||||
Matrix getGrid() const;
|
||||
SuperGrid getGrid() const;
|
||||
|
||||
Pattern setCell(int globalRow, int globalCol);
|
||||
|
||||
@@ -33,7 +34,7 @@ class Pattern {
|
||||
|
||||
Pattern octagon(int row, int col);
|
||||
|
||||
private:
|
||||
private:
|
||||
int numRowsLocal() const;
|
||||
int numRowsTotal() const;
|
||||
int numColsLocal() const;
|
||||
@@ -43,9 +44,9 @@ class Pattern {
|
||||
int np1() const;
|
||||
|
||||
MPIGridSize mpiProcs_;
|
||||
Matrix grid_;
|
||||
SuperGrid grid_;
|
||||
|
||||
MPI_Comm comm_;
|
||||
MPI_Comm comm_;
|
||||
};
|
||||
|
||||
#endif // PATTERNS_H
|
||||
#endif // PATTERNS_H
|
||||
|
||||
@@ -7,23 +7,48 @@ class SuperGrid {
|
||||
public:
|
||||
static SuperGrid zeros(int rows, int cols);
|
||||
|
||||
SuperGrid(const Matrix &other);
|
||||
|
||||
double &operator()(int i, int j);
|
||||
const double &operator()(int i, int j) const;
|
||||
|
||||
const Matrix get_matrix() const;
|
||||
|
||||
int rows() const;
|
||||
int cols() const;
|
||||
double &operator()(int i, int j);
|
||||
|
||||
private:
|
||||
Matrix grid_;
|
||||
};
|
||||
|
||||
inline SuperGrid SuperGrid::zeros(int rows, int cols)
|
||||
: grid_(Matrix::zeros(rows + 2, cols + 2)), {}
|
||||
inline SuperGrid::SuperGrid(const Matrix &other) : grid_(other) {}
|
||||
|
||||
inline SuperGrid SuperGrid::zeros(int rows, int cols) {
|
||||
return SuperGrid(Matrix::zeros(rows + 2, cols + 2));
|
||||
}
|
||||
|
||||
inline double &SuperGrid::operator()(int i, int j) {
|
||||
return this->grid_(i + 1, j + 1);
|
||||
}
|
||||
|
||||
inline const double &SuperGrid::operator()(int i, int j) const {
|
||||
return this->grid_(i + 1, j + 1);
|
||||
}
|
||||
|
||||
inline int SuperGrid::rows() const { return this->grid_.rows() - 2; }
|
||||
|
||||
inline int SuperGrid::cols() const { return this->grid_.cols() - 2; }
|
||||
|
||||
inline const Matrix SuperGrid::get_matrix() const {
|
||||
Matrix mat = Matrix::zeros(this->rows(), this->cols());
|
||||
|
||||
for (int i = 0; i < this->rows(); i++) {
|
||||
for (int j = 0; j < this->rows(); j++) {
|
||||
mat(i, j) = this->grid_(i + 1, j + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
#endif // SUPER_GRID_H
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "common.h"
|
||||
#include "game_of_life.h"
|
||||
#include "matrix.h"
|
||||
#include "utils.h"
|
||||
|
||||
Matrix init_step(Matrix start) {
|
||||
GameOfLife gol = GameOfLife(start, MPIGridSize());
|
||||
@@ -21,7 +22,10 @@ TEST(test_survive_2) {
|
||||
start(0, 0) = 1;
|
||||
start(0, 1) = 1;
|
||||
start(1, 0) = 1;
|
||||
|
||||
print(start);
|
||||
Matrix end = init_step(start);
|
||||
print(end);
|
||||
check(end(0, 0), 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "utils.h"
|
||||
#include "matrix.h"
|
||||
|
||||
void clearOrCreateFolder(const std::string& foldername) {
|
||||
void clearOrCreateFolder(const std::string &foldername) {
|
||||
namespace fs = std::filesystem;
|
||||
fs::path folder(foldername);
|
||||
if (fs::exists(folder)) {
|
||||
@@ -21,7 +22,7 @@ void clearOrCreateFolder(const std::string& foldername) {
|
||||
|
||||
std::cout << "Clearing folder '" << foldername << "'...\n";
|
||||
// Clear the folder
|
||||
for (const auto& entry : fs::directory_iterator(folder)) {
|
||||
for (const auto &entry : fs::directory_iterator(folder)) {
|
||||
if (fs::is_directory(entry)) {
|
||||
fs::remove_all(entry);
|
||||
} else if (fs::is_regular_file(entry)) {
|
||||
@@ -35,10 +36,8 @@ void clearOrCreateFolder(const std::string& foldername) {
|
||||
}
|
||||
}
|
||||
|
||||
void storeAnimation(const std::string& foldername,
|
||||
const Matrix& initstate,
|
||||
int numSteps,
|
||||
MPIGridSize mpiProcs) {
|
||||
void storeAnimation(const std::string &foldername, const Matrix &initstate,
|
||||
int numSteps, MPIGridSize mpiProcs) {
|
||||
GameOfLife game(initstate, mpiProcs);
|
||||
|
||||
MatrixIO io(mpiProcs);
|
||||
@@ -67,7 +66,7 @@ void storeAnimation(const std::string& foldername,
|
||||
}
|
||||
}
|
||||
|
||||
void print(const GameOfLife& game) {
|
||||
void print(const GameOfLife &game) {
|
||||
MatrixIO io(game.mpiProcs());
|
||||
Matrix grid = io.gatherMatrixOnRoot(game.getGrid());
|
||||
|
||||
@@ -81,4 +80,13 @@ void print(const GameOfLife& game) {
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print(Matrix &grid) {
|
||||
for (int i = 0; i < grid.rows(); ++i) {
|
||||
for (int j = 0; j < grid.cols(); ++j) {
|
||||
std::cout << ((grid(i, j) == 1) ? "X " : ". ");
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
#include "game_of_life.h"
|
||||
#include "matrix_io.h"
|
||||
#include "matrix.h"
|
||||
#include "common.h"
|
||||
#include "game_of_life.h"
|
||||
#include "matrix.h"
|
||||
#include "matrix_io.h"
|
||||
|
||||
/**
|
||||
* Clears the contents of a folder or create it if it does not exist.
|
||||
@@ -17,7 +17,7 @@
|
||||
* all folder contents are removed.
|
||||
* If the folder does not exist, it is created.
|
||||
*/
|
||||
void clearOrCreateFolder(const std::string& foldername);
|
||||
void clearOrCreateFolder(const std::string &foldername);
|
||||
|
||||
/**
|
||||
* Stores the animation of the Game of Life in a bunch of text files.
|
||||
@@ -25,12 +25,12 @@ void clearOrCreateFolder(const std::string& foldername);
|
||||
* where <n> is the step number.
|
||||
* The files are stored in the specified folder.
|
||||
*/
|
||||
void storeAnimation(const std::string& foldername,
|
||||
const Matrix& initstate,
|
||||
int numSteps,
|
||||
MPIGridSize mpiProcs);
|
||||
void storeAnimation(const std::string &foldername, const Matrix &initstate,
|
||||
int numSteps, MPIGridSize mpiProcs);
|
||||
|
||||
/** Print the current grid of the game on the console */
|
||||
void print(const GameOfLife& game);
|
||||
void print(const GameOfLife &game);
|
||||
|
||||
#endif // UTILS_H
|
||||
void print(Matrix &matrix);
|
||||
|
||||
#endif // UTILS_H
|
||||
|
||||
Reference in New Issue
Block a user