Page MenuHomec4science

simu.hh
No OneTemporary

File Metadata

Created
Mon, Nov 4, 10:06
#ifndef SIMU_HH
#define SIMU_HH
#include "client.hh"
#include "grid.hh"
#include <iostream>
#include <mpi.h>
#include <omp.h>
/* -------------------------------------------------------------------------- */
class Simu {
public:
Simu(long int dims[2], int ghost, bool periodic = true,
MPI_Comm global_comm = MPI_COMM_WORLD)
: _ghost(ghost), sender(NULL), _world(global_comm), periodic(periodic) {
int psize, prank;
MPI_Comm_size(_world, &psize);
MPI_Comm_rank(_world, &prank);
int nprocs[2] = {0, 0};
int periods[2] = {periodic, periodic};
MPI_Dims_create(psize, 2, nprocs);
MPI_Cart_create(MPI_COMM_WORLD, 2, nprocs, periods, true, &_neigbours);
MPI_Cart_coords(_neigbours, prank, 2, _coords);
long int local_dims[2];
long int offsets[2] = {0, 0};
for (int i = 0; i < 2; ++i) {
int mod = dims[i] % nprocs[i];
local_dims[i] = dims[i] / nprocs[i];
offsets[i] =
local_dims[i] * _coords[i] + (_coords[i] < mod ? _coords[i] : mod);
local_dims[i] += (_coords[i] < mod ? 1 : 0);
}
_grid = new Grid(local_dims, dims, offsets, ghost);
_old_grid = new Grid(*_grid);
_grid->initalizeCommunicationRequests(_neigbours, _coords);
_old_grid->initalizeCommunicationRequests(_neigbours, _coords);
if (prank == 0) {
std::cout << "Grid " << _old_grid->globalSize() << " -- ["
<< _old_grid->globalSize(0) << ", " << _old_grid->globalSize(1)
<< "]" << std::endl;
}
for (int p = 0; p < psize; ++p) {
if (p == prank)
std::cout << "Local grid " << prank << " - " << _old_grid->size()
<< " -- [" << _old_grid->size(0) << ", " << _old_grid->size(1)
<< "]"
<< "+ [" << _old_grid->offset(0) << ", "
<< _old_grid->offset(1) << "]" << std::endl;
MPI_Barrier(_world);
}
}
Simu(long int dims[2], int ghost, bool periodic,
MPI_Comm global_comm,
const std::string & server, int port = 4321)
: Simu(dims, ghost, periodic, global_comm) {
int psize, prank;
MPI_Comm_size(_world, &psize);
MPI_Comm_rank(_world, &prank);
sender = new GridSender(*_old_grid);
sender->setParallelContext(prank, psize);
sender->connect(server, port);
}
virtual ~Simu() { delete sender; }
virtual void determineCells(int tid) {
#pragma omp single nowait
_old_grid->commAll();
#pragma omp for schedule(runtime)
for (long int j = _ghost; j < _grid->size(1) - _ghost; j++) {
for (long int i = _ghost; i < _grid->size(0) - _ghost; i++) {
this->determineCell(i, j, tid);
}
}
#pragma omp single
_old_grid->waitRecv();
#pragma omp for schedule(runtime)
for (long int i = 0; i < _grid->size(0); i++) {
this->determineCell(i, 0, tid);
this->determineCell(i, _grid->size(1) - 1, tid);
}
#pragma omp for schedule(runtime)
for (long int j = 0; j < _grid->size(1); j++) {
this->determineCell(0, j, tid);
this->determineCell(_grid->size(0) - 1, j, tid);
}
#pragma omp single
_old_grid->waitSend();
}
virtual void determineCell(long int i, long int j, int tid) = 0;
virtual void initialState(bool random) = 0;
void swap() { _grid->swap(*_old_grid); }
void send() { if(sender) sender->send(); }
void recv() { if(sender) sender->recv_update(); }
GridSender & getSender() { return *sender; }
protected:
long int _ghost;
Grid * _grid;
Grid * _old_grid;
GridSender * sender;
MPI_Comm _world;
MPI_Comm _neigbours;
int _coords[2];
bool periodic;
};
#endif /* SIMU_HH */

Event Timeline