Commit ba786ec7 authored by Johannes Leins's avatar Johannes Leins
Browse files

made Benchmark class a Singleton and changed benchmark output marks

parent f8221fb9
......@@ -9,7 +9,7 @@
#define SRC_BENCHMARK_H_
#include <chrono>
#include <unordered_map>
#include <map>
#include <iostream>
#include <time.h>
#include <date.h>
......@@ -22,13 +22,20 @@ using namespace std::chrono;
class Benchmark {
private:
Benchmark(bool active = false);
Benchmark(Benchmark const& other) = delete;
Benchmark(Benchmark&& other) = delete;
virtual ~Benchmark();
bool active;
unordered_map<long, pair<milliseconds,milliseconds>> marks;
map<long, pair<milliseconds,milliseconds>> marks;
protected:
static long NEXT_ID;
public:
Benchmark(bool active = false);
virtual ~Benchmark();
static Benchmark& getInstance()
{
static Benchmark instance;
return instance;
}
bool flick();
long mark(long ID = -1);
void stop(long ID);
......
......@@ -175,6 +175,8 @@ namespace Constants
Point(20,34),Point(21,34),Point(22,34),Point(23,34),Point(24,34),Point(25,34),Point(26,34),Point(27,34),
Point(21,35),Point(22,35),Point(23,35),Point(24,35),Point(25,35),Point(26,35),Point(29,35),Point(30,35),Point(31,35)
});
extern Benchmark BENCHMARK();
}
......
......@@ -26,6 +26,7 @@
#include <vector>
#include <string>
#include "Point.h"
#include "Benchmark.h"
enum GlobalModel {
CCCma, CNRM, ICHEC, MIROC, MOHC, MPI
......
......@@ -151,21 +151,27 @@ Climate* Environment::getClimate() {
}
Measure* Environment::getMeasure(Point coord) {
vector<int> timing;
Measure* measure = new Measure(Constants::NAME_DISTURBANCE_NONE, timing);
if(uniformDisturbances && fixedDisturbanceCoords.find(coord) == fixedDisturbanceCoords.end()) {
auto itMeasuresAtCoord = activeMeasures.find(coord);
if(itMeasuresAtCoord != activeMeasures.end()) {
auto itMeasures = itMeasuresAtCoord->second.find(uniformDisturbanceName);
if(itMeasures != itMeasuresAtCoord->second.end()) {
return itMeasures->second;
measure = itMeasures->second;
}
}
} else {
if(cellsByCoord.find(coord) != cellsByCoord.end()) {
return cellsByCoord[coord]->getMeasure();
Benchmark::getInstance().mark(1000101);
if(activeCellsByCoord.find(coord) != activeCellsByCoord.end()) {
measure = activeCellsByCoord[coord]->getMeasure();
}
else if(cellsByCoord.find(coord) != cellsByCoord.end()) {
measure = cellsByCoord[coord]->getMeasure();
}
Benchmark::getInstance().stop(1000101);
}
vector<int> timing;
return new Measure(Constants::NAME_DISTURBANCE_NONE, timing);
return measure;
}
bool Environment::hasDisturbanceScheduled(Point coord) {
......@@ -175,8 +181,14 @@ bool Environment::hasDisturbanceScheduled(Point coord) {
float Environment::getValue(ClimateVariable climVar, Point coord) {
return climate->getValue(climVar, timestep, indexTime, cellsByCoord[coord]);
// return climate->getValue(climVar, indexTime, coord);
Benchmark::getInstance().mark(1014350);
Cell* cell = activeCellsByCoord[coord];
if(cell == NULL) {
cell = cellsByCoord[coord];
}
float value = climate->getValue(climVar, timestep, indexTime, cell);
Benchmark::getInstance().stop(1014350);
return value;
}
void Environment::setDisturbanceAt(Point coord, string disturbanceName) {
......@@ -192,7 +204,9 @@ void Environment::setDisturbanceAt(Point coord, string disturbanceName) {
if(itMeasuresAtCoord != measures.end()) {
auto itMeasures = itMeasuresAtCoord->second.find(disturbanceName);
if(itMeasures != itMeasuresAtCoord->second.end()) {
Benchmark::getInstance().mark(1011001);
cellsByCoord[coord]->setMeasure(itMeasures->second);
Benchmark::getInstance().stop(1011001);
}
}
}
......@@ -201,7 +215,10 @@ string Environment::getDisturbanceAt(Point coord) {
if(uniformDisturbances && fixedDisturbanceCoords.find(coord) == fixedDisturbanceCoords.end()) {
return uniformDisturbanceName;
}
return cellsByCoord[coord]->getMeasure()->getName();
Benchmark::getInstance().mark(1000104);
string distName = cellsByCoord[coord]->getMeasure()->getName();
Benchmark::getInstance().mark(1000104);
return distName;
}
void Environment::clearDisturbances() {
......@@ -210,6 +227,7 @@ void Environment::clearDisturbances() {
fixedDisturbanceCoords.clear();
measures.clear();
activeMeasures.clear();
activeCellsByCoord.clear();
for(auto cellAt : cellsByCoord) {
cellAt.second->setMeasure(); // sets empty measure
}
......@@ -378,37 +396,47 @@ void Environment::addActiveNeighbor(string key, Point activeNeighbor) {
if(activeNeighborhoods.find(key) != activeNeighborhoods.end()) {
activeNeighborhood = activeNeighborhoods[key];
}
Benchmark::getInstance().mark(1000105);
if(activeNeighborhood.find(activeNeighbor) == activeNeighborhood.end()) {
activeNeighborhood[activeNeighbor] = neighborhoods[key].at(activeNeighbor);
}
activeNeighborhoods[key] = activeNeighborhood;
if(activeMeasures.find(activeNeighbor) == activeMeasures.end()) {
activeMeasures[activeNeighbor] = measures.at(activeNeighbor);
activeCellsByCoord[activeNeighbor] = cellsByCoord.at(activeNeighbor);
}
Benchmark::getInstance().stop(1000105);
activeNeighborhoods[key] = activeNeighborhood;
}
void Environment::removeActiveNeighbor(string key, Point activeNeighbor) {
activeNeighborhoods[key].erase(activeNeighbor);
if(activeNeighborhoods[key].size() == 0) {
activeMeasures.erase(activeNeighbor);
activeCellsByCoord.erase(activeNeighbor);
}
}
void Environment::addActiveNeighbors(string key, unordered_set<Point> activeNeighbors) {
unordered_map<Point, Population*> activeNeighborhood;
Benchmark::getInstance().mark(1013210);
if(activeNeighborhoods.find(key) != activeNeighborhoods.end()) {
Benchmark::getInstance().mark(1013211);
activeNeighborhood = activeNeighborhoods[key];
Benchmark::getInstance().stop(1013211);
}
Benchmark::getInstance().stop(1013210);
Benchmark::getInstance().mark(1013220);
for(auto activeNeighbor : activeNeighbors) {
if(activeNeighborhood.find(activeNeighbor) == activeNeighborhood.end()) {
Benchmark::getInstance().mark(1013221);
activeNeighborhood[activeNeighbor] = neighborhoods[key].at(activeNeighbor);
}
if(activeMeasures.find(activeNeighbor) == activeMeasures.end()) {
activeMeasures[activeNeighbor] = measures.at(activeNeighbor);
activeCellsByCoord[activeNeighbor] = cellsByCoord.at(activeNeighbor);
Benchmark::getInstance().stop(1013221);
}
}
Benchmark::getInstance().stop(1013220);
Benchmark::getInstance().mark(1013230);
activeNeighborhoods[key] = activeNeighborhood;
Benchmark::getInstance().stop(1013230);
}
unordered_map<Point, Population*> Environment::getActiveNeighborhood(string key) {
......
......@@ -29,6 +29,7 @@
#include <map>
#include <unordered_map>
#include "Disturbance.h"
#include "Benchmark.h"
// forward declaration to prevent circular inclusion
class Population;
......@@ -42,6 +43,7 @@ class Environment
private:
Climate* climate;
unordered_map<Point, Cell*> cellsByCoord;
unordered_map<Point, Cell*> activeCellsByCoord;
unordered_set<Point> grasslandCoords;
unsigned int minX = std::numeric_limits<int>::max();
unsigned int minY = std::numeric_limits<int>::max();
......
......@@ -130,32 +130,44 @@ vector<LifeStage*> Population::getStages() {
unordered_set<Point> Population::updateFlows(Environment* environment) {
Benchmark::getInstance().mark(1013101);
for(auto flow : immigrationFlows) {
flow->update(environment);
}
Benchmark::getInstance().stop(1013101);
unordered_set<Point> activatedNeighbors;
if(vitality == DEAD) {
return activatedNeighbors;
}
Benchmark::getInstance().mark(1013102);
for(auto flow : flowsByType[REPRODUCTION]) {
flow->update(environment);
}
Benchmark::getInstance().stop(1013102);
vector<Flow*> flowsMigr = flowsByType[MIGRATION];
Benchmark::getInstance().mark(1013103);
shuffle(flowsMigr.begin(), flowsMigr.end(), *(environment->getRandGenLocal(atts->getCoord())));
Benchmark::getInstance().stop(1013103);
Benchmark::getInstance().mark(1013104);
for(auto flow : flowsMigr) {
if(flow->update(environment)) {
activatedNeighbors.insert(flow->getTo()->getAtts()->getCoord());
}
}
Benchmark::getInstance().stop(1013104);
Benchmark::getInstance().mark(1013105);
for(auto flow : flowsByType[MORTALITY]) {
flow->update(environment);
}
Benchmark::getInstance().stop(1013105);
Benchmark::getInstance().mark(1013106);
for(auto flow : flowsByType[TRANSFER]) {
flow->update(environment);
}
Benchmark::getInstance().stop(1013106);
return activatedNeighbors;
}
......
......@@ -58,7 +58,6 @@ const vector<ClimateScenario*> climateScenarios = {
// technical application run parameters
bool memorySavingMode = false; // year climate data preload only
Benchmark benchmark;
// input file handler
CSVHandlerDisturbance* handlerDisturbances;
......@@ -579,6 +578,11 @@ bool handleDisturbances() {
for(auto coord : fixedCells) {
distByCoord[coord] = handlerScheme->getDisturbanceNameAt(coord);
}
if(grasslandCells.size() == fixedCells.size()) { //if all cells are fixed, only create one scheme
nameBaseScheme = "fixed";
disturbanceSchemes[nameBaseScheme] = distByCoord;
break;
}
disturbanceSchemes[distName] = distByCoord;
iDist++;
}
......@@ -1314,7 +1318,7 @@ bool handleArgs(int argc, char** argv) {
dailyPrint = true;
}
else if (arg == "--benchmark") { // run in prognosis mode applying all disturbance scenarios in unfixed cells of scheme
benchmark.flick();
Benchmark::getInstance().flick();
}
else {
cout << "ERROR: invalid command line parameter '" << arg << "' defined. Printing help page" << endl;;
......@@ -1540,6 +1544,7 @@ bool setup() {
int batchRun() {
// get current timestamp from system clock
runID = runID < 0 ? static_cast<long int>(time(NULL)) : runID;
auto& benchmark = Benchmark::getInstance();
// BEGIN create output folders
const char* folderNameOutput = "output";
......@@ -1682,19 +1687,21 @@ int batchRun() {
int nAliveTotal = 0;
int nAlivePrevTotal = 0;
// TODO load next time frame if not the full time slice is looped
benchmark.mark(1);
Benchmark::getInstance().mark(1010000);
for (auto disturbanceScheme : disturbanceSchemes) { // loop over each disturbance scheme
benchmark.mark(10);
Benchmark::getInstance().mark(1011000);
disturbanceSchemeName = disturbanceScheme.first;
for(auto lastSchemeCoord : lastSchemeCoords) {
environment->setDisturbanceAt(lastSchemeCoord, baseDisturbanceScheme[lastSchemeCoord]);
}
Benchmark::getInstance().stop(1011000);
lastSchemeCoords.clear();
if(nAlivePrev[disturbanceSchemeName] == 0 && dispersalType != BASE_IMMIGRATION && dispersalType != BOTH) { // all dead and no base immigration
benchmark.stop(10);
// benchmark.stop(10);
continue;
}
nAlivePrev[disturbanceSchemeName] = 0;
Benchmark::getInstance().mark(1012000);
for(auto pairCoordDist : disturbanceScheme.second) {
Point currSchemeCoord = pairCoordDist.first;
string newDisturbanceName = pairCoordDist.second;
......@@ -1703,73 +1710,68 @@ int batchRun() {
}
environment->setDisturbanceAt(currSchemeCoord, newDisturbanceName);
}
Benchmark::getInstance().stop(1012000);
unordered_map<Point, Population*> activeNeighborhood = environment->getActiveNeighborhood(disturbanceSchemeName);
// unordered_set<Point> newActiveNeighborhood;
benchmark.stop(10);
benchmark.mark(11);
Benchmark::getInstance().mark(1013000);
for(auto activeNeighbor : activeNeighborhood) {
benchmark.mark(110);
Population* population = activeNeighbor.second;
benchmark.stop(110);
if(dispersalType != DispersalType::IMMOBILE // dispersal and/or base immigration
|| population->isAlive()) { // or population not extinct
benchmark.mark(111);
Benchmark::getInstance().mark(1013100);
unordered_set<Point> activatedNeighbors = population->updateFlows(environment);
benchmark.stop(111);
benchmark.mark(112);
Benchmark::getInstance().stop(1013100);
Benchmark::getInstance().mark(1013200);
environment->addActiveNeighbors(disturbanceSchemeName, activatedNeighbors);
benchmark.stop(112);
benchmark.mark(113);
Benchmark::getInstance().stop(1013200);
Benchmark::getInstance().mark(1013300);
if(population->isAlive()) {
nAlivePrev[disturbanceSchemeName]++;
nAlivePrevTotal++;
}
benchmark.stop(113);
Benchmark::getInstance().stop(1013300);
}
}
benchmark.stop(11);
Benchmark::getInstance().stop(1013000);
unsigned int iCoord = 0;
// loop through all defined coordinates
benchmark.mark(12);
Benchmark::getInstance().mark(1014000);
Benchmark::getInstance().mark(1014100);
activeNeighborhood = environment->getActiveNeighborhood(disturbanceSchemeName); // get updated list of neighbors
Benchmark::getInstance().stop(1014100);
for(auto activeNeighbor : activeNeighborhood) {
benchmark.mark(121);
currentCoord = activeNeighbor.first;
benchmark.mark(1211);
Population* population = activeNeighbor.second;
benchmark.stop(1211);
benchmark.mark(1212);
Benchmark::getInstance().mark(1014200);
disturbanceName = environment->getDisturbanceAt(currentCoord);
benchmark.stop(1212);
Benchmark::getInstance().stop(1014200);
iCoord++;
benchmark.stop(121);
benchmark.mark(122);
Benchmark::getInstance().mark(1014300);
if(dispersalType != DispersalType::IMMOBILE // dispersal and/or base immigration
|| population->isAlive()) { // and population extinct
benchmark.mark(1221);
Benchmark::getInstance().mark(1014310);
population->updateStages(environment);
benchmark.stop(1221);
benchmark.mark(1222);
Benchmark::getInstance().stop(1014310);
Benchmark::getInstance().mark(1014320);
population->updateStats(environment);
benchmark.stop(1222);
benchmark.mark(1223);
Benchmark::getInstance().stop(1014320);
Benchmark::getInstance().mark(1014330);
outputRun(nTimesteps, population);
benchmark.stop(1223);
benchmark.mark(1224);
Benchmark::getInstance().stop(1014330);
Benchmark::getInstance().mark(1014340);
if(population->isAlive()) {
nAliveTotal++;
}else{
environment->removeActiveNeighbor(disturbanceSchemeName, currentCoord);
}
benchmark.stop(1224);
Benchmark::getInstance().stop(1014340);
}
benchmark.stop(122);
Benchmark::getInstance().stop(1014300);
} // end coord loop
benchmark.stop(12);
Benchmark::getInstance().stop(1014000);
} // end disturbance loop
benchmark.stop(1);
Benchmark::getInstance().stop(1010000);
if(dailyPrint) {
milliseconds dailyEnd = duration_cast< milliseconds >(
system_clock::now().time_since_epoch()
......@@ -1813,11 +1815,11 @@ int batchRun() {
cout << "All population extinct in simulation time frame. Skipping" << endl;
break;
}
benchmark.mark(2);
// benchmark.mark(2);
if(environment->update()) {
updateClimate();
}
benchmark.stop(2);
// benchmark.stop(2);
nTimesteps++;
} // end loop begin to end of time frame
if(!prognosis) {
......
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