Commit 02812fd7 authored by a.zitz's avatar a.zitz

Flag zur Auswahl der HPC-Architektur wurde eingebaut (ArgumentParser und...

Flag zur Auswahl der HPC-Architektur wurde eingebaut (ArgumentParser und Simulation), manuelle Aufteilung der Arbeit auf die Threads (ForceModel.cpp CalculateForceLC) wurde aufgehoben. Die for-Schleifen laufen jetzt ueber alle Fussgaenger und werden mit dem Pragma omp for versehen.
parent 5e2b4a04
......@@ -43,6 +43,8 @@ Simulation::Simulation() {
_iod = new IODispatcher();
_fps=1;
_em=NULL;
_profiling = false;
_hpc = 0;
}
Simulation::~Simulation() {
......@@ -65,6 +67,7 @@ void Simulation::SetPedsNumber(int i) {
}
/************************************************
// Getter-Funktionen
************************************************/
......@@ -78,6 +81,13 @@ Building * Simulation::GetBuilding() const {
return _building;
}
bool Simulation::GetProfileFlag(){
return _profiling;
}
int Simulation::GetHPCFlag(){
return _hpc;
}
void Simulation::InitArgs(ArgumentParser* args) {
char tmp[CLENGTH];
......@@ -388,10 +398,21 @@ void Simulation::InitArgs(ArgumentParser* args) {
_em->SetProjectRootDir(args->GetProjectRootDir());
_em->readEventsXml();
_em->listEvents();
//profiling enabled?
_profiling = args->GetProfileFlag();
//which hpc-architecture?
_hpc = args->GetHPCFlag();
}
int Simulation::RunSimulation() {
time_t startinitSim, endinitSim, startfirstUpdate, endfirstUpdate, startLoop, endLoop, startSolveODE, endSolveODE, startLoopUpdate, endLoopUpdate, startEventUpdate, endEventUpdate;
double initSimTime, firstUpdateTime, solveODETime = 0.0, loopUpdateTime = 0.0, eventUpdateTime = 0.0, loopTime, upBuilding = 0.0, upPeds = 0.0, upTime = 0.0, upGrid = 0.0;
if(GetProfileFlag()){
time(&startinitSim);
}
int frameNr = 1; // Frame Number
int writeInterval = (int) ((1. / _fps) / _deltaT + 0.5);
writeInterval = (writeInterval <= 0) ? 1 : writeInterval; // mustn't be <= 0
......@@ -403,24 +424,76 @@ int Simulation::RunSimulation() {
_iod->WriteHeader(_nPeds, _fps, _building,_seed);
_iod->WriteGeometry(_building);
_iod->WriteFrame(0,_building);
if(GetProfileFlag()){
time(&endinitSim);
initSimTime = difftime(endinitSim,startinitSim);
}
//first initialisation needed by the linked-cells
Update();
if(GetProfileFlag())
time(&startfirstUpdate);
Update(upBuilding,upPeds,upTime,upGrid);
if(GetProfileFlag()){
time(&endfirstUpdate);
firstUpdateTime = difftime(endfirstUpdate,startfirstUpdate);
}
// main program loop
if(GetProfileFlag()){
time(&startLoop);
solveODETime = 0.0, loopUpdateTime = 0.0, eventUpdateTime = 0.0;
}
for (t = 0; t < _tmax && _nPeds > 0; ++frameNr) {
t = 0 + (frameNr - 1) * _deltaT;
// solve ODE: berechnet Kräfte und setzt neue Werte für x und v
_solver->solveODE(t, t + _deltaT, _building);
// gucken ob Fußgänger in neuen Räumen/Unterräumen
Update();
if(GetProfileFlag())
time(&startSolveODE);
_solver->solveODE(t, t + _deltaT, _building);
if(GetProfileFlag()){
time(&endSolveODE);
solveODETime += difftime(endSolveODE, startSolveODE);
}
// gucken ob Fußgänger in neuen Räumen/Unterräum
if(GetProfileFlag())
time(&startLoopUpdate);
Update(upBuilding,upPeds,upTime,upGrid);
if(GetProfileFlag()){
time(&endLoopUpdate);
loopUpdateTime += difftime(endLoopUpdate, startLoopUpdate);
}
//Eventupdate
if(GetProfileFlag())
time(&startEventUpdate);
_em->Update_Events(t,_deltaT);
if(GetProfileFlag()){
time(&endEventUpdate);
eventUpdateTime += difftime(endEventUpdate, startEventUpdate);
}
// ggf. Ausgabe für TraVisTo
if (frameNr % writeInterval == 0) {
_iod->WriteFrame(frameNr / writeInterval, _building);
}
}
if(GetProfileFlag()){
time(&endLoop);
loopTime = difftime(endLoop,startLoop);
cout << "Messungen in Simulation.cpp: " << endl;
cout << "\tInit Sim [s]: " << initSimTime << endl;
cout << "\tFirst Update [s]: " << firstUpdateTime << endl;
cout << "\tLoop [s]: " << loopTime << endl;
cout << "\tMessungen in der Loop: " << endl;
cout << "\t\tSolve ODE [s]: " << solveODETime << endl;
cout << "\t\tUpdate [s]: " << loopUpdateTime << endl;
cout << "\t\tMessungen in der Update(): " << endl;
cout << "\t\t\tUpdate Building[s]: " << upBuilding << endl;
cout << "\t\t\tUpdate Pedestrians[s]: " << upPeds << endl;
cout << "\t\t\tUpdate GlobalTime[s]: " << upTime << endl;
cout << "\t\t\tUpdate Grid[s]: " << upGrid << endl;
cout << "\t\tEventUpdate [s]: " << eventUpdateTime << endl;
}
// writing the footer
_iod->WriteFooter();
......@@ -430,14 +503,36 @@ int Simulation::RunSimulation() {
// TODO: make the building class more independent by moving the update routing here.
void Simulation::Update() {
void Simulation::Update(double &b, double &p, double &t, double &g) {
time_t startBuilding, endBuilding, startPeds, endPeds, startTime, endTime, startGrid, endGrid;
//_building->Update();
if(GetProfileFlag())
time(&startBuilding);
_building->UpdateVerySlow();
if(GetProfileFlag()){
time(&endBuilding);
// b += difftime(endBuilding,startBuilding);
b += endBuilding-startBuilding;
time(&startPeds);
}
//someone might have leave the building
_nPeds=_building->GetAllPedestrians().size();
if(GetProfileFlag()){
time(&endPeds);
p += difftime(endPeds,startPeds);
time(&startTime);
}
// update the global time
Pedestrian::SetGlobalTime(Pedestrian::GetGlobalTime()+_deltaT);
if(GetProfileFlag()){
time(&endTime);
t += difftime(endTime,startTime);
time(&startGrid);
}
//update the cells position
_building->UpdateGrid();
if(GetProfileFlag()){
time(&endGrid);
g += difftime(endGrid,startGrid);
}
}
......@@ -76,7 +76,8 @@ private:
IODispatcher* _iod;
///new: EventManager
EventManager* _em;
bool _profiling;
int _hpc;
public:
Simulation();
......@@ -117,7 +118,22 @@ public:
/**
* Update the pedestrians states: positions, velocity, route
*/
void Update();
void Update(double &b, double &p, double &t, double &g);
/**
* Set the ProfilingFlag
*/
void SetProfileFlag(bool flag);
/**
* Get the ProfileFlag
*/
bool GetProfileFlag();
/**
* Get the HPCFlag
*/
int GetHPCFlag();
};
......
......@@ -926,6 +926,6 @@ bool ArgumentParser::GetProfileFlag(){
return _profilingFlag;
}
int ArgumentParser::GetHPCFlag()(){
int ArgumentParser::GetHPCFlag(){
return _hpcFlag;
}
......@@ -37,7 +37,6 @@
#define omp_get_thread_num() 0
#define omp_get_max_threads() 1
#endif
using namespace std;
ForceModel::ForceModel() {
......@@ -83,7 +82,7 @@ inline Point GCFMModel::ForceDriv(Pedestrian* ped, Room* room) const {
* Rückgabewerte:
* - Vektor(x,y) mit abstoßender Kraft
* */
Point GCFMModel::ForceRepPed(Pedestrian* ped1, Pedestrian* ped2) const {
inline Point GCFMModel::ForceRepPed(Pedestrian* ped1, Pedestrian* ped2) const {
Point F_rep;
// x- and y-coordinate of the distance between p1 and p2
......@@ -459,42 +458,44 @@ void GCFMModel::CalculateForce(double time, vector< Point >& result_acc, Buildin
void GCFMModel::CalculateForceLC(double time, double tip1, Building* building) const {
double delta = 0.5;
double h = tip1 - time;
double h = tip1 - time;
// collect all pedestrians in the simulation.
const vector< Pedestrian* >& allPeds = building->GetAllPedestrians();
unsigned int nSize = allPeds.size();
unsigned int nSize = allPeds.size();
int nThreads = omp_get_max_threads();
// check if worth sharing the work
if (nSize < 20) nThreads = 1;
int partSize = nSize / nThreads;
if (nSize < 20) nThreads = 1;
int partSize = nSize / nThreads;
vector< Point > result_acc(nSize);
//cout << "openMp startet" << endl;
#pragma omp parallel default(shared) num_threads(nThreads)
{
vector< Point > result_acc = vector<Point > ();
result_acc.reserve(2200);
const int threadID = omp_get_thread_num();
int start = threadID*partSize;
int end = (threadID + 1) * partSize - 1;
if ((threadID == nThreads - 1)) end = nSize - 1;
{
for (int p = start; p <= end; ++p) {
//vector< Point > result_acc = vector<Point > ();
//result_acc.reserve(2200);
const int threadID = omp_get_thread_num();
//cout << threadID << endl;
//int start = threadID*partSize;
//int end = (threadID + 1) * partSize - 1;
//if ((threadID == nThreads - 1)) end = nSize - 1;
//for (int p = start; p <= end; ++p) {
#pragma omp for
for(int p=0;p<nSize;p++){
Pedestrian* ped = allPeds[p];
Room* room = building->GetRoom(ped->GetRoomID());
SubRoom* subroom = room->GetSubRoom(ped->GetSubRoomID());
double normVi = ped->GetV().ScalarP(ped->GetV());
double tmp = (ped->GetV0Norm() + delta) * (ped->GetV0Norm() + delta);
if (normVi > tmp && ped->GetV0Norm() > 0) {
fprintf(stderr, "GCFMModel::calculateForce() WARNING: actual velocity (%f) of iped %d "
"is bigger than desired velocity (%f) at time: %fs\n",
sqrt(normVi), ped->GetID(), ped->GetV0Norm(), time);
sqrt(normVi), ped->GetID(), ped->GetV0Norm(), time);////time statt t
// remove the pedestrian and abort
for(int p=0;p<subroom->GetNumberOfPedestrians();p++){
......@@ -510,13 +511,12 @@ void GCFMModel::CalculateForceLC(double time, double tip1, Building* building) c
// continue;
exit(EXIT_FAILURE);
}
//cout << threadID << ": nach der if." << endl;
Point F_rep;
vector<Pedestrian*> neighbours;
building->GetGrid()->GetNeighbourhood(ped,neighbours);
int nSize=neighbours.size();
for (int i = 0; i < nSize; i++) {
int NSize=neighbours.size();
for (int i = 0; i < NSize; i++) {
Pedestrian* ped1 = neighbours[i];
//if they are in the same subroom
if (ped->GetUniqueRoomID() == ped1->GetUniqueRoomID()) {
......@@ -534,14 +534,20 @@ void GCFMModel::CalculateForceLC(double time, double tip1, Building* building) c
Point repwall = ForceRepRoom(allPeds[p], subroom);
Point acc = (ForceDriv(ped, room) + F_rep + repwall) / ped->GetMass();
result_acc.push_back(acc);
}
//result_acc.push_back(acc);
// cout << threadID << " " << result_acc.begin()+2 << ": " << nSize << endl;
//#pragma omp barrier
result_acc[p]=acc;
}
//cout << threadID << ": erste for geschafft." << endl;
#pragma omp barrier
// update
for (int p = start; p <= end; ++p) {
//for (int p = start; p <= end; ++p) {
#pragma omp for
for (int p = 0; p < nSize; p++) {
Pedestrian* ped = allPeds[p];
Point v_neu = ped->GetV() + result_acc[p - start] * h;
//Point v_neu = ped->GetV() + result_acc[p - start] * h;
Point v_neu = ped->GetV() + result_acc[p] * h;
Point pos_neu = ped->GetPos() + v_neu * h;
//Jam is based on the current velocity
......@@ -555,6 +561,6 @@ void GCFMModel::CalculateForceLC(double time, double tip1, Building* building) c
ped->SetV(v_neu);
ped->SetPhiPed();
}
}//end parallel
}//end parallel
//cout << "openmp endet" << endl;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment