Newer
Older
MpiSimulation::MpiSimulation(int& argc, char**& argv) {
Body b[2];
int blocklengths[7] = {1, 3, 3, 3, 1, 1, 1};
MPI::Datatype datatypes[7] = {MPI::LB, MPI::DOUBLE, MPI::DOUBLE, MPI::DOUBLE, MPI::DOUBLE, MPI::BOOL, MPI::UB};
MPI::Aint displacements[7];
this->bodyType = MPI::DATATYPE_NULL;
//MPI::Init(argc, argv);
displacements[0] = MPI::Get_address(&(b[0])) - MPI::Get_address(&(b[0]));
displacements[1] = MPI::Get_address(&(b[0].position[0])) - MPI::Get_address(&(b[0]));
displacements[2] = MPI::Get_address(&(b[0].velocity[0])) - MPI::Get_address(&(b[0]));
displacements[3] = MPI::Get_address(&(b[0].acceleration[0])) - MPI::Get_address(&(b[0]));
displacements[4] = MPI::Get_address(&(b[0].mass)) - MPI::Get_address(&(b[0]));
displacements[5] = MPI::Get_address(&(b[0].refinement)) - MPI::Get_address(&(b[0]));
displacements[6] = MPI::Get_address(&(b[1])) - MPI::Get_address(&(b[0]));
this->bodyType = this->bodyType.Create_struct(7, blocklengths, displacements, datatypes);
this->bodyType.Commit();
this->mpiSize = MPI::COMM_WORLD.Get_size();
this->mpiRank = MPI::COMM_WORLD.Get_rank();
this->correctState = true;
/*
//number of (array) elements in struct elements
//dataytypes with lower bound and upper bound adresses of the structure
MPI::Datatype datatypes[7] = {MPI::LB, MPI::DOUBLE, MPI::DOUBLE, MPI::DOUBLE, MPI::DOUBLE, MPI::BOOL, MPI::UB};
MPI::Aint displacements[7];
this->mpiSize = MPI::COMM_WORLD.Get_size();
this->mpiRank = MPI::COMM_WORLD.Get_rank();
//displacements are calculated from the start of the structure
displacements[0] = MPI::Get_address(&(b[0])) - MPI::Get_address(&(b[0]));
displacements[1] = MPI::Get_address(&(b[0].position[0])) - MPI::Get_address(&(b[0]));
displacements[2] = MPI::Get_address(&(b[0].velocity[0])) - MPI::Get_address(&(b[0]));
displacements[3] = MPI::Get_address(&(b[0].acceleration[0])) - MPI::Get_address(&(b[0]));
displacements[4] = MPI::Get_address(&(b[0].mass)) - MPI::Get_address(&(b[0]));
displacements[5] = MPI::Get_address(&(b[0].refinement)) - MPI::Get_address(&(b[0]));
displacements[6] = MPI::Get_address(&(b[1])) - MPI::Get_address(&(b[0]));
this->bodyType = this->bodyType.Create_struct(7, blocklengths, displacements, datatypes);
this->bodyType.Commit();
if (argc == 2) {
this->correctState = this->readInputData(string(argv[1]));
} else {
this->correctState = false;
MPI::COMM_WORLD.Bcast(&this->correctState, 1, MPI::BOOL, 0);
if (!this->correctState) {
cerr << "Error occurred: terminating ..." << endl;
this->bodyType.Free();
MPI::Finalize();
exit(-1);
}
if (this->mpiRank == 0) {
MPI::COMM_WORLD.Send(b, 2, this->bodyType, 1, 0);
} else if (this->mpiRank == 1) {
MPI::COMM_WORLD.Recv(b, 2, this->bodyType, 0, 0);
}
}
bool MpiSimulation::readInputData(string filename) {
if (this->mpiRank == 0) {
this->bodies = Tree::dubinskiParse(filename);
if (this->bodies.empty()) {
return false;
}
}
return true;
void MpiSimulation::cleanup() {
while (!this->comms.empty()) {
this->comms.back().cleanup();
this->comms.pop_back();
}
bool MpiSimulation::stateCorrect() {
return this->correctState;
int MpiSimulation::getNumberOfProcesses() {
return this->mpiSize;
}
int MpiSimulation::getProcessId() {
return this->mpiRank;
}
MPI::Datatype* MpiSimulation::getDatatype() {
return &this->bodyType;
}
void MpiSimulation::distributeBodies() {
if (this->mpiRank == 0) {
nodes.push_back(Node(NULL));
nodes.front().setBodies(this->bodies);
bb = nodes.front().getBB();
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
nodes.front().setBB(bb);
while (nodes.size() < this->mpiSize) {
int mostBodiesIndex = 0;
for (unsigned int i = 0; i < nodes.size(); i++) {
if (nodes[i].getBodies().size() > nodes[mostBodiesIndex].getBodies().size()) {
mostBodiesIndex = i;
}
}
vector<Box> subdomains = nodes[mostBodiesIndex].getBB().splitLongestSide();
vector<Body> buf = nodes[mostBodiesIndex].getBodies();
Node n(NULL);
Box bb;
n.setBodies(subdomains[0].extractBodies(buf));
bb.extendForBodies(n.getBodies());
n.setBB(bb);
nodes.insert(nodes.begin() + mostBodiesIndex, n);
n = Node(NULL);
n.setBodies(subdomains[1].extractBodies(buf));
bb.extendForBodies(n.getBodies());
n.setBB(bb);
nodes.insert(nodes.begin() + mostBodiesIndex, n);
nodes.erase(nodes.begin() + mostBodiesIndex + 2);
}
this->bodies = nodes[0].getBodies();
for (unsigned int i = 0; i < nodes.size(); i++) {
cout << i << ": " << nodes[i].getBodies().size() << endl;
}
for (unsigned int i = 1; i < nodes.size(); i++) {
this->comms.push_back(MpiBodyComm(&this->bodyType));
this->comms.back().sendBlocking(i, nodes[i].getBodies());
/*
//vector<MpiBodyComm>::iterator it = this->comms.begin();
//while (!it->sendUnblocking(i, nodes[i].getBodies()) && it != this->comms.end()) it++;
if (it == this->comms.end()) {
this->comms.push_back(MpiBodyComm(&this->bodyType));
this->comms.back().sendUnblocking(i, nodes[i].getBodies());
it->sendBlocking(i, nodes[i].getBodies());
*/
this->comms.push_back(MpiBodyComm(&this->bodyType));
this->comms[0].recvBlocking(0, this->bodies);
cout << this->mpiRank << ": SIZE: " << this->bodies.size() << endl;