diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f975629
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+*.o
+*.a
+*.gcov
+*.gcda
+*.gcno
+proc.out
+/src/external/mammut/*
+/src/external/knarr/*
+/test/googletest/*
+microbench/check
+microbench/ticksPerNs
+microbench/voltageTable
+microbench/voltageTable.cpp
diff --git a/.gitmodules b/.gitmodules
index f0c76ac..1c6f437 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
-[submodule "src/external/Mammut"]
- path = src/external/Mammut
- url = https://github.com/DanieleDeSensi/Mammut.git
-[submodule "src/external/orlog"]
- path = src/external/orlog
- url = https://github.com/DanieleDeSensi/orlog.git
+[submodule "src/external/mammut"]
+ path = src/external/mammut
+ url = https://github.com/DanieleDeSensi/mammut.git
+[submodule "src/external/knarr"]
+ path = src/external/knarr
+ url = https://github.com/DanieleDeSensi/knarr.git
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..1ba4d6d
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,26 @@
+language: cpp
+compiler:
+ - gcc
+# - clang
+sudo: required
+dist: trusty
+
+install:
+ # CppCheck
+ - sudo apt-get install -qq cppcheck
+
+script:
+ # Runs compilation, cppcheck, tests and coverage collection
+ - make develcheck
+
+after_success:
+ # codecov.io
+ - bash <(curl -s https://codecov.io/bash) -X gcov -f 'test/gcov/*.gcov'
+
+notifications:
+ email:
+ recipients:
+ - d.desensi.software@gmail.com
+ on_success: never # default: change
+ on_failure: always # default: always
+
diff --git a/Makefile b/Makefile
index 6f87765..e172053 100644
--- a/Makefile
+++ b/Makefile
@@ -4,14 +4,14 @@ export NORNIR_PATH_INCLUDE = $(NORNIR_PATH)/include/nornir
export CC = gcc
export CXX = g++
-export OPTIMIZE_FLAGS = -finline-functions -O3 #-DPOOL
+export OPTIMIZE_FLAGS = -finline-functions -O3 #-DPOOL
export DEBUG_FLAGS = #-DDEBUG_PREDICTORS -DDEBUG_SELECTORS #-DDEBUG_DF_STREAM -DDEBUG_NODE -DDEBUG_KNOB -DDEBUG_MANAGER
-export CXXFLAGS = -Wall -pedantic --std=c++11 $(OPTIMIZE_FLAGS) $(DEBUG_FLAGS)
-export LDLIBS = -lnornir -pthread -lrt -lm -lmlpack -llapack -lblas -lgsl -lgslcblas -larmadillo -lorlog -lanl
-export INCS = -I$(realpath ./src/external/fastflow) -I/usr/include/libxml2
-export LDFLAGS = -L$(realpath .)/src -L$(realpath .)/src/external/orlog/src
+export CXXFLAGS = $(COVERAGE_FLAGS) -Wall -pedantic --std=c++11 $(OPTIMIZE_FLAGS) $(DEBUG_FLAGS)
+export LDLIBS = $(COVERAGE_LIBS) -lnornir -pthread -lrt -lm -lmlpack -llapack -lblas -lgsl -lgslcblas -larmadillo -lknarr -lanl
+export INCS = -I$(realpath ./src/external/fastflow) -I$(realpath ./src/external/tclap-1.2.1/include) -I/usr/include/libxml2
+export LDFLAGS = -L$(realpath .)/src -L$(realpath .)/src/external/knarr/src
-.PHONY: all demo clean cleanall install uninstall microbench bin
+.PHONY: all demo clean cleanall install uninstall microbench bin test gcov develcheck
all:
python submodules_init.py
@@ -21,16 +21,38 @@ all:
$(MAKE) -C microbench checksupported
clean:
$(MAKE) -C src clean
+ $(MAKE) -C demo clean
+ $(MAKE) -C examples clean
+ $(MAKE) -C microbench clean
+ $(MAKE) -C bin clean
+ $(MAKE) -C test clean
demo:
$(MAKE) -C demo
$(MAKE) -C examples
bin:
$(MAKE) -C bin
+cppcheck:
+ cppcheck --xml --xml-version=2 --enable=warning,performance,information,style --inline-suppr --error-exitcode=1 --force . --suppressions-list=./test/cppcheck/suppressions-list.txt -isrc/external -itest -iexamples 2> cppcheck-report.xml || (cat cppcheck-report.xml; exit 2)
+# Compiles and runs all the tests.
+test:
+ make cleanall
+ make "COVERAGE_FLAGS=-fprofile-arcs -ftest-coverage"
+ cd test && ./installdep.sh
+ cd ..
+ $(MAKE) "COVERAGE_LIBS=-lgcov" -C test && cd test && ./runtests.sh
+ cd ..
+gcov:
+ ./test/gcov/gcov.sh
+# Performs all the checks
+develcheck:
+ $(MAKE) cppcheck && $(MAKE) test && $(MAKE) gcov && $(MAKE) bin
cleanall:
$(MAKE) -C src cleanall
$(MAKE) -C demo cleanall
$(MAKE) -C examples cleanall
$(MAKE) -C microbench cleanall
+ $(MAKE) -C bin cleanall
+ $(MAKE) -C test cleanall
install:
$(MAKE) -C src install
uninstall:
diff --git a/bin/Makefile b/bin/Makefile
index f7ed637..47fe1d2 100644
--- a/bin/Makefile
+++ b/bin/Makefile
@@ -1,4 +1,4 @@
-TARGET = manager-single manager-external
+TARGET = manager-single manager-external manager-blackbox
.PHONY: all clean cleanall
diff --git a/bin/manager-blackbox.cpp b/bin/manager-blackbox.cpp
new file mode 100644
index 0000000..697cb6a
--- /dev/null
+++ b/bin/manager-blackbox.cpp
@@ -0,0 +1,357 @@
+/*
+ * manager-external.cpp
+ *
+ * Created on: 21/06/2016
+ *
+ * This executable starts a manager which can monitor applications not written
+ * with the Nornir framework.
+ *
+ * =========================================================================
+ * Copyright (C) 2015-, Daniele De Sensi (d.desensi.software@gmail.com)
+ *
+ * This file is part of nornir.
+ *
+ * nornir is free software: you can redistribute it and/or
+ * modify it under the terms of the Lesser GNU General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+
+ * nornir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Lesser GNU General Public License for more details.
+ *
+ * You should have received a copy of the Lesser GNU General Public
+ * License along with nornir.
+ * If not, see .
+ *
+ * =========================================================================
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../src/nornir.hpp"
+#include
+
+using namespace nornir;
+
+#undef DEBUG
+#undef DEBUGB
+
+#define DEBUG_MBB
+
+#ifdef DEBUG_MBB
+#define DEBUG(x) do { cerr << "[BlackBox Manager] " << x << endl; } while (0)
+#define DEBUGB(x) do {x;} while(0)
+#else
+#define DEBUG(x)
+#define DEBUGB(x)
+#endif
+
+struct ScheduledProgram;
+
+typedef struct ScheduledProgram{
+ friend std::ostream& operator <<(std::ostream& os, const ScheduledProgram& instance);
+ double start;
+ double minPerfRequired;
+ std::vector program;
+ pid_t pid;
+}ScheduledProgram;
+
+std::ostream& operator <<(std::ostream& os, const ScheduledProgram& instance){
+ os << "Starts at: [" << instance.start << "] ";
+ os << "Minimum performance required: [" << instance.minPerfRequired << "] ";
+ os << "Program: [";
+ for(size_t i = 0; i < instance.program.size(); i++){
+ os << instance.program[i] << " ";
+ }
+ os << "]";
+ return os;
+}
+
+void initializeParameters(Parameters& p){
+ p.requirements.bandwidth = NORNIR_REQUIREMENT_MAX;
+ p.samplingIntervalCalibration = 100;
+ p.samplingIntervalSteady = 1000;
+ p.strategySelection = STRATEGY_SELECTION_LEARNING;
+ p.strategyPredictionPerformance = STRATEGY_PREDICTION_PERFORMANCE_USLP;
+ p.knobMappingEnabled = false;
+ p.knobHyperthreadingEnabled = false;
+}
+
+static std::string pidToString(pid_t pid){
+ stringstream out;
+ out << pid;
+ return out.str();
+}
+
+int main(int argc, char * argv[]){
+ std::vector pids;
+ std::vector pidPerfs;
+ std::vector scheduledPrograms;
+ std::string logDir;
+ std::string parametersFile;
+ double powerCap;
+ double startTime = mammut::utils::getMillisecondsTime();
+ try {
+ TCLAP::CmdLine cmd("Runs Nornir on already existing processes, coordinating "
+ "their requirements. It is also possible to specify new "
+ "programs to be ran. One parameter between --pid or "
+ "--schedule must be specified.", ' ', "1.0");
+ TCLAP::ValueArg logArg("l", "logdir", "Directory where the log files will be stored. (default = ./logs)", false, "./logs/", "string", cmd);
+ TCLAP::ValueArg parametersArg("r", "parameters", "Nornir parameters file. Can be specified only when only one application needs "
+ "to be controlled.", false, "", "string", cmd);
+ TCLAP::ValueArg capArg("c", "cap", "Power cap, expressed in watts. If 0, no power cap will "
+ "be applied and we will just maximise performance for each submitted "
+ "application. (default = 0).", false, 0, "double", cmd);
+ TCLAP::MultiArg pidArg("p", "pid", "PID of a running process.", false, "long", cmd);
+ TCLAP::MultiArg perfArg("m", "minperf", "Minimum performance required (one value for each PID, in the same "
+ "order. It is expressed as a percentage of the maximum achievable performance. For "
+ "example, a value of 80 means that we would like to do not decrease the performance "
+ "of the application below the 80% of its maximum. 0 means no specific requirement.",
+ false, "double", cmd);
+ TCLAP::ValueArg scheduleArg("s", "schedule", "Name of the file containing the schedule of "
+ "the programs to be run. The file has multiple lines, each one with "
+ "the following syntax:\n"
+ "StartTime MinPerformanceRequired ProgramPath ProgramArguments\n"
+ "The start time is a relative offset starting from the start of this "
+ "executable.\n"
+ "MinPerformanceRequired is a value in the range [0, 100] "
+ "representing the minimum required performance, expressed as a percentage "
+ "of the maximum achievable performance. For example, a value of 80 means "
+ "that we would like to do not decrease the performance of the application "
+ "below the 80% of its maximum. 0 means no specific requirement.\n"
+ "The lines must be sorted increasingly by start time.",
+ false, "", "string", cmd);
+ cmd.parse(argc, argv);
+
+ /* Validate parameters. */
+ if(!pidArg.getValue().size() &&
+ !scheduleArg.getValue().compare("")){
+ std::cerr << "[ERROR] One between --pid or --schedule must be specified." << std::endl;
+ return -1;
+ }
+
+ if(pidArg.getValue().size() !=
+ perfArg.getValue().size()){
+ std::cerr << "[ERROR] You must specify one minimum performance requirement for each pid." << std::endl;
+ return -1;
+ }
+
+ logDir = logArg.getValue();
+ powerCap = capArg.getValue();
+ pids = pidArg.getValue();
+ pidPerfs = perfArg.getValue();
+ parametersFile = parametersArg.getValue();
+
+ if(pids.size()){
+ std::cerr << "Sorry, --pid is still not supported. This is mainly due to difficulties in attaching to an already running "
+ "(non child) process to read the counters. Moreover, even if we could attach, we would not be able to monitor "
+ "the already created childrens/threads." << std::endl;
+ }
+
+ if(!mammut::utils::existsDirectory(logDir)){
+ std::cerr << "Specified logging directory doesn't exist. Please create it before running." << std::endl;
+ return -1;
+ }
+
+ /* Load schedule. */
+ std::ifstream scheduleFile(scheduleArg.getValue());
+ std::string line;
+ while(std::getline(scheduleFile, line)){
+ std::vector fields;
+ fields = mammut::utils::split(line, ' ');
+ if(fields.size() < 3){
+ std::cerr << "Invalid scheduled line: " << line << ". You must at least "
+ "specify the scheduled time, minimum performance required "
+ "and program name." << std::endl;
+ return -1;
+ }
+ ScheduledProgram sp;
+ sp.start = mammut::utils::stringToDouble(fields[0]);
+ sp.minPerfRequired = mammut::utils::stringToDouble(fields[1]);
+ sp.program = std::vector(fields.begin() + 2, fields.end());
+ DEBUG("Read schedule: " << sp);
+ scheduledPrograms.push_back(sp);
+ }
+ scheduleFile.close();
+ }catch (TCLAP::ArgException &e){
+ std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
+ return -1;
+ }
+
+ if(parametersFile.compare("") && scheduledPrograms.size() > 1){
+ std::cerr << "Parameter file can only be specified when you want to control only one application." << std::endl;
+ return -1;
+ }
+
+ ManagerMultiConfiguration mmc;
+ mmc.powerCap = powerCap;
+ ManagerMulti mm(mmc);
+ bool multiManagerNeeded = false;
+ if(pids.size() + scheduledPrograms.size() > 1){
+ multiManagerNeeded = true;
+ mm.start();
+ DEBUG("Multi manager started.");
+ }
+
+ /* First we add the already running pid. */
+ for(size_t i = 0; i < pids.size(); i++){
+ Parameters p;
+ if(parametersFile.compare("")){
+ p.load(parametersFile);
+ }else{
+ initializeParameters(p);
+ }
+ std::string logPrefix = logDir + "/" + pidToString(pids.at(i));
+ p.loggers.push_back(new LoggerFile(logPrefix + "_stats.csv",
+ logPrefix + "_calibration.csv",
+ logPrefix + "_summary.csv",
+ mammut::utils::getMillisecondsTime() - startTime));
+ ManagerBlackBox* m = new ManagerBlackBox(pids.at(i), p);
+ if(multiManagerNeeded){
+ mm.addManager(m, pidPerfs.at(i));
+ DEBUG("Added PID: " << pids.at(i) <<
+ " to the multimanager with minPerf " << pidPerfs.at(i));
+ }else{
+ m->start();
+ DEBUG("Started PID: " << pids.at(i));
+ m->join();
+ delete m;
+ delete p.loggers.back();
+ p.loggers.pop_back();
+ }
+ }
+
+ /* Then we start following the schedule. */
+ volatile bool* started = (bool*) mmap(NULL, sizeof(volatile bool), PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ volatile bool* handlerCreated = (bool*) mmap(NULL, sizeof(volatile bool), PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+
+ if(started == MAP_FAILED || handlerCreated == MAP_FAILED){
+ std::cerr << "mmap failed."<< std::endl;
+ return -1;
+ }
+
+ *started = false;
+ *handlerCreated = false;
+ double lastStart = 0;
+
+ for(size_t i = 0; i < scheduledPrograms.size(); i++){
+ ScheduledProgram& sp = scheduledPrograms[i];
+ sleep(sp.start - lastStart);
+ lastStart = sp.start;
+
+ void* mmem = (void*) mmap(NULL, sizeof(ManagerBlackBox), PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ if(mmem == MAP_FAILED){
+ std::cerr << "mmap failed." << std::endl;
+ return -1;
+ }
+
+ pid_t pid = fork();
+ if(pid == -1){
+ std::cerr << "Fork failed." << std::endl;
+ return -1;
+ }else if(pid){
+ /* Father - Manager. */
+ sp.pid = pid;
+ Parameters p;
+ if(parametersFile.compare("")){
+ p.load(parametersFile);
+ }else{
+ initializeParameters(p);
+ }
+ stringstream out;
+ out << sp.start;
+ std::string logPrefix = logDir + "/" + out.str() + "_" + mammut::utils::split(sp.program.at(0), '/').back();
+ p.loggers.push_back(new LoggerFile(logPrefix + "_stats.csv",
+ logPrefix + "_calibration.csv",
+ logPrefix + "_summary.csv",
+ mammut::utils::getMillisecondsTime() - startTime));
+ while(!*started){;}
+
+ ManagerBlackBox* m = new (mmem) ManagerBlackBox(pid, p);
+ *handlerCreated = true;
+ DEBUG("Started scheduled: " << sp.program[0] << " with pid " << pid << " on manager " << m);
+
+ if(multiManagerNeeded){
+ mm.addManager(m, sp.minPerfRequired);
+ // Wait for the child to reset the flags.
+ while(*handlerCreated){;}
+ }else{
+ m->start();
+ waitpid(pid, NULL, 0);
+ m->join();
+ m->~ManagerBlackBox(); // Because created with placement new
+ delete p.loggers.back();
+ p.loggers.pop_back();
+ }
+ }else{
+ /* Child - Application */
+ //ptrace(PTRACE_TRACEME, 0, 0, NULL);
+ *started = true;
+ // If the handler is not created, we would not catch the counters of
+ // the threads/processes created by this process
+ while(!*handlerCreated){;}
+
+ extern char** environ;
+ char** arguments = new char*[sp.program.size() + 1];
+ for(size_t i = 0; i < sp.program.size(); i++){
+ arguments[i] = new char[sp.program[i].size() + 1];
+ strcpy(arguments[i], sp.program[i].c_str());
+ }
+ arguments[sp.program.size()] = NULL;
+ DEBUG("Running program " << sp.program[0]);
+ /* Resets flag for next scheduled application. */
+ *started = false;
+ *handlerCreated = false;
+ if(execve(arguments[0], arguments, environ) == -1){
+ std::cerr << "Impossible to run the specified executable. Terminating the manager." << std::endl;
+ static_cast(mmem)->terminate();
+ // Useless since is never executed, inserted only to avoid cppcheck errors.
+ for(size_t i = 0; i < sp.program.size(); i++){
+ delete[] arguments[i];
+ }
+ delete[] arguments;
+ return -1;
+ }
+ // Useless since is never executed, inserted only to avoid cppcheck errors.
+ for(size_t i = 0; i < sp.program.size(); i++){
+ delete[] arguments[i];
+ }
+ delete[] arguments;
+ return -1; // execve never returns (except in the error case above).
+ }
+ }
+
+ DEBUG("All specified programs have been added to the monitoring system. Waiting for their termination...");
+ /* All programs scheduled, now wait for termination and clean. */
+ if(multiManagerNeeded){
+ for(size_t i = 0; i < scheduledPrograms.size(); i++){
+ waitpid(scheduledPrograms[i].pid, NULL, 0);
+ DEBUG(scheduledPrograms[i].pid << " PID terminated (" << scheduledPrograms[i].program << ")");
+ }
+
+ for(size_t i = 0; i < pids.size() + scheduledPrograms.size(); i++){
+ ManagerBlackBox* m;
+ while((m = static_cast(mm.getTerminatedManager())) == NULL){
+ sleep(1);
+ }
+ DEBUG("Manager (" << m << ") terminated.");
+ if(mammut::utils::contains(pids, (long) m->getPid())){
+ delete m;
+ }else{
+ m->~ManagerBlackBox(); // Because we used placement new
+ }
+ //delete m->_p.observer;
+ }
+ }
+}
+
diff --git a/bin/manager-external.cpp b/bin/manager-external.cpp
index 409e2f6..300849e 100644
--- a/bin/manager-external.cpp
+++ b/bin/manager-external.cpp
@@ -4,7 +4,9 @@
* Created on: 21/06/2016
*
* This executable starts a manager which can monitor applications not written
- * with the Nornir framework.
+ * with the Nornir framework. Albeit more of such applications can run concurrently,
+ * no coordination between them is provided. The result may thus be inconsistent.
+ * Please use this binary to control at most one application at a time.
*
* =========================================================================
* Copyright (C) 2015-, Daniele De Sensi (d.desensi.software@gmail.com)
@@ -32,9 +34,7 @@
#include
#include
#include
-#include "../src/manager.hpp"
-#include "../src/manager-multi.hpp"
-#include "../src/monitor.hpp"
+#include "../src/nornir.hpp"
using namespace nornir;
using namespace nn;
@@ -56,40 +56,71 @@ class ApplicationInstance{
public:
nn::socket channel;
int chid;
- ManagerExternal *manager;
- Observer* observer;
+ ManagerInstrumented *manager;
- ApplicationInstance():channel(AF_SP, NN_PAIR), chid(0), manager(NULL), observer(NULL){;}
+ ApplicationInstance():channel(AF_SP, NN_PAIR), chid(0), manager(NULL){;}
};
+void managerCleanup(Manager* m, std::list& instances){
+ if(m){
+ for(auto it = instances.begin(); it != instances.end(); it++){
+ if((*it)->manager == m){
+ auto newit = std::next(it);
+ DEBUG("Application manager terminated, cleaning.");
+ delete ((*it)->manager);
+ (*it)->channel.shutdown((*it)->chid);
+ ApplicationInstance* ai = (*it);
+ instances.erase(it);
+ it = newit;
+ delete ai;
+ }
+ }
+ }
+}
+
int main(int argc, char * argv[]){
+ // TODO: at the moment we do not support concurrent applications.
+ // In the future the value of this flag should be given by the user
+ // when starts this executable.
+ bool multipleApplications = false;
+
nn::socket mainChannel(AF_SP, NN_PAIR);
int mainChid;
- mainChid = mainChannel.bind(EXTERNAL_CHANNEL_NAME);
+ mainChid = mainChannel.bind(INSTRUMENTATION_CONNECTION_CHANNEL);
std::list instances;
if(system("mkdir -p /tmp/nornir") == -1){throw std::runtime_error("Impossible to create nornir dir.");}
if(system("chmod ugo+rwx /tmp/nornir.ipc") == -1){throw std::runtime_error("Impossible to set permission to nornir channel.");}
if(system("chmod ugo+rwx /tmp/nornir/") == -1){throw std::runtime_error("Impossible to set permission nornir dir.");}
ManagerMulti mm;
- mm.start();
+ if(multipleApplications){
+ mm.start();
+ DEBUG("ManagerMulti started.");
+ }
+
while(true){
pid_t pid;
- assert(mainChannel.recv(&pid, sizeof(pid), 0) == sizeof(pid));
+ size_t r = mainChannel.recv(&pid, sizeof(pid), 0);
+ assert(r == sizeof(pid));
DEBUG("Received a request from process " << pid);
ApplicationInstance* ai = new ApplicationInstance;
- ai->chid = ai->channel.bind((string("ipc:///tmp/nornir/") + mammut::utils::intToString(pid) + string(".ipc")).c_str());
+ ai->chid = ai->channel.bind((string("ipc:///tmp/nornir/") +
+ mammut::utils::intToString(pid) +
+ string(".ipc")).c_str());
DEBUG("Created app channel.");
DEBUG("Sending ack.");
- char ack;
- assert(mainChannel.send(&ack, sizeof(ack), 0) == sizeof(ack));
+ char ack = 0;
+ r = mainChannel.send(&ack, sizeof(ack), 0);
+ assert(r == sizeof(ack));
size_t length = 0;
- assert(ai->channel.recv(&length, sizeof(length), 0) == sizeof(length));
+ r = ai->channel.recv(&length, sizeof(length), 0);
+ assert(r == sizeof(length));
char* parameters = new char[length];
DEBUG("Receiving parameters.");
- assert(ai->channel.recv(parameters, length*sizeof(char), 0) == (int) (sizeof(char)*length));
+ r = ai->channel.recv(parameters, length*sizeof(char), 0);
+ assert(r == (sizeof(char)*length));
std::string parametersString(parameters);
std::ofstream out("parameters.xml");
out << parametersString;
@@ -101,30 +132,30 @@ int main(int argc, char * argv[]){
Parameters p("parameters.xml");
ParametersValidation pv = p.validate();
DEBUG("Sending validation result.");
- assert(ai->channel.send(&pv, sizeof(pv), 0) == sizeof(pv));
- ai->observer = new Observer();
- p.observer = ai->observer;
- ai->manager = new ManagerExternal(ai->channel, ai->chid, p);
+ r = ai->channel.send(&pv, sizeof(pv), 0);
+ assert(r == sizeof(pv));
+ ai->manager = new ManagerInstrumented(ai->channel, ai->chid, p);
ai->manager->start();
- instances.push_back(ai);
- mm.addManager(ai->manager);
+ DEBUG("Manager started.");
+
+ // Add to the list of running managers and to the multimanager.
+ if(multipleApplications){
+ instances.push_back(ai);
+ mm.addManager(ai->manager);
+ }
/** Try to join and delete already terminated managers. **/
Manager* m;
- m = mm.getTerminatedManager();
- if(m){
- for(auto it = instances.begin(); it != instances.end(); it++){
- if((*it)->manager == m){
- DEBUG("Application manager terminated, cleaning.");
- delete ((*it)->manager);
- (*it)->channel.shutdown((*it)->chid);
- ApplicationInstance* ai = (*it);
- instances.erase(it);
- delete ((*it)->observer);
- delete ai;
- }
- }
+ // Corunning applications.
+ if(multipleApplications){
+ m = mm.getTerminatedManager();
+ }else{
+ // Single application.
+ m = ai->manager;
+ DEBUG("Joining manager.");
+ m->join();
}
+ managerCleanup(m, instances);
}
mainChannel.shutdown(mainChid);
return 0;
diff --git a/bin/manager-single.cpp b/bin/manager-single.cpp
index 44695ae..b3099b4 100644
--- a/bin/manager-single.cpp
+++ b/bin/manager-single.cpp
@@ -1,6 +1,9 @@
/*
* manager-single.cpp
*
+ * Monitors and adapt an external application by using the knarr library.
+ * Needs the explicit channel name. This is deprecated. Use manager-external.
+ *
* Created on: 21/06/2016
*
* =========================================================================
@@ -28,7 +31,7 @@
#include
#include
#include
-#include "../src/manager.hpp"
+#include "../src/nornir.hpp"
using namespace nornir;
@@ -43,7 +46,7 @@ int main(int argc, char * argv[]) {
channelName = argv[1];
Parameters p("parameters.xml");
- ManagerExternal m(channelName, p);
+ ManagerInstrumented m(channelName, p);
m.start();
m.join();
diff --git a/demo/Makefile b/demo/Makefile
index 739ef1e..9f1dcee 100644
--- a/demo/Makefile
+++ b/demo/Makefile
@@ -1,4 +1,4 @@
-TARGET = application_external farm farm_ffcompat farm_accelerator_1 farm_accelerator_2 farm_accelerator_3 farm_accelerator_4
+TARGET = application_instrumented farm farm_ffcompat farm_accelerator_1 farm_accelerator_2 farm_accelerator_3 farm_accelerator_4
INCS += -I$(realpath ../src)
.PHONY: all clean cleanall
diff --git a/demo/application_instrumented.cpp b/demo/application_instrumented.cpp
new file mode 100644
index 0000000..c2845bf
--- /dev/null
+++ b/demo/application_instrumented.cpp
@@ -0,0 +1,57 @@
+/*
+ * application_instrumented.cpp
+ *
+ * Created on: 05/07/2016
+ *
+ * =========================================================================
+ * Copyright (C) 2015-, Daniele De Sensi (d.desensi.software@gmail.com)
+ *
+ * This file is part of nornir.
+ *
+ * nornir is free software: you can redistribute it and/or
+ * modify it under the terms of the Lesser GNU General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+
+ * nornir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Lesser GNU General Public License for more details.
+ *
+ * You should have received a copy of the Lesser GNU General Public
+ * License along with nornir.
+ * If not, see .
+ *
+ * =========================================================================
+ */
+
+#include "../src/nornir.hpp"
+
+#include
+
+/**
+ * Basic example on how to monitor an instrumented iterative application.
+ * Original code was:
+ * --------------------------------
+ * int main(int argc, char** argv){
+ * size_t i = 0;
+ * while(i++ < 10){
+ * sleep(2);
+ * }
+ * return 0;
+ * }
+ * --------------------------------
+ * Instrumented code is:
+ */
+int main(int argc, char** argv){
+ nornir::Instrumenter instr("parameters.xml");
+ size_t i = 0;
+ while(i++ < 10){
+ instr.begin();
+ sleep(2);
+ instr.end();
+ }
+ instr.terminate();
+ return 0;
+}
+
diff --git a/demo/dataflow/asciiMandelbrot.cpp b/demo/dataflow/asciiMandelbrot.cpp
index 63c89b1..21ec6ea 100644
--- a/demo/dataflow/asciiMandelbrot.cpp
+++ b/demo/dataflow/asciiMandelbrot.cpp
@@ -27,18 +27,18 @@
#include
#include
-#include "../../src/dataflow/interpreter.hpp"
+#include "../../src/nornir.hpp"
using namespace nornir::dataflow;
class MandelInputStream: public nornir::dataflow::InputStream{
private:
- int x, y;
- bool eos;
- clock_t t;
+ int x, y;
+ bool eos;
+ clock_t t;
public:
- inline MandelInputStream():x(-39), y(-39), eos(false),
- t(clock()){;}
+ inline MandelInputStream():x(-39), y(-39), eos(false),
+ t(clock()){;}
inline void* next(){
if(x == 39 && y == 38){
@@ -56,25 +56,25 @@ class MandelInputStream: public nornir::dataflow::InputStream{
t->set(1, y/40.0f);
++x;
return t;
- }
+ }
- inline bool hasNext(){return !eos;}
+ inline bool hasNext(){return !eos;}
};
class MandelOutputStream: public nornir::dataflow::OutputStream{
public:
void put(void* a){
- float* dt = (float*) a;
- float x = *dt;
- if(x == 0)
- std::cout << "*";
- else if(x == -1)
- std::cout << std::endl;
- else
- std::cout << " ";
- delete dt;
- }
+ float* dt = (float*) a;
+ float x = *dt;
+ if(x == 0)
+ std::cout << "*";
+ else if(x == -1)
+ std::cout << std::endl;
+ else
+ std::cout << " ";
+ delete dt;
+ }
};
int BAILOUT = 16;
@@ -82,52 +82,50 @@ int MAX_ITERATIONS;
/**Function taken from http://www.timestretch.com/FractalBenchmark.html#67b4f5a3200c7b7e900c38ff21321741 **/
float* iterateTask(ArrayWrapper* t){
- float f1 = t->get(1);
- float f2 = t->get(0);
- delete t;
- if(f2 == -100000){
- return new float(-1);
- }
+ float f1 = t->get(1);
+ float f2 = t->get(0);
+ delete t;
+ if(f2 == -100000){
+ return new float(-1);
+ }
- float cr = f1-0.5f;
- float ci = f2;
- float zi = 0.0f;
- float zr = 0.0f;
- int i = 0;
+ float cr = f1-0.5f;
+ float ci = f2;
+ float zi = 0.0f;
+ float zr = 0.0f;
+ int i = 0;
while (true){
- i++;
- float temp = zr * zi;
- float zr2 = zr * zr;
- float zi2 = zi * zi;
- zr = zr2 - zi2 + cr;
- zi = temp + temp + ci;
- if (zi2 + zr2 > BAILOUT)
- return new float(i);
+ i++;
+ float temp = zr * zi;
+ float zr2 = zr * zr;
+ float zi2 = zi * zi;
+ zr = zr2 - zi2 + cr;
+ zi = temp + temp + ci;
+ if (zi2 + zr2 > BAILOUT)
+ return new float(i);
- if (i > MAX_ITERATIONS)
- return new float(0);
+ if (i > MAX_ITERATIONS)
+ return new float(0);
- }
+ }
}
int main(int argc, char** argv){
- if(argc < 2){
- std::cerr << "Usage:" << std::endl;
- std::cerr << argv[0] << " maxIterations" << std::endl;
- return -1;
- }else{
- MAX_ITERATIONS = atoi(argv[1]);
- MandelInputStream inp;
- MandelOutputStream out;
- nornir::dataflow::Farm* f = createStandardFarm, float, iterateTask>();
- nornir::Parameters p("parameters.xml");
- nornir::Observer o;
- p.observer = &o;
- Interpreter m(&p, f, &inp, &out);
- m.start();
- m.wait();
- delete f;
- return 0;
- }
+ if(argc < 2){
+ std::cerr << "Usage:" << std::endl;
+ std::cerr << argv[0] << " maxIterations" << std::endl;
+ return -1;
+ }else{
+ MAX_ITERATIONS = atoi(argv[1]);
+ MandelInputStream inp;
+ MandelOutputStream out;
+ nornir::dataflow::Farm* f = createStandardFarm, float, iterateTask>();
+ nornir::Parameters p("parameters.xml");
+ Interpreter m(&p, f, &inp, &out);
+ m.start();
+ m.wait();
+ delete f;
+ return 0;
+ }
}
diff --git a/demo/dataflow/graph.cpp b/demo/dataflow/graph.cpp
index da86656..bcf07fa 100644
--- a/demo/dataflow/graph.cpp
+++ b/demo/dataflow/graph.cpp
@@ -27,25 +27,26 @@
#include
#include
-#include "../../src/dataflow/interpreter.hpp"
+#include "../../src/nornir.hpp"
using namespace nornir::dataflow;
class DemoInputStream: public nornir::dataflow::InputStream{
private:
size_t _currentElem;
- size_t _streamSize;
- bool _eos;
+ size_t _streamSize;
+ bool _eos;
public:
- inline DemoInputStream(size_t streamSize):
- _currentElem(0), _streamSize(streamSize), _eos(false){
- srand(time(NULL));
+ explicit inline DemoInputStream(size_t streamSize):
+ _currentElem(0), _streamSize(streamSize), _eos(false){
+ srand(time(NULL));
}
inline void* next(){
if(_currentElem < _streamSize){
++_currentElem;
- int* s = new int(rand());
+ int* s = new int();
+ *s = rand();
std::cout << "Generated " << *s << std::endl;
std::cout << "Expected output " << ((*s + 1)*2 + (*s + 2) + 10 + 2) * ( (*s + 2) + 20) << std::endl;
return (void*) s;
diff --git a/demo/dataflow/mapSimple.cpp b/demo/dataflow/mapSimple.cpp
index c4d545d..1ef9cb9 100644
--- a/demo/dataflow/mapSimple.cpp
+++ b/demo/dataflow/mapSimple.cpp
@@ -27,7 +27,7 @@
#include
#include
-#include "../../src/dataflow/interpreter.hpp"
+#include "../../src/nornir.hpp"
using namespace nornir::dataflow;
@@ -39,20 +39,20 @@ class DemoInputStream: public nornir::dataflow::InputStream{
size_t _streamSize;
bool _eos;
public:
- inline DemoInputStream(size_t streamSize):
+ explicit inline DemoInputStream(size_t streamSize):
_currentElem(0), _streamSize(streamSize), _eos(false){
srand(time(NULL));
}
inline void* next(){
- ArrayWrapper* aw;
if(_currentElem < _streamSize){
++_currentElem;
size_t size = rand() % MAX_SIZE;
- aw = new ArrayWrapper(size);
+ ArrayWrapper* aw = new ArrayWrapper(size);
std::cout << "Generated: [";
for(size_t i = 0; i < size; i++){
- float* x = new float((rand() % 100)* 0.1);
+ float* x = new float();
+ *x = (rand() % 100)* 0.1;
aw->set(i, x);
std::cout << *x << ", ";
}
@@ -84,6 +84,7 @@ class DemoOutputStream: public nornir::dataflow::OutputStream{
int* fun(float* x){
*x = floor(*x);
+ //cppcheck-suppress invalidPointerCast
return (int*) x;
}
diff --git a/demo/dataflow/pipeMap.cpp b/demo/dataflow/pipeMap.cpp
index 0cd19b2..5ea2ce4 100644
--- a/demo/dataflow/pipeMap.cpp
+++ b/demo/dataflow/pipeMap.cpp
@@ -27,7 +27,7 @@
#include
#include
-#include "../../src/dataflow/interpreter.hpp"
+#include "../../src/nornir.hpp"
using namespace nornir::dataflow;
@@ -39,20 +39,20 @@ class DemoInputStream: public nornir::dataflow::InputStream{
size_t _streamSize;
bool _eos;
public:
- inline DemoInputStream(size_t streamSize):
+ explicit inline DemoInputStream(size_t streamSize):
_currentElem(0), _streamSize(streamSize), _eos(false){
srand(time(NULL));
}
inline void* next(){
- ArrayWrapper* aw;
if(_currentElem < _streamSize){
++_currentElem;
size_t size = rand() % MAX_SIZE;
- aw = new ArrayWrapper(size);
+ ArrayWrapper* aw = new ArrayWrapper(size);
std::cout << "Generated: [";
for(size_t i = 0; i < size; i++){
- float* x = new float((rand() % 100)* 0.1);
+ float* x = new float();
+ *x = (rand() % 100)* 0.1;
aw->set(i, x);
std::cout << *x << ", ";
}
@@ -84,6 +84,7 @@ class DemoOutputStream: public nornir::dataflow::OutputStream{
int* fun(float* x){
*x = floor(*x);
+ //cppcheck-suppress invalidPointerCast
return (int*) x;
}
diff --git a/demo/dataflow/pipeMap2.cpp b/demo/dataflow/pipeMap2.cpp
index 21b7954..8d7c317 100644
--- a/demo/dataflow/pipeMap2.cpp
+++ b/demo/dataflow/pipeMap2.cpp
@@ -27,7 +27,7 @@
#include
#include
-#include "../../src/dataflow/interpreter.hpp"
+#include "../../src/nornir.hpp"
using namespace nornir::dataflow;
@@ -39,20 +39,20 @@ class DemoInputStream: public nornir::dataflow::InputStream{
size_t _streamSize;
bool _eos;
public:
- inline DemoInputStream(size_t streamSize):
+ explicit inline DemoInputStream(size_t streamSize):
_currentElem(0), _streamSize(streamSize), _eos(false){
srand(time(NULL));
}
inline void* next(){
- ArrayWrapper* aw;
if(_currentElem < _streamSize){
++_currentElem;
size_t size = rand() % MAX_SIZE;
- aw = new ArrayWrapper(size);
+ ArrayWrapper* aw = new ArrayWrapper(size);
std::cout << "Generated: [";
for(size_t i = 0; i < size; i++){
- float* x = new float((rand() % 100)* 0.1);
+ float* x = new float();
+ *x = (rand() % 100)* 0.1;
aw->set(i, x);
std::cout << *x << ", ";
}
@@ -89,6 +89,7 @@ float* fun1(float* x){
int* fun2(float* x){
*x = floor(*x);
+ //cppcheck-suppress invalidPointerCast
return (int*) x;
}
diff --git a/demo/dataflow/pipeline.cpp b/demo/dataflow/pipeline.cpp
index da8e185..5c41bbd 100644
--- a/demo/dataflow/pipeline.cpp
+++ b/demo/dataflow/pipeline.cpp
@@ -27,7 +27,7 @@
#include
#include
-#include "../../src/dataflow/interpreter.hpp"
+#include "../../src/nornir.hpp"
using namespace nornir::dataflow;
@@ -39,7 +39,7 @@ class DemoInputStream: public nornir::dataflow::InputStream{
size_t _streamSize;
bool _eos;
public:
- inline DemoInputStream(size_t streamSize):
+ explicit inline DemoInputStream(size_t streamSize):
_currentElem(0), _streamSize(streamSize), _eos(false){
srand(time(NULL));
}
@@ -49,7 +49,8 @@ class DemoInputStream: public nornir::dataflow::InputStream{
if(_currentElem < _streamSize){
int* x;
++_currentElem;
- x = new int(rand() % 1000);
+ x = new int();
+ *x = rand() % 1000;
std::cout << "Generated: " << *x << std::endl;
std::cout << "ExpectedOutput: " << ((*x + 3) * 4) + 1 << std::endl;
return (void*) x;
diff --git a/demo/farm.cpp b/demo/farm.cpp
index a67c643..843fff4 100644
--- a/demo/farm.cpp
+++ b/demo/farm.cpp
@@ -33,7 +33,7 @@
#include
#include
#include
-#include "../src/interface.hpp"
+#include "../src/nornir.hpp"
using namespace ff;
@@ -52,8 +52,10 @@ class Emitter: public nornir::Scheduler{
--maxTasks;
if (maxTasks < 0){
std::cout << "Scheduler finished" << std::endl;
+ //cppcheck-suppress memleak
return NULL;
}
+ //cppcheck-suppress memleak
return task;
}
};
diff --git a/demo/farm_accelerator_1.cpp b/demo/farm_accelerator_1.cpp
index 764cd7e..1f14561 100644
--- a/demo/farm_accelerator_1.cpp
+++ b/demo/farm_accelerator_1.cpp
@@ -32,7 +32,7 @@
#include
#include
#include
-#include "../src/interface.hpp"
+#include "../src/nornir.hpp"
using namespace ff;
@@ -77,9 +77,6 @@ int main(int argc, char * argv[]) {
maxTasks = streamlen;
nornir::Parameters p("parameters.xml");
- p.contractType = nornir::CONTRACT_NONE;
- nornir::Observer o;
- p.observer = &o;
nornir::FarmAccelerator farm(&p);
for(size_t i = 0; i < (size_t) nworkers; i++){
farm.addWorker(new Worker);
diff --git a/demo/farm_accelerator_2.cpp b/demo/farm_accelerator_2.cpp
index f2a195f..f084787 100644
--- a/demo/farm_accelerator_2.cpp
+++ b/demo/farm_accelerator_2.cpp
@@ -32,7 +32,7 @@
#include
#include
#include
-#include "../src/interface.hpp"
+#include "../src/nornir.hpp"
using namespace ff;
@@ -88,9 +88,6 @@ int main(int argc, char * argv[]) {
maxTasks = streamlen;
nornir::Parameters p("parameters.xml");
- p.contractType = nornir::CONTRACT_NONE;
- nornir::Observer o;
- p.observer = &o;
nornir::FarmAccelerator farm(&p);
farm.addScheduler(new Scheduler);
for(size_t i = 0; i < (size_t) nworkers; i++){
diff --git a/demo/farm_accelerator_3.cpp b/demo/farm_accelerator_3.cpp
index cc2571c..cb47eef 100644
--- a/demo/farm_accelerator_3.cpp
+++ b/demo/farm_accelerator_3.cpp
@@ -32,7 +32,7 @@
#include
#include
#include
-#include "../src/interface.hpp"
+#include "../src/nornir.hpp"
using namespace ff;
@@ -95,9 +95,6 @@ int main(int argc, char * argv[]) {
maxTasks = streamlen;
nornir::Parameters p("parameters.xml");
- p.contractType = nornir::CONTRACT_NONE;
- nornir::Observer o;
- p.observer = &o;
nornir::FarmAccelerator farm(&p);
farm.addScheduler(new Scheduler);
for(size_t i = 0; i < (size_t) nworkers; i++){
diff --git a/demo/farm_accelerator_4.cpp b/demo/farm_accelerator_4.cpp
index 85daa51..50fc510 100644
--- a/demo/farm_accelerator_4.cpp
+++ b/demo/farm_accelerator_4.cpp
@@ -32,7 +32,7 @@
#include
#include
#include
-#include "../src/interface.hpp"
+#include "../src/nornir.hpp"
using namespace ff;
@@ -97,9 +97,6 @@ int main(int argc, char * argv[]) {
maxTasks = streamlen;
nornir::Parameters p("parameters.xml");
- p.contractType = nornir::CONTRACT_NONE;
- nornir::Observer o;
- p.observer = &o;
nornir::FarmAccelerator farm(&p);
farm.addScheduler(new Scheduler);
for(size_t i = 0; i < (size_t) nworkers; i++){
diff --git a/demo/farm_ffcompat.cpp b/demo/farm_ffcompat.cpp
index d28aa67..e71bed2 100644
--- a/demo/farm_ffcompat.cpp
+++ b/demo/farm_ffcompat.cpp
@@ -44,7 +44,7 @@
#include
#include
#include
-#include "../src/manager.hpp"
+#include "../src/nornir.hpp"
using namespace ff;
@@ -55,7 +55,7 @@ using namespace ff;
*/
class Emitter: public nornir::AdaptiveNode {
public:
- Emitter(int max_task):ntask(max_task) {};
+ explicit Emitter(int max_task):ntask(max_task){;}
void * svc(void *) {
usleep(MICROSECSSLEEP);
@@ -63,8 +63,10 @@ class Emitter: public nornir::AdaptiveNode {
--ntask;
if (ntask<0){
std::cout << "Emitter finished" << std::endl;
+ //cppcheck-suppress memleak
TERMINATE_APPLICATION;
}
+ //cppcheck-suppress memleak
return task;
}
private:
@@ -146,7 +148,7 @@ int main(int argc, char * argv[]) {
/* START - New code needed with respect to the existing code. */
/***************************************************************/
nornir::Parameters ap("parameters.xml"); // Load parameters.
- nornir::ManagerFarm<> amf(&farm, ap); // Create nornir manager.
+ nornir::ManagerFastFlow<> amf(&farm, ap); // Create nornir manager.
amf.start(); // Start farm.
amf.join(); // Wait for farm end.
/***************************************************************/
diff --git a/demo/parameters.xml b/demo/parameters.xml
deleted file mode 100644
index f885d4f..0000000
--- a/demo/parameters.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- PERF_BANDWIDTH
- 10
-
diff --git a/examples/blackscholes/blackscholes-ext.c b/examples/blackscholes/blackscholes-ext.c
index 0024713..4e85423 100644
--- a/examples/blackscholes/blackscholes-ext.c
+++ b/examples/blackscholes/blackscholes-ext.c
@@ -12,7 +12,7 @@
#include
#include
-#include "../../src/external/orlog/src/orlog.hpp"
+#include "../../src/external/knarr/src/knarr.hpp"
#ifdef ENABLE_PARSEC_HOOKS
#include
@@ -377,7 +377,7 @@ int bs_thread(void *tid_ptr) {
int start = tid * (numOptions / nThreads);
int end = start + (numOptions / nThreads);
- orlog::Application app("ipc:///tmp/prova");
+ knarr::Application app("ipc:///tmp/prova");
for (j=0; j farm(&ap);
farm.start(nThreads);
diff --git a/examples/blackscholes/blackscholes.c b/examples/blackscholes/blackscholes.c
index 12df9de..332d055 100644
--- a/examples/blackscholes/blackscholes.c
+++ b/examples/blackscholes/blackscholes.c
@@ -42,7 +42,7 @@ using namespace tbb;
#ifdef ENABLE_FF
//#define BLOCKING_MODE
#include
-#include "../../src/interface.hpp"
+#include "../../src/nornir.hpp"
using namespace ff;
#endif //ENABLE_FF
@@ -553,10 +553,8 @@ int main (int argc, char **argv)
bs_thread(&tid);
#else //ENABLE_TBB
#ifdef ENABLE_FF
- nornir::Observer obs;
nornir::Parameters ap("parameters.xml");
- ap.observer = &obs;
- ap.expectedTasksNumber = numOptions * NUM_RUNS / CHUNKSIZE;
+ ap.requirements.expectedTasksNumber = numOptions * NUM_RUNS / CHUNKSIZE;
nornir::Farm farm(&ap);
farm.start(nThreads);
std::cout << "Farm started" << std::endl;
diff --git a/examples/blackscholes/parameters.xml b/examples/blackscholes/parameters.xml
deleted file mode 100644
index 857b58c..0000000
--- a/examples/blackscholes/parameters.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- POWER_BUDGET
- 60
-
-
-
diff --git a/examples/blackscholes/run.py b/examples/blackscholes/run.py
deleted file mode 100644
index cec1599..0000000
--- a/examples/blackscholes/run.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import math
-import subprocess
-import shlex
-import socket
-import os
-
-run = "cpupower frequency-set -g userspace"
-process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
-out, err = process.communicate()
-
-parametersFile = open("parameters.xml", "w")
-parametersFile.write("\n")
-parametersFile.write("\n")
-parametersFile.write("4\n")
-parametersFile.write("1000\n")
-parametersFile.write("NONE\n")
-parametersFile.write("SLEEP_SMALL\n")
-parametersFile.write("\n")
-parametersFile.close()
-
-outfile = open("REPARA_results.csv", "w")
-outfile.write("#Workers\tFrequency\tTime\tWatts\n")
-
-for c in xrange(1, 24):
- for f in [1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000]:
- run = "cpupower frequency-set -f " + str(f)
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
-
- run = "./blackscholes " + str(c) + " inputs/in_10M.txt tmp.txt"
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
-
- run = "tail -1 summary.csv"
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
- res = out.split("\t")
-
- watts = res[0]
- time = res[2]
- outfile.write("{}\t{}\t{}\t{}\n".format(c, f, time, watts))
- outfile.flush()
- os.fsync(outfile.fileno())
-
-outfile.close()
diff --git a/examples/canneal/main.cpp b/examples/canneal/main.cpp
index 72fe0c7..955737d 100644
--- a/examples/canneal/main.cpp
+++ b/examples/canneal/main.cpp
@@ -46,7 +46,7 @@
#include "netlist.h"
#include "rng.h"
-#include "../../src/interface.hpp"
+#include "../../src/nornir.hpp"
using namespace std;
using namespace nornir;
@@ -286,10 +286,8 @@ int main (int argc, char * const argv[]) {
#ifdef ENABLE_THREADS
#ifdef ENABLE_FF
- nornir::Observer obs;
nornir::Parameters ap("parameters.xml");
- ap.observer = &obs;
- ap.expectedTasksNumber = number_temp_steps;
+ ap.requirements.expectedTasksNumber = number_temp_steps;
ap.synchronousWorkers = true;
Farm farm(&ap);
diff --git a/examples/canneal/parameters.xml b/examples/canneal/parameters.xml
deleted file mode 100644
index 857b58c..0000000
--- a/examples/canneal/parameters.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- POWER_BUDGET
- 60
-
-
-
diff --git a/examples/canneal/run.py b/examples/canneal/run.py
deleted file mode 100644
index c914215..0000000
--- a/examples/canneal/run.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import math
-import subprocess
-import shlex
-import socket
-import os
-
-run = "cpupower frequency-set -g userspace"
-process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
-out, err = process.communicate()
-
-parametersFile = open("parameters.xml", "w")
-parametersFile.write("\n")
-parametersFile.write("\n")
-parametersFile.write("4\n")
-parametersFile.write("1000\n")
-parametersFile.write("NONE\n")
-parametersFile.write("SLEEP_SMALL\n")
-parametersFile.write("\n")
-parametersFile.close()
-
-outfile = open("REPARA_results.csv", "w")
-outfile.write("#Workers\tFrequency\tTime\tWatts\n")
-
-for c in xrange(1, 24):
- for f in [1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000]:
- os.remove("summary.csv")
- run = "cpupower frequency-set -f " + str(f)
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
-
- run = "./canneal " + str(c) + " 15000 2000 2500000.nets 6000"
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
-
- run = "tail -1 summary.csv"
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
- res = out.split("\t")
-
- watts = res[0]
- time = res[2]
- outfile.write("{}\t{}\t{}\t{}\n".format(c, f, time, watts))
- outfile.flush()
- os.fsync(outfile.fileno())
-
-outfile.close()
diff --git a/examples/dataflow/blackscholes/blackscholes.c b/examples/dataflow/blackscholes/blackscholes.c
index 28aaab0..afa5ea4 100644
--- a/examples/dataflow/blackscholes/blackscholes.c
+++ b/examples/dataflow/blackscholes/blackscholes.c
@@ -42,7 +42,7 @@ using namespace tbb;
#ifdef ENABLE_FF
//#define BLOCKING_MODE
#include
-#include "../../../src/dataflow/interpreter.hpp"
+#include "../../../src/nornir.hpp"
using namespace ff;
using namespace nornir;
@@ -550,17 +550,12 @@ int main (int argc, char **argv)
bs_thread(&tid);
#else //ENABLE_TBB
#ifdef ENABLE_FF
- nornir::Observer obs;
- nornir::Parameters ap("parameters.xml");
- ap.observer = &obs;
OptionsStreamRate oss(rateFile);
oss.init();
dataflow::Computable* farm = dataflow::createStandardFarm();
Parameters p("parameters.xml");
p.dataflow.maxInterpreters = nThreads;
- Observer o;
- p.observer = &o;
dataflow::Interpreter inter(&p, farm, &oss);
inter.start();
inter.wait();
diff --git a/examples/dataflow/ffprobe/ffProbe.cpp b/examples/dataflow/ffprobe/ffProbe.cpp
index 419dffb..06c0f50 100644
--- a/examples/dataflow/ffprobe/ffProbe.cpp
+++ b/examples/dataflow/ffprobe/ffProbe.cpp
@@ -8,7 +8,7 @@
* The main file.
*/
-#include "../../../src/dataflow/interpreter.hpp"
+#include "../../../src/nornir.hpp"
#include "ProbeTask.hpp"
#include "Flow.hpp"
#include "Stages.hpp"
@@ -133,8 +133,6 @@ void executeWithFaskel(){
for(uint i=2; i
#include
-#include "../../../src/dataflow/interpreter.hpp"
+#include "../../../src/nornir.hpp"
#define FIXED_STREAM
@@ -621,11 +621,9 @@ int main(int argc, char** argv){
/* Create interpreter. */
nornir::Parameters par("parameters.xml");
- nornir::Observer obs;
- par.observer = &obs;
#ifdef FIXED_STREAM
- par.expectedTasksNumber = atoi(argv[1])*graph.getNumMdfi();
- std::cout << "Expected tasks number: " << par.expectedTasksNumber << std::endl;
+ par.requirements.expectedTasksNumber = atoi(argv[1])*graph.getNumMdfi();
+ std::cout << "Expected tasks number: " << par.requirements.expectedTasksNumber << std::endl;
#endif
nornir::dataflow::Interpreter inter(&par, &graph, &inp, &out);
inter.start();
diff --git a/examples/denoiser/parameters.xml b/examples/denoiser/parameters.xml
deleted file mode 100644
index 857b58c..0000000
--- a/examples/denoiser/parameters.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- POWER_BUDGET
- 60
-
-
-
diff --git a/examples/denoiser/run.py b/examples/denoiser/run.py
deleted file mode 100644
index ce41d17..0000000
--- a/examples/denoiser/run.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import math
-import subprocess
-import shlex
-import socket
-import os
-
-run = "cpupower frequency-set -g userspace"
-process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
-out, err = process.communicate()
-
-parametersFile = open("parameters.xml", "w")
-parametersFile.write("\n")
-parametersFile.write("\n")
-parametersFile.write("1\n")
-parametersFile.write("1000\n")
-parametersFile.write("NONE\n")
-parametersFile.write("SLEEP_SMALL\n")
-parametersFile.write("\n")
-parametersFile.close()
-
-outfile = open("REPARA_results.csv", "w")
-outfile.write("#Workers\tFrequency\tTime\tWatts\n")
-
-for c in xrange(1, 23):
- for f in [1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000]:
- run = "cpupower frequency-set -f " + str(f)
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
-
- #run = "./video 0 1 0 " + str(c) + " VIRAT/960X540.mp4"
- run = "./video 0 1 0 " + str(c) + " VIRAT/480X270.mp4"
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
-
- run = "tail -1 summary.csv"
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
- res = out.split("\t")
-
- watts = res[0]
- time = res[2]
- outfile.write("{}\t{}\t{}\t{}\n".format(c, f, time, watts))
- outfile.flush()
- os.fsync(outfile.fileno())
-
-outfile.close()
diff --git a/examples/denoiser/video.cpp b/examples/denoiser/video.cpp
index f9b4abe..4670249 100644
--- a/examples/denoiser/video.cpp
+++ b/examples/denoiser/video.cpp
@@ -34,7 +34,7 @@
// ofarm(Stage1+Stage2)
#include
-#include "../../manager.hpp"
+#include "../../src/nornir.hpp"
using namespace ff;
using namespace cv;
@@ -172,13 +172,11 @@ int main(int argc, char *argv[]) {
Drain drain(outvideo);
ofarm.setCollectorF((ff_node*) &drain);
- nornir::Observer obs;
nornir::Parameters ap("parameters.xml");
- ap.observer = &obs;
if(numframes){
ap.expectedTasksNumber = numframes*numfiles;
}
- nornir::ManagerFarm amf(&ofarm, ap);
+ nornir::ManagerFastFlow amf(&ofarm, ap);
amf.start();
amf.join();
diff --git a/examples/mandelbrot/mandel_ff.cpp b/examples/mandelbrot/mandel_ff.cpp
index f0a59d6..53a4eef 100644
--- a/examples/mandelbrot/mandel_ff.cpp
+++ b/examples/mandelbrot/mandel_ff.cpp
@@ -46,7 +46,7 @@
*/
#include
-#include "../../src/manager.hpp"
+#include "../../src/nornir.hpp"
#include
#include "marX2.h"
@@ -246,11 +246,9 @@ int main(int argc, char ** argv) {
if(ncores>=4)
farm.add_collector(&C);
- nornir::Observer obs;
nornir::Parameters ap("parameters.xml");
- ap.observer = &obs;
ap.expectedTasksNumber = dim;
- nornir::ManagerFarm<> amf(&farm, ap);
+ nornir::ManagerFastFlow<> amf(&farm, ap);
amf.start();
std::cout << "amf started" << std::endl;
amf.join();
diff --git a/examples/mandelbrot/parameters.xml b/examples/mandelbrot/parameters.xml
deleted file mode 100644
index 857b58c..0000000
--- a/examples/mandelbrot/parameters.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- POWER_BUDGET
- 60
-
-
-
diff --git a/examples/mandelbrot/run.py b/examples/mandelbrot/run.py
deleted file mode 100644
index cab0262..0000000
--- a/examples/mandelbrot/run.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import math
-import subprocess
-import shlex
-import socket
-import os
-
-run = "cpupower frequency-set -g userspace"
-process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
-out, err = process.communicate()
-
-parametersFile = open("parameters.xml", "w")
-parametersFile.write("\n")
-parametersFile.write("\n")
-parametersFile.write("4\n")
-parametersFile.write("1000\n")
-parametersFile.write("NONE\n")
-parametersFile.write("SLEEP_SMALL\n")
-parametersFile.write("\n")
-parametersFile.close()
-
-outfile = open("REPARA_results.csv", "w")
-outfile.write("#Workers\tFrequency\tTime\tWatts\n")
-
-for c in xrange(1, 23):
- for f in [1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000]:
- run = "cpupower frequency-set -f " + str(f)
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
-
- run = "./mandel_ff 8192 4096 1 " + str(c)
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
-
- run = "tail -1 summary.csv"
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
- res = out.split("\t")
-
- watts = res[0]
- time = res[2]
- outfile.write("{}\t{}\t{}\t{}\n".format(c, f, time, watts))
- outfile.flush()
- os.fsync(outfile.fileno())
-
-outfile.close()
diff --git a/examples/pbzip2/parameters.xml b/examples/pbzip2/parameters.xml
deleted file mode 100644
index 857b58c..0000000
--- a/examples/pbzip2/parameters.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- POWER_BUDGET
- 60
-
-
-
diff --git a/examples/pbzip2/pbzip2_ff.cpp b/examples/pbzip2/pbzip2_ff.cpp
index 8ceedf4..6f3ac27 100644
--- a/examples/pbzip2/pbzip2_ff.cpp
+++ b/examples/pbzip2/pbzip2_ff.cpp
@@ -150,7 +150,7 @@
#define PRIu64 "llu"
#endif
-#include "../../src/interface.hpp"
+#include "../../src/nornir.hpp"
/* ------------------ FastFlow specific ---------------- */
@@ -358,7 +358,7 @@ class FileWriter: public nornir::Gatherer{
public:
FileWriter():
OutFilename(NULL),currBlock(0),hOutfile(1),// default to stdout
- CompressedSize(0),OutputBuffer(NumBlocks,(ff_task_t*)0), firstRun(true) {};
+ CompressedSize(0),OutputBuffer(NumBlocks,(ff_task_t*)0),firstRun(true){};
void set_input_data(char * f) {
OutFilename = f;
@@ -380,6 +380,7 @@ class FileWriter: public nornir::Gatherer{
return -1;
}
}
+ firstRun = false;
}
return 0;
}
@@ -464,18 +465,18 @@ class FileWriter: public nornir::Gatherer{
}
void svc_end() {
- if(firstRun){
- if (OutputStdOut == 0)
- close(hOutfile);
- if ((QuietMode != 1))
- {
+ ;
+ }
+
+ ~FileWriter(){
+ if (OutputStdOut == 0)
+ close(hOutfile);
+ if ((QuietMode != 1)){
fprintf(stderr, " Output Size: %llu bytes\n", (unsigned long long)CompressedSize);
- }
+ }
- OutputBuffer.clear();
- firstRun = false;
- }
- }
+ OutputBuffer.clear();
+ }
private:
const char * OutFilename;
@@ -483,7 +484,7 @@ class FileWriter: public nornir::Gatherer{
int hOutfile;
OFF_T CompressedSize;
std::vector OutputBuffer;
- bool firstRun;
+ bool firstRun;
};
@@ -2533,12 +2534,9 @@ int main(int argc, char* argv[])
if (FW) FW->set_input_data(OutFilename);
- nornir::Observer obs;
nornir::Parameters ap("parameters.xml");
- ap.observer = &obs;
- ap.expectedTasksNumber = std::ceil(fileSize / blockSize);
- std::cout << "Expected tasks: " << ap.expectedTasksNumber << std::endl;
- nornir::ManagerFarm<> amf(&farm, ap);
+ ap.expectedTasksNumber = std::ceil(fileSize / blockSize);
+ nornir::ManagerFastFlow<> amf(&farm, ap);
amf.start();
amf.join();
#if 0
@@ -2593,13 +2591,10 @@ int main(int argc, char* argv[])
if (FW) FW->set_input_data(OutFilename);
- nornir::Observer obs;
nornir::Parameters ap("parameters.xml");
- ap.observer = &obs;
- ap.expectedTasksNumber = std::ceil(fileSize / blockSize);
- std::cout << "Expected tasks: " << ap.expectedTasksNumber << std::endl;
-
- nornir::ManagerFarm<> amf(&farm, ap);
+ ap.expectedTasksNumber = std::ceil(fileSize / blockSize);
+ std::cout << "Expected tasks: " << ap.expectedTasksNumber << std::endl;
+ nornir::ManagerFastFlow<> amf(&farm, ap);
amf.start();
amf.join();
diff --git a/examples/pbzip2/run.py b/examples/pbzip2/run.py
deleted file mode 100644
index 33a439a..0000000
--- a/examples/pbzip2/run.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import math
-import subprocess
-import shlex
-import socket
-import os
-
-run = "cpupower frequency-set -g userspace"
-process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
-out, err = process.communicate()
-
-parametersFile = open("parameters.xml", "w")
-parametersFile.write("\n")
-parametersFile.write("\n")
-parametersFile.write("4\n")
-parametersFile.write("1000\n")
-parametersFile.write("NONE\n")
-parametersFile.write("SLEEP_SMALL\n")
-parametersFile.write("\n")
-parametersFile.close()
-
-outfile = open("REPARA_results.csv", "w")
-outfile.write("#Workers\tFrequency\tTime\tWatts\n")
-
-for c in xrange(1, 12):
-#for c in xrange(1, 25):
- for f in [1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000]:
- run = "cpupower frequency-set -f " + str(f)
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
-
- run = "./pbzip2_ff -f -k -p" + str(c) + " /home/desensi/enwiki-20151201-abstract.xml"
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
-
- run = "tail -1 summary.csv"
- process = subprocess.Popen(shlex.split(run), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- out, err = process.communicate()
- res = out.split("\t")
-
- watts = res[0]
- time = res[2]
- outfile.write("{}\t{}\t{}\t{}\n".format(c, f, time, watts))
- outfile.flush()
- os.fsync(outfile.fileno())
-
-outfile.close()
diff --git a/microbench/Makefile b/microbench/Makefile
index 2ab3584..9d264bb 100644
--- a/microbench/Makefile
+++ b/microbench/Makefile
@@ -19,8 +19,8 @@ checksupported:
@echo "========================================================================="
sudo ./check
microbench:
- cp ../src/external/Mammut/demo/energy/voltageTable.cpp .
- $(CXX) $(CXXFLAGS) -o voltageTable voltageTable.cpp $(INCS) -I../src/external/Mammut/ -L../src/external/Mammut/mammut $(LDFLAGS) $(LDLIBS)
+ cp ../src/external/mammut/demo/energy/voltageTable.cpp .
+ $(CXX) $(CXXFLAGS) -o voltageTable voltageTable.cpp $(INCS) -I../src/external/mammut/ -L../src/external/mammut/mammut $(LDFLAGS) $(LDLIBS)
@echo ""
@echo ""
@echo "=============================== ATTENTION ==============================="
diff --git a/microbench/check.cpp b/microbench/check.cpp
index 1f5f62f..d0cd83a 100644
--- a/microbench/check.cpp
+++ b/microbench/check.cpp
@@ -28,7 +28,7 @@
*/
#include
-#include "../src/external/Mammut/mammut/mammut.hpp"
+#include "../src/external/mammut/mammut/mammut.hpp"
using namespace std;
using namespace mammut;
diff --git a/microbench/runmicrobenchs.sh b/microbench/runmicrobenchs.sh
index 13cb56f..43d57d0 100644
--- a/microbench/runmicrobenchs.sh
+++ b/microbench/runmicrobenchs.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# When a new parameter is added to the archdata.xml configuration file.
-# 1. Change the CURRENT_VERSION_VARIABLE
+# 1. Change the CONFIGURATION_VERSION #define in parameters.cpp file.
# 2. Insert another condition in the if for checking if the new field
# has been correctly created (e.g. 'grep "ticksPerNs" ... ')
@@ -14,7 +14,7 @@ if [ "$(id -u)" != "0" ]; then
exit 1
fi
-CURRENT_VERSION=$(grep "define CONFIGURATION_VERSION" ../src/parameters.cpp | cut -d ' ' -f 3)
+CURRENT_VERSION=$(grep "define CONFIGURATION_VERSION" ../src/parameters.cpp | cut -d ' ' -f 3 | tr -d '"')
CONFPATH_ROOT=$XDG_CONFIG_DIRS
if [ -z "$CONFPATH_ROOT" ];
diff --git a/nornir.config b/nornir.config
new file mode 100644
index 0000000..e0284f4
--- /dev/null
+++ b/nornir.config
@@ -0,0 +1,2 @@
+// Add predefined macros for your project here. For example:
+// #define THE_ANSWER 42
diff --git a/nornir.creator b/nornir.creator
new file mode 100644
index 0000000..e94cbbd
--- /dev/null
+++ b/nornir.creator
@@ -0,0 +1 @@
+[General]
diff --git a/src/Makefile b/src/Makefile
index 6d38350..8fb25ef 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,4 +1,4 @@
-TARGET = monitor.o manager-multi.o manager.o knob.o trigger.o node.o parameters.o selectors.o predictors.o explorers.o configuration.o stats.o
+TARGET = instrumenter.o manager-multi.o manager.o knob.o trigger.o node.o parameters.o selectors.o predictors.o explorers.o configuration.o stats.o
.PHONY: all clean cleanall install uninstall lib
@@ -17,6 +17,7 @@ cleanall:
$(MAKE) -C dataflow cleanall
# $(MAKE) -C external cleanall
lib: $(TARGET)
+ rm -rf libnornir.a
ar rc libnornir.a $(TARGET) dataflow/*.o
ranlib libnornir.a
ar -M < buildlib.ar
diff --git a/src/buildlib.ar b/src/buildlib.ar
index 5e70d21..f24e22d 100644
--- a/src/buildlib.ar
+++ b/src/buildlib.ar
@@ -1,8 +1,9 @@
OPEN libnornir.a
-ADDLIB external/Mammut/mammut/libmammut.a
-ADDLIB external/orlog/src/liborlog.a
+ADDLIB external/mammut/mammut/libmammut.a
+ADDLIB external/knarr/src/libknarr.a
ADDMOD external/leo/leo.o
ADDMOD external/queues/hzdptr.o
ADDMOD external/queues/xxhash.o
+ADDMOD external/graphite-c-client/graphite-client.o
SAVE
END
diff --git a/src/configuration.cpp b/src/configuration.cpp
index 0279f76..ef177a2 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -38,21 +38,32 @@
namespace nornir{
Configuration::Configuration(const Parameters& p):
- _p(p), _combinationsCreated(false), _knobsChangeNeeded(false){
- ;
+ _numServiceNodes(0),
+ _p(p), _combinationsCreated(false),
+ _knobsChangeNeeded(false){
+ memset(_knobs, 0, sizeof(_knobs));
+ memset(_triggers, 0, sizeof(_triggers));
}
Configuration::~Configuration(){
- for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
- delete _knobs[i];
+ for(size_t i = 0; i < KNOB_NUM; i++){
+ if(_knobs[i]){
+ delete _knobs[i];
+ }
+ }
+ for(size_t i = 0; i < TRIGGER_TYPE_NUM; i++){
+ if(_triggers[i]){
+ delete _triggers[i];
+ }
}
}
//TODO: Works even if a std::vector is empty? (i.e. a knob has no values)
-void Configuration::combinations(std::vector > array, size_t i, std::vector accum){
+void Configuration::combinations(std::vector > array,
+ size_t i, std::vector accum){
if(i == array.size()){
KnobsValues kv(KNOB_VALUE_REAL);
- for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
+ for(size_t i = 0; i < KNOB_NUM; i++){
kv[(KnobType) i] = accum.at(i);
}
_combinations.push_back(kv);
@@ -66,18 +77,29 @@ void Configuration::combinations(std::vector > array, size_t
}
}
-bool Configuration::equal(KnobsValues values) const{
+bool Configuration::equal(const KnobsValues& values) const{
+ KnobsValues real = getRealValues(values);
+ for(size_t i = 0; i < KNOB_NUM; i++){
+ KnobType kt = static_cast(i);
+ if(real[kt] != getRealValue(kt)){
+ return false;
+ }
+ }
+ return true;
+}
+
+KnobsValues Configuration::getRealValues(const KnobsValues& values) const{
if(values.areReal()){
- return values == getRealValues();
+ return values;
}else{
+ KnobsValues r(KNOB_VALUE_REAL);
double real;
- for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
- if(_knobs[(KnobType) i]->getRealFromRelative(values[(KnobType) i], real) &&
- real != getRealValue((KnobType) i)){
- return false;
+ for(size_t i = 0; i < KNOB_NUM; i++){
+ if(_knobs[(KnobType) i]->getRealFromRelative(values[(KnobType) i], real)){
+ r[(KnobType) i] = real;
}
}
- return true;
+ return r;
}
}
@@ -89,7 +111,7 @@ void Configuration::createAllRealCombinations(){
std::vector> values;
std::vector accum;
_combinations.clear();
- for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
+ for(size_t i = 0; i < KNOB_NUM; i++){
values.push_back(_knobs[i]->getAllowedValues());
if(!_knobs[i]->isLocked()){
_knobsChangeNeeded = true;
@@ -108,7 +130,7 @@ const std::vector& Configuration::getAllRealCombinations() const{
void Configuration::setFastReconfiguration(){
if(_p.fastReconfiguration){
- ((KnobFrequency*) _knobs[KNOB_TYPE_FREQUENCY])->setRelativeValue(100.0);
+ dynamic_cast(_knobs[KNOB_FREQUENCY])->setRelativeValue(100.0);
}
}
@@ -117,11 +139,8 @@ Knob* Configuration::getKnob(KnobType t) const{
}
void Configuration::maxAllKnobs(){
- if(_p.contractType == CONTRACT_NONE || !_knobsChangeNeeded){
- return;
- }
DEBUG("Maxing all the knobs.");
- for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
+ for(size_t i = 0; i < KNOB_NUM; i++){
_knobs[(KnobType) i]->setToMax();
}
}
@@ -132,20 +151,15 @@ double Configuration::getRealValue(KnobType t) const{
KnobsValues Configuration::getRealValues() const{
KnobsValues kv(KNOB_VALUE_REAL);
- for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
+ for(size_t i = 0; i < KNOB_NUM; i++){
kv[(KnobType) i] = getRealValue((KnobType) i);
}
return kv;
}
bool Configuration::virtualCoresWillChange(const KnobsValues& values) const{
- double newNumWorkers = 0;
- if(values.areRelative()){
- assert(_knobs[KNOB_TYPE_VIRTUAL_CORES]->getRealFromRelative(values[KNOB_TYPE_VIRTUAL_CORES], newNumWorkers));
- }else{
- newNumWorkers = values[KNOB_TYPE_VIRTUAL_CORES];
- }
- return newNumWorkers != _knobs[KNOB_TYPE_VIRTUAL_CORES]->getRealValue();
+ KnobsValues real = getRealValues(values);
+ return real[KNOB_VIRTUAL_CORES] != _knobs[KNOB_VIRTUAL_CORES]->getRealValue();
}
ticks Configuration::startReconfigurationStatsKnob() const{
@@ -162,7 +176,7 @@ ticks Configuration::startReconfigurationStatsTotal() const{
void Configuration::stopReconfigurationStatsKnob(ticks start, KnobType type,
bool vcChanged){
if(_p.statsReconfiguration){
- if(type == KNOB_TYPE_VIRTUAL_CORES && !vcChanged){
+ if(type == KNOB_VIRTUAL_CORES && !vcChanged){
// We do not add statistics about workers reconfiguration
// since they did not changed.
;
@@ -187,7 +201,7 @@ void Configuration::setValues(const KnobsValues& values){
ticks totalStart = startReconfigurationStatsTotal();
setFastReconfiguration();
- for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
+ for(size_t i = 0; i < KNOB_NUM; i++){
ticks reconfigurationStart = startReconfigurationStatsKnob();
// Start of the real reconfiguration
@@ -199,7 +213,9 @@ void Configuration::setValues(const KnobsValues& values){
}
}else if(values.areRelative()){
if(_knobs[i]->isLocked()){
- _knobs[i]->setRelativeValue(0); // Only one value possible, any relative value would be ok.
+ // Any relative value would be ok since the knob only has one
+ // possible value.
+ _knobs[i]->setRelativeValue(0);
}else{
_knobs[i]->setRelativeValue(values[(KnobType)i]);
}
@@ -226,19 +242,17 @@ void Configuration::trigger(){
ConfigurationExternal::ConfigurationExternal(const Parameters& p):
Configuration(p){
-
- _knobs[KNOB_TYPE_VIRTUAL_CORES] = new KnobVirtualCores(p);
- _knobs[KNOB_TYPE_HYPERTHREADING] = new KnobHyperThreading(p);
- _knobs[KNOB_TYPE_MAPPING] = new KnobMappingExternal(p,
- *((KnobVirtualCores*) _knobs[KNOB_TYPE_VIRTUAL_CORES]),
- *((KnobHyperThreading*) _knobs[KNOB_TYPE_HYPERTHREADING]));
- _knobs[KNOB_TYPE_FREQUENCY] = new KnobFrequency(p,
- *((KnobMappingExternal*) _knobs[KNOB_TYPE_MAPPING]));
+ _knobs[KNOB_VIRTUAL_CORES] = new KnobVirtualCores(p);
+ _knobs[KNOB_HYPERTHREADING] = new KnobHyperThreading(p);
+ _knobs[KNOB_MAPPING] = new KnobMappingExternal(p,
+ *dynamic_cast(_knobs[KNOB_VIRTUAL_CORES]),
+ *dynamic_cast(_knobs[KNOB_HYPERTHREADING]));
+ _knobs[KNOB_FREQUENCY] = new KnobFrequency(p,
+ *dynamic_cast(_knobs[KNOB_MAPPING]));
_triggers[TRIGGER_TYPE_Q_BLOCKING] = NULL;
}
-
ConfigurationFarm::ConfigurationFarm(const Parameters& p,
Smoother const* samples,
AdaptiveNode* emitter,
@@ -246,22 +260,22 @@ ConfigurationFarm::ConfigurationFarm(const Parameters& p,
AdaptiveNode* collector,
ff::ff_gatherer* gt,
volatile bool* terminated):
- Configuration(p), _numServiceNodes(0){
-
- _knobs[KNOB_TYPE_VIRTUAL_CORES] = new KnobVirtualCoresFarm(p,
+ Configuration(p){
+ _knobs[KNOB_VIRTUAL_CORES] = new KnobVirtualCoresFarm(p,
emitter, collector, gt, workers,
terminated);
- _knobs[KNOB_TYPE_HYPERTHREADING] = new KnobHyperThreading(p);
- _knobs[KNOB_TYPE_MAPPING] = new KnobMappingFarm(p,
- *((KnobVirtualCoresFarm*) _knobs[KNOB_TYPE_VIRTUAL_CORES]),
- *((KnobHyperThreading*) _knobs[KNOB_TYPE_HYPERTHREADING]),
- emitter, collector);
- _knobs[KNOB_TYPE_FREQUENCY] = new KnobFrequency(p,
- *((KnobMappingFarm*) _knobs[KNOB_TYPE_MAPPING]));
+ _knobs[KNOB_HYPERTHREADING] = new KnobHyperThreading(p);
+ _knobs[KNOB_MAPPING] = new KnobMappingFarm(p,
+ *dynamic_cast(_knobs[KNOB_VIRTUAL_CORES]),
+ *dynamic_cast(_knobs[KNOB_HYPERTHREADING]),
+ emitter, collector);
+ _knobs[KNOB_FREQUENCY] = new KnobFrequency(p,
+ *dynamic_cast(_knobs[KNOB_MAPPING]));
_triggers[TRIGGER_TYPE_Q_BLOCKING] = new TriggerQBlocking(p.triggerQBlocking,
p.thresholdQBlocking,
+ p.thresholdQBlockingBelt,
samples,
emitter);
@@ -269,22 +283,6 @@ ConfigurationFarm::ConfigurationFarm(const Parameters& p,
if(collector){++_numServiceNodes;}
}
-
-KnobsValues getRealValues(const Configuration& configuration, const KnobsValues& values){
- KnobsValues real(KNOB_VALUE_REAL);
-
- if(values.areRelative()){
- for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
- double realv;
- assert(configuration.getKnob((KnobType)i)->getRealFromRelative(values[(KnobType)i], realv));
- real[(KnobType)i] = realv;
- }
- }else{
- real = values;
- }
- return real;
-}
-
std::vector convertWorkers(ff::svector w){
std::vector r;
for(size_t i = 0; i < w.size(); i++){
diff --git a/src/configuration.hpp b/src/configuration.hpp
index b068382..8783665 100644
--- a/src/configuration.hpp
+++ b/src/configuration.hpp
@@ -35,14 +35,18 @@
#include "stats.hpp"
#include "trigger.hpp"
-#include "external/Mammut/mammut/utils.hpp"
+#include "external/mammut/mammut/utils.hpp"
namespace nornir{
+class ManagerTest;
+
class Configuration: public mammut::utils::NonCopyable {
+ friend class ManagerTest;
protected:
- Knob* _knobs[KNOB_TYPE_NUM];
+ Knob* _knobs[KNOB_NUM];
Trigger* _triggers[TRIGGER_TYPE_NUM];
+ uint _numServiceNodes;
private:
const Parameters& _p;
bool _combinationsCreated;
@@ -63,7 +67,7 @@ class Configuration: public mammut::utils::NonCopyable {
void stopReconfigurationStatsTotal(ticks start);
public:
- Configuration(const Parameters& p);
+ explicit Configuration(const Parameters& p);
virtual ~Configuration() = 0;
@@ -73,7 +77,14 @@ class Configuration: public mammut::utils::NonCopyable {
* @return true if the values of this configuration are equal to those
* passed as parameters, false otherwise.
*/
- bool equal(KnobsValues values) const;
+ bool equal(const KnobsValues& values) const;
+
+ /**
+ * Given some knobs values, returns the corresponding real values.
+ * @param values The knobs values.
+ * @return The corresponding real values.
+ */
+ KnobsValues getRealValues(const KnobsValues& values) const;
/**
* Returns true if the knobs values need to be changed, false otherwise.
@@ -142,17 +153,15 @@ class Configuration: public mammut::utils::NonCopyable {
return _reconfigurationStats;
}
- virtual uint getNumServiceNodes() const{return 0;}
+ inline uint getNumServiceNodes() const{return _numServiceNodes;}
};
class ConfigurationExternal: public Configuration{
public:
- ConfigurationExternal(const Parameters& p);
+ explicit ConfigurationExternal(const Parameters& p);
};
class ConfigurationFarm: public Configuration{
-private:
- uint _numServiceNodes;
public:
ConfigurationFarm(const Parameters& p,
Smoother const* samples,
@@ -161,14 +170,8 @@ class ConfigurationFarm: public Configuration{
AdaptiveNode* collector,
ff::ff_gatherer* gt,
volatile bool* terminated);
-
- inline uint getNumServiceNodes() const{
- return _numServiceNodes;
- }
};
-KnobsValues getRealValues(const Configuration& configuration, const KnobsValues& values);
-
std::vector convertWorkers(ff::svector w);
}
diff --git a/src/dataflow/interpreter.cpp b/src/dataflow/interpreter.cpp
index 2bdc754..ed4c853 100644
--- a/src/dataflow/interpreter.cpp
+++ b/src/dataflow/interpreter.cpp
@@ -26,7 +26,7 @@
*/
#include "interpreter.hpp"
-#include "../external/Mammut/mammut/mammut.hpp"
+#include "../external/mammut/mammut/mammut.hpp"
#include