Merge branch 'failpanda'

Conflicts:
	src/core/comm/DatabaseCampaignMessage.proto.in
	src/core/cpn/CMakeLists.txt
	src/core/cpn/DatabaseCampaign.cc
	src/core/sal/ConcreteCPU.hpp
	src/core/sal/SALConfig.hpp
	src/core/util/CMakeLists.txt

Change-Id: Id86b93d0e3ea4d9963fcc88605eec0603575ec83
This commit is contained in:
Horst Schirmeier
2014-06-03 12:24:38 +02:00
1230 changed files with 579380 additions and 28 deletions

View File

@ -7,8 +7,21 @@ set(SRCS
find_package(MySQL REQUIRED)
include_directories(${MYSQL_INCLUDE_DIR})
# only compile concrete implementation of InjectionPoint
if(CONFIG_INJECTIONPOINT_HOPS)
set (SRCS ${SRCS} InjectionPointHops.cc)
else(CONFIG_INJECTIONPOINT_HOPS)
set (SRCS ${SRCS} InjectionPointSteps.cc)
endif(CONFIG_INJECTIONPOINT_HOPS)
add_library(fail-cpn ${SRCS})
target_link_libraries(fail-cpn fail-comm fail-util ${MYSQL_LIBRARIES})
# if hop-chains need to be calculated by the server, we
# the smarthopping module
if(CONFIG_INJECTIONPOINT_HOPS)
add_dependencies(fail-cpn fail-smarthops)
endif(CONFIG_INJECTIONPOINT_HOPS)
# make sure protobufs are generated before we include them
add_dependencies(fail-cpn fail-comm)

View File

@ -4,7 +4,7 @@
#include "util/Logger.hpp"
#include "util/Database.hpp"
#include "comm/ExperimentData.hpp"
#include "InjectionPoint.hpp"
#ifndef __puma
#include <boost/thread.hpp>
@ -131,10 +131,13 @@ bool DatabaseCampaign::run_variant(Database::Variant variant) {
/* Gather jobs */
int experiment_count;
std::stringstream ss;
std::string sql_select = "SELECT p.id, p.fspmethod_id, p.variant_id, p.injection_instr, p.injection_instr_absolute, p.data_address, p.data_width ";
std::string sql_select = "SELECT p.id, p.injection_instr, p.injection_instr_absolute, p.data_address, p.data_width, t.instr1, t.instr2 ";
ss << " FROM fsppilot p "
<< " WHERE p.fspmethod_id = " << fspmethod_id
<< " AND p.variant_id = " << variant.id;
<< " JOIN trace t"
<< " ON t.variant_id = p.variant_id AND t.data_address = p.data_address AND t.instr2 = p.instr2"
<< " WHERE p.fspmethod_id = " << fspmethod_id
<< " AND p.variant_id = " << variant.id
<< " ORDER BY t.instr1"; // Smart-Hopping needs this ordering
std::string sql_body = ss.str();
/* Get the number of unfinished experiments */
@ -148,6 +151,12 @@ bool DatabaseCampaign::run_variant(Database::Variant variant) {
log_send << "Found " << experiment_count << " jobs in database. ("
<< variant.variant << "/" << variant.benchmark << ")" << std::endl;
// abstraction of injection point:
// must not be initialized in loop, because hop chain calculator would lose
// state after loop pass and so for every hop chain it would have to begin
// calculating at trace instruction zero
ConcreteInjectionPoint ip;
unsigned expected_results = expected_number_of_results(variant.variant, variant.benchmark);
unsigned sent_pilots = 0, skipped_pilots = 0;
@ -158,20 +167,26 @@ bool DatabaseCampaign::run_variant(Database::Variant variant) {
continue;
}
unsigned injection_instr = strtoul(row[3], NULL, 10);
unsigned data_address = strtoul(row[5], NULL, 10);
unsigned data_width = strtoul(row[6], NULL, 10);
unsigned injection_instr = strtoul(row[1], NULL, 10);
unsigned data_address = strtoul(row[3], NULL, 10);
unsigned data_width = strtoul(row[4], NULL, 10);
unsigned instr1 = strtoul(row[5], NULL, 10);
unsigned instr2 = strtoul(row[6], NULL, 10);
DatabaseCampaignMessage pilot;
pilot.set_pilot_id(pilot_id);
pilot.set_fspmethod_id(fspmethod_id);
pilot.set_variant_id(variant.id);
// ToDo: Remove this, if all experiments work with abstract API (InjectionPoint)
pilot.set_injection_instr(injection_instr);
pilot.set_variant(variant.variant);
pilot.set_benchmark(variant.benchmark);
if (row[4]) {
unsigned injection_instr_absolute = strtoul(row[4], NULL, 10);
ip.parseFromInjectionInstr(instr1, instr2);
ip.addToCampaignMessage(pilot);
if (row[2]) {
unsigned injection_instr_absolute = strtoul(row[2], NULL, 10);
pilot.set_injection_instr_absolute(injection_instr_absolute);
}
pilot.set_data_address(data_address);

View File

@ -0,0 +1,119 @@
#ifndef INJECTIONPOINT_HPP_
#define INJECTIONPOINT_HPP_
#include "comm/DatabaseCampaignMessage.pb.h"
#include "util/Logger.hpp"
#include "config/FailConfig.hpp"
#include <vector>
namespace fail {
/**
* \class InjectionPointBase
*
* Interface for a generic InjectionPoint (e.g. trace instruction offset or
* hop chain) for use in the generic DatabaseCampaign. Every
* DataBaseCampaignMessage contains a concrete InjectionPoint.
*/
class InjectionPointBase {
protected:
InjectionPointMessage m_ip; // !< Protobuf message of concrete injection point, this class wraps
Logger m_log;
public:
InjectionPointBase() : m_log("InjectionPoint") {}
/**
* Parses generic representation from a injection instruction (trace offset).
* Used by server.
* @param inj_instr trace instruction offset to be parsed
*/
virtual void parseFromInjectionInstr(unsigned instr1, unsigned instr2) = 0;
/**
* Parses (extracts) generic representation from a DatabaseCampaignMessage.
* Used by client.
* @param pilot DatabaseCampaignMessage which contains a InjectionPoint
*/
void parseFromCampaignMessage(const DatabaseCampaignMessage &pilot) {m_ip.CopyFrom(pilot.injection_point());}
/**
* Adds generic representation to a DatabaseCampaignMessage
* @param pilot DatabaseCampaignMessage to which the generic protobuf representation will be added
*/
void addToCampaignMessage(DatabaseCampaignMessage &pilot) {pilot.mutable_injection_point()->CopyFrom(m_ip);}
/**
* Get a copy of the contained InjectionPointMessage
* @param ipm Generic InjectionPointMessage to which the content will be copied
*/
void copyInjectionPointMessage(InjectionPointMessage &ipm) {ipm.CopyFrom(m_ip);}
};
#ifdef CONFIG_INJECTIONPOINT_HOPS
#include "comm/InjectionPointHopsMessage.pb.h"
class SmartHops;
/**
* \class InjectionPointHops
*
* Concrete injection point which contains a hop chain to the target
* trace instruction.
*/
class InjectionPointHops : public InjectionPointBase {
private:
SmartHops *m_sa; // !< Hop calculator which generates the hop chain
// Boundaries must be signed to ensure, they can be initialized as outside of beginning
// of the trace (instr is -1).
long m_curr_instr1; // !< Lower end of instructions for which currently a hop chain is available
long m_curr_instr2; // !< Upper end of instructions for which currently a hop chain is available
bool m_initialized;
std::vector<InjectionPointMessage> m_results;
void init();
public:
InjectionPointHops() : InjectionPointBase(), m_sa(NULL), m_curr_instr1(-1),
m_curr_instr2(-1), m_initialized(false) {}
virtual ~InjectionPointHops();
/**
* Parses a hop chain from a injection instruction (trace offset).
* @param instr1 trace instruction offset of beginning of equivalence class
* @param instr2 trace instruction offset of ending of equivalence class
*/
virtual void parseFromInjectionInstr(unsigned instr1, unsigned instr2);
};
typedef InjectionPointHops ConcreteInjectionPoint;
#else
#include "comm/InjectionPointStepsMessage.pb.h"
/**
* \class InjectionPointSteps
*
* Concrete injection point which contains a trace instruction offset.
*/
class InjectionPointSteps : public InjectionPointBase {
public:
virtual ~InjectionPointSteps() {}
/**
* Parses a trace offset from a injection instruction (trace offset),
* so it effectively just stores the value in the protobuf message.
* @param instr1 trace instruction offset of beginning of equivalence class
* @param instr2 trace instruction offset of ending of equivalence class
*/
virtual void parseFromInjectionInstr(unsigned instr1, unsigned instr2);
};
typedef InjectionPointSteps ConcreteInjectionPoint;
#endif
} /* namespace fail */
#endif /* INJECTIONPOINT_HPP_ */

View File

@ -0,0 +1,110 @@
#include "InjectionPoint.hpp"
#include "util/smarthops/SmartHops.hpp"
#include <algorithm>
#include <limits>
namespace fail {
InjectionPointHops::~InjectionPointHops() {
if (m_initialized) {
delete m_sa;
}
}
void InjectionPointHops::init()
{
m_sa = new SmartHops();
char * elfpath = getenv("FAIL_TRACE_PATH");
if (elfpath == NULL) {
m_log << "FAIL_TRACE_PATH not set :(" << std::endl;
exit(-1);
} else {
m_sa->init((const char*) elfpath);
}
m_initialized = true;
}
/*
* if (!it->has_costs()) {
m_log << "FATAL ERROR: Costs must be delivered in order to calculate minimum costs" << endl;
}
*/
void InjectionPointHops::parseFromInjectionInstr(unsigned instr1, unsigned instr2) {
if (!m_initialized) {
init();
}
// clear results older than instr1, as the input needs to be sorted by instr1, these
// results won't be needed anymore
std::vector<InjectionPointMessage>::iterator it = m_results.begin(), delete_iterator = m_results.end();
for (; it != m_results.end(); it++) {
if (!it->has_target_trace_position()) {
m_log << "FATAL ERROR: Target trace offset must be delivered in order to calculate minimum costs" << std::endl;
m_log << m_results.size() << std::endl;
exit(0);
}
if (it->target_trace_position() < instr1) {
delete_iterator = it;
}
}
// Delete as chunk
if (delete_iterator != m_results.end()) {
m_results.erase(m_results.begin(), delete_iterator);
m_curr_instr1 = instr1;
}
// Calculate next needed results
while ((long)instr2 > m_curr_instr2) {
// if instr1 is bigger than nex instr2, we can skip instructions
// And current instr1 will be newly defined
unsigned new_curr_instr2;
if ((long)instr1 > m_curr_instr2) {
m_curr_instr1 = instr1;
new_curr_instr2 = instr1;
} else {
new_curr_instr2 = m_curr_instr2 + 1;
}
InjectionPointMessage m;
if (!m_sa->calculateFollowingHop(m, new_curr_instr2)) {
m_log << "FATAL ERROR: Trace does not contain enough instructions (no instruction with offset "
<< new_curr_instr2 << ")" << std::endl;
exit(-1);
}
m_results.push_back(m);
m_curr_instr2 = new_curr_instr2;
}
// Choose minimum
InjectionPointMessage *min_cost_msg;
uint32_t min_costs = std::numeric_limits<uint32_t>::max();
std::vector<InjectionPointMessage>::iterator search, search_end;
search = m_results.begin() + (instr1 - m_curr_instr1);
search_end = m_results.begin() + (instr2 - m_curr_instr1);
// Single-instruction eqivalence class
if (search == search_end) {
m_ip = *search;
} else {
for (;search != search_end; search++) {
if (!search->has_costs()) {
m_log << "FATAL ERROR: Costs must be delivered in order to calculate minimum costs" << std::endl;
exit(-1);
}
if (search->costs() < min_costs) {
min_cost_msg = &(*search);
min_costs = search->costs();
}
}
m_ip = *min_cost_msg;
}
}
} /* namespace fail */

View File

@ -0,0 +1,10 @@
#include "InjectionPoint.hpp"
namespace fail {
void InjectionPointSteps::parseFromInjectionInstr(unsigned instr1, unsigned instr2) {
// compute hops
m_ip.set_injection_instr(instr2);
}
} /* namespace fail */