...
 
Commits (189)
......@@ -5,6 +5,7 @@ build
*.o
*.a
*.mod
*.json
test/mericMeasurement*
test/hdeemMeasurement*
tools/__pycache__/
......@@ -14,6 +15,7 @@ tools/staticMERICtool/energyMeasureStart
tools/staticMERICtool/energyMeasureStop
tools/systemInfo
tools/DBI/*
tools/wrapper
include/meric
test/sleepTest
......
### XX.XX.XXXX #################################################################
- new MERICwrapper tool, that provides state space search and analysis of already measured data instead of the RADAR
- powercap is now set in milliwatts and milliseconds instead of watts and microseconds
- RAPL energy consumption measurements show millijoules inseat of joules
- new MERIC_COUNTERS=msr - CPU core and uncore freq monitoring using libmsr
- fixed restore of the system hardware settings in the energyMeasureStop
- improved systemInfo tool
+ extended amount of the reported information
+ provides posibility to restore the system settings
- HW tuning and RAPL energy measurement using GEOPM
- continual mode is now default
- it is not necessary any more to set MERIC_CONTINUAL for energy measurement systems that does not support non-continual measurement
- unified output label for all the energy measurement systems
- removed the duty to compile MERIC with numactl when libmsr or x86_adapt or GEOPM not available
### 30.04.2019 #################################################################
- new Dynamic Binary Instrymentation (DBI) tool for MERIC instrumentation
- user should not specify value of requested CPU core frequency, uncore frequency and number of active threads in the name of the output file any more - it is done automatically
......@@ -15,7 +30,7 @@
- default MERIC mode is RUN (3) instead of HDEEM (0)
- CPU core and uncore frequency may be specified without unit in Hz or with unit
- removed mericMeasurementCounters - when runing an application several times with the same configuration MERIC_ITERATION=$iteration must be exported
- support for msr-safe RAPL reading, DVFS, UFS and power cap
- support for libmsr RAPL reading, DVFS, UFS and power cap
- systemInfo - new tool to show system parameters limits
- energyMeasureStart/Stop tuning the same system parameteres as MERIC
- energyMeasureStart/Stop now compile together with MERIC
......@@ -41,7 +56,7 @@
- MERIC MPI now works in MERIC_AGGREGATE mode as default
- removed duty for c++14 standart
- reduced MERIC overhead
- new MERIC function MERIC_MeasureStopStart to avoid extra environment swithing
- new MERIC function MERIC_MeasureStopStart to avoid extra environment switching
- analysis data directory should contain file measurementInfo.json that describes the test
- new possibility to turn off MPI or OpenMP barriers for production runs
- updated labels in output files
......
MERIC library license (BSD-3)
Copyright (c) 2018, IT4Innovations National Supercomputing Centre, Ostrava, Czech Republic
Copyright (c) 2020, IT4Innovations National Supercomputing Centre, Ostrava, Czech Republic
All rights reserved.
......@@ -11,4 +11,4 @@ Redistribution and use in source and binary forms, with or without modification,
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
......@@ -66,10 +66,6 @@ gcc:
fortran:
$(FC) -c include/meric_mod.F90 $(FORTFLAGS) include/ -o include/meric_mod.o
arm:
./waf configure --withgcc --cpp=g++ --includes="$(INCLUDES_MERIC)" --libpaths="$(LIBPATH_MERIC)" --dummy
make install
love:
./waf distclean
......
This diff is collapsed.
......@@ -9,6 +9,7 @@
#include <sys/stat.h>
#include <algorithm>
#include <limits.h>
#include <iostream>
#ifdef VERBOSE
#define MERIC_INFO std::cout
......@@ -69,7 +70,8 @@ struct mutils {
{
std::stringstream ss;
ss << "mkdir -p " + dir;
int status = std::system(ss.str().c_str());
if (std::system(ss.str().c_str()))
std::cerr << "MERIC ERROR: directory '"<<dir<<"' cannot be created\n";
}
}
};
......
This diff is collapsed.
......@@ -6,8 +6,7 @@
#include "../meric.h"
#include "../../store/aggregated/aggregatestore.h"
#include "../../store/aggregated/detailedaggregatestore.h"
#include "../../store/aggregated/samplesaggregatestore.h"
#include "../../store/aggregated/debugaggregatestore.h"
#include "../../store/aggregated/countersaggregatestore.h"
#include "../../store/aggregated/infoaggregatestore.h"
......@@ -28,8 +27,10 @@ public:
}
#pragma omp single nowait
{
if (_storeList[0]->getMPIWrite())
if (_storeList.size() && _storeList[0]->getMPIWrite())
{
MERIC_INFO << "region '" << region << "' starting\n";
}
SocketsRegionParameters change = regionValue(currentState, region, _nodeId);
if (MPIbarriers)
MPI_Barrier(_currentNode);
......@@ -58,8 +59,10 @@ public:
}
#pragma omp single nowait
{
if (_storeList[0]->getMPIWrite())
if (_storeList.size() && _storeList[0]->getMPIWrite())
{
MERIC_INFO << "region '" << getRegionName(_stack.size(), _stack.back()) << "' stopping\n";
}
SocketsRegionParameters change = regionValue(currentState, getRegionName(_stack.size()-1, _stack.back()-1), _nodeId);
if (MPIbarriers)
MPI_Barrier(_currentNode);
......@@ -178,7 +181,7 @@ public:
}
}
for(int i=0; i<_storeList.size(); i++)
for(unsigned int i=0; i<_storeList.size(); i++)
{
if (!_MPInodeRank)
{
......
......@@ -5,7 +5,7 @@ using namespace meric;
int Meric::ITERATION = mutils::getenv("MERIC_ITERATION", 0);
int Meric::MODE = mutils::getenv<int>("MERIC_MODE" , MODE_RUN);
bool Meric::CONTINUAL = mutils::getenv("MERIC_CONTINUAL" , false);
bool Meric::CONTINUAL = mutils::getenv("MERIC_CONTINUAL" , true);
bool Meric::DETAILED = mutils::getenv("MERIC_DETAILED" , false);
bool Meric::AGGREGATE = mutils::getenv("MERIC_AGGREGATE" , true);
bool Meric::DEBUG = mutils::getenv("MERIC_DEBUG" , false);
......@@ -46,13 +46,8 @@ int Meric::getDefaultParameters()
{
int ret=0;
//OBLIGATORY SECTION
defaultParameter.nthreads = mutils::getenv("MERIC_NUM_THREADS", -1);
defaultParameter.frequency = mutils::frequencyToHz(mutils::getenv("MERIC_FREQUENCY", std::string("")));
defaultParameter.uncoreFrequency = mutils::frequencyToHz(mutils::getenv("MERIC_UNCORE_FREQUENCY", std::string("")));
defaultParameter.powerCapPKG = mutils::getenv("MERIC_PWRCAP_POWER", -1);
defaultParameter.powerCapPKGtime = mutils::getenv("MERIC_PWRCAP_TIME", -1);
#if defined (HAVE_CPUFREQ_H) || defined (HAVE_X86_ADAPT_H) || defined (HAVE_MSR_CORE_H)
#if defined HAVE_CPUFREQ_H || defined HAVE_X86_ADAPT_H || defined HAVE_MSR_CORE_H || defined HAVE_GEOPM_H
defaultParameter.frequency = mutils::frequencyToHz(mutils::getenv("MERIC_FREQUENCY", std::string("")));
if (defaultParameter.frequency < 0)
{
std::cerr << "MERIC ERROR: set MERIC_FREQUENCY [Hz]\n";
......@@ -62,10 +57,12 @@ int Meric::getDefaultParameters()
{
Meric::outputFilenameInfo +="CF_";
}
#else
defaultParameter.frequency = 0;
#endif
#if defined (HAVE_X86_ADAPT_H) || defined (HAVE_MSR_CORE_H)
#if defined HAVE_X86_ADAPT_H || defined HAVE_MSR_CORE_H || defined HAVE_GEOPM_H
defaultParameter.uncoreFrequency = mutils::frequencyToHz(mutils::getenv("MERIC_UNCORE_FREQUENCY", std::string("")));
if (defaultParameter.uncoreFrequency < 0)
{
std::cerr << "MERIC ERROR: set MERIC_UNCORE_FREQUENCY [Hz]\n";
......@@ -75,9 +72,12 @@ int Meric::getDefaultParameters()
{
Meric::outputFilenameInfo +="UnCF_";
}
#else
defaultParameter.uncoreFrequency = 0;
#endif
#ifdef HAVE_OMP_H
defaultParameter.nthreads = mutils::getenv("MERIC_NUM_THREADS", -1);
if (defaultParameter.nthreads < 0)
{
std::cerr << "MERIC ERROR: set MERIC_NUM_THREADS\n"
......@@ -88,9 +88,13 @@ int Meric::getDefaultParameters()
{
Meric::outputFilenameInfo +="thrds_";
}
#else
defaultParameter.nthreads = 0;
#endif
#if defined (HAVE_X86_ADAPT_H) || defined (HAVE_MSR_CORE_H)
#if defined HAVE_X86_ADAPT_H || defined HAVE_MSR_CORE_H || defined HAVE_GEOPM_H
defaultParameter.powerCapPKG = mutils::getenv("MERIC_PWRCAP_POWER", -1);
defaultParameter.powerCapPKGtime = mutils::getenv("MERIC_PWRCAP_TIME", -1);
if (defaultParameter.powerCapPKG < 0 || defaultParameter.powerCapPKGtime < 0)
{
std::cerr << "MERIC ERROR: set MERIC_PWRCAP_POWER [W] and MERIC_PWRCAP_TIME [us]\n";
......@@ -107,6 +111,9 @@ int Meric::getDefaultParameters()
std::cerr << "MERIC ERROR: MERIC_PWRCAP_POWER [W] must be set to change MERIC_PWRCAP_TIME [us]\n";
ret = 1;
}
#else
defaultParameter.powerCapPKG = 0;
defaultParameter.powerCapPKGtime = 0;
#endif
#ifndef HAVE_HDF5_H
......@@ -117,10 +124,10 @@ int Meric::getDefaultParameters()
return ret;
//OPTIONAL SECTION
MERIC_INFO << "Default number of threads: " << defaultParameter.nthreads << " Hz\n";
MERIC_INFO << "Default number of threads: " << defaultParameter.nthreads << "\n";
MERIC_INFO << "Default frequency: " << defaultParameter.frequency << " Hz\n";
MERIC_INFO << "Default uncore frequency: " << defaultParameter.uncoreFrequency << "\n";
MERIC_INFO << "Default powercap: " << defaultParameter.powerCapPKG << " W\t" << defaultParameter.powerCapPKGtime << " us\n";
MERIC_INFO << "Default uncore frequency: " << defaultParameter.uncoreFrequency << " Hz\n";
MERIC_INFO << "Default powercap: " << defaultParameter.powerCapPKG << " mW\t" << defaultParameter.powerCapPKGtime << " ms\n";
std::string outputFilenameSuffix = mutils::getenv("MERIC_OUTPUT_FILENAME", std::string(""));
if (outputFilenameSuffix.size() == 0)
......@@ -176,7 +183,7 @@ int Meric::getDefaultParameters()
if (Meric::COUNTERS != "none")
{
if (Meric::COUNTERS != "papi" && Meric::COUNTERS != "perfevent")
if (Meric::COUNTERS != "papi" && Meric::COUNTERS != "perfevent" && Meric::COUNTERS != "msr")
{
if (Meric::COUNTERS != "")
std::cerr << "MERIC WARNING: unknown counter type "<<Meric::COUNTERS<<std::endl;
......
......@@ -12,10 +12,7 @@
#include "../basis/tokenizer.h"
#include "../basis/utils.h"
#include "../basis/json.h"
#include "../store/detailedenergystore.h"
#include "../store/energystore.h"
#include "../store/timestore.h"
#include "../store/detailedtimestore.h"
#include "../store/samplesstore.h"
#include "../store/timeenergystore.h"
#include "../store/countersstore.h"
#include "../store/infostore.h"
......@@ -24,6 +21,7 @@
#include "../wrapper/perfeventwrapper.h"
#include "../wrapper/papiwrapper.h"
#include "../wrapper/raplwrapper.h"
#include "../wrapper/msrcounterswrapper.h"
namespace meric {
......@@ -33,7 +31,7 @@ public:
virtual void start(const std::string &region)
{
for (int i=0; i<_storeList.size(); i++)
for (unsigned int i=0; i<_storeList.size(); i++)
{
if (_storeList[i]->getMPIWrite())
_storeList[i]->addStart(getRegionID(region), currentState.socket[0]); //data storing into file with name according socket#0
......@@ -45,7 +43,7 @@ public:
{
//stop should be in opposite order as start
//if MERIC_CONTINUAL is used, we want to start it first and stop it last
for(int i=_storeList.size()-1;i>=0; i--)
for(int i=-1+_storeList.size();i>=0; i--)
{
if (_storeList[i]->getMPIWrite())
_storeList[i]->addEnd(_stack.back());
......@@ -112,7 +110,7 @@ public:
virtual void save()
{
MERIC_INFO << "save stored data\n";
for(int i=0; i<_storeList.size(); i++)
for(unsigned int i=0; i<_storeList.size(); i++)
_storeList[i]->save(Meric::OUTPUT_DIR, Meric::OUTPUT_FILENAME, _name);
MERIC_INFO << "store data saved\n";
}
......@@ -162,7 +160,7 @@ protected:
auto cmpSettings = [&] (SocketsRegionParameters & prev, RegionParameters & next, int socket)
{
long paramChange;
long paramChange = 0;
//core frequency
if (next.frequency)
{
......@@ -206,7 +204,7 @@ protected:
//threads
if(next.nthreads)
{
paramChange = paramChange = prev.socket[socket].nthreads > next.nthreads ? prev.socket[socket].nthreads-next.nthreads : next.nthreads-prev.socket[socket].nthreads;
paramChange = prev.socket[socket].nthreads > next.nthreads ? prev.socket[socket].nthreads-next.nthreads : next.nthreads-prev.socket[socket].nthreads;
if (paramChange > ignoreSettings.nthreads)
{
change.socket[socket].nthreads = paramChange;
......@@ -215,7 +213,7 @@ protected:
}
else
{
paramChange = paramChange = prev.socket[socket].nthreads > defaultParameter.nthreads ? prev.socket[socket].nthreads-defaultParameter.nthreads : defaultParameter.nthreads-prev.socket[socket].nthreads;
paramChange = prev.socket[socket].nthreads > defaultParameter.nthreads ? prev.socket[socket].nthreads-defaultParameter.nthreads : defaultParameter.nthreads-prev.socket[socket].nthreads;
if (paramChange > ignoreSettings.nthreads)
{
change.socket[socket].nthreads = paramChange;
......@@ -265,12 +263,12 @@ protected:
};
if (parameter.find(region) == parameter.end()) //region name not in list
for (int socket=0; socket<Environment::NODE_SIZE_SOCKET; socket++)
for (int socket=0; socket<Environment::SOCKETS_PER_NODE; socket++)
cmpSettings(settings, defaultParameter, socket);
else
{
std::map<std::pair<int, int>, struct RegionParameters>::iterator it;
for (int socket=0; socket<Environment::NODE_SIZE_SOCKET; socket++)
for (int socket=0; socket<Environment::SOCKETS_PER_NODE; socket++)
{
if (node != -1 && (it = parameter[region].find(std::make_pair(node, socket))) != parameter[region].end())
cmpSettings(settings, it->second, socket);
......@@ -308,7 +306,7 @@ protected:
//set core frequency
bool differentSettingsForSockets = false;
long diffCore = change.socket[0].frequency;
for (int socket=1; socket < Environment::NODE_SIZE_SOCKET; socket++)
for (int socket=1; socket < Environment::SOCKETS_PER_NODE; socket++)
{
if (diffCore != change.socket[socket].frequency)
differentSettingsForSockets = true;
......@@ -316,7 +314,7 @@ protected:
if (differentSettingsForSockets)
{
for (int socket=0; socket < Environment::NODE_SIZE_SOCKET; socket++)
for (int socket=0; socket < Environment::SOCKETS_PER_NODE; socket++)
{
if(change.socket[socket].frequency)
Environment::frequency(currentState.socket[socket].frequency, socket);
......@@ -328,7 +326,7 @@ protected:
//set uncore frequncy
differentSettingsForSockets = false;
long diffUncore = change.socket[0].uncoreFrequency;
for (int socket=1; socket < Environment::NODE_SIZE_SOCKET; socket++)
for (int socket=1; socket < Environment::SOCKETS_PER_NODE; socket++)
{
if (diffUncore != change.socket[socket].uncoreFrequency)
differentSettingsForSockets = true;
......@@ -336,7 +334,7 @@ protected:
if (differentSettingsForSockets)
{
for (int socket=0; socket < Environment::NODE_SIZE_SOCKET; socket++)
for (int socket=0; socket < Environment::SOCKETS_PER_NODE; socket++)
{
if(change.socket[socket].uncoreFrequency)
Environment::uncoreFrequency(currentState.socket[socket].uncoreFrequency, currentState.socket[socket].uncoreFrequency, socket);
......@@ -349,7 +347,7 @@ protected:
differentSettingsForSockets = false;
long diffCapPower = change.socket[0].powerCapPKG;
long diffCapTime = change.socket[0].powerCapPKGtime;
for (int socket=1; socket < Environment::NODE_SIZE_SOCKET; socket++)
for (int socket=1; socket < Environment::SOCKETS_PER_NODE; socket++)
{
if (diffCapPower != change.socket[socket].powerCapPKG || diffCapTime != change.socket[0].powerCapPKGtime)
{
......@@ -360,7 +358,7 @@ protected:
if (differentSettingsForSockets)
{
for (int socket=0; socket < Environment::NODE_SIZE_SOCKET; socket++)
for (int socket=0; socket < Environment::SOCKETS_PER_NODE; socket++)
{
if(change.socket[socket].powerCapPKG)
Environment::powercap(currentState.socket[socket].powerCapPKG, currentState.socket[socket].powerCapPKGtime, socket);
......
......@@ -7,7 +7,7 @@ SharedMeric::SharedMeric()
{
if (Meric::MODE == MODE_HDEEM || Meric::MODE == MODE_BOTH)
{
HDEEM::init();
HDEEM::init(Meric::DETAILED);
HDEEM::start(_startTime);
if (Meric::DEBUG)
......@@ -16,88 +16,68 @@ SharedMeric::SharedMeric()
} else {
if (Meric::CONTINUAL)
{
if (Meric::DETAILED) {
_storeList.push_back(new DetailedTimeStore(Meric::SAMPLES));
} else {
_storeList.push_back(new TimeStore<HDEEM>(Meric::SAMPLES));
}
_storeList.push_back(new SamplesStore<HDEEM>(Meric::SAMPLES));
} else {
if (Meric::DETAILED)
{
_storeList.push_back(new DetailedEnergyStore(Meric::SAMPLES));
} else {
//_storeList.push_back(new EnergyStore(Meric::SAMPLES));
_storeList.push_back(new CountersStore<HDEEM, double>(Meric::SAMPLES));
}
_storeList.push_back(new CountersStore<HDEEM, double>());
}
}
}
if (Meric::MODE == MODE_RAPL || Meric::MODE == MODE_BOTH)
{
_storeList.push_back(new CountersStore<RAPL, unsigned long long int>(Meric::SAMPLES));
_storeList.push_back(new CountersStore<RAPL, unsigned long long int>());
}
if (Meric::MODE == MODE_JETSON && Meric::CONTINUAL)
if (Meric::MODE == MODE_JETSON)
{
_storeList.push_back(new TimeStore<JETSON>(Meric::SAMPLES));
_storeList.push_back(new SamplesStore<JETSON>(Meric::SAMPLES));
}
else if (Meric::MODE == MODE_THUNDER && Meric::CONTINUAL)
else if (Meric::MODE == MODE_THUNDER)
{
_storeList.push_back(new TimeStore<THUNDER>(Meric::SAMPLES));
_storeList.push_back(new SamplesStore<THUNDER>(Meric::SAMPLES));
}
else if (Meric::MODE == MODE_DAVIDE && Meric::CONTINUAL)
else if (Meric::MODE == MODE_DAVIDE)
{
_storeList.push_back(new TimeStore<DAVIDE>(Meric::SAMPLES));
_storeList.push_back(new SamplesStore<DAVIDE>(Meric::SAMPLES));
}
if (Meric::COUNTERS != "none")
{
if (Meric::COUNTERS == "perfevent")
_storeList.push_back(new CountersStore<PERFEVENT, unsigned long long int>(Meric::SAMPLES));
_storeList.push_back(new CountersStore<PERFEVENT, unsigned long long int>());
else if (Meric::COUNTERS == "papi")
_storeList.push_back(new CountersStore<PAPI, unsigned long long int>(Meric::SAMPLES));
_storeList.push_back(new CountersStore<PAPI, unsigned long long int>());
else if (Meric::COUNTERS == "msr")
_storeList.push_back(new CountersStore<MSR, uint64_t>());
}
if (_storeList.size() > 0 || Meric::MODE == MODE_TIME)
_storeList.insert(_storeList.begin(), new InfoStore());
for (int i=0; i<_storeList.size(); i++)
_storeList[i]->setMPIWrite(true);
if (Meric::MODE == MODE_JETSON)
if (Meric::MODE == MODE_JETSON) //we do not really need to know, that system is Jetson, we may initialize the env as SYS_OTHER
Environment::init(SYS_JETSON, defaultParameter, 0);
else if (Meric::MODE == MODE_THUNDER)
Environment::init(SYS_THUNDER, defaultParameter, 0);
// else if (Meric::MODE == MODE_DAVIDE)
// Environment::init(SYS_DAVIDE, defaultParameter, 0);
else
Environment::init(SYS_OTHER, defaultParameter, 0);
// Environment::init(SYS_HASWELL, defaultParameter, 0); //this default settings must persist due to many nodes with min uncore frequency limit set to maximum - now it is fixed
for (int socket=0; socket < Environment::NODE_SIZE_SOCKET; socket++)
for (unsigned int socket=0; socket < Environment::SOCKETS_PER_NODE; socket++)
currentState.socket[socket] = defaultParameter;
//wrappers must be initialized after meric instantiation
//RAPL counter expects that environment::init() was already called
//RAPL + MSR wrappers expects that environment::init() was already called
if (Meric::COUNTERS == "perfevent")
PERFEVENT::init();
if (Meric::COUNTERS == "papi")
PAPI::init();
if (Meric::MODE == MODE_RAPL || Meric::MODE == MODE_BOTH)
{
// if (Meric::DETAILED)
// RAPL::detailed();
RAPL::init(Meric::DETAILED);
}
if (Meric::MODE == MODE_JETSON && Meric::CONTINUAL)
if (Meric::COUNTERS == "msr")
MSR::init();
if (Meric::MODE == MODE_JETSON)
JETSON::init();
else if (Meric::MODE == MODE_THUNDER && Meric::CONTINUAL)
else if (Meric::MODE == MODE_THUNDER)
THUNDER::init();
else if (Meric::MODE == MODE_DAVIDE && Meric::CONTINUAL)
else if (Meric::MODE == MODE_DAVIDE)
{
DAVIDE::init();
DAVIDE::start(_startTime);
......@@ -121,12 +101,12 @@ SharedMeric::~SharedMeric()
{
HDEEM::close();
}
else if (Meric::MODE == MODE_DAVIDE && Meric::CONTINUAL)
else if (Meric::MODE == MODE_DAVIDE)
{
DAVIDE::close();
}
for(int i=0;i<_storeList.size(); i++)
for(unsigned int i=0;i<_storeList.size(); i++)
delete _storeList[i];
}
......
......@@ -157,7 +157,7 @@ public:
exit(-1);
}
for(int i=0; i<_storeList.size(); i++)
for(unsigned int i=0; i<_storeList.size(); i++)
{
_storeList[i]->initStore(Meric::ITERATION, Meric::OUTPUT_DIR, Meric::OUTPUT_FILENAME, Meric::outputFilenameInfo);
_storeList[i]->save(Meric::OUTPUT_DIR, Meric::OUTPUT_FILENAME, _name);
......
#ifndef SRC_STORE_AGGREGATED_AGGREGATESTORE_H_
#define SRC_STORE_AGGREGATED_AGGREGATESTORE_H_
#include "mpi.h"
#include "aggregatestorebase.h"
namespace meric {
template <class TStore>
class AggregateStore: public AggregateStoreBase<TStore> {
public:
//AggregateStore(MPI_Comm &comm, bool write): AggregateStoreBase<TStore>(comm, write)
AggregateStore(MPI_Comm &comm): AggregateStoreBase<TStore>(comm)
{
_buffer.resize(this->_size);
}
protected:
void saveInterval(std::ofstream &ss, std::vector<size_t> &iStarts, size_t iEnd);
void saveInterval(std::vector<size_t> &iStarts, size_t iEnd);
std::vector<RegionStats> _buffer;
};
}
#include "aggregatestore.hpp"
#endif /* SRC_STORE_AGGREGATED_AGGREGATESTORE_H_ */
#include "aggregatestore.h"
namespace meric {
template <class TStore>
void AggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector<size_t> &iStarts, size_t iEnd)
{
RegionStats stats;
this->_store->fillRegionStats(stats, iStarts.back(), iEnd);
//TODO we send the whole structure despite we use just the information about energy
MPI_Gather(&stats, sizeof(RegionStats), MPI_BYTE, _buffer.data(), sizeof(RegionStats), MPI_BYTE, 0, this->_comm);
ss << "# CALLTREE;init_" << this->_store->_initCounter;
for (size_t j = 0; j < iStarts.size()-1; j++) {
ss << ";" << this->_store->_name[this->_store->_records[iStarts[j]].region] << "_" << this->_store->_counters[this->_store->_records[iStarts[j]].region];
}
double sumEnergy = 0,
maxEnergy = 0,
minEnergy = _buffer[0].energy;
for (size_t i = 0; i < this->_size; i++)
{
if(maxEnergy < _buffer[i].energy) {
maxEnergy = _buffer[i].energy;
} else if (minEnergy > _buffer[i].energy) {
minEnergy = _buffer[i].energy;
}
sumEnergy += _buffer[i].energy;
}
ss << "\n# Blade summary - hdeem\n"
<< "Average energy consumption [J]," << sumEnergy/this->_size << '\n'
<< "Maximal energy consumption [J]," << maxEnergy << '\n'
<< "Minimal energy consumption [J]," << minEnergy << '\n'
<< "Summary energy consumption [J]," << sumEnergy << '\n';
}
template <class TStore>
void AggregateStore<TStore>::saveInterval(std::vector<size_t> &iStarts, size_t iEnd)
{
RegionStats stats;
this->_store->fillRegionStats(stats, iStarts.back(), iEnd);
MPI_Gather(&stats, sizeof(RegionStats), MPI_BYTE, _buffer.data(), sizeof(RegionStats), MPI_BYTE, 0, this->_comm);
}
}
......@@ -2,7 +2,7 @@
#ifndef SRC_STORE_AGGREGATED_AGGREGATESTOREBASE_H_
#define SRC_STORE_AGGREGATED_AGGREGATESTOREBASE_H_
#include "mpi.h"
#include <mpi.h>
#include "../store.h"
namespace meric {
......@@ -11,24 +11,10 @@ template <class TStore>
class AggregateStoreBase: public StoreBase {
public:
/* AggregateStoreBase(MPI_Comm &comm, bool write): _comm(comm)
{
_store = new TStore(write);
MPI_Comm_rank(_comm, &_rank);
MPI_Comm_size(_comm, &_size);
}
AggregateStoreBase(const std::string counterType, MPI_Comm &comm, bool write): _comm(comm)
{
_store = new TStore(counterType, write);
MPI_Comm_rank(_comm, &_rank);
MPI_Comm_size(_comm, &_size);
}
*/
AggregateStoreBase(MPI_Comm &comm): _comm(comm)
AggregateStoreBase(MPI_Comm &comm, bool write): StoreBase(false, write), _comm(comm)
{
_store = new TStore(false);
_store = new TStore(false, write);
MPI_Comm_rank(_comm, &_rank);
MPI_Comm_size(_comm, &_size);
}
......
......@@ -2,7 +2,7 @@
#ifndef SRC_STORE_AGGREGATED_COUNTERSAGGREGATESTORE_H_
#define SRC_STORE_AGGREGATED_COUNTERSAGGREGATESTORE_H_
#include "mpi.h"
#include <mpi.h>
#include "aggregatestorebase.h"
namespace meric {
......@@ -13,25 +13,40 @@ class CountersAggregateStore: public AggregateStoreBase<TStore> {
public:
typedef typename TStore::dataType StoreDataType;
typedef typename TStore::counterType StoreCounterType;
// CountersAggregateStore(const std::string wrapper, MPI_Comm &comm, bool write): AggregateStoreBase<TStore>(wrapper, comm, write)
CountersAggregateStore(MPI_Comm &comm): AggregateStoreBase<TStore>(comm)
CountersAggregateStore(MPI_Comm &comm, bool write): AggregateStoreBase<TStore>(comm, write)
{
_bufferCounters.resize(this->_size);
_bufferTime.resize(this->_size);
_bufferRatios.resize(this->_size);
};
protected:
void saveInterval(std::ofstream &ss, std::vector<size_t> &iStarts, size_t iEnd);
void saveInterval(std::vector<size_t> &iStarts, size_t iEnd);
double printStats (const std::string description, std::vector<double>& data, const int dataSize, const int stride, bool storeSum, std::ofstream &ss);
unsigned long long int printStats (const std::string description, const unsigned long long int * data, const int dataSize, const int stride, bool storeSum, std::ofstream &ss);
double printStats (const std::string description, const double * data, const int dataSize, const int stride, bool storeSum, std::ofstream &ss);
std::vector <StoreDataType> _bufferCounters;
std::vector <double> _bufferTime;
template <typename T> void printStats (const std::string description, const T * data, const int dataSize, const int stride, bool storeSum, std::ofstream &ss)
{
T max = data[0];
T min = data[0];
T sum = data[0];
for(int i=stride; i<dataSize; i+=stride)
{
if (max < data[i])
max = data[i];
else if (min > data[i])
min = data[i];
sum += data[i];
}
T avg = sum/(dataSize/stride);
ss << "AVG "<< description << "," << std::fixed << std::setprecision(5) << avg << std::endl
<< "MAX "<< description << "," << max << std::endl
<< "MIN "<< description << "," << min << std::endl;
if (storeSum)
ss << "SUM "<< description << "," << sum << std::endl;
}
std::vector <StoreDataType> _bufferCounters;
std::vector <double> _bufferRatios;
MPI_Datatype consolidate;
};
......
......@@ -4,144 +4,44 @@
namespace meric {
template <class TStore>
unsigned long long int CountersAggregateStore<TStore>::printStats (const std::string description, const unsigned long long int * data, const int dataSize, const int stride, bool storeSum, std::ofstream &ss)
{
unsigned long long int max = data[0];
unsigned long long int min = data[0];
unsigned long long int sum = data[0];
for(int i=stride; i<dataSize; i+=stride)
{
if (max < data[i])
max = data[i];
else if (min > data[i])
min = data[i];
sum += data[i];
}
unsigned long long int avg = sum/(dataSize/stride);
ss << "AVG "<< description << "," << avg << std::endl
<< "MAX "<< description << "," << max << std::endl
<< "MIN "<< description << "," << min << std::endl;
if (storeSum)
ss << "SUM "<< description << "," << sum << std::endl;
return avg;
}
template <class TStore>
double CountersAggregateStore<TStore>::printStats (const std::string description, const double * data, const int dataSize, const int stride, bool storeSum, std::ofstream &ss)
{
double max = data[0];
double min = data[0];
double sum = data[0];
for(int i=stride; i<dataSize; i+=stride)
{
if (max < data[i])
max = data[i];
else if (min > data[i])
min = data[i];
sum += data[i];
}
double avg = sum/(dataSize/stride);
ss << "AVG "<< description << "," << avg << std::endl
<< "MAX "<< description << "," << max << std::endl
<< "MIN "<< description << "," << min << std::endl;
if (storeSum)
ss << "SUM "<< description << "," << sum << std::endl;
return avg;
}
template <class TStore>
double CountersAggregateStore<TStore>::printStats (const std::string description, std::vector<double>& data, const int dataSize, const int stride, bool storeSum, std::ofstream &ss)
{
double max = data[0];
double min = data[0];
double sum = data[0];
for(int i=stride; i<dataSize; i+=stride)
{
if (max < data[i])
max = data[i];
else if (min > data[i])
min = data[i];
sum += data[i];
}
double avg = sum/(dataSize/stride);
ss << "AVG "<< description << "," << avg << std::endl
<< "MAX "<< description << "," << max << std::endl
<< "MIN "<< description << "," << min << std::endl;
if (storeSum)
ss << "SUM "<< description << "," << sum << std::endl;
return avg;
}
template <class TStore>
void CountersAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector<size_t> &iStarts, size_t iEnd)
{
std::vector<StoreDataType> stats;
std::map <std::string, double> ratios;
double time;
this->_store->fillRegionStats(stats, &time, iStarts.back(), iEnd);
this->_store->fillRegionStats(stats, ratios, &time, iStarts.back(), iEnd);
_bufferCounters.resize(this->_size * stats.size());
std::vector <double> ratiosList;
for (const auto &r : ratios)
ratiosList.push_back(r.second);
_bufferRatios.resize(this->_size * ratiosList.size());
//INFO - basic mpi vs aggregate mpi counter store se lisi predevsim v tom, ktere procesy sbiraji a nasledne zapisuji vysledky
MPI_Gather(stats.data(), stats.size(), MPI_UNSIGNED_LONG_LONG, _bufferCounters.data(), stats.size(), MPI_UNSIGNED_LONG_LONG, 0, this->_comm);
MPI_Gather(&time, 1, MPI_DOUBLE, &_bufferTime[0], 1, MPI_DOUBLE, 0, this->_comm);
/*
auto printStats = [&ss](const std::string description, const auto& data, const int dataSize, const int stride, bool storeSum) //lambda C++14 (auto argument)
{
auto max = data[0];
auto min = data[0];
auto sum = data[0];
for(int i=stride; i<dataSize; i+=stride)
{
if (max < data[i])
max = data[i];
else if (min > data[i])
min = data[i];
sum += data[i];
}
auto avg = sum/(dataSize/stride);
ss << "AVG "<< description << "," << avg << std::endl
<< "MAX "<< description << "," << max << std::endl
<< "MIN "<< description << "," << min << std::endl;
if (storeSum)
ss << "SUM "<< description << "," << sum << std::endl;
return avg;
};
*/
MPI_Gather(ratiosList.data(), ratiosList.size(), MPI_DOUBLE, _bufferRatios.data(), ratiosList.size(), MPI_DOUBLE, 0, this->_comm);
ss << "# CALLTREE;init_" << this->_store->_initCounter;
for (size_t j = 0; j < iStarts.size()-1; j++)
{
ss << ";" << this->_store->_name[this->_store->_records[iStarts[j]].region] << "_" << this->_store->_counters[this->_store->_records[iStarts[j]].region];
}
ss << "\n# COUNTERS - "<<StoreCounterType::getCountersLabel() << ": \n";
ss << "\n# COUNTERS - "<<StoreCounterType::getSourceLabel() << ":\n";
int j = 0;
CountersRecord<StoreDataType> averageRecord;
//for(std::map<std::string, StoreDataType>::iterator counterIt = this->_store->_records[iEnd].record.begin(); ...)
for(auto counterIt = this->_store->_records[iEnd].record.begin(); counterIt != this->_store->_records[iEnd].record.end(); ++counterIt)
{
//averageRecord.record[counterIt->first] = printStats(counterIt->first, &_bufferCounters[j++],this->_size*stats.size(),stats.size(), true);
averageRecord.record[counterIt->first] = printStats(counterIt->first, & _bufferCounters[j++],this->_size*stats.size(),stats.size(), true, ss);
printStats(counterIt->first, & _bufferCounters[j++],this->_size*stats.size(),stats.size(), true, ss);
}
// Counters ratios
CountersRecord<StoreDataType> startRecord;
std::map <std::string, double> ratios;
double sumTime = 0.0;
for(double nodeTime : _bufferTime)
if (ratiosList.size())
{
sumTime += nodeTime;
}
time = sumTime/_bufferTime.size();
StoreCounterType::getRatios(startRecord.record, averageRecord.record, time, ratios);
if (ratios.size())
{
ss << "# RATIOS: \n";
for(auto const &element : ratios)
ss << StoreCounterType::getCounterLabel(element.first) <<"," << std::fixed << std::setprecision(5) << element.second <<std::endl;
ss << "# RATIOS:\n";
int j=0;
for(auto const &r : ratios)
printStats(StoreCounterType::getCounterLabel(r.first), & _bufferRatios[j++],this->_size*ratiosList.size(),ratiosList.size(), false, ss);
}
}
......@@ -149,11 +49,15 @@ template <class TStore>
void CountersAggregateStore<TStore>::saveInterval(std::vector<size_t> &iStarts, size_t iEnd)
{
std::vector<StoreDataType> stats;
double time;
this->_store->fillRegionStats(stats, &time, iStarts.back(), iEnd);
std::map <std::string, double> ratios;
double time; //we do not the runtime any more, since the ratios are evaluated in the fillRegionStats()
this->_store->fillRegionStats(stats, ratios, &time, iStarts.back(), iEnd);
std::vector <double> ratiosList;
for (const auto &r : ratios)
ratiosList.push_back(r.second);
MPI_Gather(stats.data(), stats.size(), MPI_UNSIGNED_LONG_LONG, _bufferCounters.data(), stats.size(), MPI_UNSIGNED_LONG_LONG, 0, this->_comm);
MPI_Gather(&time, 1, MPI_DOUBLE, &_bufferTime[0], 1, MPI_DOUBLE, 0, this->_comm);
MPI_Gather(ratiosList.data(), ratiosList.size(), MPI_DOUBLE, _bufferRatios.data(), ratiosList.size(), MPI_DOUBLE, 0, this->_comm);
}
}
......@@ -2,7 +2,7 @@
#ifndef SRC_STORE_AGGREGATED_DEBUGAGGREGATESTORE_H_
#define SRC_STORE_AGGREGATED_DEBUGAGGREGATESTORE_H_
#include "mpi.h"
#include <mpi.h>
#include "aggregatestorebase.h"
namespace meric {
......@@ -11,8 +11,7 @@ template <class TStore>
class DebugAggregateStore: public AggregateStoreBase<TStore> {
public:
// DebugAggregateStore(MPI_Comm &comm, bool write): AggregateStoreBase<TStore>(comm, write)
DebugAggregateStore(MPI_Comm &comm): AggregateStoreBase<TStore>(comm)
DebugAggregateStore(MPI_Comm &comm, bool write): AggregateStoreBase<TStore>(comm, write)
{
_buffer.resize(this->_size);
}
......
......@@ -17,18 +17,18 @@ void DebugAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector<si
ss << ";" << this->_store->_name[this->_store->_records[iStarts[j]].region] << "_" << this->_store->_counters[this->_store->_records[iStarts[j]].region];
}
ss << "\n# Job info - hdeem" << std::endl
ss << "\n# Job info - HDEEM" << std::endl
<< "JOB ID," << this->_store->_jobID << "." << this->_store->_stepID << '\n'
<< "Nodelist," << this->_store->_nodelist << '\n';
double avgEnergy = 0,
maxEnergy = 0,
minEnergy = _buffer[0].energy[0],
sumEnergy = 0;
minEnergy = _buffer[0].energy[0];
// sumEnergy = 0;
double avgEnergyStatsStruct = 0,
maxEnergyStatsStruct = 0,
minEnergyStatsStruct = _buffer[0].energyStatsStructure[0],
sumEnergyStatsStruct = 0;
minEnergyStatsStruct = _buffer[0].energyStatsStructure[0];
// sumEnergyStatsStruct = 0;
double avgDuration = 0,
maxDuration = 0,
minDuration = _buffer[0].mericDuration,
......@@ -72,8 +72,8 @@ void DebugAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector<si
avgHdeemDuration += _buffer[i].hdeemDuration;
}
sumEnergy = avgEnergy;
sumEnergyStatsStruct = avgEnergyStatsStruct;
// sumEnergy = avgEnergy;
// sumEnergyStatsStruct = avgEnergyStatsStruct;
sumDuration = avgDuration;
sumHdeemDuration = avgHdeemDuration;
......
......@@ -2,7 +2,7 @@
#ifndef SRC_STORE_AGGREGATED_INFOAGGREGATESTORE_H_
#define SRC_STORE_AGGREGATED_INFOAGGREGATESTORE_H_
#include "mpi.h"
#include <mpi.h>
#include "aggregatestorebase.h"
namespace meric {
......@@ -11,7 +11,7 @@ template <class TStore>
class InfoAggregateStore: public AggregateStoreBase<TStore> {
public:
InfoAggregateStore(MPI_Comm &comm): AggregateStoreBase<TStore>(comm)
InfoAggregateStore(MPI_Comm &comm, bool write): AggregateStoreBase<TStore>(comm, write)
{
_buffer.resize(this->_size);
}
......@@ -19,8 +19,7 @@ public:
protected:
void saveInterval(std::ofstream &ss, std::vector<size_t> &iStarts, size_t iEnd);
void saveInterval(std::vector<size_t> &iStarts, size_t iEnd);
std::vector<RegionStats> _buffer;
std::vector<InfoStats> _buffer;
};
}
......
......@@ -6,10 +6,9 @@ namespace meric {
template <class TStore>
void InfoAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector<size_t> &iStarts, size_t iEnd)
{
RegionStats stats;
InfoStats stats;
this->_store->fillRegionStats(stats, iStarts.back(), iEnd);
MPI_Gather(&stats, sizeof(RegionStats), MPI_BYTE, _buffer.data(), sizeof(RegionStats), MPI_BYTE, 0, this->_comm);
MPI_Gather(&stats, sizeof(InfoStats), MPI_BYTE, _buffer.data(), sizeof(InfoStats), MPI_BYTE, 0, this->_comm);
ss << "# CALLTREE;init_" << this->_store->_initCounter;
for (size_t j = 0; j < iStarts.size()-1; j++)
......@@ -25,8 +24,8 @@ void InfoAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector<siz
maxDuration = 0,
minDuration = _buffer[0].duration;
for (size_t i = 0; i < this->_size; i++)
{
for (size_t i = 0; i < this->_size; i++)
{
if(maxDuration < _buffer[i].duration)
{
maxDuration = _buffer[i].duration;
......@@ -35,21 +34,37 @@ void InfoAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector<siz
minDuration = _buffer[i].duration;
}
sumDuration += _buffer[i].duration;
}
}
ss << "AVG runtime of function [s]," << sumDuration/this->_size << std::endl
<< "MAX runtime of function [s]," << maxDuration << std::endl
<< "MIN runtime of function [s]," << minDuration << std::endl;
ss << "Average runtime of function [s]," << sumDuration/this->_size << std::endl
<< "Maximal runtime of function [s]," << maxDuration << std::endl
<< "Minimal runtime of function [s]," << minDuration << std::endl;
double sumStart = 0,
maxStart = 0,
minStart = _buffer[0].startTime;
for (size_t i = 0; i < this->_size; i++)
{
if(maxStart < _buffer[i].startTime)
{
maxStart = _buffer[i].startTime;
} else if (minStart > _buffer[i].startTime)
{
minStart = _buffer[i].startTime;
}
sumStart += _buffer[i].startTime;
}
ss << "AVG Function start timestamp," << std::setprecision (15) << sumStart/this->_size << std::endl
<< "MAX Function start timestamp," << maxStart << std::endl
<< "MIN Function start timestamp," << minStart << std::endl;
}
template <class TStore>
void InfoAggregateStore<TStore>::saveInterval(std::vector<size_t> &iStarts, size_t iEnd)
{
RegionStats stats;
InfoStats stats;
this->_store->fillRegionStats(stats, iStarts.back(), iEnd);
MPI_Gather(&stats, sizeof(RegionStats), MPI_BYTE, _buffer.data(), sizeof(RegionStats), MPI_BYTE, 0, this->_comm);
MPI_Gather(&stats, sizeof(InfoStats), MPI_BYTE, _buffer.data(), sizeof(InfoStats), MPI_BYTE, 0, this->_comm);
}
}
......
#ifndef SRC_STORE_AGGREGATED_DETAILEDAGGREGATESTORE_H_
#define SRC_STORE_AGGREGATED_DETAILEDAGGREGATESTORE_H_
#ifndef SRC_STORE_AGGREGATED_SAMPLESAGGREGATESTORE_H_
#define SRC_STORE_AGGREGATED_SAMPLESAGGREGATESTORE_H_
#include "mpi.h"
#include <mpi.h>
#include "aggregatestorebase.h"
namespace meric {
template <class TStore>
class DetailedAggregateStore: public AggregateStoreBase<TStore> {
class SamplesAggregateStore: public AggregateStoreBase<TStore> {
public:
// DetailedAggregateStore(MPI_Comm &comm, bool write): AggregateStoreBase<TStore>(comm, write)
DetailedAggregateStore(MPI_Comm &comm): AggregateStoreBase<TStore>(comm)
typedef typename TStore::samplesType StoreSamplesType;
// typedef TSystem samplesType;
SamplesAggregateStore(MPI_Comm &comm, bool write): AggregateStoreBase<TStore>(comm, write)
{
_buffer.resize(this->_size);
};
}
protected:
void saveInterval(std::ofstream &ss, std::vector<size_t> &iStarts, size_t iEnd);
......@@ -27,9 +28,7 @@ protected:
}
#include "detailedaggregatestore.hpp"
#include "samplesaggregatestore.hpp"
#endif /* SRC_STORE_AGGREGATED_DETAILEDAGGREGATESTORE_H_ */
#endif /* SRC_STORE_AGGREGATED_SAMPLESAGGREGATESTORE_H_ */
#include "detailedaggregatestore.h"
#include "samplesaggregatestore.h"
namespace meric {
template <class TStore>
void DetailedAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector<size_t> &iStarts, size_t iEnd)
void SamplesAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector<size_t> &iStarts, size_t iEnd)
{
DetailedRegionStats stats;
this->_store->fillRegionStats(stats, iStarts.back(), iEnd);
MPI_Gather(&stats, sizeof(DetailedRegionStats), MPI_BYTE, _buffer.data(), sizeof(DetailedRegionStats), MPI_BYTE, 0, this->_comm);
ss << "# CALLTREE;init_" << this->_store->_initCounter;
......@@ -18,8 +17,8 @@ void DetailedAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector
}
double sumEnergy = 0,
maxEnergy = 0,
minEnergy = _buffer[0].energy[0];
maxEnergy = 0,
minEnergy = _buffer[0].energy[0];
for (size_t i = 0; i < this->_size; i++)
{
......@@ -30,34 +29,29 @@ void DetailedAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector
{
minEnergy = _buffer[i].energy[0];
}
sumEnergy += _buffer[i].energy[0];
}
//////////////////
// Blade values //
//////////////////
ss << "\n# Blade summary - HDEEM\n"
<< "Average energy consumption [J]," << sumEnergy/this->_size << '\n'
<< "Maximal energy consumption [J]," << maxEnergy << '\n'
<< "Minimal energy consumption [J]," << minEnergy << '\n'
<< "Summary energy consumption [J]," << sumEnergy << '\n';
///////////////////////
// VR sensors values //
///////////////////////
std::vector<std::string> vrSensor = {"CPU0", "CPU1", "DDR AB", "DDR CD", "DDR EF", "DDR GH"};
unsigned int vrSensorNum = vrSensor.size()+1;
for (unsigned int sensorID = 1; sensorID < vrSensorNum; sensorID++)
if (sumEnergy > 0.0)
{
ss << "\n# SAMPLES - " << StoreSamplesType::getSourceLabel() << ":" << std::endl
<< "AVG energy consumption [J]," << sumEnergy/this->_size << std::endl
<< "MAX energy consumption [J]," << maxEnergy << std::endl
<< "MIN energy consumption [J]," << minEnergy << std::endl
<< "SUM energy consumption [J]," << sumEnergy << std::endl;
}
else
{
ss << "# Voltage regulator (" << vrSensor[sensorID-1] << ") summary - HDEEM\n";
ss << "\n# SAMPLES - " << StoreSamplesType::getSourceLabel() << ":" << std::endl
<< "# Blade summary - ERROR" << std::endl
<< "SUM energy consumption [J],0"<< std::endl;
}
for (unsigned int sensorID = 1; sensorID < StoreSamplesType::vrSensorLabel.size(); sensorID++)
{
sumEnergy = 0;
maxEnergy = 0;
minEnergy = _buffer[sensorID].energy[sensorID];
minEnergy = _buffer[0].energy[sensorID];
// Iterate through nodes
for (size_t i = 0; i < this->_size; i++)
......@@ -69,25 +63,28 @@ void DetailedAggregateStore<TStore>::saveInterval(std::ofstream &ss, std::vector
{
minEnergy = _buffer[i].energy[sensorID];
}
sumEnergy += _buffer[i].energy[sensorID];
}
ss << "Average energy consumption [J]," << sumEnergy/this->_size << '\n'
<< "Maximal energy consumption [J]," << maxEnergy << '\n'
<< "Minimal energy consumption [J]," << minEnergy << '\n'
<< "Summary energy consumption [J]," << sumEnergy << '\n';
if (sumEnergy > 0.0)
ss << "# Voltage regulator (" << StoreSamplesType::vrSensorLabel[sensorID] << ") - " << StoreSamplesType::getSourceLabel() << ":" << std::endl
<< "AVG energy consumption [J]," << sumEnergy/this->_size << std::endl
<< "MAX energy consumption [J]," << maxEnergy << std::endl
<< "MIN energy consumption [J]," << minEnergy << std::endl
<< "SUM energy consumption [J]," << sumEnergy << std::endl;
}
}
template <class TStore>
void DetailedAggregateStore<TStore>::saveInterval(std::vector<size_t> &iStarts, size_t iEnd)
void SamplesAggregateStore<TStore>::saveInterval(std::vector<size_t> &iStarts, size_t iEnd)
{
DetailedRegionStats stats;
this->_store->fillRegionStats(stats, iStarts.back(), iEnd);
//TODO in non-detailed mode we should send just the BLADE
MPI_Gather(&stats, sizeof(DetailedRegionStats), MPI_BYTE, _buffer.data(), sizeof(DetailedRegionStats), MPI_BYTE, 0, this->_comm);
}
}
......@@ -5,6 +5,7 @@
#include "countersstore.h"
#include "../wrapper/perfeventwrapper.h"
#include "../wrapper/papiwrapper.h"
#include "../wrapper/msrcounterswrapper.h"
#include "../wrapper/raplwrapper.h"
#ifdef HAVE_MPI_H
......@@ -35,7 +36,7 @@ template <class TCounter, typename TType> void CountersStore<TCounter, TType>::a
_records.push_back(CountersRecord<TType>(region, record, time, _records.back().configuration));
}
template <class TCounter, typename TType> void CountersStore<TCounter, TType>::fillRegionStats(std::vector<TType> &stats, double *time, size_t iStarts, size_t iEnd)
template <class TCounter, typename TType> void CountersStore<TCounter, TType>::fillRegionStats(std::vector<TType> &stats, std::map <std::string, double> &ratios, double *time, size_t iStarts, size_t iEnd)
{
unsigned long long int summary = 0;
TType value;
......@@ -49,9 +50,10 @@ template <class TCounter, typename TType> void CountersStore<TCounter, TType>::f
if (TCounter::getSummaryCounterName() != "")
{
TCounter::getSummaryValue(*time, &summary);
stats[distance(_records[iEnd].record.begin(),_records[iEnd].record.find(TCounter::getSummaryCounterName()))] = summary;
}
TCounter::getRatios(_records[iStarts].record, _records[iEnd].record, *time, ratios);
}
template <class TCounter, typename TType> void CountersStore<TCounter, TType>::saveInterval(std::ofstream &ss, std::vector<size_t> &iStarts, size_t iEnd)
......@@ -63,15 +65,15 @@ template <class TCounter, typename TType> void CountersStore<TCounter, TType>::s
ss << std::endl;
double runtime = mutils::timeToDouble(_records[iEnd].time - _records[iStarts.back()].time);
// ss << "# Job info - "<< TCounter::getCountersLabel() << std::endl
// ss << "# Job info - "<< TCounter::getSourceLabel() << std::endl
// << "JOB ID," << _jobID << "." << _stepID << std::endl
// << "Nodelist," << _nodelist << std::endl
// << "Runtime of function [s]," << runtime << std::endl;
unsigned long long int summary = 0;
TType summary = 0;
TType value;
ss << "# COUNTERS - "<< TCounter::getCountersLabel() <<": \n"
ss << "# COUNTERS - "<< TCounter::getSourceLabel() <<":\n"
<< "Runtime of function [s]," << runtime << std::endl;
for(auto const &counterIt : _records[iEnd].record)
{
......@@ -82,17 +84,17 @@ template <class TCounter, typename TType> void CountersStore<TCounter, TType>::s
ss << TCounter::getCounterLabel(counterIt.first) << "," << value << std::endl;
}
TCounter::getSummaryValue(runtime, &summary);
if (summary != ULLONG_MAX)
if (TCounter::getSummaryCounterName() != "") //RAPL only
{
ss << TCounter::getSummaryCounterName() << "," << summary << std::endl;
}
// Counters ratios
std::map <std::string, double> ratios;
TCounter::getRatios(_records[iStarts.back()].record, _records[iEnd].record, runtime, ratios);
if (ratios.size())
{