Initial commit
This commit is contained in:
Executable
+208
@@ -0,0 +1,208 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <wfr/common/exceptions/exceptions.h>
|
||||
#include <random>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace wfs { class Workflow; }
|
||||
namespace wfs { class WorkflowTemplate; }
|
||||
|
||||
class WorkflowRuntime {
|
||||
friend class wfs::WorkflowTemplate;
|
||||
private:
|
||||
struct ConfigEntry {
|
||||
std::string stringData; // std::string and unions don't go well together
|
||||
union {
|
||||
bool boolData;
|
||||
uint64_t uintData;
|
||||
int64_t intData;
|
||||
double doubleData;
|
||||
} data;
|
||||
};
|
||||
|
||||
static std::map<std::string, ConfigEntry> globalConfig;
|
||||
|
||||
static std::default_random_engine randomEngine;
|
||||
|
||||
static std::unordered_set<std::shared_ptr<wfs::Workflow>> workflowInstances;
|
||||
|
||||
static void addWorkflowInstance(const std::shared_ptr<wfs::Workflow>& wf) {
|
||||
workflowInstances.insert(wf);
|
||||
}
|
||||
|
||||
public:
|
||||
static void init(int argc = 0, char** argv = nullptr);
|
||||
|
||||
static void finish();
|
||||
|
||||
static void logMessage( std::string message,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now(),
|
||||
bool noLocking = false );
|
||||
|
||||
template<class T>
|
||||
static T setGlobalConfig(const std::string& key, const T& value) {
|
||||
throw exception::wfr_fatal_error("Function \"setGlobalConfig\" not implemented.");
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static T getGlobalConfig(const std::string& key, const T& defaultValue = T()) {
|
||||
throw exception::wfr_fatal_error("Function \"getGlobalConfig\" not implemented.");
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static T getRandomNumber(const T& min, const T& max) {
|
||||
throw exception::wfr_fatal_error("Function not implemented.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
inline bool WorkflowRuntime::setGlobalConfig<bool>(const std::string& key, const bool& value) {
|
||||
bool retval = false;
|
||||
auto e = globalConfig.find(key);
|
||||
if (e != globalConfig.end()) {
|
||||
retval = e->second.data.boolData;
|
||||
e->second.data.boolData = value;
|
||||
} else {
|
||||
ConfigEntry e;
|
||||
e.data.boolData = value;
|
||||
globalConfig.insert({key, e});
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint64_t WorkflowRuntime::setGlobalConfig<uint64_t>(const std::string& key, const uint64_t& value) {
|
||||
uint64_t retval = 0;
|
||||
auto e = globalConfig.find(key);
|
||||
if (e != globalConfig.end()) {
|
||||
retval = e->second.data.uintData;
|
||||
e->second.data.uintData = value;
|
||||
} else {
|
||||
ConfigEntry e;
|
||||
e.data.uintData = value;
|
||||
globalConfig.insert({key, e});
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline int64_t WorkflowRuntime::setGlobalConfig<int64_t>(const std::string& key, const int64_t& value) {
|
||||
int64_t retval = 0;
|
||||
auto e = globalConfig.find(key);
|
||||
if (e != globalConfig.end()) {
|
||||
retval = e->second.data.intData;
|
||||
e->second.data.intData = value;
|
||||
} else {
|
||||
ConfigEntry e;
|
||||
e.data.intData = value;
|
||||
globalConfig.insert({key, e});
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline double WorkflowRuntime::setGlobalConfig<double>(const std::string& key, const double& value) {
|
||||
double retval = 0;
|
||||
auto e = globalConfig.find(key);
|
||||
if (e != globalConfig.end()) {
|
||||
retval = e->second.data.doubleData;
|
||||
e->second.data.doubleData = value;
|
||||
} else {
|
||||
ConfigEntry e;
|
||||
e.data.doubleData = value;
|
||||
globalConfig.insert({key, e});
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
inline std::string WorkflowRuntime::getGlobalConfig<std::string>(const std::string& key, const std::string& defaultValue) {
|
||||
std::string retval = defaultValue;
|
||||
auto e = globalConfig.find(key);
|
||||
if (e != globalConfig.end()) {
|
||||
retval = e->second.stringData;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool WorkflowRuntime::getGlobalConfig<bool>(const std::string& key, const bool& defaultValue) {
|
||||
bool retval = defaultValue;
|
||||
auto e = globalConfig.find(key);
|
||||
if (e != globalConfig.end()) {
|
||||
retval = e->second.data.boolData;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint64_t WorkflowRuntime::getGlobalConfig<uint64_t>(const std::string& key, const uint64_t& defaultValue) {
|
||||
uint64_t retval = defaultValue;
|
||||
auto e = globalConfig.find(key);
|
||||
if (e != globalConfig.end()) {
|
||||
retval = e->second.data.uintData;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline int64_t WorkflowRuntime::getGlobalConfig<int64_t>(const std::string& key, const int64_t& defaultValue) {
|
||||
int64_t retval = defaultValue;
|
||||
auto e = globalConfig.find(key);
|
||||
if (e != globalConfig.end()) {
|
||||
retval = e->second.data.intData;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline double WorkflowRuntime::getGlobalConfig<double>(const std::string& key, const double& defaultValue) {
|
||||
double retval = defaultValue;
|
||||
auto e = globalConfig.find(key);
|
||||
if (e != globalConfig.end()) {
|
||||
retval = e->second.data.doubleData;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string WorkflowRuntime::setGlobalConfig<std::string>(const std::string& key, const std::string& value) {
|
||||
std::string retval;
|
||||
auto e = globalConfig.find(key);
|
||||
if (e != globalConfig.end()) {
|
||||
retval = e->second.stringData;
|
||||
e->second.stringData = value;
|
||||
} else {
|
||||
ConfigEntry e;
|
||||
e.stringData = value;
|
||||
globalConfig.insert({key, e});
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline double WorkflowRuntime::getRandomNumber(const double& min, const double& max) {
|
||||
std::uniform_real_distribution<double> distribution(min, max);
|
||||
return distribution(randomEngine);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline wfr_size_t WorkflowRuntime::getRandomNumber(const wfr_size_t& min, const wfr_size_t& max) {
|
||||
std::uniform_int_distribution<wfr_size_t> distribution(min, max);
|
||||
return distribution(randomEngine);
|
||||
}
|
||||
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+276
@@ -0,0 +1,276 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
namespace wfs {
|
||||
// Forward declarations
|
||||
class Workflow;
|
||||
class Activity;
|
||||
class ActivityInstance;
|
||||
class AtomicActivityImplementation;
|
||||
}
|
||||
|
||||
|
||||
// main namespace
|
||||
namespace eventsystem {
|
||||
|
||||
|
||||
/**
|
||||
* Event Types.
|
||||
**/
|
||||
enum class EventType
|
||||
: int { GeneralLoggingEvent,
|
||||
WorkflowStatusEvent,
|
||||
ActivityStatusEvent,
|
||||
ActivityInstanceStatusEvent,
|
||||
ComputingResourceStatusEvent,
|
||||
ComponentStatusEvent };
|
||||
|
||||
/**
|
||||
* Abstract event base class.
|
||||
**/
|
||||
class Event {
|
||||
|
||||
// Invariant parameters that can be accessed directly
|
||||
public:
|
||||
const EventType eventType;
|
||||
const wfr_timestamp_sc_t timestamp;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
Event(EventType type, const wfr_timestamp_sc_t& timestamp) noexcept
|
||||
: eventType(type), timestamp(timestamp) {}
|
||||
virtual ~Event() noexcept {}
|
||||
|
||||
virtual std::string toString() const noexcept = 0;
|
||||
|
||||
template<class T>
|
||||
T& as() noexcept { return *static_cast<T*>(this); }
|
||||
|
||||
template<class T>
|
||||
const T& as() const noexcept { return *static_cast<const T*>(this); }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event for logging arbitrary messages
|
||||
**/
|
||||
class GeneralLoggingEvent : public Event {
|
||||
protected:
|
||||
std::string logMessage;
|
||||
|
||||
public:
|
||||
GeneralLoggingEvent( const std::string& message,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now() ) noexcept
|
||||
: Event(EventType::GeneralLoggingEvent, timestamp), logMessage(message) {}
|
||||
|
||||
const std::string& getMessage() const noexcept { return logMessage; }
|
||||
|
||||
virtual std::string toString() const noexcept override;
|
||||
|
||||
static std::shared_ptr<GeneralLoggingEvent> fireEvent( const std::string& message,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now(),
|
||||
bool noLocking = false ) noexcept;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event to indicate that the state of a workflow changed.
|
||||
**/
|
||||
class WorkflowStatusEvent : public Event {
|
||||
protected:
|
||||
wfr::wfs::Workflow& workflow;
|
||||
wfr::wfs::WorkflowStatus oldStatus;
|
||||
wfr::wfs::WorkflowStatus newStatus;
|
||||
|
||||
public:
|
||||
WorkflowStatusEvent( wfr::wfs::Workflow& workflow,
|
||||
wfr::wfs::WorkflowStatus& oldStatus,
|
||||
wfr::wfs::WorkflowStatus& newStatus,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now() ) noexcept
|
||||
: Event(EventType::WorkflowStatusEvent, timestamp), workflow(workflow), oldStatus(oldStatus), newStatus(newStatus) {}
|
||||
|
||||
wfr::wfs::WorkflowStatus getNewStatus() const noexcept { return newStatus; }
|
||||
|
||||
wfr::wfs::WorkflowStatus getOldStatus() const noexcept { return oldStatus; }
|
||||
|
||||
wfr::wfs::Workflow& getWorkflow() const noexcept { return workflow; }
|
||||
|
||||
virtual std::string toString() const noexcept override;
|
||||
|
||||
static std::shared_ptr<WorkflowStatusEvent> fireEvent( wfr::wfs::Workflow& workflow,
|
||||
wfr::wfs::WorkflowStatus& oldStatus,
|
||||
wfr::wfs::WorkflowStatus& newStatus,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now(),
|
||||
bool noLocking = false ) noexcept;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event to indicate that the state of an activity changed.
|
||||
**/
|
||||
class ActivityStatusEvent : public Event {
|
||||
protected:
|
||||
wfr::wfs::Activity& activity;
|
||||
wfr::wfs::ActivityStatus oldStatus;
|
||||
wfr::wfs::ActivityStatus newStatus;
|
||||
|
||||
public:
|
||||
ActivityStatusEvent( wfr::wfs::Activity& activity,
|
||||
wfr::wfs::ActivityStatus oldStatus,
|
||||
wfr::wfs::ActivityStatus newStatus,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now() ) noexcept
|
||||
: Event(EventType::ActivityStatusEvent, timestamp), activity(activity), oldStatus(oldStatus), newStatus(newStatus) {}
|
||||
|
||||
wfr::wfs::Activity& getActivity() const noexcept { return activity; }
|
||||
|
||||
wfr::wfs::ActivityStatus getNewStatus() const noexcept { return newStatus; }
|
||||
|
||||
wfr::wfs::ActivityStatus getOldStatus() const noexcept { return oldStatus; }
|
||||
|
||||
virtual std::string toString() const noexcept override;
|
||||
|
||||
static std::shared_ptr<ActivityStatusEvent> fireEvent( wfr::wfs::Activity& activity,
|
||||
wfr::wfs::ActivityStatus oldStatus,
|
||||
wfr::wfs::ActivityStatus newStatus,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now(),
|
||||
bool noLocking = false ) noexcept;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event to indicate that the state of an activity instance changed.
|
||||
**/
|
||||
class ActivityInstanceStatusEvent : public Event {
|
||||
protected:
|
||||
wfr::wfs::ActivityInstance& activityInstance;
|
||||
wfr::wfs::ActivityInstanceStatus oldStatus;
|
||||
wfr::wfs::ActivityInstanceStatus newStatus;
|
||||
|
||||
public:
|
||||
ActivityInstanceStatusEvent( wfr::wfs::ActivityInstance& activityInstance,
|
||||
wfr::wfs::ActivityInstanceStatus oldStatus,
|
||||
wfr::wfs::ActivityInstanceStatus newStatus,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now() ) noexcept
|
||||
: Event(EventType::ActivityInstanceStatusEvent, timestamp), activityInstance(activityInstance), oldStatus(oldStatus), newStatus(newStatus) {}
|
||||
|
||||
wfr::wfs::ActivityInstance& getActivityInstance() const noexcept { return activityInstance; }
|
||||
|
||||
wfr::wfs::ActivityInstanceStatus getNewStatus() const noexcept { return newStatus; }
|
||||
|
||||
wfr::wfs::ActivityInstanceStatus getOldStatus() const noexcept { return oldStatus; }
|
||||
|
||||
virtual std::string toString() const noexcept override;
|
||||
|
||||
static std::shared_ptr<ActivityInstanceStatusEvent> fireEvent( wfr::wfs::ActivityInstance& activity,
|
||||
wfr::wfs::ActivityInstanceStatus oldStatus,
|
||||
wfr::wfs::ActivityInstanceStatus newStatus,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now(),
|
||||
bool noLocking = false ) noexcept;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event to indicate that the state of a WFR component changed.
|
||||
*/
|
||||
class ComponentStatusEvent : public Event {
|
||||
protected:
|
||||
wfs::ComponentType componentType;
|
||||
wfs::ComponentStatus oldStatus;
|
||||
wfs::ComponentStatus newStatus;
|
||||
wfr::wfs::Workflow* workflow;
|
||||
|
||||
public:
|
||||
ComponentStatusEvent( wfs::ComponentType componentType,
|
||||
wfs::ComponentStatus oldStatus,
|
||||
wfs::ComponentStatus newStatus,
|
||||
wfr::wfs::Workflow* wf = nullptr,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now()) noexcept
|
||||
: Event(EventType::ComponentStatusEvent, timestamp), componentType(componentType), oldStatus(oldStatus), newStatus(newStatus), workflow(wf) {}
|
||||
|
||||
wfs::ComponentType getComponentType() const noexcept { return componentType; }
|
||||
|
||||
wfs::ComponentStatus getNewStatus() const noexcept { return newStatus; }
|
||||
|
||||
wfs::ComponentStatus getOldStatus() const noexcept { return oldStatus; }
|
||||
|
||||
wfr::wfs::Workflow* getWorkflow() const noexcept { return workflow; }
|
||||
|
||||
virtual std::string toString() const noexcept override;
|
||||
|
||||
static std::shared_ptr<ComponentStatusEvent> fireEvent( wfs::ComponentType componentType,
|
||||
wfs::ComponentStatus oldStatus,
|
||||
wfs::ComponentStatus newStatus,
|
||||
wfr::wfs::Workflow* wf = nullptr,
|
||||
const wfr_timestamp_sc_t& timestamp = std::chrono::system_clock::now(),
|
||||
bool noLocking = false ) noexcept;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event to indicate that the state of a computing resource changed.
|
||||
**/
|
||||
class ComputingResourceStatusEvent : public Event {
|
||||
protected:
|
||||
wfr::wfs::Workflow* workflow;
|
||||
wfr::wfs::ActivityImplementationType deviceType;
|
||||
wfr_id_t deviceID;
|
||||
wfr::wfs::ComputingResourceStatus oldStatus;
|
||||
wfr::wfs::ComputingResourceStatus newStatus;
|
||||
wfr::wfs::ActivityInstance* executedTask;
|
||||
wfr::wfs::AtomicActivityImplementation* executedImpl;
|
||||
wfr_size_t deviceSlotCount;
|
||||
|
||||
public:
|
||||
ComputingResourceStatusEvent(wfr::wfs::Workflow* wf, wfr::wfs::ActivityImplementationType deviceType, wfr_id_t deviceID,
|
||||
wfr::wfs::ComputingResourceStatus oldStatus, wfr::wfs::ComputingResourceStatus newStatus,
|
||||
wfr::wfs::ActivityInstance* executedTask = nullptr, wfr::wfs::AtomicActivityImplementation* executedImpl = nullptr,
|
||||
wfr_size_t deviceSlotCount = 0,
|
||||
wfr_timestamp_sc_t timestamp = std::chrono::system_clock::now()) noexcept
|
||||
: Event(EventType::ComputingResourceStatusEvent, timestamp), workflow(wf), deviceType(deviceType),
|
||||
deviceID(deviceID), oldStatus(oldStatus), newStatus(newStatus), executedTask(executedTask),
|
||||
executedImpl(executedImpl), deviceSlotCount(deviceSlotCount) {}
|
||||
|
||||
wfr::wfs::ActivityImplementationType getDeviceType() const noexcept { return deviceType; }
|
||||
|
||||
wfr::wfs::Workflow* getWorkflow() const noexcept { return workflow; }
|
||||
|
||||
wfr_id_t getDeviceID() const noexcept { return deviceID; }
|
||||
|
||||
wfr::wfs::ComputingResourceStatus getNewStatus() const noexcept { return newStatus; }
|
||||
|
||||
wfr::wfs::ComputingResourceStatus getOldStatus() const noexcept { return oldStatus; }
|
||||
|
||||
wfr::wfs::ActivityInstance* getExecutedTask() const noexcept { return executedTask; }
|
||||
|
||||
wfr::wfs::AtomicActivityImplementation* getExecutedImpl() const noexcept { return executedImpl; }
|
||||
|
||||
wfr_size_t getDeviceSlotCount() const noexcept { return deviceSlotCount; }
|
||||
|
||||
virtual std::string toString() const noexcept override;
|
||||
|
||||
static std::shared_ptr<ComputingResourceStatusEvent> fireEvent( wfr::wfs::Workflow* wf,
|
||||
wfr::wfs::ActivityImplementationType deviceType,
|
||||
wfr_id_t deviceID,
|
||||
wfr::wfs::ComputingResourceStatus oldStatus,
|
||||
wfr::wfs::ComputingResourceStatus newStatus,
|
||||
wfr::wfs::ActivityInstance* executedTask = nullptr,
|
||||
wfr::wfs::AtomicActivityImplementation* executedImpl = nullptr,
|
||||
wfr_size_t deviceSlotCount = 0,
|
||||
wfr_timestamp_sc_t timestamp = std::chrono::system_clock::now(),
|
||||
bool noLocking = false ) noexcept;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace eventsystem */
|
||||
} /* namespace wfr */
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace wfr {
|
||||
namespace eventsystem {
|
||||
|
||||
class Event;
|
||||
|
||||
/*
|
||||
* Event listener interface
|
||||
*/
|
||||
class EventListener {
|
||||
public:
|
||||
virtual ~EventListener() {}
|
||||
|
||||
virtual void notifyEvent(const std::shared_ptr<Event>& event) noexcept = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace eventsystem */
|
||||
} /* namespace wfr */
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
#include <queue>
|
||||
#include <unordered_set>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <wfr/config.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// forward declarations
|
||||
class WorkflowRuntime;
|
||||
|
||||
namespace eventsystem {
|
||||
|
||||
// forward declarations
|
||||
class EventListener;
|
||||
class Event;
|
||||
class OStreamLogger;
|
||||
class SQLiteLogger;
|
||||
|
||||
|
||||
class EventSystem {
|
||||
friend class wfr::WorkflowRuntime;
|
||||
|
||||
// Singleton instances
|
||||
private:
|
||||
static EventSystem singleton;
|
||||
#ifdef WFR_ENABLE_STDLOGGER
|
||||
static std::unique_ptr<OStreamLogger> oStreamLogger;
|
||||
#endif
|
||||
#ifdef WFR_ENABLE_PERFDATABASE
|
||||
static std::unique_ptr<SQLiteLogger> sqliteLogger;
|
||||
#endif
|
||||
|
||||
// Non-public parameters
|
||||
private:
|
||||
std::unordered_set<EventListener*> eventListeners;
|
||||
std::queue<std::shared_ptr<Event>> eventQueue;
|
||||
std::unique_ptr<std::thread> eventThread;
|
||||
std::mutex eventThreadMutex;
|
||||
std::condition_variable eventThreadCondVar;
|
||||
bool stopThread = false;
|
||||
std::atomic_bool threadStarted;
|
||||
bool isFinished = false;
|
||||
|
||||
// Non-public static functions
|
||||
private:
|
||||
static void eventThreadFunc(EventSystem* eventSystem) noexcept;
|
||||
|
||||
static void init(int argc, char** argv);
|
||||
static void finish() noexcept;
|
||||
|
||||
// Non-public functions
|
||||
private:
|
||||
EventSystem() noexcept;
|
||||
|
||||
void finishInstance() noexcept;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
~EventSystem() noexcept;
|
||||
static EventSystem& getInstance() noexcept { return singleton; }
|
||||
|
||||
/**
|
||||
* Adds an event to the event queue.
|
||||
*
|
||||
* It is discouraged to use this function directly.
|
||||
* Use the static fireEvent function found in each Event class instead (e.g. GeneralLoggingEvent::fireEvent(....)).
|
||||
**/
|
||||
void fireEvent(std::shared_ptr<Event> event, bool noLocking = false) noexcept;
|
||||
|
||||
bool addListener(EventListener& listener) noexcept;
|
||||
bool removeListener(EventListener& listener) noexcept;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace eventsystem */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace wfr {
|
||||
namespace exception {
|
||||
|
||||
|
||||
/**
|
||||
* Exception base class.
|
||||
*/
|
||||
class wfr_exception : public std::exception {
|
||||
protected:
|
||||
const std::string message;
|
||||
std::shared_ptr<std::exception> cause;
|
||||
|
||||
public:
|
||||
wfr_exception(const std::string& message = "", std::shared_ptr<std::exception> cause = std::shared_ptr<std::exception>()) noexcept
|
||||
: message(message), cause(cause) {}
|
||||
|
||||
wfr_exception(const wfr_exception& e) noexcept
|
||||
: message(e.message), cause(e.cause) {}
|
||||
|
||||
virtual ~wfr_exception() noexcept {}
|
||||
|
||||
virtual const std::string& getMessage() noexcept { return message; }
|
||||
virtual std::weak_ptr<std::exception> getCause() noexcept { return cause; }
|
||||
virtual const char* what() const noexcept override { return message.c_str(); };
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Represents a fatal error that results in program abortion
|
||||
**/
|
||||
class wfr_fatal_error : public wfr_exception {
|
||||
public:
|
||||
using wfr_exception::wfr_exception;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Represents a not found exception.
|
||||
**/
|
||||
class wfr_not_found : public wfr_exception {
|
||||
public:
|
||||
using wfr_exception::wfr_exception;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Represents a not found activity instance.
|
||||
**/
|
||||
class wfr_missing_instance : public wfr_exception {
|
||||
public:
|
||||
using wfr_exception::wfr_exception;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Represents an illegal argument.
|
||||
**/
|
||||
class wfr_illegal_argument : public wfr_exception {
|
||||
public:
|
||||
using wfr_exception::wfr_exception;
|
||||
};
|
||||
|
||||
|
||||
} // namespace exception
|
||||
} // namespace wfr
|
||||
Executable
+836
@@ -0,0 +1,836 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <wfr/common/utils/utils.h>
|
||||
|
||||
|
||||
|
||||
/*******************
|
||||
* LWD Type Macros *
|
||||
*******************/
|
||||
|
||||
|
||||
#define WFR_PORT_STRUCT(name, id, members) \
|
||||
struct name : public wfr::lwd::_wfr_lwd { \
|
||||
name() : _wfr_lwd(id, sizeof(name)) {} \
|
||||
members \
|
||||
};
|
||||
|
||||
|
||||
#define WFR_PORT_MEMBER(name, type) \
|
||||
wfr::lwd::_lwd_member_type<type> name;
|
||||
|
||||
|
||||
#define WFR_PORT_MEMBER_IWIRINT(name) \
|
||||
wfr::lwd::iwir_int name;
|
||||
|
||||
|
||||
#define WFR_PORT_MEMBER_IWIRDOUBLE(name) \
|
||||
wfr::lwd::iwir_double name;
|
||||
|
||||
|
||||
#define WFR_PORT_MEMBER_IWIRBOOL(name) \
|
||||
wfr::lwd::iwir_bool name;
|
||||
|
||||
|
||||
#define WFR_PORT_MEMBER_IWIRSTRING(name) \
|
||||
wfr::lwd::iwir_string name;
|
||||
|
||||
|
||||
#define WFR_PORT_MEMBER_IWIRFILE(name) \
|
||||
wfr::lwd::iwir_file name;
|
||||
|
||||
|
||||
#define WFR_PORT_MEMBER_IWIRCOLLECTION(name, type, level) \
|
||||
wfr::lwd::iwir_collection<type, level> name;
|
||||
|
||||
|
||||
#define WFR_PORT_MEMBER_LOOPPORT(name, type) \
|
||||
wfr::lwd::_lwd_loop_port<type> name;
|
||||
|
||||
|
||||
|
||||
/*********************
|
||||
* LWD Access Macros *
|
||||
*********************/
|
||||
|
||||
|
||||
//// Outbuffer ////
|
||||
|
||||
#define WFR_SELF_OUTBUFFER_INIT(name, type) \
|
||||
type* name = (type*)instance.getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
instance.setOutputData(name); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SELF_OUTBUFFER_GET(name, type) \
|
||||
type* name = (type*)instance.getOutputData();
|
||||
|
||||
|
||||
#define WFR_INSTANCE_OUTBUFFER_INIT(name, type, instance) \
|
||||
type* name = nullptr; \
|
||||
if (instance != nullptr) { \
|
||||
name = (type*)(instance)->getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(instance)->setOutputData(name); \
|
||||
} \
|
||||
} else { \
|
||||
throw wfr::exception::wfr_missing_instance("Cannot initialise the outbuffer of a non-existing instance."); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_INSTANCE_OUTBUFFER_TRYINIT(name, type, instance) \
|
||||
type* name nullptr; \
|
||||
if (instance != nullptr) { \
|
||||
name = (type*)(instance)->getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(instance)->setOutputData(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_INSTANCE_OUTBUFFER_GET(name, type, instance) \
|
||||
type* name = nullptr; \
|
||||
if (instance != nullptr) { \
|
||||
name = (type*)(instance)->getOutputData(); \
|
||||
} else { \
|
||||
throw wfr::exception::wfr_missing_instance("Cannot get the outbuffer of a non-existing instance."); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_INSTANCE_OUTBUFFER_TRYGET(name, type, instance) \
|
||||
type* name = nullptr; \
|
||||
if (instance != nullptr) { \
|
||||
name = (type*)(instance)->getOutputData(); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PARENT_OUTBUFFER_INIT(name, type, parentname) \
|
||||
auto parentname = instance.getParentActivity(); \
|
||||
type* name = nullptr; \
|
||||
if (parentname != nullptr) { \
|
||||
name = (type*)(parentname)->getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(parentname)->setOutputData(name); \
|
||||
} \
|
||||
} else { \
|
||||
throw wfr::exception::wfr_missing_instance("Cannot initialise the outbuffer of a non-existing parent."); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PARENT_OUTBUFFER_TRYINIT(name, type, parentname) \
|
||||
auto parentname = instance.getParentActivity(); \
|
||||
type* name = nullptr; \
|
||||
if (parentname != nullptr) { \
|
||||
name = (type*)(parentname)->getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(parentname)->setOutputData(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PARENT_OUTBUFFER_GET(name, type, parentname) \
|
||||
auto parentname = instance.getParentActivity(); \
|
||||
type* name = nullptr; \
|
||||
if (parentname != nullptr) { \
|
||||
name = (type*)(parentname)->getOutputData(); \
|
||||
} else { \
|
||||
throw wfr::exception::wfr_missing_instance("Cannot get the outbuffer of a non-existing parent."); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PARENT_OUTBUFFER_TRYGET(name, type, parentname) \
|
||||
auto parentname = instance.getParentActivity(); \
|
||||
type* name = nullptr; \
|
||||
if (parentname != nullptr) { \
|
||||
name = (type*)(parentname)->getOutputData(); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_CHILD_OUTBUFFER_INIT(name, type, childname, childActivityID, childIterationID) \
|
||||
auto childname = WFR_SELF_GETCHILDBYID(childActivityID, childIterationID); \
|
||||
type* name = nullptr; \
|
||||
if (childname != nullptr) { \
|
||||
name = (type*)(childname)->getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(childname)->setOutputData(name); \
|
||||
} \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot initialise the outbuffer of non-existing child with activityID=" << childActivityID; \
|
||||
ss << " and iterationID=" << childIterationID << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_CHILD_OUTBUFFER_TRYINIT(name, type, childname, childActivityID, childIterationID) \
|
||||
auto childname = WFR_SELF_GETCHILDBYID(childActivityID, childIterationID); \
|
||||
type* name = nullptr; \
|
||||
if (childname != nullptr) { \
|
||||
name = (type*)(childname)->getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(childname)->setOutputData(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_CHILD_OUTBUFFER_GET(name, type, childname, childActivityID, childIterationID) \
|
||||
auto childname = WFR_SELF_GETCHILDBYID(childActivityID, childIterationID); \
|
||||
type* name = nullptr; \
|
||||
if (childname != nullptr) { \
|
||||
name = (type*)(childname)->getOutputData(); \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot get the outbuffer of non-existing child with activityID=" << childActivityID; \
|
||||
ss << " and iterationID=" << childIterationID << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_CHILD_OUTBUFFER_TRYGET(name, type, childname, childActivityID, childIterationID) \
|
||||
auto childname = WFR_SELF_GETCHILDBYID(childActivityID, childIterationID); \
|
||||
type* name = nullptr; \
|
||||
if (childname != nullptr) { \
|
||||
name = (type*)(childname)->getOutputData(); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PRED_OUTBUFFER_INIT(name, type, predname, predIndex) \
|
||||
auto predname = instance.getPredecessor(predIndex); \
|
||||
type* name = nullptr; \
|
||||
if (predname != nullptr) { \
|
||||
name = (type*)(predname)->getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(predname)->setOutputData(name); \
|
||||
} \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot initialise the inbuffer of non-existing predecessor with index=" << predIndex << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PRED_OUTBUFFER_TRYINIT(name, type, predname, predIndex) \
|
||||
auto predname = instance.getPredecessor(predIndex); \
|
||||
type* name = nullptr; \
|
||||
if (predname != nullptr) { \
|
||||
name = (type*)(predname)->getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(predname)->setOutputData(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PRED_OUTBUFFER_GET(name, type, predname, predIndex) \
|
||||
auto predname = instance.getPredecessor(predIndex); \
|
||||
type* name = nullptr; \
|
||||
if (predname != nullptr) { \
|
||||
name = (type*)(predname)->getOutputData(); \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot get the inbuffer of non-existing predecessor with index=" << predIndex << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PRED_OUTBUFFER_TRYGET(name, type, predname, predIndex) \
|
||||
auto predname = instance.getPredecessor(predIndex); \
|
||||
type* name = nullptr; \
|
||||
if (predname != nullptr) { \
|
||||
name = (type*)(predname)->getOutputData(); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SUCC_OUTBUFFER_INIT(name, type, succname, succIndex) \
|
||||
auto succname = instance.getSuccessors()[succIndex]; \
|
||||
type* name = nullptr; \
|
||||
if (succname != nullptr) { \
|
||||
name = (type*)(succname)->getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(succname)->setOutputData(name); \
|
||||
} \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot initialise the inbuffer of non-existing successor with index=" << succIndex << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SUCC_OUTBUFFER_TRYINIT(name, type, succname, succIndex) \
|
||||
auto succname = instance.getSuccessors()[succIndex]; \
|
||||
type* name = nullptr; \
|
||||
if (succname != nullptr) { \
|
||||
name = (type*)(succname)->getOutputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(succname)->setOutputData(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SUCC_OUTBUFFER_GET(name, type, succname, succIndex) \
|
||||
auto succname = instance.getSuccessors()[succIndex]; \
|
||||
type* name = nullptr; \
|
||||
if (succname != nullptr) { \
|
||||
name = (type*)(succname)->getOutputData(); \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot get the inbuffer of non-existing successor with index=" << succIndex << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SUCC_OUTBUFFER_TRYGET(name, type, succname, succIndex) \
|
||||
auto succname = instance.getSuccessors()[succIndex]; \
|
||||
type* name = nullptr; \
|
||||
if (succname != nullptr) { \
|
||||
name = (type*)(succname)->getOutputData(); \
|
||||
}
|
||||
|
||||
|
||||
//// Inbuffer ////
|
||||
|
||||
|
||||
#define WFR_SELF_INBUFFER_INIT(name, type) \
|
||||
type* name = (type*)instance.getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
instance.setInputData(name); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SELF_INBUFFER_GET(name, type) \
|
||||
type* name = (type*)instance.getInputData();
|
||||
|
||||
|
||||
#define WFR_INSTANCE_INBUFFER_INIT(name, type, instance) \
|
||||
type* name = nullptr; \
|
||||
if (instance != nullptr) { \
|
||||
name = (type*)(instance)->getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(instance)->setInputData(name); \
|
||||
} \
|
||||
} else { \
|
||||
throw wfr::exception::wfr_missing_instance("Cannot initialise the inbuffer of a non-existing instance."); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_INSTANCE_INBUFFER_TRYINIT(name, type, instance) \
|
||||
type* name nullptr; \
|
||||
if (instance != nullptr) { \
|
||||
name = (type*)(instance)->getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(instance)->setInputData(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_INSTANCE_INBUFFER_GET(name, type, instance) \
|
||||
type* name = nullptr; \
|
||||
if (instance != nullptr) { \
|
||||
name = (type*)(instance)->getInputData(); \
|
||||
} else { \
|
||||
throw wfr::exception::wfr_missing_instance("Cannot get the inbuffer of a non-existing instance."); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_INSTANCE_INBUFFER_TRYGET(name, type, instance) \
|
||||
type* name = nullptr; \
|
||||
if (instance != nullptr) { \
|
||||
name = (type*)(instance)->getInputData(); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PARENT_INBUFFER_INIT(name, type, parentname) \
|
||||
auto parentname = instance.getParentActivity(); \
|
||||
type* name = nullptr; \
|
||||
if (parentname != nullptr) { \
|
||||
name = (type*)(parentname)->getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(parentname)->setInputData(name); \
|
||||
} \
|
||||
} else { \
|
||||
throw wfr::exception::wfr_missing_instance("Cannot initialise the inbuffer of a non-existing parent."); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PARENT_INBUFFER_TRYINIT(name, type, parentname) \
|
||||
auto parentname = instance.getParentActivity(); \
|
||||
type* name = nullptr; \
|
||||
if (parentname != nullptr) { \
|
||||
name = (type*)(parentname)->getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(parentname)->setInputData(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PARENT_INBUFFER_GET(name, type, parentname) \
|
||||
auto parentname = instance.getParentActivity(); \
|
||||
type* name = nullptr; \
|
||||
if (parentname != nullptr) { \
|
||||
name = (type*)(parentname)->getInputData(); \
|
||||
} else { \
|
||||
throw wfr::exception::wfr_missing_instance("Cannot get the inbuffer of a non-existing parent."); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PARENT_INBUFFER_TRYGET(name, type, parentname) \
|
||||
auto parentname = instance.getParentActivity(); \
|
||||
type* name = nullptr; \
|
||||
if (parentname != nullptr) { \
|
||||
name = (type*)(parentname)->getInputData(); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_CHILD_INBUFFER_INIT(name, type, childname, childActivityID, childIterationID) \
|
||||
auto childname = WFR_SELF_GETCHILDBYID(childActivityID, childIterationID); \
|
||||
type* name = nullptr; \
|
||||
if (childname != nullptr) { \
|
||||
name = (type*)(childname)->getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(childname)->setInputData(name); \
|
||||
} \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot initialise the inbuffer of non-existing child with activityID=" << childActivityID; \
|
||||
ss << " and iterationID=" << childIterationID << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_CHILD_INBUFFER_TRYINIT(name, type, childname, childActivityID, childIterationID) \
|
||||
auto childname = WFR_SELF_GETCHILDBYID(childActivityID, childIterationID); \
|
||||
type* name = nullptr; \
|
||||
if (childname != nullptr) { \
|
||||
name = (type*)(childname)->getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(childname)->setInputData(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_CHILD_INBUFFER_GET(name, type, childname, childActivityID, childIterationID) \
|
||||
auto childname = WFR_SELF_GETCHILDBYID(childActivityID, childIterationID); \
|
||||
type* name = nullptr; \
|
||||
if (childname != nullptr) { \
|
||||
name = (type*)(childname)->getInputData(); \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot get the inbuffer of non-existing child with activityID=" << childActivityID; \
|
||||
ss << " and iterationID=" << childIterationID << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_CHILD_INBUFFER_TRYGET(name, type, childname, childActivityID, childIterationID) \
|
||||
auto childname = WFR_SELF_GETCHILDBYID(childActivityID, childIterationID); \
|
||||
type* name = nullptr; \
|
||||
if (childname != nullptr) { \
|
||||
name = (type*)(childname)->getInputData(); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PRED_INBUFFER_INIT(name, type, predname, predIndex) \
|
||||
auto predname = instance.getPredecessor(predIndex); \
|
||||
type* name = nullptr; \
|
||||
if (predname != nullptr) { \
|
||||
name = (type*)(predname)->getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(predname)->setInputData(name); \
|
||||
} \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot initialise the inbuffer of non-existing predecessor with index=" << predIndex << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PRED_INBUFFER_TRYINIT(name, type, predname, predIndex) \
|
||||
auto predname = instance.getPredecessor(predIndex); \
|
||||
type* name = nullptr; \
|
||||
if (predname != nullptr) { \
|
||||
name = (type*)(predname)->getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(predname)->setInputData(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PRED_INBUFFER_GET(name, type, predname, predIndex) \
|
||||
auto predname = instance.getPredecessor(predIndex); \
|
||||
type* name = nullptr; \
|
||||
if (predname != nullptr) { \
|
||||
name = (type*)(predname)->getInputData(); \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot get the inbuffer of non-existing predecessor with index=" << predIndex << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_PRED_INBUFFER_TRYGET(name, type, predname, predIndex) \
|
||||
auto predname = instance.getPredecessor(predIndex); \
|
||||
type* name = nullptr; \
|
||||
if (predname != nullptr) { \
|
||||
name = (type*)(predname)->getInputData(); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SUCC_INBUFFER_INIT(name, type, succname, succIndex) \
|
||||
auto succname = instance.getSuccessors()[succIndex]; \
|
||||
type* name = nullptr; \
|
||||
if (succname != nullptr) { \
|
||||
name = (type*)(succname)->getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(succname)->setInputData(name); \
|
||||
} \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot initialise the inbuffer of non-existing successor with index=" << succIndex << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SUCC_INBUFFER_TRYINIT(name, type, succname, succIndex) \
|
||||
auto succname = instance.getSuccessors()[succIndex]; \
|
||||
type* name = nullptr; \
|
||||
if (succname != nullptr) { \
|
||||
name = (type*)(succname)->getInputData(); \
|
||||
if (name == nullptr) { \
|
||||
name = new type(); \
|
||||
(succname)->setInputData(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SUCC_INBUFFER_GET(name, type, succname, succIndex) \
|
||||
auto succname = instance.getSuccessors()[succIndex]; \
|
||||
type* name = nullptr; \
|
||||
if (succname != nullptr) { \
|
||||
name = (type*)(succname)->getInputData(); \
|
||||
} else { \
|
||||
std::stringstream ss; \
|
||||
ss << "Cannot get the inbuffer of non-existing successor with index=" << succIndex << "."; \
|
||||
throw wfr::exception::wfr_missing_instance(ss.str()); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SUCC_INBUFFER_TRYGET(name, type, succname, succIndex) \
|
||||
auto succname = instance.getSuccessors()[succIndex]; \
|
||||
type* name = nullptr; \
|
||||
if (succname != nullptr) { \
|
||||
name = (type*)(succname)->getInputData(); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_LOOP_FINALIZE_COLLECTION(collection, member) \
|
||||
if (instance.as<wfr::wfs::LoopActivityInstance>().isFinalised() && !collection->member.isFinalised() \
|
||||
&& instance.as<wfr::wfs::LoopActivityInstance>().getIterationCount() == collection->member.getSize()) { \
|
||||
collection->member.setFinalised(true); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_FINALIZE_COLLECTION(collection, member) \
|
||||
if (!collection->member.isFinalised() && collection->member.getSize() > 0 \
|
||||
&& collection->member.getSize() == collection->member.getReadyCount()) { \
|
||||
collection->member.setFinalised(true); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_LOOP_FINALIZE() \
|
||||
instance.as<wfr::wfs::LoopActivityInstance>().setFinalised(true);
|
||||
|
||||
|
||||
#define WFR_FORLOOP_GET_COUNTER_VALUE(forloop, member) \
|
||||
if (forloop->as<wfr::wfs::ForLoopActivityInstance>().isLoopCounterValueAvailable()) { \
|
||||
member.setValue(forloop->as<wfr::wfs::ForLoopActivityInstance>().getLoopCounterValue(instance.iterationID)); \
|
||||
}
|
||||
|
||||
|
||||
#define WRF_PRED_ISFINISHED(predIndex) \
|
||||
wfr_pred_isfinished(instance, predIndex)
|
||||
|
||||
#define WRF_PRED_ISREADY(predIndex) \
|
||||
wfr_pred_isready(instance, predIndex)
|
||||
|
||||
#define WRF_PARENT_ISFINISHED() \
|
||||
wfr_parent_isfinished(instance)
|
||||
|
||||
#define WRF_PARENT_ISREADY() \
|
||||
wfr_parent_isReady(instance)
|
||||
|
||||
#define WFR_PARENT_ISPREVITERFINISHED() \
|
||||
wfr_previter_isfinished(*instance.getParentActivity(), instance.iterationID)
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#define WFR_SELF_CHECK_AREALLINPUTSAVAILABLE(condition) \
|
||||
if (condition) { \
|
||||
instance.setAllInputsAvailable(true); \
|
||||
}
|
||||
|
||||
#define WFR_SELF_CHECK_AREALLOUTPUTSAVAILABLE(condition) \
|
||||
if (condition) { \
|
||||
instance.setAllOutputsAvailable(true); \
|
||||
}
|
||||
|
||||
#define WFR_SELF_CHECK_ISREADYFOREXECUTION(condition) \
|
||||
if (condition && instance.getInstanceStatus() < wfr::wfs::ActivityInstanceStatus::ReadyForExecution) { \
|
||||
instance.setInstanceStatus(wfr::wfs::ActivityInstanceStatus::ReadyForExecution); \
|
||||
}
|
||||
|
||||
#define WFR_SELF_CHECK_ISREADYFOREXECUTION2(condition1, condition2) \
|
||||
if (condition1 && condition2 && instance.getInstanceStatus() < wfr::wfs::ActivityInstanceStatus::ReadyForExecution ) { \
|
||||
instance.setInstanceStatus(wfr::wfs::ActivityInstanceStatus::ReadyForExecution); \
|
||||
} else if (condition1 && instance.getInstanceStatus() < wfr::wfs::ActivityInstanceStatus::ReadyForExecution) { \
|
||||
instance.setInstanceStatus(wfr::wfs::ActivityInstanceStatus::WaitingForDependency); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define WFR_INIT_FORLOOPCOUNTER(start, step, stop) \
|
||||
if (!instance.as<wfr::wfs::LoopActivityInstance>().isFinalised()) { \
|
||||
instance.setLoopCounter(start, step, stop); \
|
||||
instance.setInstanceStatus(wfr::wfs::ActivityInstanceStatus::ReadyForExecution); \
|
||||
instance.as<wfr::wfs::LoopActivityInstance>().setFinalised(true); \
|
||||
retval = true; \
|
||||
}
|
||||
|
||||
#define WFR_INIT_FORLOOPCOUNTER2(start, step, stop) \
|
||||
if (!instance.as<wfr::wfs::LoopActivityInstance>().isFinalised()) { \
|
||||
instance.setLoopCounter(start, step, stop); \
|
||||
instance.as<wfr::wfs::LoopActivityInstance>().setFinalised(true); \
|
||||
retval = true; \
|
||||
}
|
||||
|
||||
#define WFR_COLLECT_OUTVALUES_FROM_CHILDREN(collection, type, member, childID) \
|
||||
for (wfr_size_t t = 0; t < WFR_SELF_GETITERATIONCOUNT(); t++) { \
|
||||
WFR_CHILD_OUTBUFFER_GET(chout, type, ch, childID, t); \
|
||||
if (chout != nullptr /*&& collection.getSize() > t*/) { \
|
||||
WFR_HOOK_SET_RETVAL(wfr::portbuffer_copy(collection, chout->member, t)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WFR_COLLECT_OUTVALUES_FROM_CHILDREN_FLATTEN(collection, flatten, type, member, childID) \
|
||||
{ \
|
||||
bool doFinalize = false; \
|
||||
wfr_size_t index = 0; \
|
||||
for (wfr_size_t t = 0; t < WFR_SELF_GETITERATIONCOUNT(); t++) { \
|
||||
WFR_CHILD_OUTBUFFER_GET(chout, type, ch, childID, t); \
|
||||
if (chout != nullptr) { \
|
||||
wfr_size_t ecount = wfr::portbuffer_copy_flatten<flatten>(collection, chout->member, index); \
|
||||
if (ecount == 0) { \
|
||||
doFinalize = false; \
|
||||
break; \
|
||||
} else { \
|
||||
index += ecount; \
|
||||
doFinalize = true; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (doFinalize) { \
|
||||
collection.setFinalised(true); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WFR_PORT_INIT_COLLECTION(collection) \
|
||||
if (!collection.isFinalised() ) { \
|
||||
collection.init(0); \
|
||||
}
|
||||
|
||||
#define WFR_PORT_INIT_COLLECTION_LOOP(collection) \
|
||||
if (!collection.isFinalised() ) { \
|
||||
collection.init(WFR_SELF_GETITERATIONCOUNT()); \
|
||||
if (instance.as<wfr::wfs::LoopActivityInstance>().isFinalised()) { \
|
||||
collection.setFinalised(true); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WFR_LOOPPORT_COPY_LAST(dest, srcmember, type, childID) \
|
||||
if (instance.as<wfr::wfs::LoopActivityInstance>().isFinalised()) { \
|
||||
WFR_CHILD_OUTBUFFER_GET(chout, type, ch, childID, WFR_SELF_GETITERATIONCOUNT()-1); \
|
||||
if (chout != nullptr) { \
|
||||
WFR_HOOK_SET_RETVAL(wfr::portbuffer_copy(dest, chout->srcmember)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WFR_PORT_SETVALUE(var, val) \
|
||||
if (!var.isReady()) { \
|
||||
var.setValue(val); \
|
||||
retval = true; \
|
||||
}
|
||||
|
||||
#define WFR_PORT_SETVALUE2(var, val) \
|
||||
if (!var.isReady()) { \
|
||||
var.setValue(val); \
|
||||
}
|
||||
|
||||
|
||||
#define WFR_SELF_GETCHILDBYID(activityID, iterationID) \
|
||||
instance.as<wfr::wfs::CompositeActivityInstance>().getChild(activityID, iterationID)
|
||||
|
||||
#define WFR_SELF_GETPREDECESSORBYINDEX(index) \
|
||||
(instance).getPredecessor(index)
|
||||
|
||||
|
||||
#define WFR_SELF_GETITERATIONCOUNT() \
|
||||
instance.as<wfr::wfs::LoopActivityInstance>().getIterationCount()
|
||||
|
||||
#define WFR_SELF_GETITERATIONID() \
|
||||
instance.as<wfr::wfs::LoopActivityInstance>().iterationID
|
||||
|
||||
#define WFR_INSTANCE_GETITERATIONCOUNT(instance) \
|
||||
instance.as<wfr::wfs::LoopActivityInstance>().getIterationCount()
|
||||
|
||||
#define WFR_SELF_SETITERATIONCOUNT(count) \
|
||||
instance.as<wfr::wfs::LoopActivityInstance>().setIterationCount(count);
|
||||
|
||||
#define WFR_SELF_SETFORLOOPCOUNTERVALUES(start, step, max) \
|
||||
instance.as<wfr::wfs::ForLoopActivityInstance>().setLoopCounter(start, step, max);
|
||||
|
||||
#define WFR_SELF_GETCONDBRANCHID() \
|
||||
instance.as<wfr::wfs::ConditionalActivityInstance>().getExecutionBranchID()
|
||||
|
||||
#define WFR_SELF_SETCONDBRANCHID(value) \
|
||||
instance.as<wfr::wfs::ConditionalActivityInstance>().setExecutionBranchID(value)
|
||||
|
||||
#define WFR_SELF_GETHANDLEDITERATIONCOUNT() \
|
||||
instance.as<wfr::wfs::LoopActivityInstance>().getHandledIterationCount()
|
||||
|
||||
|
||||
|
||||
|
||||
#define WFR_ACTIVITY_IMPLEMENTATIONS(name, label, ...) \
|
||||
auto name = wfr::wfs::AtomicActivityType::create(label, { \
|
||||
__VA_ARGS__ \
|
||||
});
|
||||
|
||||
|
||||
#define WFR_WORKFLOW(name, label, actTableName, topLevelID, ...) \
|
||||
std::unique_ptr<wfr::wfs::WorkflowTemplate> name(new wfr::wfs::WorkflowTemplate(label, topLevelID, { \
|
||||
__VA_ARGS__ \
|
||||
}));
|
||||
|
||||
|
||||
/*
|
||||
* WRF Hook Function Macros
|
||||
*/
|
||||
|
||||
#define WFR_INPUT_HOOK(name) \
|
||||
bool name(wfr::wfs::ActivityInstance& instance)
|
||||
|
||||
#define WFR_OUTPUT_HOOK(name) \
|
||||
bool name(wfr::wfs::ActivityInstance& instance)
|
||||
|
||||
#define WFR_EXEC_HOOK(name) \
|
||||
bool name(wfr::wfs::ActivityInstance& instance)
|
||||
|
||||
#define WFR_BRANCHCONDITION_HOOK(name) \
|
||||
bool name(wfr::wfs::ConditionalActivityInstance& instance)
|
||||
|
||||
#define WFR_LOOPITERATION_HOOK(name) \
|
||||
bool name(wfr::wfs::LoopActivityInstance& instance)
|
||||
|
||||
#define WFR_WHILECONDITION_HOOK(name) \
|
||||
bool name(wfr::wfs::WhileLoopActivityInstance& instance)
|
||||
|
||||
#define WFR_FORCOUNTER_HOOK(name) \
|
||||
bool name(wfr::wfs::ForLoopActivityInstance& instance)
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#define WFR_HOOK_SET_RETVAL(func) \
|
||||
if (func) { \
|
||||
retval = true; \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Simulation Mode
|
||||
*/
|
||||
|
||||
#define EXECUTE_SIMULATION_MODE instance.executeSimMode();
|
||||
|
||||
|
||||
/*********************************
|
||||
* Hook Function Prologs/Epilogs *
|
||||
*********************************/
|
||||
|
||||
#define WFR_INPUT_HOOK_PROLOG \
|
||||
bool retval = false;
|
||||
|
||||
#define WFR_INPUT_HOOK_EPILOG \
|
||||
return retval;
|
||||
|
||||
#define WFR_OUTPUT_HOOK_PROLOG \
|
||||
bool retval = false;
|
||||
|
||||
#define WFR_OUTPUT_HOOK_EPILOG \
|
||||
return retval;
|
||||
|
||||
#define WFR_EXEC_HOOK_PROLOG \
|
||||
bool retval = false;
|
||||
|
||||
#define WFR_EXEC_HOOK_EPILOG \
|
||||
return retval;
|
||||
|
||||
#define WFR_BRANCHCONDITION_HOOK_PROLOG \
|
||||
bool retval = false;
|
||||
|
||||
#define WFR_BRANCHCONDITION_HOOK_EPILOG \
|
||||
return retval;
|
||||
|
||||
#define WFR_LOOPITERATION_HOOK_PROLOG \
|
||||
bool retval = false;
|
||||
|
||||
#define WFR_LOOPITERATION_HOOK_EPILOG \
|
||||
return retval;
|
||||
|
||||
#define WFR_WHILECONDITION_HOOK_PROLOG \
|
||||
bool retval = false;
|
||||
|
||||
#define WFR_WHILECONDITION_HOOK_EPILOG \
|
||||
return retval;
|
||||
|
||||
#define WFR_FORCOUNTER_HOOK_PROLOG \
|
||||
bool retval = false;
|
||||
|
||||
#define WFR_FORCOUNTER_HOOK_EPILOG \
|
||||
return retval;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace wfr {
|
||||
namespace prediction {
|
||||
|
||||
|
||||
class PredictionService {
|
||||
public:
|
||||
virtual ExecutionTimeResult predictExecutionTime(wfs::ActivityInstance& instance, wfs::ActivityImplementation& implementation,
|
||||
const std::string& resourceName, const wfr_size_t& slots = 1) = 0;
|
||||
|
||||
virtual CommunicationTimeResult predictCommunicationTime(wfs::ActivityInstance& srcInstance, resource::ComputingResource& srcResource,
|
||||
wfs::ActivityInstance& destInstance, resource::ComputingResource& destResource) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace prediction */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+174
@@ -0,0 +1,174 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/ResourceTypes.h>
|
||||
#include <wfr/common/resource/ResourceCapabilities.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <initializer_list>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace wfs { class AtomicActivityImplementation; }
|
||||
|
||||
namespace resource {
|
||||
|
||||
|
||||
|
||||
class AbstractResource {
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const ResourceClass resourceClass;
|
||||
const std::string resourceIdentifier;
|
||||
|
||||
// Public Functions
|
||||
public:
|
||||
AbstractResource( ResourceClass resourceClass, const std::string& resourceIdentifier ) noexcept
|
||||
: resourceClass(resourceClass), resourceIdentifier(resourceIdentifier) {}
|
||||
virtual ~AbstractResource() {}
|
||||
|
||||
virtual bool hasCapability(const RequiredResourceCapability& type) const noexcept = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class AbstractResourceType {
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const ResourceClass resourceClass;
|
||||
const std::string resourceTypeName;
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
std::set<ResourceCapability> capabilities;
|
||||
std::map<std::string, std::string> properties;
|
||||
|
||||
// Public Functions
|
||||
public:
|
||||
AbstractResourceType( ResourceClass resourceClass, const std::string& resourceName,
|
||||
const std::set<ResourceCapability>& capabilities = std::set<ResourceCapability>(),
|
||||
const std::map<std::string, std::string>& properties = std::map<std::string, std::string>() ) noexcept
|
||||
: resourceClass(resourceClass), resourceTypeName(resourceName), capabilities(capabilities), properties(properties) {}
|
||||
virtual ~AbstractResourceType() {}
|
||||
|
||||
wfr_size_t getCapabilityCount() const noexcept { return capabilities.size(); }
|
||||
const std::set<ResourceCapability>& getCapabilities() const noexcept { return capabilities; }
|
||||
bool hasCapability(const RequiredResourceCapability& type) const noexcept;
|
||||
bool hasCapability(wfr::resource::ResourceCapabilityType type) const noexcept;
|
||||
|
||||
wfr_size_t getPropertyCount() const noexcept { return properties.size(); }
|
||||
const std::map<std::string, std::string>& getProperties() const noexcept { return properties; }
|
||||
std::vector<std::string> getPropertyKeys() const noexcept;
|
||||
std::string getProperty(const std::string& key) const noexcept;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<class Resource>
|
||||
class ResourceTypeBase : public AbstractResourceType {
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
std::vector<Resource*> resources;
|
||||
|
||||
// Public Functions
|
||||
public:
|
||||
ResourceTypeBase( ResourceClass resourceClass, const std::string& resourceName,
|
||||
const std::set<ResourceCapability>& capabilities = std::set<ResourceCapability>(),
|
||||
const std::map<std::string, std::string>& properties = std::map<std::string, std::string>() ) noexcept
|
||||
: AbstractResourceType(resourceClass, resourceName, capabilities, properties) {}
|
||||
|
||||
wfr_size_t getResourceCount() const noexcept { return resources.size(); }
|
||||
const std::vector<Resource*> getResources() const noexcept { return resources; }
|
||||
void addResource(Resource* resource) noexcept { resources.push_back(resource); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<class RType>
|
||||
class ResourceBase : public AbstractResource {
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
RType& resourceType;
|
||||
|
||||
// Public Functions
|
||||
public:
|
||||
ResourceBase(ResourceClass resourceClass, const std::string& resourceIdentifier, RType& resourceType ) noexcept
|
||||
: AbstractResource(resourceClass, resourceIdentifier), resourceType(resourceType) {}
|
||||
|
||||
virtual bool hasCapability(const RequiredResourceCapability& type) const noexcept { return resourceType.hasCapability(type); }
|
||||
virtual bool hasCapability(wfr::resource::ResourceCapabilityType type) const noexcept { return resourceType.hasCapability(type); }
|
||||
};
|
||||
|
||||
|
||||
class ComputingResource;
|
||||
|
||||
class ComputingResourceType : public ResourceTypeBase<ComputingResource> {
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const ComputingDeviceClass computingDeviceClass;
|
||||
const wfr_size_t maxSlots;
|
||||
|
||||
|
||||
// Public Functions
|
||||
public:
|
||||
ComputingResourceType( const std::string& resourceName, ComputingDeviceClass computingDeviceClass, wfr_size_t maxSlots,
|
||||
const std::set<ResourceCapability>& capabilities = std::set<ResourceCapability>(),
|
||||
const std::map<std::string, std::string>& properties = std::map<std::string, std::string>() ) noexcept
|
||||
: ResourceTypeBase(ResourceClass::ComputingResource, resourceName, capabilities, properties),
|
||||
computingDeviceClass(computingDeviceClass), maxSlots(maxSlots) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ComputingResource : public ResourceBase<ComputingResourceType> {
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
wfr_size_t reservedSlots =0;
|
||||
wfr_size_t busySlots = 0;
|
||||
|
||||
// Public Functions
|
||||
public:
|
||||
ComputingResource( const std::string& resourceIdentifier, ComputingResourceType& resourceType ) noexcept
|
||||
: ResourceBase(ResourceClass::ComputingResource, resourceIdentifier, resourceType) {
|
||||
resourceType.addResource(this);
|
||||
}
|
||||
|
||||
wfr_size_t getMaxSlotCount() const noexcept { return resourceType.maxSlots; }
|
||||
wfr_size_t getReservedSlotCount() const noexcept { return reservedSlots; }
|
||||
wfr_size_t getBusySlotCount() const noexcept { return busySlots; }
|
||||
wfr_size_t getFreeSlotCount() const noexcept { return resourceType.maxSlots - (busySlots + reservedSlots); }
|
||||
|
||||
bool reserveSlots(const wfr_size_t& slots) noexcept;
|
||||
bool markReservedSlotsBusy(const wfr_size_t& slots) noexcept;
|
||||
bool markFreeSlotsBusy(const wfr_size_t& slots) noexcept;
|
||||
bool releaseBusySlots(const wfr_size_t& slots) noexcept;
|
||||
};
|
||||
|
||||
|
||||
|
||||
ComputingDeviceClass parseComputingDeviceType(const std::string& type);
|
||||
|
||||
std::string getComputingDeviceTypeString(const ComputingDeviceClass& type);
|
||||
|
||||
|
||||
|
||||
ResourceCapabilityType parseResourceCapabilityType(const std::string& type);
|
||||
|
||||
std::string getResourceCapabilityTypeString(const ResourceCapabilityType& type);
|
||||
|
||||
|
||||
|
||||
} /* namespace resource */
|
||||
} /* namespace wfr */
|
||||
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/ResourceTypes.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace resource {
|
||||
|
||||
|
||||
/**
|
||||
* Represents the capabilities of a resource.
|
||||
*/
|
||||
class ResourceCapability {
|
||||
public:
|
||||
const ResourceCapabilityType type;
|
||||
const wfr_size_t majorVersion;
|
||||
const wfr_size_t minorVersion;
|
||||
|
||||
public:
|
||||
ResourceCapability()
|
||||
: type(ResourceCapabilityType::Unknown), majorVersion(0), minorVersion(0) {}
|
||||
|
||||
ResourceCapability(const ResourceCapabilityType& type, const wfr_size_t& majorVersion, const wfr_size_t& minorVersion)
|
||||
: type(type), majorVersion(majorVersion), minorVersion(minorVersion) {}
|
||||
|
||||
|
||||
static ResourceCapability GenericCPU() {
|
||||
return ResourceCapability(ResourceCapabilityType::GenericCPU, 0, 0);
|
||||
}
|
||||
|
||||
static ResourceCapability OpenCL(const wfr_size_t& majorVersion, const wfr_size_t& minorVersion) {
|
||||
return ResourceCapability(ResourceCapabilityType::OpenCL, majorVersion, minorVersion);
|
||||
}
|
||||
|
||||
static ResourceCapability CUDA(const wfr_size_t& majorVersion, const wfr_size_t& minorVersion) {
|
||||
return ResourceCapability(ResourceCapabilityType::CUDA, majorVersion, minorVersion);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Represents the requirements of an activity implementation.
|
||||
**/
|
||||
class RequiredResourceCapability {
|
||||
public:
|
||||
const ResourceCapabilityType type;
|
||||
const wfr_size_t minMajorVersion;
|
||||
const wfr_size_t minMinorVersion;
|
||||
const wfr_size_t maxMajorVersion;
|
||||
const wfr_size_t maxMinorVersion;
|
||||
|
||||
public:
|
||||
RequiredResourceCapability()
|
||||
: type(ResourceCapabilityType::Unknown), minMajorVersion(0), minMinorVersion(0), maxMajorVersion(0), maxMinorVersion(0) {}
|
||||
|
||||
RequiredResourceCapability(const ResourceCapabilityType& type, const wfr_size_t& minMajorVersion, const wfr_size_t& minMinorVersion,
|
||||
const wfr_size_t& maxMajorVersion = 0, const wfr_size_t& maxMinorVersion = 0)
|
||||
: type(type), minMajorVersion(minMajorVersion), minMinorVersion(minMinorVersion),
|
||||
maxMajorVersion(maxMajorVersion), maxMinorVersion(maxMinorVersion) {}
|
||||
|
||||
|
||||
static RequiredResourceCapability GenericCPU() {
|
||||
return RequiredResourceCapability(ResourceCapabilityType::GenericCPU, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static RequiredResourceCapability OpenCL(const wfr_size_t& minMajorVersion, const wfr_size_t& minMinorVersion,
|
||||
const wfr_size_t& maxMajorVersion = 0, const wfr_size_t& maxMinorVersion = 0) {
|
||||
return RequiredResourceCapability(ResourceCapabilityType::OpenCL, minMajorVersion, minMinorVersion, maxMajorVersion, maxMinorVersion);
|
||||
}
|
||||
|
||||
static RequiredResourceCapability CUDA(const wfr_size_t& minMajorVersion, const wfr_size_t& minMinorVersion,
|
||||
const wfr_size_t& maxMajorVersion = 0, const wfr_size_t& maxMinorVersion = 0) {
|
||||
return RequiredResourceCapability(ResourceCapabilityType::CUDA, minMajorVersion, minMinorVersion, maxMajorVersion, maxMinorVersion);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef std::initializer_list<resource::ResourceCapability> CapabilityList;
|
||||
typedef std::initializer_list<resource::RequiredResourceCapability> RequiredCapabilityList;
|
||||
|
||||
inline bool operator<(const wfr::resource::ResourceCapability& dev1, const wfr::resource::ResourceCapability& dev2) {
|
||||
if (dev1.type == dev2.type) {
|
||||
if (dev1.majorVersion == dev2.majorVersion) {
|
||||
return dev1.minorVersion < dev2.minorVersion;
|
||||
} else {
|
||||
return dev1.majorVersion < dev2.majorVersion;
|
||||
}
|
||||
} else {
|
||||
return dev1.type < dev2.type;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool operator==(const wfr::resource::ResourceCapability& cap, const wfr::resource::RequiredResourceCapability& rcap) {
|
||||
if (cap.type == rcap.type) {
|
||||
if (cap.majorVersion >= rcap.minMajorVersion && cap.majorVersion <= rcap.maxMajorVersion) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace resource */
|
||||
} /* namespace wfr */
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <ostream>
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <wfr/common/types/ResourceTypes.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace resource {
|
||||
|
||||
class AbstractResource;
|
||||
class ComputingResource;
|
||||
class ComputingResourceType;
|
||||
class ComputingResourceReservation;
|
||||
class RequiredResourceCapability;
|
||||
|
||||
class ResourceManager {
|
||||
private:
|
||||
static ResourceManager* singleton;
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
std::mutex managerMutex;
|
||||
std::map<std::string, ComputingResourceType*> computingResourceTypes;
|
||||
std::map<std::string, ComputingResource*> computingResources;
|
||||
|
||||
// Non-public functions
|
||||
private:
|
||||
ResourceManager(std::string resourceConfigFile, bool cpuAutoConfig, bool printResourceTable);
|
||||
|
||||
void readConfigFile(std::string configFile);
|
||||
|
||||
// Public static functions
|
||||
public:
|
||||
static void init(int argc, char** argv);
|
||||
static void finish() noexcept;
|
||||
static ResourceManager& getInstance() noexcept;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
~ResourceManager() noexcept;
|
||||
|
||||
wfr_size_t getComputingResourceCount() const noexcept { return computingResources.size(); }
|
||||
std::vector<ComputingResource*> getComputingResources() const noexcept;
|
||||
ComputingResource* getComputingResource(std::string identifier) const noexcept;
|
||||
std::vector<ComputingResource*> filterComputingResources(std::vector<RequiredResourceCapability> filter) const noexcept;
|
||||
|
||||
ComputingResourceReservation reserveComputingResource(ComputingResource* device, const wfr_size_t& slots = 1) noexcept;
|
||||
bool releaseComputingResources(ComputingResourceReservation* handle) noexcept;
|
||||
|
||||
wfr_size_t getComputingResourceTypeCount() const noexcept { return computingResourceTypes.size(); }
|
||||
std::vector<ComputingResourceType*> getComputingResourceTypes() const noexcept;
|
||||
ComputingResourceType* getComputingResourceType(std::string name) const noexcept;
|
||||
|
||||
void printResourceTable(std::ostream& out) const noexcept;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace resource */
|
||||
} /* namespace wfr */
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
|
||||
namespace wfr {
|
||||
namespace resource {
|
||||
|
||||
class ComputingResource;
|
||||
|
||||
class ComputingResourceReservation {
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
resource::ComputingResource* const resource = nullptr;
|
||||
const wfr_size_t slotCount = 0;
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
bool isValidFlag = false;
|
||||
|
||||
// Public Functions
|
||||
public:
|
||||
ComputingResourceReservation() noexcept {}
|
||||
ComputingResourceReservation(resource::ComputingResource* resource, const wfr_size_t& slotCount = 1) noexcept
|
||||
: resource(resource), slotCount(slotCount), isValidFlag(true) {}
|
||||
virtual ~ComputingResourceReservation() noexcept {}
|
||||
|
||||
bool isValid() const noexcept { return isValidFlag; }
|
||||
void invalidateReservation() noexcept { isValidFlag = false; }
|
||||
};
|
||||
|
||||
} /* namespace resource */
|
||||
} /* namespace wfr */
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <wfr/common/resource/ResourceReservation.h>
|
||||
#include <wfr/prediction/PredictionManager.h>
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
class ActivityInstance;
|
||||
class AtomicActivityImplementation;
|
||||
}
|
||||
namespace wep {
|
||||
class WorkflowExecutionPlan;
|
||||
}
|
||||
|
||||
|
||||
namespace scheduling {
|
||||
|
||||
class SchedulingDecision {
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
wfs::ActivityInstance* const activityInstance = nullptr;
|
||||
wfs::AtomicActivityImplementation* const activityImplementation = nullptr;
|
||||
wep::WorkflowExecutionPlan* const wep = nullptr;
|
||||
resource::ComputingResource* const resource = nullptr;
|
||||
resource::ComputingResourceReservation reservationHandle;
|
||||
wfr_size_t slotCount = 0;
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
// Some of them are invariant, but this class needs to be copyable, so no const properties :(
|
||||
private:
|
||||
prediction::ExecutionTimeResult prediction;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
SchedulingDecision(wfs::ActivityInstance* activityInstance, wfs::AtomicActivityImplementation* activityImplementation,
|
||||
wep::WorkflowExecutionPlan* wep, resource::ComputingResourceReservation reservationHandle) noexcept
|
||||
: activityInstance(activityInstance), activityImplementation(activityImplementation), wep(wep),
|
||||
resource(reservationHandle.resource), reservationHandle(reservationHandle), slotCount(reservationHandle.slotCount) {}
|
||||
SchedulingDecision(wfs::ActivityInstance* activityInstance, wfs::AtomicActivityImplementation* activityImplementation,
|
||||
wep::WorkflowExecutionPlan* wep, resource::ComputingResource* resource = nullptr, const wfr_size_t& slotCount = 1) noexcept
|
||||
: activityInstance(activityInstance), activityImplementation(activityImplementation), wep(wep),
|
||||
resource(resource), slotCount(slotCount) {}
|
||||
~SchedulingDecision() noexcept {}
|
||||
|
||||
const prediction::ExecutionTimeResult& getPrediction() const noexcept { return prediction; }
|
||||
void setPrediction(const prediction::ExecutionTimeResult& prediction) noexcept { this->prediction = prediction; }
|
||||
};
|
||||
|
||||
} /* namespace scheduling */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+233
@@ -0,0 +1,233 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace lwd {
|
||||
|
||||
|
||||
/**
|
||||
* Base-class of all lightweight data structs holding input and output values.
|
||||
**/
|
||||
class _wfr_lwd {
|
||||
private:
|
||||
uint32_t type_id;
|
||||
uint32_t payload_size;
|
||||
// actual content will be stored here (in derived structs)
|
||||
|
||||
public:
|
||||
virtual ~_wfr_lwd() noexcept {}
|
||||
|
||||
_wfr_lwd(const uint32_t& type, const uint32_t& struct_size) : type_id(type), payload_size(struct_size - sizeof(_wfr_lwd)) {}
|
||||
uint32_t getTypeID() const { return type_id; }
|
||||
uint32_t getPayloadSize() const { return payload_size; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enum representing the status of lightweight data struct members
|
||||
**/
|
||||
enum class LWDMemberStatus
|
||||
: int { Pending,
|
||||
Ready };
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base-class for a lwd struct data member.
|
||||
**/
|
||||
template<class T>
|
||||
class _lwd_member_type {
|
||||
protected:
|
||||
T data;
|
||||
lwd::LWDMemberStatus status;
|
||||
|
||||
public:
|
||||
_lwd_member_type() : data(), status(lwd::LWDMemberStatus::Pending) {}
|
||||
_lwd_member_type(const T& data, const LWDMemberStatus& status = LWDMemberStatus::Ready) : data(data), status(status) {}
|
||||
virtual ~_lwd_member_type() noexcept {}
|
||||
|
||||
bool isReady() const { return (status == wfr::lwd::LWDMemberStatus::Ready); }
|
||||
const T& getValue() const { return data; }
|
||||
void setValue (const T& value) {
|
||||
data = value;
|
||||
status = wfr::lwd::LWDMemberStatus::Ready;
|
||||
}
|
||||
void setValue (const _lwd_member_type<T>& value) {
|
||||
if (value.isReady()) {
|
||||
setValue(value.getValue());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base-class for a loop port.
|
||||
**/
|
||||
template<class T>
|
||||
class _lwd_loop_port : public T {
|
||||
private:
|
||||
wfr_id_t nextIterationID = 0;
|
||||
|
||||
public:
|
||||
virtual ~_lwd_loop_port() noexcept {}
|
||||
|
||||
wfr_id_t getNextIterationID() const { return nextIterationID; }
|
||||
void setNextIterationID(const wfr_id_t& id) { nextIterationID = id; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<wfr_size_t NESTINGLEVEL>
|
||||
struct collection_is_level_greater_one {
|
||||
static const bool value = true;
|
||||
};
|
||||
template<>
|
||||
struct collection_is_level_greater_one<1> {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base-class for a collection.
|
||||
**/
|
||||
template<class BASETYPE, wfr_size_t NESTINGLEVEL>
|
||||
class iwir_collection : public _lwd_member_type<std::vector<_lwd_member_type<typename std::conditional<collection_is_level_greater_one<NESTINGLEVEL>::value, iwir_collection<BASETYPE, NESTINGLEVEL-1>, BASETYPE>::type>>> {
|
||||
public:
|
||||
typedef typename std::conditional<collection_is_level_greater_one<NESTINGLEVEL>::value, iwir_collection<BASETYPE, NESTINGLEVEL-1>, BASETYPE>::type CollectionBaseType;
|
||||
private:
|
||||
wfr_size_t size = 0;
|
||||
wfr_size_t readyCount = 0;
|
||||
bool finalisedFlag = false;
|
||||
public:
|
||||
iwir_collection() {
|
||||
assert(NESTINGLEVEL>0);
|
||||
}
|
||||
bool init(const wfr_size_t& csize, const CollectionBaseType& defaultvalue = CollectionBaseType()) {
|
||||
if (csize > 0 && this->size < csize) {
|
||||
for (wfr::wfr_size_t t = this->size; t < csize; t++) {
|
||||
//this->data.push_back({defaultvalue, wfr::lwd::LWDMemberStatus::Pending});
|
||||
this->data.push_back(_lwd_member_type<CollectionBaseType>(defaultvalue, wfr::lwd::LWDMemberStatus::Pending));
|
||||
}
|
||||
this->size = csize;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
wfr_size_t getNestingLevel() const noexcept { return NESTINGLEVEL; }
|
||||
bool isFinalised() const { return finalisedFlag; }
|
||||
void setFinalised(const bool& v) {
|
||||
finalisedFlag = v;
|
||||
if (finalisedFlag && readyCount == this->size) {
|
||||
this->status = wfr::lwd::LWDMemberStatus::Ready;
|
||||
}
|
||||
}
|
||||
wfr_size_t getReadyCount() const { return readyCount; }
|
||||
wfr_size_t getSize() const { return size; }
|
||||
_lwd_member_type<CollectionBaseType>& getEntry(const wfr_id_t& index) {
|
||||
return this->data[index];
|
||||
}
|
||||
const CollectionBaseType& getEntryValue(const wfr_id_t& index) const {
|
||||
return this->data[index].getValue();
|
||||
}
|
||||
bool getEntryStatus(const wfr_id_t& index) const {
|
||||
return this->data[index].isReady();
|
||||
}
|
||||
void setEntryValue(const wfr_id_t& index, const CollectionBaseType& value) {
|
||||
if (this->size <= index) {
|
||||
for (wfr::wfr_size_t t = this->size; t < index; t++) {
|
||||
this->data.emplace_back(CollectionBaseType(), wfr::lwd::LWDMemberStatus::Pending);
|
||||
}
|
||||
this->data.emplace_back(value, wfr::lwd::LWDMemberStatus::Ready);
|
||||
this->size = index+1;
|
||||
readyCount++;
|
||||
} else {
|
||||
if (!this->data[index].isReady()) {
|
||||
this->data[index].setValue(value);
|
||||
readyCount++;
|
||||
}
|
||||
}
|
||||
if (finalisedFlag && readyCount == this->size) {
|
||||
this->status = wfr::lwd::LWDMemberStatus::Ready;
|
||||
}
|
||||
}
|
||||
void assign(const std::initializer_list<CollectionBaseType>& ilist, const bool& finalize = false) {
|
||||
this->data.clear();
|
||||
for (auto& e : ilist) {
|
||||
this->data.push_back(_lwd_member_type<CollectionBaseType>(e));
|
||||
}
|
||||
size = ilist.size();
|
||||
readyCount = size;
|
||||
if (finalize) {
|
||||
finalisedFlag = finalize;
|
||||
this->status = wfr::lwd::LWDMemberStatus::Ready;
|
||||
}
|
||||
}
|
||||
typename std::vector<_lwd_member_type<CollectionBaseType>>::iterator begin() {
|
||||
return this->data.begin();
|
||||
}
|
||||
typename std::vector<_lwd_member_type<CollectionBaseType>>::iterator end() {
|
||||
return this->data.end();
|
||||
}
|
||||
typename std::vector<_lwd_member_type<CollectionBaseType>>::const_iterator begin() const {
|
||||
return this->data.begin();
|
||||
}
|
||||
typename std::vector<_lwd_member_type<CollectionBaseType>>::const_iterator end() const {
|
||||
return this->data.end();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Typedefs representing IWIR base types.
|
||||
**/
|
||||
|
||||
typedef long _lwd_iwir_basetype_int;
|
||||
|
||||
typedef double _lwd_iwir_basetype_double;
|
||||
|
||||
typedef bool _lwd_iwir_basetype_bool;
|
||||
|
||||
typedef std::string _lwd_iwir_basetype_string;
|
||||
|
||||
typedef std::string _lwd_iwir_basetype_file;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Typedefs representing IWIR lwd members types.
|
||||
**/
|
||||
|
||||
typedef _lwd_member_type<_lwd_iwir_basetype_string> iwir_string;
|
||||
|
||||
typedef _lwd_member_type<_lwd_iwir_basetype_int> iwir_int;
|
||||
|
||||
typedef _lwd_member_type<_lwd_iwir_basetype_double> iwir_double;
|
||||
|
||||
typedef _lwd_member_type<_lwd_iwir_basetype_bool> iwir_bool;
|
||||
|
||||
typedef _lwd_member_type<_lwd_iwir_basetype_file> iwir_file;
|
||||
|
||||
|
||||
/**
|
||||
* Typedefs representing other lwd member types.
|
||||
**/
|
||||
|
||||
typedef _lwd_member_type<void*> lwdm_void_pointer;
|
||||
|
||||
|
||||
|
||||
} // namespace lwd
|
||||
} // namespace wfr
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <string>
|
||||
|
||||
namespace wfr {
|
||||
namespace resource {
|
||||
|
||||
|
||||
|
||||
enum class ResourceClass {
|
||||
Unknown,
|
||||
ComputingResource
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum class ComputingDeviceClass
|
||||
: int { Unknown,
|
||||
CPU,
|
||||
GPU };
|
||||
|
||||
|
||||
enum class ResourceCapabilityType
|
||||
: int { Unknown,
|
||||
// ComputingResource Capabilities
|
||||
GenericCPU,
|
||||
OpenCL,
|
||||
CUDA };
|
||||
|
||||
|
||||
} // namespace wfr
|
||||
} // namespace resource
|
||||
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace wfr {
|
||||
namespace wep {
|
||||
|
||||
/**
|
||||
* Enum representing the different types of the workflow execution plan nodes.
|
||||
**/
|
||||
enum class WepNodeType
|
||||
: int { Unknown,
|
||||
Atomic,
|
||||
Assign,
|
||||
CompositeStart,
|
||||
CompositeEnd,
|
||||
IterationStart,
|
||||
IterationEnd,
|
||||
Hole };
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <chrono>
|
||||
|
||||
// main namespace
|
||||
namespace wfr {
|
||||
|
||||
/**
|
||||
* Type used for IDs.
|
||||
**/
|
||||
typedef uint64_t wfr_id_t;
|
||||
|
||||
/**
|
||||
* Type used for sizes or counts.
|
||||
**/
|
||||
typedef uint64_t wfr_size_t;
|
||||
|
||||
/**
|
||||
* Type used for timestamps and time durations.
|
||||
**/
|
||||
typedef std::chrono::system_clock::time_point wfr_timestamp_sc_t;
|
||||
typedef std::chrono::system_clock::duration wfr_duration_sc_t;
|
||||
|
||||
|
||||
/**
|
||||
* Type used for numeric measurements.
|
||||
*
|
||||
* Numeric measurements usually come with a value and a standard deviation (or variance).
|
||||
**/
|
||||
class NumericalMeasurement {
|
||||
private:
|
||||
double value;
|
||||
double deviation;
|
||||
bool valid;
|
||||
public:
|
||||
NumericalMeasurement()
|
||||
: value(0), deviation(0), valid(false) {}
|
||||
|
||||
NumericalMeasurement(double value, double deviation = 0, bool valid = true)
|
||||
: value(value), deviation(deviation), valid(valid) {}
|
||||
|
||||
double getValue() const { return value; }
|
||||
double getDeviation() const { return deviation; }
|
||||
bool isValid() const { return valid; }
|
||||
|
||||
bool operator<(const NumericalMeasurement& other) const {
|
||||
return value < other.value;
|
||||
}
|
||||
|
||||
bool operator<=(const NumericalMeasurement& other) const {
|
||||
return value <= other.value;
|
||||
}
|
||||
|
||||
bool operator>(const NumericalMeasurement& other) const {
|
||||
return value > other.value;
|
||||
}
|
||||
|
||||
bool operator>=(const NumericalMeasurement& other) const {
|
||||
return value >= other.value;
|
||||
}
|
||||
|
||||
bool operator==(const NumericalMeasurement& other) const {
|
||||
return value == other.value;
|
||||
}
|
||||
|
||||
NumericalMeasurement& operator+=(const NumericalMeasurement& other) {
|
||||
value += other.value;
|
||||
// ToDo: Fehlerfortpflanzungsgesetz
|
||||
valid = other.valid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
NumericalMeasurement operator+(const NumericalMeasurement& other) {
|
||||
NumericalMeasurement retval(*this);
|
||||
if (retval.isValid() && other.isValid()) {
|
||||
retval.value += other.value;
|
||||
}
|
||||
// ToDo: Fehlerfortpflanzungsgesetz
|
||||
return retval;
|
||||
}
|
||||
|
||||
NumericalMeasurement& operator/=(wfr_size_t other) {
|
||||
value /= other;
|
||||
// ToDo: Fehlerfortpflanzungsgesetz
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace wfr
|
||||
|
||||
|
||||
Executable
+137
@@ -0,0 +1,137 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class ActivityInstance;
|
||||
class ConditionalActivityInstance;
|
||||
class WhileLoopActivityInstance;
|
||||
class ForLoopActivityInstance;
|
||||
class LoopActivityInstance;
|
||||
|
||||
|
||||
/**
|
||||
* Enum representing the different types of workflow items.
|
||||
**/
|
||||
enum class ActivityType
|
||||
: int { Unknown,
|
||||
Atomic,
|
||||
Container,
|
||||
ForLoop,
|
||||
WhileLoop,
|
||||
Conditional,
|
||||
Assign };
|
||||
|
||||
enum class ActivityImplementationType
|
||||
: int { Unknown,
|
||||
PThread,
|
||||
OpenMP,
|
||||
OpenCL,
|
||||
CUDA };
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enum for Workflow status
|
||||
**/
|
||||
enum class WorkflowStatus
|
||||
: int { Unknown,
|
||||
Created,
|
||||
Initialized,
|
||||
Running,
|
||||
Finished,
|
||||
Error
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enum for Activity status
|
||||
**/
|
||||
enum class ActivityStatus
|
||||
: int { Unknown,
|
||||
Created,
|
||||
Initialized,
|
||||
Running,
|
||||
Finished,
|
||||
Error
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enum for Activity Instance status
|
||||
**/
|
||||
enum class ActivityInstanceStatus
|
||||
: int { Unknown,
|
||||
Created,
|
||||
Initialized,
|
||||
WaitingForData,
|
||||
WaitingForDependency,
|
||||
ReadyForExecution,
|
||||
// SchedulerStates
|
||||
Scheduled,
|
||||
// ExecutionLayerStates
|
||||
Queued,
|
||||
WaitingForFreeResources,
|
||||
Running,
|
||||
Finished,
|
||||
Error
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enum for Device Instance status
|
||||
**/
|
||||
enum class ComputingResourceStatus
|
||||
: int { Unknown,
|
||||
Created,
|
||||
Idle,
|
||||
Sleep,
|
||||
WokenUp,
|
||||
Busy,
|
||||
ExecutingTask,
|
||||
FinishedTask,
|
||||
Shutdown,
|
||||
Error
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
enum class ComponentType
|
||||
: int { Unknown,
|
||||
Enactment,
|
||||
Scheduler,
|
||||
ExecutionLayer };
|
||||
|
||||
|
||||
enum class ComponentStatus
|
||||
: int { Unknown,
|
||||
Idle,
|
||||
Busy,
|
||||
Finished,
|
||||
Error };
|
||||
|
||||
|
||||
/**
|
||||
* Types used for hook functions.
|
||||
**/
|
||||
typedef std::function<bool(ActivityInstance& instance)> InputHookFunc;
|
||||
typedef std::function<bool(ActivityInstance& instance)> OutputHookFunc;
|
||||
typedef std::function<bool(ActivityInstance& instance)> ExecutionHookFunc;
|
||||
typedef std::function<bool(ConditionalActivityInstance& instance)> BranchConditionHookFunc;
|
||||
typedef std::function<bool(LoopActivityInstance& instance)> LoopIterationHookFunc;
|
||||
typedef std::function<bool(WhileLoopActivityInstance& instance)> WhileConditionHookFunc;
|
||||
typedef std::function<bool(ForLoopActivityInstance& instance)> ForCounterHookFunc;
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace lwd
|
||||
} // namespace wfr
|
||||
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <wfr/common/exceptions/exceptions.h>
|
||||
#include <wfr/common/resource/ResourceCapabilities.h>
|
||||
#include <boost/format.hpp>
|
||||
#include <initializer_list>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace utils {
|
||||
|
||||
typedef std::initializer_list<std::pair<std::string, std::string>> PropertyList;
|
||||
|
||||
|
||||
class Properties {
|
||||
private:
|
||||
std::map<std::string, std::string> properties;
|
||||
|
||||
public:
|
||||
Properties() {}
|
||||
Properties(PropertyList props) {
|
||||
for (auto i : props) {
|
||||
properties.insert(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool hasProperty(const std::string& key) const noexcept {
|
||||
return properties.find(key) != properties.end();
|
||||
}
|
||||
|
||||
const std::string& getProperty(const std::string& key) const {
|
||||
auto i = properties.find(key);
|
||||
if (i != properties.end()) {
|
||||
return i->second;
|
||||
} else {
|
||||
throw exception::wfr_not_found((boost::format("Property \"%1%\" not found.") % key).str());
|
||||
}
|
||||
}
|
||||
|
||||
const std::map<std::string, std::string>& getProperties() const {
|
||||
return properties;
|
||||
}
|
||||
|
||||
void addProperty(const std::string& key, const std::string& value) noexcept {
|
||||
properties[key] = value;
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace utils */
|
||||
} /* namespace wfr */
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
/* Precompiled boost was not compiled with -std=c++11 */
|
||||
#define BOOST_NO_CXX11_SCOPED_ENUMS
|
||||
|
||||
#include <wfr/common/wfs/ActivityInstance.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
namespace filesystem {
|
||||
|
||||
|
||||
boost::filesystem::path createWorkingFolder(wfr::wfs::ActivityInstance& instance);
|
||||
boost::filesystem::path createWorkingFolder(std::string name);
|
||||
|
||||
boost::filesystem::path createFolder(wfr::wfs::ActivityInstance& instance, boost::filesystem::path pdir, std::string fname);
|
||||
|
||||
void copy_file(const boost::filesystem::path& from, const boost::filesystem::path& to,
|
||||
boost::filesystem::copy_option::enum_type option = boost::filesystem::copy_option::enum_type::overwrite_if_exists);
|
||||
|
||||
|
||||
} // end namespace filesystem
|
||||
} // end namespace wfr
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace print {
|
||||
|
||||
|
||||
inline std::string toString(const wfs::WorkflowStatus& status) {
|
||||
std::string retval;
|
||||
switch (status) {
|
||||
case wfs::WorkflowStatus::Unknown:
|
||||
retval = "Unknown";
|
||||
break;
|
||||
case wfs::WorkflowStatus::Created:
|
||||
retval = "Created";
|
||||
break;
|
||||
case wfs::WorkflowStatus::Initialized:
|
||||
retval = "Initialized";
|
||||
break;
|
||||
case wfs::WorkflowStatus::Running:
|
||||
retval = "Running";
|
||||
break;
|
||||
case wfs::WorkflowStatus::Finished:
|
||||
retval = "Finished";
|
||||
break;
|
||||
case wfs::WorkflowStatus::Error:
|
||||
retval = "Error";
|
||||
break;
|
||||
default:
|
||||
retval = "<<Unknown Status>>";
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
inline std::string toString(const wfs::ActivityStatus& status) {
|
||||
std::string retval;
|
||||
switch (status) {
|
||||
case wfs::ActivityStatus::Unknown:
|
||||
retval = "Unknown";
|
||||
break;
|
||||
case wfs::ActivityStatus::Created:
|
||||
retval = "Created";
|
||||
break;
|
||||
case wfs::ActivityStatus::Initialized:
|
||||
retval = "Initialized";
|
||||
break;
|
||||
case wfs::ActivityStatus::Running:
|
||||
retval = "Running";
|
||||
break;
|
||||
case wfs::ActivityStatus::Finished:
|
||||
retval = "Finished";
|
||||
break;
|
||||
case wfs::ActivityStatus::Error:
|
||||
retval = "Error";
|
||||
break;
|
||||
default:
|
||||
retval = "<<Unknown Status>>";
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
inline std::string toString(const wfs::ActivityInstanceStatus& status) {
|
||||
std::string retval;
|
||||
switch (status) {
|
||||
case wfs::ActivityInstanceStatus::Unknown:
|
||||
retval = "Unknown";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::Created:
|
||||
retval = "Created";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::Initialized:
|
||||
retval = "Initialized";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::WaitingForData:
|
||||
retval = "WaitingForData";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::WaitingForDependency:
|
||||
retval = "WaitingForDependency";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::ReadyForExecution:
|
||||
retval = "ReadyForExecution";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::Scheduled:
|
||||
retval = "Scheduled";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::Queued:
|
||||
retval = "Queued";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::WaitingForFreeResources:
|
||||
retval = "WaitingForFreeResources";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::Running:
|
||||
retval = "Running";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::Error:
|
||||
retval = "Error";
|
||||
break;
|
||||
case wfs::ActivityInstanceStatus::Finished:
|
||||
retval = "Finished";
|
||||
break;
|
||||
default:
|
||||
retval = "<<Unknown Status>>";
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
inline std::string toString(const wfs::ComputingResourceStatus& status) {
|
||||
std::string retval;
|
||||
switch (status) {
|
||||
case wfs::ComputingResourceStatus::Unknown:
|
||||
retval = "Unknown";
|
||||
break;
|
||||
case wfs::ComputingResourceStatus::Created:
|
||||
retval = "Created";
|
||||
break;
|
||||
case wfs::ComputingResourceStatus::Idle:
|
||||
retval = "Idle";
|
||||
break;
|
||||
case wfs::ComputingResourceStatus::Sleep:
|
||||
retval = "Sleep";
|
||||
break;
|
||||
case wfs::ComputingResourceStatus::WokenUp:
|
||||
retval = "WokenUp";
|
||||
break;
|
||||
case wfs::ComputingResourceStatus::Busy:
|
||||
retval = "Busy";
|
||||
break;
|
||||
case wfs::ComputingResourceStatus::ExecutingTask:
|
||||
retval = "ExecutingTask";
|
||||
break;
|
||||
case wfs::ComputingResourceStatus::FinishedTask:
|
||||
retval = "FinishedTask";
|
||||
break;
|
||||
case wfs::ComputingResourceStatus::Shutdown:
|
||||
retval = "Shutdown";
|
||||
break;
|
||||
case wfs::ComputingResourceStatus::Error:
|
||||
retval = "Error";
|
||||
break;
|
||||
default:
|
||||
retval = "<<Unknown Status>>";
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
inline std::string toString(const wfs::ActivityImplementationType& type) {
|
||||
std::string retval;
|
||||
switch (type) {
|
||||
case wfs::ActivityImplementationType::PThread:
|
||||
retval = "PThread";
|
||||
break;
|
||||
case wfs::ActivityImplementationType::OpenMP:
|
||||
retval = "OpenMP";
|
||||
break;
|
||||
case wfs::ActivityImplementationType::OpenCL:
|
||||
retval = "OpenCL";
|
||||
break;
|
||||
case wfs::ActivityImplementationType::CUDA:
|
||||
retval = "CUDA";
|
||||
break;
|
||||
default:
|
||||
retval = "<<Unknown Device>>";
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
inline std::string toString(const wfs::ComponentType& type) {
|
||||
std::string retval;
|
||||
switch (type) {
|
||||
case wfs::ComponentType::Unknown:
|
||||
retval = "Unknown";
|
||||
break;
|
||||
case wfs::ComponentType::Enactment:
|
||||
retval = "Enactment";
|
||||
break;
|
||||
case wfs::ComponentType::Scheduler:
|
||||
retval = "Scheduler";
|
||||
break;
|
||||
case wfs::ComponentType::ExecutionLayer:
|
||||
retval = "ExecutionLayer";
|
||||
break;
|
||||
default:
|
||||
retval = "<<Unknown Type>>";
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
inline std::string toString(const wfs::ComponentStatus& state) {
|
||||
std::string retval;
|
||||
switch (state) {
|
||||
case wfs::ComponentStatus::Unknown:
|
||||
retval = "Unknown";
|
||||
break;
|
||||
case wfs::ComponentStatus::Idle:
|
||||
retval = "Idle";
|
||||
break;
|
||||
case wfs::ComponentStatus::Busy:
|
||||
retval = "Busy";
|
||||
break;
|
||||
case wfs::ComponentStatus::Finished:
|
||||
retval = "Finished";
|
||||
break;
|
||||
case wfs::ComponentStatus::Error:
|
||||
retval = "Error";
|
||||
break;
|
||||
default:
|
||||
retval = "<<Unknown State>>";
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
inline std::string toString(const wfs::ActivityType& type) {
|
||||
switch (type) {
|
||||
case wfs::ActivityType::Atomic:
|
||||
return "Atomic";
|
||||
case wfs::ActivityType::Conditional:
|
||||
return "Conditional";
|
||||
case wfs::ActivityType::Container:
|
||||
return "Container";
|
||||
case wfs::ActivityType::ForLoop:
|
||||
return "ForLoop";
|
||||
case wfs::ActivityType::WhileLoop:
|
||||
return "WhileLoop";
|
||||
case wfs::ActivityType::Unknown:
|
||||
return "Unknown";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "<<Unknown Type>>";
|
||||
}
|
||||
|
||||
|
||||
inline std::string toString(const wfr_timestamp_sc_t& timestamp) {
|
||||
std::stringstream ss;
|
||||
std::time_t time = std::chrono::system_clock::to_time_t(timestamp);
|
||||
std::tm* tm_time = std::localtime(&time);
|
||||
char temp[30];
|
||||
std::strftime(temp, sizeof(temp), "%d.%m.%Y %H:%M:", tm_time);
|
||||
ss << temp;
|
||||
std::chrono::duration<double> msecs = timestamp - std::chrono::system_clock::from_time_t(time) + std::chrono::seconds(tm_time->tm_sec);
|
||||
ss << std::fixed << std::setw(9) << std::setfill('0') << msecs.count();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
} /* namespace print */
|
||||
} /* namespace wfr */
|
||||
Executable
+216
@@ -0,0 +1,216 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/common/types/LwdTypes.h>
|
||||
#include <wfr/common/wfs/ActivityInstance.h>
|
||||
#include <wfr/common/wfs/instances/LoopActivityInstance.h>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Copy port values.
|
||||
*
|
||||
* Generic case
|
||||
**/
|
||||
|
||||
template<class C>
|
||||
inline bool portbuffer_copy(C& dest, const C& src) {
|
||||
if ( !dest.isReady() && src.isReady() ) {
|
||||
dest = src;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<class C>
|
||||
inline bool portbuffer_copy(C& dest, const lwd::_lwd_member_type<C>& src) {
|
||||
if ( !dest.isReady() && src.getValue().isReady() ) {
|
||||
dest = src.getValue();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Copy port values.
|
||||
*
|
||||
* Specialised cases for loop ports.
|
||||
**/
|
||||
|
||||
template<class C>
|
||||
inline bool portbuffer_copy(lwd::_lwd_loop_port<C>& dest, const C& src, const wfr_size_t& nextIter) {
|
||||
if ( src.isReady() && dest.getNextIterationID() < nextIter ) {
|
||||
dest.setValue(src.getValue());
|
||||
dest.setNextIterationID(nextIter);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<class C>
|
||||
inline bool portbuffer_copy(C& dest, const lwd::_lwd_loop_port<C>& src, const wfr_id_t& iterationID) {
|
||||
if ( !dest.isReady() && src.getNextIterationID()-1 == iterationID ) {
|
||||
dest.setValue(src.getValue());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Copy port values.
|
||||
*
|
||||
* Specialised cases for collections.
|
||||
**/
|
||||
|
||||
template<class C>
|
||||
inline bool portbuffer_copy(lwd::iwir_collection<C, 1>& dest, const C& src, const wfr_id_t& index) {
|
||||
if (dest.getSize() <= index || !dest.getEntry(index).isReady()) {
|
||||
dest.setEntryValue(index, src);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<class C>
|
||||
inline bool portbuffer_copy(lwd::iwir_collection<C, 1>& dest, const lwd::_lwd_member_type<C>& src, const wfr_id_t& index) {
|
||||
if ((dest.getSize() <= index || !dest.getEntry(index).isReady()) && src.isReady() ) {
|
||||
dest.setEntryValue(index, src.getValue());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<class C, wfr_size_t N>
|
||||
inline bool portbuffer_copy(lwd::iwir_collection<C, N>& dest, const lwd::iwir_collection<C, N-1>& src, const wfr_id_t& index) {
|
||||
if (dest.getSize() <= index || !dest.getEntry(index).isReady()) {
|
||||
dest.setEntryValue(index, src);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<class C, wfr_size_t N>
|
||||
inline bool portbuffer_copy(lwd::iwir_collection<C, N>& dest, const lwd::_lwd_member_type<lwd::iwir_collection<C, N-1>>& src, const wfr_id_t& index) {
|
||||
if ((dest.getSize() <= index || !dest.getEntry(index).isReady()) && src.isReady() ) {
|
||||
dest.setEntryValue(index, src.getValue());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<class C, wfr_size_t N, wfr_size_t F>
|
||||
struct collection_flatten {
|
||||
inline wfr_size_t operator()(lwd::iwir_collection<C, N>& dest, const lwd::iwir_collection<C, N+F-1>& src, const wfr_id_t& index) {
|
||||
wfr_size_t retval = 0;
|
||||
for (wfr_size_t i = 0; i < src.getSize(); i++) {
|
||||
retval += collection_flatten<C, N, F-1>()(dest, src.getEntryValue(i), index + retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
};
|
||||
|
||||
template<class C, wfr_size_t N>
|
||||
struct collection_flatten<C, N, 1> {
|
||||
inline wfr_size_t operator()(lwd::iwir_collection<C, N>& dest, const lwd::iwir_collection<C, N>& src, const wfr_id_t& index) {
|
||||
for (wfr_size_t i = 0; i < src.getSize(); i++) {
|
||||
if (dest.getSize() <= index+i || !dest.getEntryStatus(index + i)) {
|
||||
dest.setEntryValue(index + i, src.getEntryValue(i));
|
||||
}
|
||||
}
|
||||
return src.getSize();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<wfr_size_t F, class C, wfr_size_t N>
|
||||
inline wfr_size_t portbuffer_copy_flatten(lwd::iwir_collection<C, N>& dest, const lwd::iwir_collection<C, N+F-1>& src, const wfr_id_t& index = 0) {
|
||||
if (!dest.isReady() && src.isReady()) {
|
||||
return collection_flatten<C, N, F>()(dest, src, index);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the predecessor with the given index has finished execution.
|
||||
**/
|
||||
inline bool wfr_pred_isfinished(const wfs::ActivityInstance& instance, const wfr_id_t& predIndex) {
|
||||
auto predname = instance.getPredecessors()[predIndex];
|
||||
if (predname != nullptr) {
|
||||
return predname->getInstanceStatus() == wfr::wfs::ActivityInstanceStatus::Finished;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the predecessor with the given index is ready-for-execution.
|
||||
**/
|
||||
inline bool wfr_pred_isReady(const wfr::wfs::ActivityInstance& instance, const wfr_id_t& predIndex) {
|
||||
auto predname = instance.getPredecessors()[predIndex];
|
||||
if (predname != nullptr) {
|
||||
return predname->getInstanceStatus() == wfr::wfs::ActivityInstanceStatus::ReadyForExecution;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the previous loop iteration has finished execution.
|
||||
**/
|
||||
inline bool wfr_previter_isfinished(const wfr::wfs::ActivityInstance& loopinstance, const wfr_id_t& currentIterID) {
|
||||
if (currentIterID == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return loopinstance.as<wfr::wfs::LoopActivityInstance>().hasIterationFinished(currentIterID -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the parent activity is ready-for-execution.
|
||||
**/
|
||||
inline bool wfr_parent_isReady(const wfr::wfs::ActivityInstance& instance) {
|
||||
auto predname = instance.getParentActivity();
|
||||
if (predname != nullptr) {
|
||||
return predname->getInstanceStatus() == wfr::wfs::ActivityInstanceStatus::ReadyForExecution;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the parent activity has finished execution.
|
||||
**/
|
||||
inline bool wfr_parent_isfinished(const wfr::wfs::ActivityInstance& instance) {
|
||||
auto predname = instance.getParentActivity();
|
||||
if (predname != nullptr) {
|
||||
return predname->getInstanceStatus() == wfr::wfs::ActivityInstanceStatus::Finished;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end namespace wfr
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/WepTypes.h>
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
|
||||
namespace wep {
|
||||
|
||||
|
||||
class AbstractWepNode {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
// Static non-public properties
|
||||
protected:
|
||||
/**
|
||||
* Static variable holding the next free wepID.
|
||||
**/
|
||||
static std::atomic<wfr_id_t> nextWepNodeID;
|
||||
|
||||
/**
|
||||
* Returns the next free wepID.
|
||||
*
|
||||
* @return next free wepID.
|
||||
*/
|
||||
static wfr_id_t getNextWepNodeID() noexcept { return nextWepNodeID.fetch_add(1); }
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
std::vector<AbstractWepNode*> predecessors;
|
||||
std::vector<AbstractWepNode*> successors;
|
||||
std::shared_ptr<void> userData;
|
||||
uint64_t visitationCount = 0;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const wfr_id_t nodeID;
|
||||
const WepNodeType nodeType;
|
||||
const bool withActivityInstance;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
AbstractWepNode(WepNodeType nodeType, bool withInstance) noexcept
|
||||
: nodeID(getNextWepNodeID()), nodeType(nodeType), withActivityInstance(withInstance) {}
|
||||
virtual ~AbstractWepNode() noexcept {}
|
||||
|
||||
const std::vector<AbstractWepNode*>& getPredecessors() const noexcept { return predecessors; }
|
||||
std::vector<AbstractWepNode*>& getPredecessors() noexcept { return predecessors; }
|
||||
const std::vector<AbstractWepNode*>& getSuccessors() const noexcept { return successors; }
|
||||
std::vector<AbstractWepNode*>& getSuccessors() noexcept { return successors; }
|
||||
|
||||
std::shared_ptr<void> getUserData() const noexcept { return userData; }
|
||||
void setUserData(std::shared_ptr<void> data) noexcept { userData = data; }
|
||||
|
||||
uint64_t getVisitationCount() const noexcept { return visitationCount; }
|
||||
virtual void addToVisitationCount(uint64_t val = 1) noexcept { visitationCount += val; }
|
||||
|
||||
template<class T>
|
||||
T& as() noexcept { return *static_cast<T*>(this); }
|
||||
|
||||
template<class T>
|
||||
const T& as() const noexcept { return *static_cast<const T*>(this); }
|
||||
};
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wep/AbstractWepNode.h>
|
||||
|
||||
|
||||
// Forward declarations
|
||||
namespace wfr {
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
namespace wfs {
|
||||
class ActivityInstance;
|
||||
}
|
||||
|
||||
// Main namespace
|
||||
namespace wep {
|
||||
|
||||
|
||||
class ActivityWepNode : public AbstractWepNode {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
wfr::wfs::ActivityInstanceStatus lastKnownActivityStatus;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
wfs::ActivityInstance& activity;
|
||||
|
||||
public:
|
||||
ActivityWepNode(WepNodeType nodeType, wfs::ActivityInstance& activity) noexcept;
|
||||
|
||||
virtual void addToVisitationCount(uint64_t val = 1) noexcept override;
|
||||
|
||||
virtual wfs::ActivityInstanceStatus getLastKnownInstanceStatus() const noexcept { return lastKnownActivityStatus; }
|
||||
|
||||
virtual void updateInstanceStatus();
|
||||
};
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <atomic>
|
||||
#include <stdint.h>
|
||||
|
||||
// Forward declarations
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
class Workflow;
|
||||
}
|
||||
|
||||
// Main namespace
|
||||
namespace wep {
|
||||
|
||||
|
||||
class AbstractWepNode;
|
||||
|
||||
class WorkflowExecutionPlan {
|
||||
|
||||
// Static non-public properties
|
||||
private:
|
||||
/**
|
||||
* Static variable holding the next free wepID.
|
||||
**/
|
||||
static std::atomic<wfr_id_t> nextWepID;
|
||||
|
||||
/**
|
||||
* Returns the next free wepID.
|
||||
*
|
||||
* @return next free wepID.
|
||||
*/
|
||||
static wfr_id_t getNextWepID() { return nextWepID.fetch_add(1); }
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
AbstractWepNode* startNode;
|
||||
AbstractWepNode* endNode;
|
||||
|
||||
wfr_id_t version = 0;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const wfr_id_t wepID;
|
||||
wfr::wfs::Workflow& workflow;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
WorkflowExecutionPlan(wfr::wfs::Workflow& wf, AbstractWepNode* startNode, AbstractWepNode* endNode) noexcept
|
||||
: startNode(startNode), endNode(endNode), wepID(getNextWepID()), workflow(wf) {}
|
||||
~WorkflowExecutionPlan() noexcept;
|
||||
|
||||
AbstractWepNode* getStartNode() const noexcept { return startNode; }
|
||||
AbstractWepNode* getEndNode() const noexcept { return endNode; }
|
||||
|
||||
wfr_id_t getVersion() const noexcept { return version; }
|
||||
|
||||
void increaseVersion(wfr_id_t value = 1) noexcept { this->version += value; }
|
||||
};
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wep/ActivityWepNode.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
|
||||
namespace wep {
|
||||
|
||||
|
||||
class AssignWepNode: public ActivityWepNode {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
public:
|
||||
AssignWepNode(wfs::ActivityInstance& instance)
|
||||
: ActivityWepNode(WepNodeType::Assign, instance) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wep/ActivityWepNode.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
|
||||
namespace wep {
|
||||
|
||||
|
||||
class AtomicWepNode: public ActivityWepNode {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
public:
|
||||
AtomicWepNode(wfs::ActivityInstance& instance)
|
||||
: ActivityWepNode(WepNodeType::Atomic, instance) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wep/ActivityWepNode.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
|
||||
namespace wep {
|
||||
|
||||
// Forward declarations
|
||||
class CompositeStartWepNode;
|
||||
|
||||
|
||||
class CompositeEndWepNode: public ActivityWepNode {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
private:
|
||||
CompositeStartWepNode* startNode = nullptr;
|
||||
|
||||
public:
|
||||
CompositeEndWepNode(wfs::ActivityInstance& instance) noexcept
|
||||
: ActivityWepNode(WepNodeType::CompositeEnd, instance) {}
|
||||
|
||||
CompositeStartWepNode* getStartNode() const noexcept { return startNode; }
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wep/ActivityWepNode.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
|
||||
namespace wep {
|
||||
|
||||
// Forward declarations
|
||||
class CompositeEndWepNode;
|
||||
|
||||
|
||||
class CompositeStartWepNode: public ActivityWepNode {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
private:
|
||||
CompositeEndWepNode* endNode = nullptr;
|
||||
|
||||
public:
|
||||
CompositeStartWepNode(wfs::ActivityInstance& instance)
|
||||
: ActivityWepNode(WepNodeType::CompositeStart, instance) {}
|
||||
|
||||
CompositeEndWepNode* getEndNode() const noexcept { return endNode; }
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wep/ActivityWepNode.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
|
||||
namespace wep {
|
||||
|
||||
class IterationStartWepNode;
|
||||
|
||||
|
||||
class IterationEndWepNode: public ActivityWepNode {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
private:
|
||||
IterationStartWepNode* startNode = nullptr;
|
||||
|
||||
public:
|
||||
const wfr_id_t iterationID;
|
||||
|
||||
public:
|
||||
IterationEndWepNode(wfs::ActivityInstance& instance, wfr_id_t iterationID)
|
||||
: ActivityWepNode(WepNodeType::IterationEnd, instance), iterationID(iterationID) {}
|
||||
|
||||
virtual void updateInstanceStatus() override;
|
||||
|
||||
virtual wfs::ActivityInstanceStatus getLastKnownInstanceStatus() const noexcept override;
|
||||
|
||||
IterationStartWepNode* getStartNode() const noexcept { return startNode; }
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wep/ActivityWepNode.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
|
||||
namespace wep {
|
||||
|
||||
class IterationEndWepNode;
|
||||
|
||||
|
||||
class IterationStartWepNode: public ActivityWepNode {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
private:
|
||||
IterationEndWepNode* endNode = nullptr;
|
||||
|
||||
public:
|
||||
const wfr_id_t iterationID;
|
||||
|
||||
public:
|
||||
IterationStartWepNode(wfs::ActivityInstance& instance, wfr_id_t iterationID)
|
||||
: ActivityWepNode(WepNodeType::IterationStart, instance), iterationID(iterationID) {}
|
||||
|
||||
virtual void updateInstanceStatus() override;
|
||||
|
||||
IterationEndWepNode* getEndNode() const noexcept { return endNode; }
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+209
@@ -0,0 +1,209 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Workflow;
|
||||
class ActivityInstance;
|
||||
class ActivityTemplate;
|
||||
|
||||
|
||||
class Activity {
|
||||
friend class ActivityTemplate;
|
||||
friend class Workflow;
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
// Static non-public properties
|
||||
private:
|
||||
/**
|
||||
* Static variable holding the next free activityID.
|
||||
**/
|
||||
static std::atomic<wfr_id_t> nextActivityID;
|
||||
|
||||
/**
|
||||
* Returns the next free activityID.
|
||||
*
|
||||
* @return next free activityID.
|
||||
*/
|
||||
static wfr_id_t getNextActivityID() { return nextActivityID.fetch_add(1); }
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
/** Status of this activity object. **/
|
||||
ActivityStatus status;
|
||||
|
||||
/** Vector holding references to instances of this workflow activity. **/
|
||||
std::vector<ActivityInstance*> instanceList;
|
||||
|
||||
/** Reference to the parent of this activity object (structure-wise). **/
|
||||
Activity* parent = nullptr;
|
||||
|
||||
std::vector<Activity*> successors;
|
||||
|
||||
std::vector<Activity*> predecessors;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
/** Unique ID of this workflow activity. **/
|
||||
const wfr_id_t activityID;
|
||||
|
||||
/** Parent workflow instance of this activity object. **/
|
||||
Workflow& workflow;
|
||||
|
||||
/** Parent activitiy template of this activity object. **/
|
||||
ActivityTemplate& baseTemplate;
|
||||
|
||||
|
||||
// Non-public functions
|
||||
private:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param workflow workflow instance this activity object belongs to.
|
||||
* @param baseTemplate activity template this object is associated with.
|
||||
* @param parent the parent activity of this object (structure-wise).
|
||||
*/
|
||||
Activity( Workflow& workflow, ActivityTemplate& baseTemplate );
|
||||
|
||||
/**
|
||||
* Initialises this activity object.
|
||||
*
|
||||
* @param activities list of activities for successor/predecessor lists generation.
|
||||
**/
|
||||
void initActivity();
|
||||
|
||||
/**
|
||||
* Creates a new activity instance of this activity object.
|
||||
*
|
||||
* @return new activity instance.
|
||||
**/
|
||||
ActivityInstance* createNewInstance(wfr_id_t iterationID = 0);
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
/** Destructor. **/
|
||||
~Activity() noexcept;
|
||||
|
||||
ActivityType activityType() const noexcept;
|
||||
|
||||
bool isCompositeActivity() const noexcept;
|
||||
|
||||
bool isLoop() const noexcept;
|
||||
|
||||
bool isConditional() const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the number of activity instances of this activity object.
|
||||
*
|
||||
* @return number of activity instances.
|
||||
**/
|
||||
wfr_size_t getInstanceCount() const noexcept { return instanceList.size(); }
|
||||
|
||||
/**
|
||||
* Returns a reference to the vector holding the activity instance references.
|
||||
*
|
||||
* @return reference to the vector holding the activity instance references.
|
||||
**/
|
||||
const std::vector<ActivityInstance*>& getInstanceList() const noexcept { return instanceList; }
|
||||
|
||||
/**
|
||||
* Returns the parent activity of this object (structure-wise).
|
||||
*
|
||||
* @return parent activity.
|
||||
**/
|
||||
Activity* getParent() const noexcept { return parent; }
|
||||
|
||||
wfr_size_t getChildrenCount(wfr_id_t branchID = 0) const noexcept;
|
||||
|
||||
std::vector<Activity*> getChildren(wfr_id_t branchID = 0) const noexcept;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of successors.
|
||||
*
|
||||
* @return number of successors.
|
||||
**/
|
||||
wfr_size_t getSuccessorCount() const noexcept { return successors.size(); }
|
||||
|
||||
/**
|
||||
* Returns a reference to the array holding the successors.
|
||||
*
|
||||
* @return reference to the array holding the successors.
|
||||
**/
|
||||
const std::vector<Activity*> getSuccessors() const noexcept { return successors; }
|
||||
|
||||
/**
|
||||
* Returns whether the given activityID belongs to a successor.
|
||||
*
|
||||
* @param aid activityID to test.
|
||||
* @return true if successor, false otherwise.
|
||||
*/
|
||||
bool isSuccessor(wfr_id_t aid) const noexcept;
|
||||
|
||||
/**
|
||||
* Returns whether the given reference is a successor.
|
||||
*
|
||||
* @param act reference to test
|
||||
* @return true if successor, false otherwise.
|
||||
*/
|
||||
bool isSuccessor(Activity& act) const noexcept;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of predecessors.
|
||||
*
|
||||
* @return number of predecessors.
|
||||
**/
|
||||
wfr_size_t getPredecessorCount() const noexcept { return predecessors.size(); }
|
||||
|
||||
/**
|
||||
* Returns a reference to the array holding the predecessors.
|
||||
*
|
||||
* @return reference to the array holding the predecessors.
|
||||
**/
|
||||
const std::vector<Activity*> getPredecessors() { return predecessors; }
|
||||
|
||||
/**
|
||||
* Returns whether the given activityID belongs to a predecessor.
|
||||
*
|
||||
* @param aid activityID to test.
|
||||
* @return true if predecessor, false otherwise.
|
||||
*/
|
||||
bool isPredecessor(wfr_id_t aid) const noexcept;
|
||||
|
||||
/**
|
||||
* Returns whether the given reference is a predecessor.
|
||||
*
|
||||
* @param act reference to test
|
||||
* @return true if predecessor, false otherwise.
|
||||
*/
|
||||
bool isPredecessor(Activity& act) const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the status of this activity.
|
||||
*
|
||||
* @return activity status.
|
||||
**/
|
||||
ActivityStatus getActivityStatus() const noexcept { return status; }
|
||||
|
||||
void setActivityStatus(ActivityStatus status);
|
||||
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+282
@@ -0,0 +1,282 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <wfr/common/types/LwdTypes.h>
|
||||
#include <wfr/common/exceptions/exceptions.h>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace scheduling { class SchedulingDecision; }
|
||||
namespace enactment { class WepBuilder; }
|
||||
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Activity;
|
||||
|
||||
|
||||
class ActivityInstance {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
// Static non-public properties
|
||||
private:
|
||||
/**
|
||||
* Static variable holding the next free activity instanceID.
|
||||
**/
|
||||
static std::atomic<wfr_id_t> nextInstanceID;
|
||||
|
||||
/**
|
||||
* Returns the next free activity instanceID.
|
||||
*
|
||||
* @return next free activity instanceID.
|
||||
*/
|
||||
static wfr_id_t getNextInstanceID();
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
/** Activity instance state. **/
|
||||
ActivityInstanceStatus status;
|
||||
|
||||
/** Reference to the parent of this activity instance object (structure-wise). **/
|
||||
ActivityInstance* parentActivity = nullptr;
|
||||
|
||||
/** Vector of successors. **/
|
||||
std::vector<ActivityInstance*> successors;
|
||||
|
||||
/** Vector of predecessors. **/
|
||||
std::vector<ActivityInstance*> predecessors;
|
||||
|
||||
/** Reference to input data struct. **/
|
||||
lwd::_wfr_lwd *inputData = nullptr;
|
||||
bool inputDataOwnership = false;
|
||||
|
||||
/** Reference to output data struct. **/
|
||||
lwd::_wfr_lwd *outputData = nullptr;
|
||||
bool outputDataOwnership = false;
|
||||
|
||||
bool allInputsAvailable = false;
|
||||
|
||||
bool allOutputsAvailable = false;
|
||||
|
||||
std::exception_ptr errorCause;
|
||||
|
||||
wfr::wfr_timestamp_sc_t readyTime;
|
||||
|
||||
wfr::wfr_timestamp_sc_t startTime;
|
||||
|
||||
wfr::wfr_timestamp_sc_t endTime;
|
||||
|
||||
uint64_t visitationCount = 0;
|
||||
|
||||
bool dirtyStateFlag = false;
|
||||
|
||||
std::shared_ptr<void> userData;
|
||||
|
||||
std::shared_ptr<scheduling::SchedulingDecision> schedulingDecision;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
/** Unique ID of this activity instance object. **/
|
||||
const wfr_id_t instanceID;
|
||||
|
||||
/** Activity this object is an instance of. **/
|
||||
const Activity& baseActivity;
|
||||
|
||||
const wfr_id_t iterationID;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param parentActivity activity this object is an instance of.
|
||||
*/
|
||||
ActivityInstance(Activity& baseActivity, const wfr_id_t& iterationID = 0) noexcept;
|
||||
|
||||
/** Destructor. **/
|
||||
virtual ~ActivityInstance() noexcept {
|
||||
if (inputData && inputDataOwnership) {
|
||||
delete inputData;
|
||||
inputData = nullptr;
|
||||
}
|
||||
if (outputData && outputDataOwnership) {
|
||||
delete outputData;
|
||||
outputData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ActivityType activityType() const noexcept;
|
||||
|
||||
bool isCompositeActivity() const noexcept;
|
||||
|
||||
bool isLoop() const noexcept;
|
||||
|
||||
bool isConditional() const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the state of this activity instance.
|
||||
*
|
||||
* @return state of this activity instance.
|
||||
**/
|
||||
ActivityInstanceStatus getInstanceStatus() const noexcept { return status; }
|
||||
|
||||
/**
|
||||
* Sets the state of this activity instance.
|
||||
*
|
||||
* @param status new state.
|
||||
**/
|
||||
void setInstanceStatus(const ActivityInstanceStatus& status);
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns a reference to this activity instance input data.
|
||||
*
|
||||
* @return input data.
|
||||
**/
|
||||
lwd::_wfr_lwd* const getInputData() const noexcept { return inputData; }
|
||||
|
||||
/**
|
||||
* Sets this instants input data.
|
||||
*
|
||||
* @param data input data.
|
||||
*/
|
||||
void setInputData(lwd::_wfr_lwd* data, bool ownership = true) noexcept {
|
||||
inputData = data;
|
||||
inputDataOwnership = ownership;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns a reference to this activity instance output data.
|
||||
*
|
||||
* @return output data.
|
||||
**/
|
||||
lwd::_wfr_lwd* const getOutputData() const noexcept { return outputData; }
|
||||
|
||||
/**
|
||||
* Sets this instants output data.
|
||||
*
|
||||
* @param data output data.
|
||||
*/
|
||||
void setOutputData(lwd::_wfr_lwd* data, bool ownership = true) noexcept {
|
||||
outputData = data;
|
||||
outputDataOwnership = ownership;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of predecessors.
|
||||
*
|
||||
* @return number of predecessors.
|
||||
**/
|
||||
wfr_size_t getPredecessorCount() const noexcept { return predecessors.size(); }
|
||||
|
||||
const std::vector<ActivityInstance*>& getPredecessors() const noexcept { return predecessors; }
|
||||
|
||||
std::vector<ActivityInstance*>& getPredecessors() noexcept { return predecessors; }
|
||||
|
||||
ActivityInstance* const getPredecessor(wfr_size_t index) const noexcept {
|
||||
return predecessors.at(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of successors.
|
||||
*
|
||||
* @return number of successors.
|
||||
**/
|
||||
wfr_size_t getSuccessorCount() const noexcept { return successors.size(); }
|
||||
|
||||
const std::vector<ActivityInstance*>& getSuccessors() const noexcept { return successors; }
|
||||
|
||||
std::vector<ActivityInstance*>& getSuccessors() noexcept { return successors; }
|
||||
|
||||
ActivityInstance* const getSuccessor(int index) const noexcept {
|
||||
return successors.at(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent of this instance (structure-wise).
|
||||
*
|
||||
* @return parent of this instance.
|
||||
**/
|
||||
ActivityInstance* const getParentActivity() const noexcept { return parentActivity; }
|
||||
|
||||
/**
|
||||
* Sets the parent of this instance (structure-wise).
|
||||
*
|
||||
* parent parent of this instance.
|
||||
**/
|
||||
void setParentActivity(ActivityInstance* parent) noexcept { this->parentActivity = parent; }
|
||||
|
||||
|
||||
bool areAllInputsAvailable() const noexcept { return allInputsAvailable; }
|
||||
|
||||
void setAllInputsAvailable(const bool& areAvailable = true) noexcept { allInputsAvailable = areAvailable; }
|
||||
|
||||
bool areAllOutputsAvailable() const noexcept { return allOutputsAvailable; }
|
||||
|
||||
void setAllOutputsAvailable(const bool& areAvailable = true) noexcept { allOutputsAvailable = areAvailable; }
|
||||
|
||||
|
||||
std::exception_ptr getErrorCause() const noexcept { return errorCause; }
|
||||
|
||||
void setErrorState(std::exception_ptr exception = nullptr)noexcept;
|
||||
|
||||
|
||||
const wfr::wfr_timestamp_sc_t& getReadyTime() const noexcept { return readyTime; }
|
||||
|
||||
const wfr::wfr_timestamp_sc_t& getStartTime() const noexcept { return startTime; }
|
||||
|
||||
const wfr::wfr_timestamp_sc_t& getEndTime() const noexcept { return endTime; }
|
||||
|
||||
|
||||
uint64_t getVisitationCount() const noexcept { return visitationCount; }
|
||||
|
||||
void addToVisitationCount(uint64_t val = 1) noexcept { visitationCount += val; }
|
||||
|
||||
|
||||
void setDirtyState() { dirtyStateFlag = true; }
|
||||
|
||||
bool isDirtyState() const { return dirtyStateFlag; }
|
||||
|
||||
void resetDirtyState() { dirtyStateFlag = false; }
|
||||
|
||||
|
||||
virtual bool executePreExecutionHooks(bool earlyEvaluation) { return false; }
|
||||
|
||||
virtual bool executeExecutionHook(bool earlyEvaluation) { return false; }
|
||||
|
||||
virtual bool executePostExecutionHooks(bool earlyEvaluation) { return false; }
|
||||
|
||||
std::shared_ptr<void> getUserData() { return userData; }
|
||||
|
||||
void setUserData(std::shared_ptr<void> data) { userData = data; }
|
||||
|
||||
void setSchedulingDecision(std::shared_ptr<scheduling::SchedulingDecision> sd = std::shared_ptr<scheduling::SchedulingDecision>()) noexcept {
|
||||
if (sd) {
|
||||
this->schedulingDecision = sd;
|
||||
} else {
|
||||
this->schedulingDecision.reset();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void executeSimMode() noexcept;
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
T& as() noexcept { return *static_cast<T*>(this); }
|
||||
|
||||
template<class T>
|
||||
const T& as() const noexcept { return *static_cast<const T*>(this); }
|
||||
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+257
@@ -0,0 +1,257 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/LwdTypes.h>
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
// forward declarations
|
||||
class Workflow;
|
||||
class WorkflowTemplate;
|
||||
class Activity;
|
||||
class AtomicActivityImplementation;
|
||||
class AtomicActivityType;
|
||||
|
||||
|
||||
class ActivityTemplate {
|
||||
friend class WorkflowTemplate;
|
||||
friend class Workflow;
|
||||
friend class Activity;
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
/** Parent activity. **/
|
||||
ActivityTemplate* parentActivity = nullptr;
|
||||
|
||||
/** Parent workflow. **/
|
||||
WorkflowTemplate* parentWorkflow = nullptr;
|
||||
|
||||
// Successors
|
||||
std::initializer_list<wfr_id_t> succRawList;
|
||||
std::vector<ActivityTemplate*> successors;
|
||||
|
||||
// Predecessors
|
||||
std::initializer_list<wfr_id_t> predRawList;
|
||||
std::vector<ActivityTemplate*> predecessors;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
/** Unique ID (>0).**/
|
||||
const wfr_id_t templateID;
|
||||
|
||||
const std::string activityName;
|
||||
|
||||
const ActivityType activityType;
|
||||
|
||||
const wfr_size_t parentActivityID;
|
||||
|
||||
/** BranchID of the parents execution branch (0 represents default branch). **/
|
||||
const wfr_id_t branchID;
|
||||
|
||||
const bool isCompositeActivity;
|
||||
|
||||
const bool isLoop;
|
||||
|
||||
const bool isConditional;
|
||||
|
||||
// Non-public functions.
|
||||
protected:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param id templateID of this template object.
|
||||
* @param type type of this template object.
|
||||
* @param branchID ID of the parents (structure-wise) execution branch this object belongs to.
|
||||
* @param succList list of templateIDs representing this objects successors (structure-wise).
|
||||
* @param predList list of templateIDs representing this objects predecessors (structure-wise).
|
||||
* @param name activity name of this object.
|
||||
**/
|
||||
ActivityTemplate( wfr_id_t id,
|
||||
ActivityType type,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
const std::initializer_list<wfr_id_t>& succList,
|
||||
const std::initializer_list<wfr_id_t>& predList,
|
||||
bool isCompositeActivity,
|
||||
bool isLoop,
|
||||
bool isConditional ) noexcept;
|
||||
|
||||
void initActivityTemplate(WorkflowTemplate& parentWorkflow);
|
||||
|
||||
virtual void checkStructure();
|
||||
|
||||
Activity* createActivityFromTemplate(wfr::wfs::Workflow& workflow);
|
||||
|
||||
// Public functions.
|
||||
public:
|
||||
virtual ~ActivityTemplate() noexcept {}
|
||||
|
||||
ActivityTemplate* getParentActivity() const noexcept { return parentActivity;}
|
||||
|
||||
WorkflowTemplate* getParentWorkflow() const noexcept {
|
||||
assert(parentWorkflow != nullptr);
|
||||
return parentWorkflow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of this objects successors.
|
||||
* @return number of successors.
|
||||
**/
|
||||
wfr_size_t getSuccessorCount() const noexcept { return successors.size(); }
|
||||
|
||||
/**
|
||||
* Returns all successors.
|
||||
* @return reference to vector with successors
|
||||
**/
|
||||
const std::vector<ActivityTemplate*>& getSuccessors() const noexcept { return successors; }
|
||||
|
||||
/**
|
||||
* Returns the successor with the given index.
|
||||
* @param index index of successor
|
||||
* @return successor with given index
|
||||
**/
|
||||
ActivityTemplate* getSuccessor(wfr_size_t index) const noexcept {
|
||||
if (index < successors.size()) {
|
||||
return successors[index];
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given activity is a successor of this object.
|
||||
* @param activity reference to test.
|
||||
* @return true if the given reference represents a successor, otherwise false.
|
||||
**/
|
||||
bool isSuccessor(const ActivityTemplate& activity) const noexcept {
|
||||
for (auto i : successors) {
|
||||
if (i == &activity) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of this objects predecessors.
|
||||
* @return number of predecessors.
|
||||
**/
|
||||
wfr_size_t getPredecessorCount() const noexcept { return predecessors.size(); }
|
||||
|
||||
/**
|
||||
* Returns all predecessors.
|
||||
* @return reference to vector with predecessors
|
||||
**/
|
||||
const std::vector<ActivityTemplate*>& getPredecessors() const noexcept { return predecessors; }
|
||||
|
||||
/**
|
||||
* Returns the predecessor with the given index.
|
||||
* @param index index of predecessor
|
||||
* @return predecessor with given index
|
||||
**/
|
||||
ActivityTemplate* getPredecessor(wfr_size_t index) const noexcept {
|
||||
if (index < predecessors.size()) {
|
||||
return predecessors[index];
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given activity is a successor of this object.
|
||||
* @param activity reference to test.
|
||||
* @return true if the given reference represents a successor, otherwise false.
|
||||
**/
|
||||
bool isPredecessor(const ActivityTemplate& activity) const noexcept {
|
||||
for (auto i : predecessors) {
|
||||
if (i == &activity) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& as() noexcept { return *static_cast<T*>(this); }
|
||||
|
||||
template<class T>
|
||||
const T& as() const noexcept { return *static_cast<const T*>(this); }
|
||||
|
||||
|
||||
/* ********************************************************** *
|
||||
* Convenience functions for activity template instantiation. *
|
||||
* ********************************************************** */
|
||||
public:
|
||||
|
||||
static ActivityTemplate* atomic( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
std::initializer_list<wfr_id_t> succList,
|
||||
std::initializer_list<wfr_id_t> predList,
|
||||
InputHookFunc inputHook,
|
||||
std::shared_ptr<AtomicActivityType> atomicActivityType );
|
||||
|
||||
static ActivityTemplate* assign( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
std::initializer_list<wfr_id_t> succList,
|
||||
std::initializer_list<wfr_id_t> predList,
|
||||
InputHookFunc inputHook,
|
||||
ExecutionHookFunc execHook );
|
||||
|
||||
static ActivityTemplate* container( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
std::initializer_list<wfr_id_t> succList,
|
||||
std::initializer_list<wfr_id_t> predList,
|
||||
InputHookFunc inputHook,
|
||||
OutputHookFunc outputHook );
|
||||
|
||||
static ActivityTemplate* forLoop( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
const std::initializer_list<wfr_id_t>& succList,
|
||||
const std::initializer_list<wfr_id_t>& predList,
|
||||
InputHookFunc inputFuncHook,
|
||||
OutputHookFunc outputFuncHook,
|
||||
ForCounterHookFunc counterFuncHook,
|
||||
LoopIterationHookFunc iterationFuncHook,
|
||||
bool isParallel );
|
||||
|
||||
static ActivityTemplate* whileLoop( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
const std::initializer_list<wfr_id_t>& succList,
|
||||
const std::initializer_list<wfr_id_t>& predList,
|
||||
InputHookFunc inputFuncHook,
|
||||
OutputHookFunc outputFuncHook,
|
||||
WhileConditionHookFunc conditionFuncHook,
|
||||
LoopIterationHookFunc iterationFuncHook );
|
||||
|
||||
static ActivityTemplate* conditional( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
const std::initializer_list<wfr_id_t>& succList,
|
||||
const std::initializer_list<wfr_id_t>& predList,
|
||||
InputHookFunc inputFuncHook,
|
||||
OutputHookFunc outputFuncHook,
|
||||
BranchConditionHookFunc branchFuncHook );
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <wfr/common/resource/ResourceCapabilities.h>
|
||||
#include <wfr/common/utils/Properties.h>
|
||||
#include <initializer_list>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
/**
|
||||
* Base class for atomic activity implementations.
|
||||
*
|
||||
* Must be cast to type specific class to be able to access type specific information.
|
||||
* Currently implemented sub-classes:
|
||||
* x) PThreadActivityImplementation
|
||||
* x) OpenCLActivityImplementation
|
||||
* x) CUDAActivityImplementation
|
||||
**/
|
||||
class AtomicActivityImplementation {
|
||||
|
||||
// Static objects to guarantee unique implementation IDs.
|
||||
private:
|
||||
static std::atomic<wfr_id_t> nextImplementationID;
|
||||
static wfr_id_t getNextImplementationID() {
|
||||
return nextImplementationID.fetch_add(1);
|
||||
}
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
std::vector<resource::RequiredResourceCapability> requiredCapabilities;
|
||||
utils::Properties properties;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const wfr_id_t implementationID;
|
||||
const ActivityImplementationType implementationType;
|
||||
const std::string name;
|
||||
|
||||
// Non-public functions.
|
||||
protected:
|
||||
AtomicActivityImplementation( ActivityImplementationType implementationType,
|
||||
const std::vector<resource::RequiredResourceCapability>& capabilities,
|
||||
const utils::Properties& properties,
|
||||
const std::string& name) noexcept
|
||||
: requiredCapabilities(capabilities), properties(properties),
|
||||
implementationID(getNextImplementationID()), implementationType(implementationType), name(name) {}
|
||||
|
||||
// Public functions.
|
||||
public:
|
||||
virtual ~AtomicActivityImplementation() noexcept {}
|
||||
|
||||
/**
|
||||
* Returns a vector with capabilities required for execution of this implementation.
|
||||
**/
|
||||
const std::vector<resource::RequiredResourceCapability>& getRequiredCapabilities() const noexcept { return requiredCapabilities; }
|
||||
|
||||
/**
|
||||
* Returns properties associated with this implementation.
|
||||
**/
|
||||
const utils::Properties& getProperties() const noexcept { return properties; }
|
||||
|
||||
/**
|
||||
* Helper function to ease cast operations.
|
||||
**/
|
||||
template<class T>
|
||||
T& as() noexcept { return *static_cast<T*>(this); }
|
||||
|
||||
/**
|
||||
* Const helper function to ease cast operations.
|
||||
**/
|
||||
template<class T>
|
||||
const T& as() const noexcept { return *static_cast<const T*>(this); }
|
||||
|
||||
/*
|
||||
* Static factory functions for creating activity implementation objects.
|
||||
*
|
||||
* Returned objects need to be manually deleted (Using smartpointers here causes too much overhead).
|
||||
* AtomicActivityImplementation objects are usually passed to an AtomicActivityType object which manages the lifecycle.
|
||||
*/
|
||||
public:
|
||||
/**
|
||||
* Returns a new pthread implementation object.
|
||||
*
|
||||
* Do not add GenericCPU capability as it is already automatically added.
|
||||
**/
|
||||
static AtomicActivityImplementation* PThread( const ExecutionHookFunc& executionFuncHook,
|
||||
const std::string& name = "",
|
||||
utils::PropertyList properties = {},
|
||||
resource::RequiredCapabilityList capabilities = {} ) noexcept;
|
||||
|
||||
/**
|
||||
* Returns a new OpenCL implementation object.
|
||||
*
|
||||
* Do not add OpenCL capability as it is already automatically added.
|
||||
**/
|
||||
static AtomicActivityImplementation* OpenCL( const ExecutionHookFunc& executionFuncHook,
|
||||
const std::string& name = "",
|
||||
std::initializer_list<wfr_size_t> minVersion = {0, 0},
|
||||
std::initializer_list<wfr_size_t> maxVersion = {0, 0},
|
||||
utils::PropertyList properties = {},
|
||||
resource::RequiredCapabilityList capabilities = {} ) noexcept;
|
||||
|
||||
/**
|
||||
* Returns a new CUDA implementation object.
|
||||
**/
|
||||
static AtomicActivityImplementation* CUDA( const ExecutionHookFunc& executionFuncHook,
|
||||
const std::string& name = "",
|
||||
std::initializer_list<wfr_size_t> minVersion = {0, 0},
|
||||
std::initializer_list<wfr_size_t> maxVersion = {0, 0},
|
||||
utils::PropertyList properties = {},
|
||||
resource::RequiredCapabilityList capabilities = {} ) noexcept;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+68
@@ -0,0 +1,68 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/LwdTypes.h>
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
// forward declarations
|
||||
class AtomicActivityImplementation;
|
||||
|
||||
/**
|
||||
* Represents an atomic activity type.
|
||||
**/
|
||||
class AtomicActivityType {
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
std::vector<wfs::AtomicActivityImplementation*> implementations;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const std::string name;
|
||||
|
||||
// Non-public functions.
|
||||
private:
|
||||
AtomicActivityType(const std::string& name, const std::initializer_list<AtomicActivityImplementation*>& implementations) noexcept
|
||||
: implementations(implementations), name(name) {}
|
||||
|
||||
// Public functions.
|
||||
public:
|
||||
~AtomicActivityType() noexcept;
|
||||
|
||||
/**
|
||||
* Returns the number of implementations.
|
||||
**/
|
||||
wfr_size_t getImplementationCount() const noexcept { return implementations.size(); }
|
||||
|
||||
/**
|
||||
* Returns a vector containing all implementations.
|
||||
**/
|
||||
const std::vector<AtomicActivityImplementation*>& getImplementations() const noexcept { return implementations; }
|
||||
|
||||
|
||||
/*
|
||||
* Static factory functions for creating atomic activity type objects.
|
||||
*
|
||||
* Returned objects may be referenced by more than one object and there is no single parent object,
|
||||
* therefore we are using shared pointers.
|
||||
*/
|
||||
public:
|
||||
/**
|
||||
* Returns a new atomic activity type object.
|
||||
**/
|
||||
static std::shared_ptr<AtomicActivityType> create(const std::string& name, const std::initializer_list<AtomicActivityImplementation*>& implementations) noexcept {
|
||||
return std::shared_ptr<AtomicActivityType>(new AtomicActivityType(name, implementations));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
Executable
+260
@@ -0,0 +1,260 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <wfr/common/types/LwdTypes.h>
|
||||
#include <wfr/common/exceptions/exceptions.h>
|
||||
#include <wfr/config.h>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Activity;
|
||||
class WorkflowTemplate;
|
||||
|
||||
|
||||
class Workflow {
|
||||
friend class WorkflowTemplate;
|
||||
|
||||
// Static non-public properties
|
||||
private:
|
||||
/**
|
||||
* Static variable holding the next free workflow instanceID.
|
||||
**/
|
||||
static std::atomic<wfr_id_t> nextWorkflowID;
|
||||
|
||||
/**
|
||||
* Returns the next free workflow instanceID.
|
||||
*
|
||||
* @return next free workflow instanceID.
|
||||
*/
|
||||
static wfr_id_t getNextWorkflowID() { return nextWorkflowID.fetch_add(1); }
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
/**
|
||||
* The current status of this workflow instance.
|
||||
**/
|
||||
WorkflowStatus status;
|
||||
|
||||
/**
|
||||
* Flag to indicate that the workflow is about to be finished.
|
||||
*/
|
||||
bool finishFlag = false;
|
||||
|
||||
/**
|
||||
* Vector holding the activities of this workflow instance.
|
||||
**/
|
||||
std::vector<Activity*> activities;
|
||||
|
||||
/**
|
||||
* Reference to top-level activity.
|
||||
**/
|
||||
Activity* topLevelActivity = nullptr;
|
||||
|
||||
/**
|
||||
* Cause of error.
|
||||
**/
|
||||
std::exception_ptr errorCause;
|
||||
|
||||
wfr::wfr_timestamp_sc_t createTime;
|
||||
wfr::wfr_timestamp_sc_t startTime;
|
||||
wfr::wfr_timestamp_sc_t endTime;
|
||||
|
||||
#ifdef WFR_ENABLE_STATISTICS
|
||||
std::mutex statMutex;
|
||||
|
||||
wfr::wfr_duration_sc_t enactmentTime = wfr::wfr_duration_sc_t::zero();
|
||||
|
||||
std::atomic<wfr_size_t> createdCompositeInstanceCount = ATOMIC_VAR_INIT(0);
|
||||
std::atomic<wfr_size_t> finishedCompositeInstanceCount = ATOMIC_VAR_INIT(0);
|
||||
std::atomic<wfr_size_t> errorCompositeInstanceCount = ATOMIC_VAR_INIT(0);
|
||||
|
||||
std::atomic<wfr_size_t> createdAtomicInstanceCount = ATOMIC_VAR_INIT(0);
|
||||
std::atomic<wfr_size_t> finishedAtomicInstanceCount = ATOMIC_VAR_INIT(0);
|
||||
std::atomic<wfr_size_t> errorAtomicInstanceCount = ATOMIC_VAR_INIT(0);
|
||||
|
||||
wfr::wfr_duration_sc_t cumulativeAtomicReadyWaitingDuration = wfr::wfr_duration_sc_t::zero();
|
||||
wfr::wfr_duration_sc_t cumulativeAtomicRunningDuration = wfr::wfr_duration_sc_t::zero();
|
||||
|
||||
std::atomic<wfr_size_t> wepNodeCount = ATOMIC_VAR_INIT(0);
|
||||
std::atomic<wfr_size_t> wepVisitationCount = ATOMIC_VAR_INIT(0);
|
||||
std::atomic<wfr_size_t> wepUpdateCount = ATOMIC_VAR_INIT(0);
|
||||
std::atomic<wfr_size_t> wepUpdateNotifyCount = ATOMIC_VAR_INIT(0);
|
||||
|
||||
std::atomic<double> cummulativePredictionTime = ATOMIC_VAR_INIT(0.0);
|
||||
#endif
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
/**
|
||||
* The instanceID of this workflow instance object.
|
||||
**/
|
||||
const wfr_id_t workflowID;
|
||||
|
||||
/**
|
||||
* The parent workflow object of this workflow instance.
|
||||
**/
|
||||
WorkflowTemplate& baseTemplate;
|
||||
|
||||
|
||||
// Non-public functions
|
||||
private:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent parent workflow object of this workflow instance.
|
||||
*/
|
||||
Workflow(WorkflowTemplate& baseTemplate);
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
/** Destructor. **/
|
||||
~Workflow() noexcept;
|
||||
|
||||
/**
|
||||
* Returns the status of this workflow instance.
|
||||
*
|
||||
* @return workflow instance status.
|
||||
*/
|
||||
WorkflowStatus getWorkflowStatus() const noexcept { return status; }
|
||||
|
||||
void setWorkflowStatus (WorkflowStatus status);
|
||||
|
||||
bool getFinishFlag() { return finishFlag; }
|
||||
|
||||
void setFinishFlag(bool val = true) { finishFlag = val; }
|
||||
|
||||
/**
|
||||
* Returns the number of contained workflow activities.
|
||||
*
|
||||
* @return number of contained workflow activities.
|
||||
**/
|
||||
wfr_size_t getActivityCount() const noexcept { return activities.size(); }
|
||||
|
||||
/**
|
||||
* Returns a reference to the static array holding the contained workflow activities.
|
||||
*
|
||||
* @return Reference to the array of contained workflow activities.
|
||||
*/
|
||||
const std::vector<Activity*> getActivities() const noexcept { return activities; }
|
||||
|
||||
/**
|
||||
* Returns the workflow activity with the given activityID.
|
||||
*
|
||||
* @param id activityID.
|
||||
* @return workflow activity with the given activityID.
|
||||
*/
|
||||
Activity* getActivityByID(wfr_id_t id) const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the workflow activity with the given templateID.
|
||||
*
|
||||
* @param id templateID.
|
||||
* @return workflow activity with the given templateID.
|
||||
*/
|
||||
Activity* getActivityByTemplateID(wfr_id_t id) const noexcept;
|
||||
|
||||
/**
|
||||
* Returns a reference to the top-level activity.
|
||||
*
|
||||
* @return top-level activity.
|
||||
*/
|
||||
Activity* getTopLevelActivity() const noexcept {
|
||||
assert(topLevelActivity);
|
||||
return topLevelActivity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the execution of this workflow instance.
|
||||
*
|
||||
* The function blocks till the execution has finished.
|
||||
*
|
||||
* @param input reference to workflow input data.
|
||||
* @param output reference to workflow output data.
|
||||
* @return
|
||||
*/
|
||||
WorkflowStatus executeSync( lwd::_wfr_lwd* input, lwd::_wfr_lwd* output );
|
||||
|
||||
|
||||
std::exception_ptr getErrorCause() const noexcept { return errorCause; }
|
||||
void setErrorState(std::exception_ptr cause = std::exception_ptr());
|
||||
|
||||
|
||||
const wfr::wfr_timestamp_sc_t& getCreateTime() const noexcept { return createTime; }
|
||||
const wfr::wfr_timestamp_sc_t& getStartTime() const noexcept { return startTime; }
|
||||
const wfr::wfr_timestamp_sc_t& getEndTime() const noexcept { return endTime; }
|
||||
wfr::wfr_duration_sc_t getWorkflowDuration() const noexcept { return endTime - startTime; };
|
||||
wfr::wfr_duration_sc_t getMakespan() const noexcept { return endTime - createTime; };
|
||||
|
||||
#ifdef WFR_ENABLE_STATISTICS
|
||||
|
||||
wfr::wfr_duration_sc_t getEnactmentTime() const noexcept { return enactmentTime; }
|
||||
void addToEnactmentTime(wfr::wfr_duration_sc_t time) {
|
||||
std::lock_guard<std::mutex> lock(statMutex);
|
||||
enactmentTime += time;
|
||||
}
|
||||
|
||||
wfr_size_t getCreatedCompositeInstanceCount() { return createdCompositeInstanceCount; }
|
||||
void addToCreatedCompositeInstanceCount(wfr_size_t value = 1) { createdCompositeInstanceCount.fetch_add(value); }
|
||||
|
||||
wfr_size_t getFinishedCompositeInstanceCount() { return finishedCompositeInstanceCount; }
|
||||
void addToFinishedCompositeInstanceCount(wfr_size_t value = 1) { finishedCompositeInstanceCount.fetch_add(value); }
|
||||
|
||||
wfr_size_t getErrorCompositeInstanceCount() { return errorCompositeInstanceCount; }
|
||||
void addToErrorCompositeInstanceCount(wfr_size_t value = 1) { errorCompositeInstanceCount.fetch_add(value); }
|
||||
|
||||
|
||||
wfr_size_t getCreatedAtomicInstanceCount() { return createdAtomicInstanceCount; }
|
||||
void addToCreatedAtomicInstanceCount(wfr_size_t value = 1) { createdAtomicInstanceCount.fetch_add(value); }
|
||||
|
||||
wfr_size_t getFinishedAtomicInstanceCount() { return finishedAtomicInstanceCount; }
|
||||
void addToFinishedAtomicInstanceCount(wfr_size_t value = 1) { finishedAtomicInstanceCount.fetch_add(value); }
|
||||
|
||||
wfr_size_t getErrorAtomicInstanceCount() { return errorAtomicInstanceCount; }
|
||||
void addToErrorAtomicInstanceCount(wfr_size_t value = 1) { errorAtomicInstanceCount.fetch_add(value); }
|
||||
|
||||
wfr::wfr_duration_sc_t getCumulaticeAtomicRunningDuration() {
|
||||
std::lock_guard<std::mutex> lock(statMutex);
|
||||
return cumulativeAtomicRunningDuration;
|
||||
}
|
||||
void addToCumulaticeAtomicRunningDuration(wfr::wfr_duration_sc_t time) {
|
||||
std::lock_guard<std::mutex> lock(statMutex);
|
||||
cumulativeAtomicRunningDuration += time;
|
||||
}
|
||||
|
||||
wfr::wfr_duration_sc_t getCumulaticeAtomicReadyWaitingDuration() {
|
||||
std::lock_guard<std::mutex> lock(statMutex);
|
||||
return cumulativeAtomicReadyWaitingDuration;
|
||||
}
|
||||
void addToCumulaticeAtomicReadyWaitingDuration(wfr::wfr_duration_sc_t time) {
|
||||
std::lock_guard<std::mutex> lock(statMutex);
|
||||
cumulativeAtomicReadyWaitingDuration += time;
|
||||
}
|
||||
|
||||
wfr_size_t getWepNodeCount() { return wepNodeCount; }
|
||||
void setWepNodeCount(wfr_size_t count) { wepNodeCount = count; }
|
||||
|
||||
wfr_size_t getWepVisitationCount() { return wepVisitationCount; }
|
||||
void addToWepVisitationCount(wfr_size_t value = 1) { wepVisitationCount.fetch_add(value); }
|
||||
|
||||
wfr_size_t getWepUpdateCount() { return wepUpdateCount; }
|
||||
void addToWepUpdateCount(wfr_size_t value = 1) { wepUpdateCount.fetch_add(value); }
|
||||
|
||||
wfr_size_t getWepUpdateNotifyCount() { return wepUpdateNotifyCount; }
|
||||
void addToWepUpdateNotifyCount(wfr_size_t value = 1) { wepUpdateNotifyCount.fetch_add(value); }
|
||||
|
||||
void printStatistics(std::ostream& sout = std::cout);
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/LwdTypes.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
class ActivityTemplate;
|
||||
class Workflow;
|
||||
|
||||
/**
|
||||
* Represents a workflow.
|
||||
*
|
||||
* Holds all invariant information that can be shared between different workflow instances (e.g. workflow name, structure).
|
||||
**/
|
||||
class WorkflowTemplate {
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
std::vector<ActivityTemplate*> activities;
|
||||
ActivityTemplate* toplevelActivity = nullptr;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const std::string workflowName;
|
||||
const wfr_id_t topLevelActivityID;
|
||||
|
||||
// Non-public functions.
|
||||
private:
|
||||
void checkStructure();
|
||||
|
||||
// Public functions.
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param activities workflow activity templates.
|
||||
* @param topLevelActivityID ID of top-level workflow activity template.
|
||||
* @param name name of the workflow.
|
||||
**/
|
||||
WorkflowTemplate( const std::string& name,
|
||||
wfr_id_t topLevelActivityID,
|
||||
std::initializer_list<ActivityTemplate*> activities );
|
||||
|
||||
~WorkflowTemplate() noexcept;
|
||||
|
||||
/**
|
||||
* Returns the number of workflow activities.
|
||||
*
|
||||
* @return number of workflow activities
|
||||
**/
|
||||
wfr_size_t getActivityCount() const noexcept { return activities.size(); }
|
||||
|
||||
/**
|
||||
* Returns a pointer to the array of workflow activities.
|
||||
*
|
||||
* @return pointer to the array of workflow activities
|
||||
**/
|
||||
const std::vector<ActivityTemplate*>& getActivities() const noexcept { return activities; }
|
||||
|
||||
/**
|
||||
* Returns the activity template with the specified ID.
|
||||
*
|
||||
* @param id ID of workflow activity template.
|
||||
* @return workflow activity template.
|
||||
**/
|
||||
ActivityTemplate* getActivityByID(wfr_id_t id) const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the ID of the top-level workflow activity template.
|
||||
*
|
||||
* @return ID of the top-level workflow activity template.
|
||||
**/
|
||||
wfr_id_t getTopLevelActivityID() const noexcept { return topLevelActivityID; }
|
||||
|
||||
/**
|
||||
* Returns the top-level workflow activity template.
|
||||
*
|
||||
* @return top-level workflow activity template.
|
||||
**/
|
||||
ActivityTemplate* getTopLevelActivity() const noexcept { return toplevelActivity; }
|
||||
|
||||
|
||||
/**
|
||||
* Executes the workflow.
|
||||
*
|
||||
* Blocks till execution has finished.
|
||||
*
|
||||
* @param input workflow input data.
|
||||
* @param input workflow output data.
|
||||
* @return status.
|
||||
**/
|
||||
std::shared_ptr<Workflow> execute(lwd::_wfr_lwd* input, lwd::_wfr_lwd* output);
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/AtomicActivityImplementation.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
class CUDAActivityImplementation : public AtomicActivityImplementation {
|
||||
public:
|
||||
const ExecutionHookFunc executionFuncHook;
|
||||
public:
|
||||
CUDAActivityImplementation( const ExecutionHookFunc& executionFuncHook,
|
||||
const std::vector<resource::RequiredResourceCapability>& capabilities,
|
||||
const utils::Properties& properties,
|
||||
const std::string& name = "") noexcept
|
||||
: AtomicActivityImplementation(ActivityImplementationType::CUDA, capabilities, properties, name),
|
||||
executionFuncHook(executionFuncHook) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/AtomicActivityImplementation.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
class OpenCLActivityImplementation : public AtomicActivityImplementation {
|
||||
public:
|
||||
const ExecutionHookFunc executionFuncHook;
|
||||
public:
|
||||
OpenCLActivityImplementation( const ExecutionHookFunc& executionFuncHook,
|
||||
const std::vector<resource::RequiredResourceCapability>& capabilities,
|
||||
const utils::Properties& properties,
|
||||
const std::string& name = "") noexcept
|
||||
: AtomicActivityImplementation(ActivityImplementationType::OpenCL, capabilities, properties, name),
|
||||
executionFuncHook(executionFuncHook) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/AtomicActivityImplementation.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
class PThreadActivityImplementation : public AtomicActivityImplementation {
|
||||
public:
|
||||
const ExecutionHookFunc executionFuncHook;
|
||||
public:
|
||||
PThreadActivityImplementation( const ExecutionHookFunc& executionFuncHook,
|
||||
const std::vector<resource::RequiredResourceCapability>& capabilities,
|
||||
const utils::Properties& properties,
|
||||
const std::string& name ) noexcept
|
||||
: AtomicActivityImplementation(ActivityImplementationType::PThread, capabilities, properties, name),
|
||||
executionFuncHook(executionFuncHook) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/ActivityInstance.h>
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Activity;
|
||||
class AtomicActivityImplementation;
|
||||
|
||||
|
||||
class AssignActivityInstance: public wfr::wfs::ActivityInstance {
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
AssignActivityInstance(Activity& baseActivity, wfr_id_t iterationID = 0) noexcept
|
||||
: ActivityInstance(baseActivity, iterationID) {}
|
||||
|
||||
virtual bool executePreExecutionHooks(bool earlyEvaluation) override;
|
||||
|
||||
virtual bool executeExecutionHook(bool earlyEvaluation) override;
|
||||
|
||||
virtual void notifyParent() noexcept;
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/ActivityInstance.h>
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Activity;
|
||||
class AtomicActivityImplementation;
|
||||
|
||||
|
||||
class AtomicActivityInstance: public wfr::wfs::ActivityInstance {
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
bool _ownedByExecutionLayer = false;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
AtomicActivityInstance(Activity& baseActivity, wfr_id_t iterationID = 0) noexcept
|
||||
: ActivityInstance(baseActivity, iterationID) {}
|
||||
|
||||
virtual bool executePreExecutionHooks(bool earlyEvaluation) override;
|
||||
|
||||
bool ownedByExecutionLayer() const noexcept { return _ownedByExecutionLayer; }
|
||||
|
||||
void setOwnedByExecutionLayer(bool owned) noexcept { _ownedByExecutionLayer = owned; }
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/ActivityInstance.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declaration
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Activity;
|
||||
|
||||
|
||||
class CompositeActivityInstance: public wfr::wfs::ActivityInstance {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
std::vector<ActivityInstance*> children;
|
||||
std::map<wfr_size_t, ActivityInstance*> childrenByInstanceID;
|
||||
std::map<wfr_size_t, std::vector<ActivityInstance*>> childrenByActivityID;
|
||||
wfr_size_t finishedChildrenCount = 0;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
CompositeActivityInstance(Activity& baseActivity, wfr_id_t iterationID = 0) noexcept
|
||||
: ActivityInstance(baseActivity, iterationID) {}
|
||||
|
||||
wfr_size_t getChildrenCount() const noexcept { return children.size(); }
|
||||
const std::vector<ActivityInstance*>& getChildren() const noexcept { return children; }
|
||||
ActivityInstance* getChild(wfr_id_t instanceID) const noexcept;
|
||||
ActivityInstance* getChild(wfr_id_t activityID, wfr_id_t iterationID) const noexcept;
|
||||
|
||||
|
||||
wfr_size_t getFinishedChildrenCount() const noexcept { return finishedChildrenCount; }
|
||||
|
||||
virtual void notifyChildHasFinished(ActivityInstance& ai) noexcept;
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/instances/CompositeActivityInstance.h>
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Activity;
|
||||
|
||||
|
||||
class ConditionalActivityInstance: public CompositeActivityInstance {
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
wfr_size_t activeExecutionBranchID = 0;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
ConditionalActivityInstance(Activity& baseActivity, wfr_id_t iterationID = 0) noexcept
|
||||
: CompositeActivityInstance(baseActivity, iterationID) {}
|
||||
|
||||
wfr_id_t getExecutionBranchID() const noexcept { return activeExecutionBranchID; }
|
||||
|
||||
void setExecutionBranchID(wfr_size_t branchId) noexcept { this->activeExecutionBranchID = branchId; }
|
||||
|
||||
virtual bool executePreExecutionHooks(bool earlyEvaluation) override;
|
||||
|
||||
virtual bool executePostExecutionHooks(bool earlyEvaluation) override;
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/instances/CompositeActivityInstance.h>
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Activity;
|
||||
|
||||
|
||||
class ContainerActivityInstance: public CompositeActivityInstance {
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
ContainerActivityInstance(Activity& baseActivity, wfr_id_t iterationID = 0) noexcept
|
||||
: CompositeActivityInstance(baseActivity, iterationID) {}
|
||||
|
||||
virtual bool executePreExecutionHooks(bool earlyEvaluation) override;
|
||||
|
||||
virtual bool executePostExecutionHooks(bool earlyEvalation) override;
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,50 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/instances/LoopActivityInstance.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Activity;
|
||||
|
||||
|
||||
class ForLoopActivityInstance: public LoopActivityInstance {
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
wfr_size_t loopCounterStart = 0;
|
||||
wfr_size_t loopCounterStep = 1;
|
||||
wfr_size_t loopCounterMax = 0;
|
||||
bool loopCounterValueSet = false;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
ForLoopActivityInstance(Activity& baseActivity, bool isParallel, wfr_id_t iterationID = 0) noexcept
|
||||
: LoopActivityInstance(baseActivity, isParallel, iterationID) {}
|
||||
|
||||
|
||||
void setLoopCounter(wfr_size_t start, wfr_size_t step, wfr_size_t max);
|
||||
|
||||
wfr_size_t getLoopCounterStart() const noexcept { return loopCounterStart; }
|
||||
|
||||
wfr_size_t getLoopCounterStep() const noexcept { return loopCounterStep; }
|
||||
|
||||
wfr_size_t getLoopCounterMax() const noexcept { return loopCounterMax; }
|
||||
|
||||
bool isLoopCounterValueAvailable() const noexcept { return loopCounterValueSet; }
|
||||
|
||||
wfr_size_t getLoopCounterValue(wfr_id_t iterationID) const noexcept { return loopCounterStart + (iterationID * loopCounterStep); }
|
||||
|
||||
|
||||
virtual void notifyChildHasFinished(ActivityInstance& ai) noexcept;
|
||||
|
||||
virtual bool executePreExecutionHooks(bool earlyEvaluation) override;
|
||||
|
||||
virtual bool executePostExecutionHooks(bool earlyEvaluation) override;
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/instances/CompositeActivityInstance.h>
|
||||
#include <vector>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace enactment {
|
||||
class WepBuilder;
|
||||
}
|
||||
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Activity;
|
||||
|
||||
|
||||
class LoopActivityInstance: public CompositeActivityInstance {
|
||||
friend class enactment::WepBuilder;
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
protected:
|
||||
wfr_size_t iterationCount = 0;
|
||||
wfr_size_t handledIterationCount = 0;
|
||||
bool finalisedFlag = false;
|
||||
std::vector<wfr_size_t> finishedChildrenPerIteration;
|
||||
std::vector<bool> finishedIterations;
|
||||
std::vector<bool> runningIterations;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const bool isParallel;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
LoopActivityInstance(Activity& baseActivity, bool isParallel, wfr_id_t iterationID = 0) noexcept
|
||||
: CompositeActivityInstance(baseActivity, iterationID), isParallel(isParallel) {}
|
||||
|
||||
wfr_size_t getIterationCount() const noexcept { return iterationCount; }
|
||||
|
||||
void setIterationCount(wfr_size_t count) noexcept;
|
||||
|
||||
void setHandledIterationCount(wfr_size_t handledIterationCount) noexcept { this->handledIterationCount = handledIterationCount; }
|
||||
|
||||
wfr_size_t getHandledIterationCount() const noexcept { return handledIterationCount; }
|
||||
|
||||
bool isFinalised() const noexcept { return finalisedFlag; }
|
||||
|
||||
void setFinalised(bool v) noexcept { finalisedFlag = v; }
|
||||
|
||||
bool hasIterationFinished(wfr_id_t iterationID) const noexcept {
|
||||
if (iterationID < finishedIterations.size())
|
||||
return finishedIterations[iterationID];
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isIterationRunning(wfr_id_t iterationID)const noexcept {
|
||||
if (iterationID < runningIterations.size())
|
||||
return runningIterations[iterationID];
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
ActivityInstanceStatus getIterationInstanceStatus(wfr_id_t iterationID) const noexcept;
|
||||
|
||||
|
||||
virtual void notifyChildHasFinished(ActivityInstance& ai) noexcept override;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/instances/LoopActivityInstance.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
// Forward declarations
|
||||
class Activity;
|
||||
|
||||
|
||||
class WhileLoopActivityInstance : public LoopActivityInstance {
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
WhileLoopActivityInstance(Activity& baseActivity, wfr_id_t iterationID = 0) noexcept
|
||||
: LoopActivityInstance(baseActivity, false, iterationID) {}
|
||||
|
||||
virtual bool executePreExecutionHooks(bool earlyEvaluation) override;
|
||||
|
||||
virtual bool executePostExecutionHooks(bool earlyEvaluation) override;
|
||||
|
||||
virtual void notifyChildHasFinished(ActivityInstance& ai) noexcept;
|
||||
};
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/ActivityTemplate.h>
|
||||
#include <wfr/common/wfs/AtomicActivityType.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
class AssignActivityTemplate : public ActivityTemplate {
|
||||
friend class ActivityTemplate;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const InputHookFunc inputFuncHook;
|
||||
const ExecutionHookFunc execFuncHook;
|
||||
|
||||
// Non-public functions.
|
||||
private:
|
||||
AssignActivityTemplate( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
const std::initializer_list<wfr_id_t>& succList,
|
||||
const std::initializer_list<wfr_id_t>& predList,
|
||||
InputHookFunc inputFuncHook,
|
||||
ExecutionHookFunc execFuncHook ) noexcept
|
||||
: ActivityTemplate(id, ActivityType::Assign, name, parentID, branchID, succList, predList, false, false, false),
|
||||
inputFuncHook(inputFuncHook), execFuncHook(execFuncHook) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/ActivityTemplate.h>
|
||||
#include <wfr/common/wfs/AtomicActivityType.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
class AtomicActivityTemplate : public ActivityTemplate {
|
||||
friend class ActivityTemplate;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const InputHookFunc inputFuncHook;
|
||||
const std::shared_ptr<AtomicActivityType> atomicActivityType;
|
||||
|
||||
// Non-public functions.
|
||||
private:
|
||||
AtomicActivityTemplate( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
const std::initializer_list<wfr_id_t>& succList,
|
||||
const std::initializer_list<wfr_id_t>& predList,
|
||||
InputHookFunc inputFuncHook,
|
||||
std::shared_ptr<AtomicActivityType> atomicActivityType ) noexcept
|
||||
: ActivityTemplate(id, ActivityType::Atomic, name, parentID, branchID, succList, predList, false, false, false),
|
||||
inputFuncHook(inputFuncHook), atomicActivityType(atomicActivityType) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/ActivityTemplate.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
class ConditionalActivityTemplate : public ActivityTemplate {
|
||||
friend class ActivityTemplate;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const InputHookFunc inputFuncHook;
|
||||
const OutputHookFunc outputFuncHook;
|
||||
const BranchConditionHookFunc branchFuncHook;
|
||||
|
||||
// Non-public functions.
|
||||
private:
|
||||
ConditionalActivityTemplate( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
const std::initializer_list<wfr_id_t>& succList,
|
||||
const std::initializer_list<wfr_id_t>& predList,
|
||||
InputHookFunc inputFuncHook,
|
||||
OutputHookFunc outputFuncHook,
|
||||
BranchConditionHookFunc branchFuncHook ) noexcept
|
||||
: ActivityTemplate(id, ActivityType::Conditional, name, parentID, branchID, succList, predList, true, false, true),
|
||||
inputFuncHook(inputFuncHook), outputFuncHook(outputFuncHook), branchFuncHook(branchFuncHook) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/ActivityTemplate.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
class ContainerActivityTemplate : public ActivityTemplate {
|
||||
friend class ActivityTemplate;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const InputHookFunc inputFuncHook;
|
||||
const OutputHookFunc outputFuncHook;
|
||||
|
||||
// Non-public functions.
|
||||
private:
|
||||
ContainerActivityTemplate( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
const std::initializer_list<wfr_id_t>& succList,
|
||||
const std::initializer_list<wfr_id_t>& predList,
|
||||
InputHookFunc inputFuncHook,
|
||||
OutputHookFunc outputFuncHook ) noexcept
|
||||
: ActivityTemplate(id, ActivityType::Container, name, parentID, branchID, succList, predList, true, false, false),
|
||||
inputFuncHook(inputFuncHook), outputFuncHook(outputFuncHook) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/ActivityTemplate.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
class ForLoopActivityTemplate : public ActivityTemplate {
|
||||
friend class ActivityTemplate;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const InputHookFunc inputFuncHook;
|
||||
const OutputHookFunc outputFuncHook;
|
||||
const ForCounterHookFunc counterFuncHook;
|
||||
const LoopIterationHookFunc iterationFuncHook;
|
||||
const bool isParallel;
|
||||
|
||||
// Non-public functions.
|
||||
private:
|
||||
ForLoopActivityTemplate( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
const std::initializer_list<wfr_id_t>& succList,
|
||||
const std::initializer_list<wfr_id_t>& predList,
|
||||
InputHookFunc inputFuncHook,
|
||||
OutputHookFunc outputFuncHook,
|
||||
ForCounterHookFunc counterFuncHook,
|
||||
LoopIterationHookFunc iterationFuncHook,
|
||||
bool isParallel ) noexcept
|
||||
: ActivityTemplate(id, ActivityType::ForLoop, name, parentID, branchID, succList, predList, true, true, false),
|
||||
inputFuncHook(inputFuncHook), outputFuncHook(outputFuncHook), counterFuncHook(counterFuncHook),
|
||||
iterationFuncHook(iterationFuncHook), isParallel(isParallel) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/wfs/ActivityTemplate.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
|
||||
|
||||
class WhileLoopActivityTemplate : public ActivityTemplate {
|
||||
friend class ActivityTemplate;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
const InputHookFunc inputFuncHook;
|
||||
const OutputHookFunc outputFuncHook;
|
||||
const WhileConditionHookFunc conditionFuncHook;
|
||||
const LoopIterationHookFunc iterationFuncHook;
|
||||
|
||||
// Non-public functions.
|
||||
private:
|
||||
WhileLoopActivityTemplate( wfr_id_t id,
|
||||
const std::string& name,
|
||||
wfr_id_t parentID,
|
||||
wfr_id_t branchID,
|
||||
const std::initializer_list<wfr_id_t>& succList,
|
||||
const std::initializer_list<wfr_id_t>& predList,
|
||||
InputHookFunc inputFuncHook,
|
||||
OutputHookFunc outputFuncHook,
|
||||
WhileConditionHookFunc conditionFuncHook,
|
||||
LoopIterationHookFunc iterationFuncHook ) noexcept
|
||||
: ActivityTemplate(id, ActivityType::WhileLoop, name, parentID, branchID, succList, predList, true, true, false),
|
||||
inputFuncHook(inputFuncHook), outputFuncHook(outputFuncHook), conditionFuncHook(conditionFuncHook),
|
||||
iterationFuncHook(iterationFuncHook) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace wfs */
|
||||
} /* namespace wfr */
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#define WFR_ENABLE_STATISTICS
|
||||
|
||||
#define WFR_ENABLE_WEPDOTWRITER
|
||||
|
||||
#define WFR_ENABLE_PERFDATABASE
|
||||
|
||||
#define WFR_ENABLE_STDLOGGER
|
||||
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/LwdTypes.h>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <memory>
|
||||
#include <condition_variable>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
//Forward declarations
|
||||
namespace wfs {
|
||||
class Workflow;
|
||||
class ActivityInstance;
|
||||
}
|
||||
namespace wep {
|
||||
class WorkflowExecutionPlan;
|
||||
}
|
||||
namespace scheduling {
|
||||
class AbstractScheduler;
|
||||
}
|
||||
|
||||
// Main namespace
|
||||
namespace enactment {
|
||||
|
||||
|
||||
class EnactmentEngine {
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
std::shared_ptr<wep::WorkflowExecutionPlan> wep;
|
||||
|
||||
bool breakExecutionLoop = false;
|
||||
|
||||
std::queue<wfs::ActivityInstance*> updateQueue;
|
||||
std::mutex updateMutex;
|
||||
std::condition_variable updateCondition;
|
||||
|
||||
bool enableWepDotFileWriter;
|
||||
bool enableEarlyEvaluation;
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
wfs::Workflow& workflow;
|
||||
scheduling::AbstractScheduler& scheduler;
|
||||
|
||||
// Public static functions
|
||||
public:
|
||||
static void init(int argc, char** argv);
|
||||
static void finish();
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
EnactmentEngine(wfs::Workflow& workflow, scheduling::AbstractScheduler& scheduler) noexcept;
|
||||
|
||||
void workflowExecutionLoop(lwd::_wfr_lwd* input, lwd::_wfr_lwd* output);
|
||||
|
||||
void notifyActivityInstanceStateUpdate(wfs::ActivityInstance& ai, scheduling::AbstractScheduler& scheduler);
|
||||
};
|
||||
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/LwdTypes.h>
|
||||
#include <stack>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
|
||||
// Forward declarations
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
class Workflow;
|
||||
class ActivityInstance;
|
||||
class CompositeActivityInstance;
|
||||
class Activity;
|
||||
}
|
||||
namespace wep {
|
||||
class WorkflowExecutionPlan;
|
||||
class AbstractWepNode;
|
||||
class AtomicWepNode;
|
||||
class AssignWepNode;
|
||||
class CompositeStartWepNode;
|
||||
class CompositeEndWepNode;
|
||||
class IterationStartWepNode;
|
||||
class IterationEndWepNode;
|
||||
}
|
||||
|
||||
|
||||
// Main namespace
|
||||
namespace enactment {
|
||||
|
||||
|
||||
class WepBuilder {
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
std::shared_ptr<wep::WorkflowExecutionPlan> wep;
|
||||
|
||||
typedef std::map<wfs::Activity*, wfr::wfs::ActivityInstance*> activityInstanceMap_t;
|
||||
typedef std::map<wfs::ActivityInstance*, std::pair<wep::AbstractWepNode*, wep::AbstractWepNode*>> wepNodeMap_t;
|
||||
|
||||
std::stack<wfs::ActivityInstance*> parentStack;
|
||||
std::stack<std::pair<wep::AbstractWepNode*, wep::AbstractWepNode*>> parentWepStack;
|
||||
std::stack<wfr_id_t> iterationIdStack;
|
||||
wepNodeMap_t wepNodeMap;
|
||||
|
||||
std::vector<wep::AtomicWepNode*> readyToExecuteAtomicNodes;
|
||||
std::vector<wep::AssignWepNode*> readyToExecuteAssignNodes;
|
||||
|
||||
wfr_size_t wepNodeCount = 0;
|
||||
wfr_size_t wepVisitationCount = 0;
|
||||
|
||||
bool earlyEvaluationMode;
|
||||
|
||||
// Non-public functions
|
||||
private:
|
||||
wepNodeMap_t::mapped_type createWEPnode(wfs::Activity& a, wfs::ActivityInstance& ai, wepNodeMap_t& wepNodeMap);
|
||||
|
||||
void visitActivity(wfs::Activity& element, activityInstanceMap_t& instanceMap, wepNodeMap_t& wepNodeMap);
|
||||
|
||||
wepNodeMap_t::mapped_type createIterationWepNodes(wfr::wfs::ActivityInstance& ai, wepNodeMap_t::mapped_type& parent, wfr_id_t iterationID);
|
||||
|
||||
void handleChildren(wfs::CompositeActivityInstance& composite, wepNodeMap_t::mapped_type& parent, wepNodeMap_t::mapped_type* prevIter = nullptr);
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
WepBuilder(bool earlyEvaluation) : earlyEvaluationMode(earlyEvaluation) {}
|
||||
virtual ~WepBuilder();
|
||||
|
||||
std::shared_ptr<wep::WorkflowExecutionPlan> createWEP(wfs::Workflow& wf, lwd::_wfr_lwd* input, lwd::_wfr_lwd* output);
|
||||
|
||||
bool updateExecutionPlan(std::queue<wfs::ActivityInstance*>& updateInstances);
|
||||
|
||||
const std::vector<wep::AtomicWepNode*>& getReadyToExecuteAtomicNodes() { return readyToExecuteAtomicNodes; }
|
||||
|
||||
const std::vector<wep::AssignWepNode*>& getReadyToExecuteAssignNodes() { return readyToExecuteAssignNodes; }
|
||||
};
|
||||
|
||||
} /* namespace enactment */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/eventsystem/EventListener.h>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace eventsystem {
|
||||
|
||||
// forward declarations
|
||||
class Event;
|
||||
class WorkflowStatusEvent;
|
||||
class ActivityStatusEvent;
|
||||
class ActivityInstanceStatusEvent;
|
||||
|
||||
/**
|
||||
* Logs events to a std::ostream (e.g. std::cout).
|
||||
**/
|
||||
class OStreamLogger: public wfr::eventsystem::EventListener {
|
||||
private:
|
||||
std::ostream& oStream;
|
||||
|
||||
public:
|
||||
OStreamLogger(std::ostream& oStream) : oStream(oStream) {};
|
||||
|
||||
virtual void notifyEvent(const std::shared_ptr<Event>& event) noexcept override;
|
||||
};
|
||||
|
||||
} /* namespace eventsystem */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+105
@@ -0,0 +1,105 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/eventsystem/EventListener.h>
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include <odb/database.hxx>
|
||||
#include <odb/transaction.hxx>
|
||||
#include <odb/session.hxx>
|
||||
|
||||
#include <odb/sqlite/database.hxx>
|
||||
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wfs {
|
||||
class Workflow;
|
||||
class Activity;
|
||||
class ActivityInstance;
|
||||
}
|
||||
}
|
||||
|
||||
namespace wfr {
|
||||
namespace eventsystem {
|
||||
|
||||
namespace odbmodel {
|
||||
|
||||
class Workflow;
|
||||
class Activity;
|
||||
class ActivityInstance;
|
||||
|
||||
}
|
||||
|
||||
class Event;
|
||||
class WorkflowStatusEvent;
|
||||
class ActivityStatusEvent;
|
||||
class ActivityInstanceStatusEvent;
|
||||
class ComputingResourceStatusEvent;
|
||||
class ComponentStatusEvent;
|
||||
|
||||
class SQLiteLogger : public EventListener {
|
||||
protected:
|
||||
static void dbwriterfunc(SQLiteLogger* logger);
|
||||
|
||||
std::unique_ptr<std::thread> loggerThread;
|
||||
bool threadRunning = false;
|
||||
bool threadBreakFlag = false;
|
||||
std::mutex threadMutex;
|
||||
std::condition_variable threadCondition;
|
||||
std::queue<std::shared_ptr<Event>> eventQueue;
|
||||
|
||||
std::string filename;
|
||||
std::unique_ptr<odb::sqlite::database> dbHandle;
|
||||
bool readyFlag = false;
|
||||
|
||||
int statProcessedEvents;
|
||||
int statWrittenEvents;
|
||||
|
||||
/*typedef std::map<wfr_id_t, std::shared_ptr<odbmodel::Workflow>> workflowMap_t;
|
||||
typedef std::map<wfr_id_t, std::shared_ptr<odbmodel::Activity>> activityMap_t;
|
||||
typedef std::map<wfr_id_t, std::shared_ptr<odbmodel::ActivityInstance>> activityInstanceMap_t;
|
||||
|
||||
workflowMap_t workflowMap;
|
||||
activityMap_t activityMap;
|
||||
activityInstanceMap_t activityInstanceMap;*/
|
||||
|
||||
/*void handleWorkflowStatusEvent(WorkflowStatusEvent &event);
|
||||
void handleActicityStatusEvent(ActivityStatusEvent &event);
|
||||
void handleActicityInstanceStatusEvent(ActivityInstanceStatusEvent &event);
|
||||
void handleComputingResourceStatusEvent(ComputingResourceStatusEvent &event);
|
||||
void handleComponentStatusEvent(ComponentStatusEvent &event);
|
||||
|
||||
std::shared_ptr<odbmodel::Workflow> getWorkflowFromWfsMap(wfs::Workflow& wf);
|
||||
void persistWorkflow(std::shared_ptr<odbmodel::Workflow>& wfp, wfs::Workflow& wf);
|
||||
std::shared_ptr<odbmodel::Activity> getActivityFromWfsMap(wfs::Activity& act);
|
||||
void persistActivity(std::shared_ptr<odbmodel::Activity>& ap, wfs::Activity& a);
|
||||
std::shared_ptr<odbmodel::ActivityInstance> getActivityInstanceFromWfsMap(wfs::ActivityInstance& act);
|
||||
void persistActivityInstance(std::shared_ptr<odbmodel::ActivityInstance>& ap, wfs::ActivityInstance& a);
|
||||
|
||||
void writeWorkflowStatus(std::shared_ptr<odbmodel::Workflow>& pWf, WorkflowStatusEvent &event);
|
||||
void writeActivityStatus(std::shared_ptr<odbmodel::Activity>& pA, ActivityStatusEvent &event);
|
||||
void writeActivityInstanceStatus(std::shared_ptr<odbmodel::ActivityInstance>& pA, ActivityInstanceStatusEvent &event);
|
||||
void writeComputingResourceStatus(std::shared_ptr<odbmodel::Workflow>& pwf, std::shared_ptr<odbmodel::ActivityInstance>& pai, ComputingResourceStatusEvent &event);
|
||||
void writeComponentStatus(std::shared_ptr<odbmodel::Workflow>& pwf, ComponentStatusEvent &event);*/
|
||||
|
||||
public:
|
||||
SQLiteLogger(std::string filename);
|
||||
virtual ~SQLiteLogger();
|
||||
|
||||
bool isReady() { return readyFlag; }
|
||||
|
||||
virtual void notifyEvent(const std::shared_ptr<Event>& event) noexcept;
|
||||
};
|
||||
|
||||
} /* namespace eventsystem */
|
||||
} /* namespace wfr */
|
||||
|
||||
+650
@@ -0,0 +1,650 @@
|
||||
/*
|
||||
* SimpleDBModel.h
|
||||
*
|
||||
* Created on: 09.05.2014
|
||||
* Author: matthias
|
||||
*/
|
||||
|
||||
#ifndef SIMPLEDBMODEL_H_
|
||||
#define SIMPLEDBMODEL_H_
|
||||
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
#include <odb/core.hxx>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace wfr {
|
||||
namespace eventsystem {
|
||||
#pragma db namespace session
|
||||
namespace odbmodel {
|
||||
|
||||
class Workflow;
|
||||
class Activity;
|
||||
class ActivityInstance;
|
||||
class WorkflowStatusEvent;
|
||||
class ActivityStatusEvent;
|
||||
class ActivityInstanceStatusEvent;
|
||||
|
||||
|
||||
#pragma db value(wfr_id_t) type("BigInt")
|
||||
#pragma db value(wfr_size_t) type("BigInt")
|
||||
|
||||
|
||||
#pragma db object pointer(std::shared_ptr)
|
||||
class Workflow {
|
||||
|
||||
friend class odb::access;
|
||||
|
||||
private:
|
||||
#pragma db id auto
|
||||
uint32_t oid;
|
||||
|
||||
wfr_id_t wfid;
|
||||
|
||||
std::string uuid;
|
||||
|
||||
std::string name;
|
||||
|
||||
#pragma db inverse(parentWorkflow)
|
||||
std::vector<std::weak_ptr<Activity>> activities;
|
||||
|
||||
std::weak_ptr<Activity> toplevelActivity;
|
||||
|
||||
#pragma db inverse(parentWorkflow)
|
||||
std::vector<std::weak_ptr<WorkflowStatusEvent>> statusEvents;
|
||||
|
||||
|
||||
public:
|
||||
Workflow() : oid(0), wfid(0) {}
|
||||
|
||||
Workflow(wfr_id_t wfid, std::string uuid) : oid(0), wfid(wfid), uuid(uuid) {}
|
||||
|
||||
std::vector<std::weak_ptr<Activity> >& getActivities() {
|
||||
return activities;
|
||||
}
|
||||
|
||||
const std::string& getName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
void setName(const std::string& name) {
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
const std::weak_ptr<Activity>& getToplevelActivity() const {
|
||||
return toplevelActivity;
|
||||
}
|
||||
|
||||
void setToplevelActivity(const std::weak_ptr<Activity>& toplevelActivity) {
|
||||
this->toplevelActivity = toplevelActivity;
|
||||
}
|
||||
|
||||
wfr_id_t getOid() const {
|
||||
return oid;
|
||||
}
|
||||
|
||||
const std::string& getUuid() const {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
wfr_id_t getWfid() const {
|
||||
return wfid;
|
||||
}
|
||||
|
||||
void setWfid(wfr_id_t wfid) {
|
||||
this->wfid = wfid;
|
||||
}
|
||||
};
|
||||
|
||||
#pragma db object pointer(std::shared_ptr)
|
||||
class WorkflowStatusEvent {
|
||||
|
||||
friend class odb::access;
|
||||
|
||||
private:
|
||||
#pragma db id auto
|
||||
uint32_t oid;
|
||||
|
||||
#pragma db not_null
|
||||
std::shared_ptr<Workflow> parentWorkflow;
|
||||
|
||||
std::string newStatus;
|
||||
|
||||
std::string oldStatus;
|
||||
|
||||
uint64_t timestamp;
|
||||
|
||||
public:
|
||||
WorkflowStatusEvent() : oid(0), timestamp(0) {}
|
||||
|
||||
const std::string& getNewStatus() {
|
||||
return newStatus;
|
||||
}
|
||||
|
||||
void setNewStatus(const std::string& newStatus) {
|
||||
this->newStatus = newStatus;
|
||||
}
|
||||
|
||||
wfr_id_t getOid() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
const std::string& getOldStatus() {
|
||||
return oldStatus;
|
||||
}
|
||||
|
||||
void setOldStatus(const std::string& oldStatus) {
|
||||
this->oldStatus = oldStatus;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Workflow>& getParentWorkflow() {
|
||||
return parentWorkflow;
|
||||
}
|
||||
|
||||
void setParentWorkflow(const std::shared_ptr<Workflow>& parentWorkflow) {
|
||||
this->parentWorkflow = parentWorkflow;
|
||||
}
|
||||
|
||||
uint64_t getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
void setTimestamp(uint64_t timestamp) {
|
||||
this->timestamp = timestamp;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#pragma db object pointer(std::shared_ptr)
|
||||
class Activity {
|
||||
|
||||
friend class odb::access;
|
||||
|
||||
private:
|
||||
#pragma db id auto
|
||||
uint32_t oid;
|
||||
|
||||
wfr_id_t actid;
|
||||
|
||||
std::string name;
|
||||
|
||||
#pragma db not_null
|
||||
std::shared_ptr<Workflow> parentWorkflow;
|
||||
|
||||
std::shared_ptr<Activity> parent;
|
||||
|
||||
#pragma db inverse(parentActivity)
|
||||
std::vector<std::weak_ptr<ActivityStatusEvent>> statusEvents;
|
||||
|
||||
std::string type;
|
||||
|
||||
wfr_id_t branchID;
|
||||
|
||||
#pragma db inverse(baseActivity)
|
||||
std::vector<std::weak_ptr<ActivityInstance>> instances;
|
||||
|
||||
std::vector<std::weak_ptr<Activity>> successors;
|
||||
|
||||
std::vector<std::weak_ptr<Activity>> predecessors;
|
||||
|
||||
public:
|
||||
Activity() : oid(0), actid(0), branchID(0) {}
|
||||
|
||||
Activity(wfr_id_t actid, wfr_id_t branchid) : oid(0), actid(actid), branchID(branchid) {}
|
||||
|
||||
wfr_id_t getBranchId() const {
|
||||
return branchID;
|
||||
}
|
||||
|
||||
std::vector<std::weak_ptr<ActivityInstance> >& getInstances() {
|
||||
return instances;
|
||||
}
|
||||
|
||||
const std::string& getName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
void setName(const std::string& name) {
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Workflow>& getParentWorkflow() const {
|
||||
return parentWorkflow;
|
||||
}
|
||||
|
||||
void setParentWorkflow(const std::shared_ptr<Workflow>& parentWorkflow) {
|
||||
this->parentWorkflow = parentWorkflow;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Activity>& getParent() const {
|
||||
return parent;
|
||||
}
|
||||
|
||||
void setParent(const std::shared_ptr<Activity>& parent) {
|
||||
this->parent = parent;
|
||||
}
|
||||
|
||||
std::vector<std::weak_ptr<Activity> >& getPredecessors() {
|
||||
return predecessors;
|
||||
}
|
||||
|
||||
std::vector<std::weak_ptr<Activity> >& getSuccessors() {
|
||||
return successors;
|
||||
}
|
||||
|
||||
const std::string& getType() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
void setType(const std::string& type) {
|
||||
this->type = type;
|
||||
}
|
||||
|
||||
wfr_id_t getOid() const {
|
||||
return oid;
|
||||
}
|
||||
|
||||
wfr_id_t getActid() const {
|
||||
return actid;
|
||||
}
|
||||
|
||||
void setActid(wfr_id_t actid) {
|
||||
this->actid = actid;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#pragma db object pointer(std::shared_ptr)
|
||||
class ActivityStatusEvent {
|
||||
|
||||
friend class odb::access;
|
||||
|
||||
private:
|
||||
#pragma db id auto
|
||||
uint32_t oid;
|
||||
|
||||
#pragma db not_null
|
||||
std::shared_ptr<Activity> parentActivity;
|
||||
|
||||
std::string newStatus;
|
||||
|
||||
std::string oldStatus;
|
||||
|
||||
uint64_t timestamp;
|
||||
|
||||
public:
|
||||
ActivityStatusEvent() : oid(0), timestamp(0) {}
|
||||
|
||||
const std::string& getNewStatus() {
|
||||
return newStatus;
|
||||
}
|
||||
|
||||
void setNewStatus(const std::string& newStatus) {
|
||||
this->newStatus = newStatus;
|
||||
}
|
||||
|
||||
wfr_id_t getOid() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
const std::string& getOldStatus() {
|
||||
return oldStatus;
|
||||
}
|
||||
|
||||
void setOldStatus(const std::string& oldStatus) {
|
||||
this->oldStatus = oldStatus;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Activity>& getParentActivity() {
|
||||
return parentActivity;
|
||||
}
|
||||
|
||||
void setParentActivity(const std::shared_ptr<Activity>& parentActivity) {
|
||||
this->parentActivity = parentActivity;
|
||||
}
|
||||
|
||||
uint64_t getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
void setTimestamp(uint64_t timestamp) {
|
||||
this->timestamp = timestamp;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#pragma db object pointer(std::shared_ptr)
|
||||
class ActivityInstance {
|
||||
|
||||
friend class odb::access;
|
||||
|
||||
private:
|
||||
#pragma db id auto
|
||||
uint32_t oid;
|
||||
|
||||
wfr_id_t instid;
|
||||
|
||||
wfr_id_t iterationID;
|
||||
|
||||
std::vector<std::weak_ptr<ActivityInstance>> successors;
|
||||
|
||||
std::vector<std::weak_ptr<ActivityInstance>> predecessors;
|
||||
|
||||
#pragma db not_null
|
||||
std::shared_ptr<Activity> baseActivity;
|
||||
|
||||
#pragma db not_null
|
||||
std::shared_ptr<Workflow> parentWorkflow;
|
||||
|
||||
std::shared_ptr<ActivityInstance> parentInstance;
|
||||
|
||||
#pragma db inverse(parentInstance)
|
||||
std::vector<std::weak_ptr<ActivityInstanceStatusEvent>> statusEvents;
|
||||
|
||||
public:
|
||||
ActivityInstance() : oid(0), instid(0), iterationID(0) {}
|
||||
|
||||
ActivityInstance(wfr_id_t instid, wfr_id_t iterationID) : oid(0), instid(instid), iterationID(iterationID) {}
|
||||
|
||||
wfr_id_t getInstid() {
|
||||
return instid;
|
||||
}
|
||||
|
||||
void setInstid(wfr_id_t instid) {
|
||||
this->instid = instid;
|
||||
}
|
||||
|
||||
wfr_id_t getIterationId() {
|
||||
return iterationID;
|
||||
}
|
||||
|
||||
void setIterationId(wfr_id_t iterationId) {
|
||||
iterationID = iterationId;
|
||||
}
|
||||
|
||||
wfr_id_t getOid() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
std::shared_ptr<Activity>& getBaseActivity() {
|
||||
return baseActivity;
|
||||
}
|
||||
|
||||
void setBaseActivity(std::shared_ptr<Activity>& parentActivity) {
|
||||
this->baseActivity = parentActivity;
|
||||
}
|
||||
|
||||
std::vector<std::weak_ptr<ActivityInstance> >& getPredecessors() {
|
||||
return predecessors;
|
||||
}
|
||||
|
||||
std::vector<std::weak_ptr<ActivityInstance> >& getSuccessors() {
|
||||
return successors;
|
||||
}
|
||||
|
||||
const std::shared_ptr<ActivityInstance>& getParentInstance() const {
|
||||
return parentInstance;
|
||||
}
|
||||
|
||||
void setParentInstance(
|
||||
const std::shared_ptr<ActivityInstance>& parentInstance) {
|
||||
this->parentInstance = parentInstance;
|
||||
}
|
||||
|
||||
std::shared_ptr<Workflow>& getParentWorkflow() {
|
||||
return parentWorkflow;
|
||||
}
|
||||
|
||||
void setParentWorkflow(std::shared_ptr<Workflow>& parentWorkflow) {
|
||||
this->parentWorkflow = parentWorkflow;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#pragma db object pointer(std::shared_ptr)
|
||||
class ActivityInstanceStatusEvent {
|
||||
|
||||
friend class odb::access;
|
||||
|
||||
private:
|
||||
#pragma db id auto
|
||||
uint32_t oid;
|
||||
|
||||
#pragma db not_null
|
||||
std::shared_ptr<ActivityInstance> parentInstance;
|
||||
|
||||
std::string newStatus;
|
||||
|
||||
std::string oldStatus;
|
||||
|
||||
uint64_t timestamp;
|
||||
|
||||
public:
|
||||
ActivityInstanceStatusEvent() : oid(0), timestamp(0) {}
|
||||
|
||||
const std::string& getNewStatus() {
|
||||
return newStatus;
|
||||
}
|
||||
|
||||
void setNewStatus(const std::string& newStatus) {
|
||||
this->newStatus = newStatus;
|
||||
}
|
||||
|
||||
wfr_id_t getOid() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
const std::string& getOldStatus() {
|
||||
return oldStatus;
|
||||
}
|
||||
|
||||
void setOldStatus(const std::string& oldStatus) {
|
||||
this->oldStatus = oldStatus;
|
||||
}
|
||||
|
||||
const std::shared_ptr<ActivityInstance>& getParentInstance() {
|
||||
return parentInstance;
|
||||
}
|
||||
|
||||
void setParentInstance(const std::shared_ptr<ActivityInstance>& parentActivity) {
|
||||
this->parentInstance = parentActivity;
|
||||
}
|
||||
|
||||
uint64_t getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
void setTimestamp(uint64_t timestamp) {
|
||||
this->timestamp = timestamp;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#pragma db object pointer(std::shared_ptr)
|
||||
class DeviceInstanceStatusEvent {
|
||||
|
||||
friend class odb::access;
|
||||
|
||||
private:
|
||||
#pragma db id auto
|
||||
uint32_t oid;
|
||||
|
||||
std::shared_ptr<Workflow> parentWorkflow;
|
||||
|
||||
std::string deviceType;
|
||||
|
||||
wfr_id_t deviceID;
|
||||
|
||||
std::string newStatus;
|
||||
|
||||
std::string oldStatus;
|
||||
|
||||
uint64_t timestamp;
|
||||
|
||||
std::shared_ptr<ActivityInstance> executedInstance;
|
||||
|
||||
wfr_id_t executedImplID;
|
||||
|
||||
wfr_size_t deviceSlotCount;
|
||||
|
||||
public:
|
||||
DeviceInstanceStatusEvent() : oid(0), deviceID(0), timestamp(0), executedImplID(0), deviceSlotCount(0) {}
|
||||
|
||||
const std::string& getNewStatus() {
|
||||
return newStatus;
|
||||
}
|
||||
|
||||
void setNewStatus(const std::string& newStatus) {
|
||||
this->newStatus = newStatus;
|
||||
}
|
||||
|
||||
wfr_id_t getOid() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
const std::string& getOldStatus() {
|
||||
return oldStatus;
|
||||
}
|
||||
|
||||
void setOldStatus(const std::string& oldStatus) {
|
||||
this->oldStatus = oldStatus;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Workflow>& getParentWorkflow() {
|
||||
return parentWorkflow;
|
||||
}
|
||||
|
||||
void setParentWorkflow(const std::shared_ptr<Workflow>& parentWorkflow) {
|
||||
this->parentWorkflow = parentWorkflow;
|
||||
}
|
||||
|
||||
uint64_t getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
void setTimestamp(uint64_t timestamp) {
|
||||
this->timestamp = timestamp;
|
||||
}
|
||||
|
||||
wfr_id_t getDeviceId() {
|
||||
return deviceID;
|
||||
}
|
||||
|
||||
void setDeviceId(wfr_id_t deviceId) {
|
||||
deviceID = deviceId;
|
||||
}
|
||||
|
||||
wfr_size_t getDeviceSlotCount() {
|
||||
return deviceSlotCount;
|
||||
}
|
||||
|
||||
void setDeviceSlotCount(wfr_size_t deviceSlotCount) {
|
||||
this->deviceSlotCount = deviceSlotCount;
|
||||
}
|
||||
|
||||
const std::string& getDeviceType() {
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
void setDeviceType(const std::string& deviceType) {
|
||||
this->deviceType = deviceType;
|
||||
}
|
||||
|
||||
wfr_id_t getExecutedImplId() {
|
||||
return executedImplID;
|
||||
}
|
||||
|
||||
void setExecutedImplId(wfr_id_t executedImplId) {
|
||||
executedImplID = executedImplId;
|
||||
}
|
||||
|
||||
const std::shared_ptr<ActivityInstance>& getExecutedInstance() {
|
||||
return executedInstance;
|
||||
}
|
||||
|
||||
void setExecutedInstance(const std::shared_ptr<ActivityInstance>& executedInstance) {
|
||||
this->executedInstance = executedInstance;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#pragma db object pointer(std::shared_ptr)
|
||||
class ComponentStatusEvent {
|
||||
|
||||
friend class odb::access;
|
||||
|
||||
private:
|
||||
#pragma db id auto
|
||||
uint32_t oid;
|
||||
|
||||
std::shared_ptr<Workflow> workflow;
|
||||
|
||||
std::string componentType;
|
||||
|
||||
std::string newStatus;
|
||||
|
||||
std::string oldStatus;
|
||||
|
||||
uint64_t timestamp;
|
||||
|
||||
public:
|
||||
ComponentStatusEvent() : oid(0), timestamp(0) {}
|
||||
|
||||
std::string& getComponentType() {
|
||||
return componentType;
|
||||
}
|
||||
|
||||
void setComponentType(const std::string& componentType) {
|
||||
this->componentType = componentType;
|
||||
}
|
||||
|
||||
std::string& getNewStatus() {
|
||||
return newStatus;
|
||||
}
|
||||
|
||||
void setNewStatus(const std::string& newStatus) {
|
||||
this->newStatus = newStatus;
|
||||
}
|
||||
|
||||
wfr_id_t getOid() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
std::string& getOldStatus() {
|
||||
return oldStatus;
|
||||
}
|
||||
|
||||
void setOldStatus(const std::string& oldStatus) {
|
||||
this->oldStatus = oldStatus;
|
||||
}
|
||||
|
||||
uint64_t getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
void setTimestamp(uint64_t timestamp) {
|
||||
this->timestamp = timestamp;
|
||||
}
|
||||
|
||||
std::shared_ptr<Workflow>& getWorkflow() {
|
||||
return workflow;
|
||||
}
|
||||
|
||||
void setWorkflow(const std::shared_ptr<Workflow>& workflow) {
|
||||
this->workflow = workflow;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} /* namespace odbmodel */
|
||||
} /* namespace eventsystem */
|
||||
} /* namespace wfr */
|
||||
|
||||
|
||||
|
||||
#endif /* SIMPLEDBMODEL_H_ */
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace scheduling {
|
||||
class SchedulingDecision;
|
||||
}
|
||||
|
||||
namespace execution {
|
||||
|
||||
|
||||
enum class ExecutionHandleState
|
||||
: int { Unknown,
|
||||
Pending,
|
||||
Running,
|
||||
Finished,
|
||||
Error };
|
||||
|
||||
class ExecutionHandle {
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
std::shared_ptr<wfr::scheduling::SchedulingDecision> schedulingDecision = nullptr;
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
private:
|
||||
ExecutionHandleState state = ExecutionHandleState::Unknown;
|
||||
std::exception_ptr errorCause = nullptr;
|
||||
|
||||
public:
|
||||
ExecutionHandle(std::shared_ptr<wfr::scheduling::SchedulingDecision> schedulingDecision) noexcept :
|
||||
schedulingDecision(schedulingDecision), state(ExecutionHandleState::Pending) {}
|
||||
|
||||
std::exception_ptr getErrorCause() const noexcept { return errorCause; }
|
||||
|
||||
void setErrorCause(std::exception_ptr errorCause) noexcept { this->errorCause = errorCause; }
|
||||
|
||||
ExecutionHandleState getState() const noexcept { return state; }
|
||||
|
||||
void setState(ExecutionHandleState state) noexcept { this->state = state; }
|
||||
};
|
||||
|
||||
} /* namespace execution */
|
||||
} /* namespace wfr */
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace wfr {
|
||||
namespace scheduling {
|
||||
class SchedulingDecision;
|
||||
class AbstractScheduler;
|
||||
class PThreadBackend;
|
||||
}
|
||||
namespace execution {
|
||||
class PThreadBackend;
|
||||
class CudaBackend;
|
||||
}
|
||||
|
||||
|
||||
namespace execution {
|
||||
|
||||
|
||||
class ExecutionHandle;
|
||||
|
||||
class ExecutionManager {
|
||||
private:
|
||||
ExecutionManager();
|
||||
static ExecutionManager singleton;
|
||||
|
||||
std::mutex managerMutex;
|
||||
|
||||
PThreadBackend* pThreadBackend = nullptr;
|
||||
CudaBackend* cudaBackend = nullptr;
|
||||
|
||||
std::map<ExecutionHandle*, scheduling::AbstractScheduler*> schedulerHandleMap;
|
||||
std::queue<ExecutionHandle*> updateQueue;
|
||||
|
||||
public:
|
||||
static void init(int argc, char** argv);
|
||||
|
||||
static void finish();
|
||||
|
||||
~ExecutionManager();
|
||||
|
||||
static ExecutionManager& getInstance() { return singleton; }
|
||||
|
||||
bool executeSchedulingDecision(std::shared_ptr<scheduling::SchedulingDecision> sd, scheduling::AbstractScheduler& scheduler);
|
||||
|
||||
void notifyExecutionHandleUpdate(ExecutionHandle& handle);
|
||||
};
|
||||
|
||||
} /* namespace execution */
|
||||
} /* namespace wfr */
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <set>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
namespace resource {
|
||||
class Resource;
|
||||
class ComputingResource;
|
||||
}
|
||||
|
||||
namespace execution {
|
||||
|
||||
class ExecutionManager;
|
||||
class ExecutionHandle;
|
||||
class PThreadWorker;
|
||||
|
||||
class PThreadBackend {
|
||||
private:
|
||||
std::mutex objMutex;
|
||||
std::condition_variable workerCondVar;
|
||||
ExecutionManager& manager;
|
||||
std::set<PThreadWorker*> workers;
|
||||
std::set<PThreadWorker*> idleWorkers;
|
||||
std::set<resource::ComputingResource*> resources;
|
||||
std::queue<ExecutionHandle*> taskQueue;
|
||||
wfr_size_t maxWorkerCount;
|
||||
wfr_size_t currentTotalWorkerCount = 0;
|
||||
wfr_size_t currentBusyWorkerCount = 0;
|
||||
wfr_size_t occupiedSlotCount = 0;
|
||||
wfr_size_t slotsInQueue = 0;
|
||||
bool isShutdown = false;
|
||||
|
||||
public:
|
||||
PThreadBackend(ExecutionManager& manager, const std::set<resource::ComputingResource*>& resources);
|
||||
virtual ~PThreadBackend();
|
||||
|
||||
void notifyExecutionHandleUpdate(ExecutionHandle& handle, PThreadWorker& worker);
|
||||
|
||||
bool queueTaskExecution(ExecutionHandle& handle);
|
||||
|
||||
ExecutionHandle* popTaskExecution(PThreadWorker& worker);
|
||||
|
||||
wfr_size_t getBusyWorkerCount() { return currentBusyWorkerCount; }
|
||||
|
||||
wfr_size_t getTotalSlotCount() { return maxWorkerCount; }
|
||||
|
||||
};
|
||||
|
||||
} /* namespace execution */
|
||||
} /* namespace wfr */
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <atomic>
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
|
||||
namespace resource {
|
||||
class Resource;
|
||||
}
|
||||
|
||||
namespace scheduling {
|
||||
class SchedulingDecision;
|
||||
}
|
||||
|
||||
namespace execution {
|
||||
|
||||
class PThreadBackend;
|
||||
class ExecutionHandle;
|
||||
|
||||
class PThreadWorker {
|
||||
private:
|
||||
/**
|
||||
* Static variable holding the next free threadID.
|
||||
**/
|
||||
static std::atomic<wfr_id_t> nextThreadID;
|
||||
|
||||
/**
|
||||
* Returns the next free threadID.
|
||||
*
|
||||
* @return next free threadID.
|
||||
*/
|
||||
static wfr_id_t getNextThreadID();
|
||||
|
||||
static void workerFunc(PThreadWorker* threadObj);
|
||||
|
||||
private:
|
||||
wfr_id_t threadID;
|
||||
bool stopThread;
|
||||
bool threadRunning;
|
||||
bool threadBusy;
|
||||
PThreadBackend& backend;
|
||||
std::mutex threadMutex;
|
||||
std::thread* thread;
|
||||
wfr_size_t usedSlotCount;
|
||||
wfs::ComputingResourceStatus status;
|
||||
|
||||
PThreadWorker(PThreadBackend& backend);
|
||||
|
||||
public:
|
||||
virtual ~PThreadWorker();
|
||||
|
||||
wfr_size_t getThreadID() { return threadID; }
|
||||
|
||||
bool isBusy() { return threadBusy; }
|
||||
|
||||
void setBusy(bool val) {threadBusy = val; }
|
||||
|
||||
wfr_size_t getUsedSlotCount() { return usedSlotCount; }
|
||||
|
||||
void setUsedSlotCount(wfr_size_t count) { usedSlotCount += count; }
|
||||
|
||||
void finishThread();
|
||||
|
||||
void join();
|
||||
|
||||
wfs::ComputingResourceStatus getStatus() { return status; }
|
||||
|
||||
void setStatus(wfs::ComputingResourceStatus status, std::shared_ptr<wfr::scheduling::SchedulingDecision> sd = nullptr);
|
||||
|
||||
static PThreadWorker* createNewThread(PThreadBackend& backend);
|
||||
};
|
||||
|
||||
} /* namespace execution */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+108
@@ -0,0 +1,108 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <string>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
namespace wfs {
|
||||
class AtomicActivityImplementation;
|
||||
class ActivityInstance;
|
||||
}
|
||||
|
||||
namespace resource {
|
||||
class Resource;
|
||||
class ComputingResourceType;
|
||||
class ComputingResource;
|
||||
class ResourceManager;
|
||||
}
|
||||
|
||||
namespace prediction {
|
||||
|
||||
class PredictionService;
|
||||
|
||||
|
||||
|
||||
class ExecutionTimeResult {
|
||||
|
||||
// Mutable properties that need to be accessed via getter-/setter-functions.
|
||||
// Some of them are invariant, but this class needs to be copyable, so no const properties :(
|
||||
public:
|
||||
wfs::ActivityInstance* instance = nullptr;
|
||||
wfs::AtomicActivityImplementation* implementation = nullptr;
|
||||
resource::ComputingResourceType* resourceType = nullptr;
|
||||
wfr::NumericalMeasurement executionTime;
|
||||
wfr_size_t slots = 0;
|
||||
bool validFlag = false;
|
||||
|
||||
// Public functions
|
||||
public:
|
||||
ExecutionTimeResult() noexcept {}
|
||||
ExecutionTimeResult(wfs::ActivityInstance* instance, wfs::AtomicActivityImplementation* implementation,
|
||||
resource::ComputingResourceType* resourceType, wfr::NumericalMeasurement executionTime, wfr_size_t slots = 1, bool validFlag = true) noexcept
|
||||
: instance(instance), implementation(implementation), resourceType(resourceType), executionTime(executionTime),
|
||||
slots(slots), validFlag(validFlag) {}
|
||||
|
||||
wfs::ActivityInstance* getActivityInstance() const noexcept { return instance; }
|
||||
wfs::AtomicActivityImplementation* getActivityImplementation() const noexcept { return implementation; }
|
||||
resource::ComputingResourceType* getResourceType() const noexcept { return resourceType; }
|
||||
const wfr::NumericalMeasurement& getExecutionTime() const noexcept { return executionTime; }
|
||||
wfr_size_t getSlots() const noexcept { return slots; }
|
||||
bool isValid() const noexcept { return validFlag; }
|
||||
operator bool() const noexcept { return validFlag; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CommunicationTimeResult {
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
wfs::ActivityInstance* const srcInstance = nullptr;
|
||||
resource::ComputingResource* const srcResource = nullptr;
|
||||
wfs::ActivityInstance* const destInstance = nullptr;
|
||||
resource::ComputingResource* const destResource = nullptr;
|
||||
const wfr::NumericalMeasurement communicationTime;
|
||||
const bool isValid = false;
|
||||
public:
|
||||
CommunicationTimeResult() noexcept {}
|
||||
CommunicationTimeResult(wfs::ActivityInstance* srcInstance, resource::ComputingResource* srcResource,
|
||||
wfs::ActivityInstance* destInstance, resource::ComputingResource* destResource,
|
||||
wfr::NumericalMeasurement communicationTime, bool validFlag = true) noexcept
|
||||
: srcInstance(srcInstance), srcResource(srcResource), destInstance(destInstance), destResource(destResource),
|
||||
communicationTime(communicationTime), isValid(validFlag) {}
|
||||
|
||||
operator bool() const {
|
||||
return isValid;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class PredictionManager {
|
||||
private:
|
||||
static PredictionManager singleton;
|
||||
PredictionService* service = nullptr;
|
||||
public:
|
||||
static void init(int argc, char** argv);
|
||||
|
||||
static void finish() noexcept;
|
||||
|
||||
static PredictionManager& getInstance() noexcept { return singleton; }
|
||||
|
||||
public:
|
||||
~PredictionManager() noexcept;
|
||||
|
||||
ExecutionTimeResult predictExecutionTime(wfs::ActivityInstance& instance, wfs::AtomicActivityImplementation& implementation,
|
||||
resource::ComputingResourceType& resourceType, const wfr_size_t& slots = 1) noexcept;
|
||||
|
||||
CommunicationTimeResult predictCommunicationTime(wfs::ActivityInstance& srcInstance, resource::ComputingResource& srcResource,
|
||||
wfs::ActivityInstance& destInstance, resource::ComputingResource& destResource) noexcept;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace prediction */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/prediction/PredictionManager.h>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
namespace resource {
|
||||
class Resource;
|
||||
class ComputingResourceType;
|
||||
class ComputingResource;
|
||||
class ResourceManager;
|
||||
}
|
||||
|
||||
namespace prediction {
|
||||
|
||||
class PredictionService {
|
||||
public:
|
||||
virtual ~PredictionService() {}
|
||||
|
||||
virtual ExecutionTimeResult predictExecutionTime(wfs::ActivityInstance& instance, wfs::AtomicActivityImplementation& implementation,
|
||||
resource::ComputingResourceType& resourceType, const wfr_size_t& slots = 1) = 0;
|
||||
|
||||
virtual CommunicationTimeResult predictCommunicationTime(wfs::ActivityInstance& srcInstance, resource::ComputingResource& srcResource,
|
||||
wfs::ActivityInstance& destInstance, resource::ComputingResource& destResource) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace prediction */
|
||||
} /* namespace wfr */
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wfr/prediction/PredictionService.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
namespace prediction {
|
||||
|
||||
|
||||
class OraclePredictionService : public PredictionService {
|
||||
private:
|
||||
struct PredictionTableEntry {
|
||||
NumericalMeasurement prediction;
|
||||
};
|
||||
|
||||
// Primary Key: (ActivityType, ActivityImplementation, Device)
|
||||
std::map<std::string, std::map<std::string, std::map<std::string, PredictionTableEntry>>> predictionTable;
|
||||
public:
|
||||
OraclePredictionService(const std::string& config = std::string());
|
||||
|
||||
virtual ExecutionTimeResult predictExecutionTime(wfs::ActivityInstance& instance, wfs::AtomicActivityImplementation& implementation,
|
||||
resource::ComputingResourceType& resourceType, const wfr_size_t& slots = 1) override;
|
||||
|
||||
virtual CommunicationTimeResult predictCommunicationTime(wfs::ActivityInstance& srcInstance, resource::ComputingResource& srcResource,
|
||||
wfs::ActivityInstance& destInstance, resource::ComputingResource& destResource) override;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace prediction */
|
||||
} /* namespace wfr */
|
||||
Executable
+141
@@ -0,0 +1,141 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/common/resource/Resource.h>
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
// Forward declarations
|
||||
namespace wep {
|
||||
class WorkflowExecutionPlan;
|
||||
class AtomicWepNode;
|
||||
}
|
||||
namespace enactment {
|
||||
class EnactmentEngine;
|
||||
}
|
||||
namespace execution {
|
||||
class ExecutionManager;
|
||||
}
|
||||
namespace prediction {
|
||||
class PredictionManager;
|
||||
}
|
||||
namespace resource {
|
||||
class ResourceManager;
|
||||
}
|
||||
|
||||
|
||||
// Main namespace
|
||||
namespace scheduling {
|
||||
|
||||
// Forward declaration
|
||||
class SchedulingDecision;
|
||||
|
||||
|
||||
/*
|
||||
* Represents the interface every scheduler needs to implement.
|
||||
*
|
||||
* Workflow execution sequence:
|
||||
* 1) registerWEP() is called by enactment engine to register new workflow instance
|
||||
* 2) notifyWEPUpdate() is called by enactment engine to notify scheduler of workflow progress
|
||||
* 3) The scheduler creates scheduling decisions objects and passes them to the execution layer
|
||||
* - uses convenience function SchedulerBase::executeSchedulingDecision, or
|
||||
* - directly calls ExecutionManager::executeSchedulingDecision
|
||||
* 4) The execution layer calls notifySchedulingDecisionStatusUpdate to notify scheduler about executed (or failed) activities.
|
||||
* - the scheduler needs then to call EnactmentEngine::notifyActivityInstanceStateUpdate() to notify the enactment engine.
|
||||
* - SchedulerBase already automatically notifies the enactment engine.
|
||||
* 5) Goto 2) till unregisterWEP() is called.
|
||||
*/
|
||||
class AbstractScheduler {
|
||||
public:
|
||||
virtual ~AbstractScheduler() noexcept {}
|
||||
|
||||
/*
|
||||
* Is called by the enactment engine to let the scheduler know of a new workflow instance.
|
||||
*
|
||||
* @param wep workflow execution plan object representing the workflow instance
|
||||
* @param ee reference to enactment engine
|
||||
*/
|
||||
virtual void registerWEP(wep::WorkflowExecutionPlan& wep, enactment::EnactmentEngine& ee) noexcept = 0;
|
||||
|
||||
/*
|
||||
* Is called by the enactment engine to let the scheduler know that a workflow instance has finished
|
||||
*
|
||||
* @param wep workflow execution plan object representing the workflow instance
|
||||
*/
|
||||
virtual void unregisterWEP(wep::WorkflowExecutionPlan& wep) noexcept = 0;
|
||||
|
||||
/*
|
||||
* Is called by the enactment engine to let the scheduler know about changes to the workflow execution plan.
|
||||
*
|
||||
* @param wep workflow execution plan object representing the workflow instance
|
||||
* @param readytoExecute set of new ready-to-execute activities (for convenience)
|
||||
*/
|
||||
virtual void notifyWEPUpdate(wep::WorkflowExecutionPlan& wep, std::set<wep::AtomicWepNode*> readyToExecute) noexcept = 0;
|
||||
|
||||
/*
|
||||
* Called by the execution layer to notify the scheduler that an activity finished (or failed) execution.
|
||||
*
|
||||
* @param sd reference to scheduling decision object.
|
||||
*/
|
||||
virtual void notifySchedulingDecisionStatusUpdate(std::shared_ptr<SchedulingDecision> sd) noexcept = 0;
|
||||
|
||||
virtual double getCummulativePredictionTime() noexcept = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Scheduler base class implementing common scheduler functionality.
|
||||
*/
|
||||
class SchedulerBase : public AbstractScheduler {
|
||||
public:
|
||||
struct WepMapEntry {
|
||||
WepMapEntry(enactment::EnactmentEngine* engine, wep::WorkflowExecutionPlan* wep)
|
||||
: engine(engine), wep(wep) {}
|
||||
enactment::EnactmentEngine* engine;
|
||||
wep::WorkflowExecutionPlan* wep;
|
||||
std::set<std::shared_ptr<SchedulingDecision>> decisions;
|
||||
void* userData = nullptr;
|
||||
};
|
||||
protected:
|
||||
typedef std::map<wep::WorkflowExecutionPlan*, WepMapEntry> wepMap_t;
|
||||
std::mutex schedulerMutex;
|
||||
wepMap_t wepMap;
|
||||
bool simulationMode;
|
||||
double cummulativePredictionTime = 0;
|
||||
|
||||
protected:
|
||||
// Hook functions for AbstractScheduler functions below to allow customisation of common functionality
|
||||
virtual void _registerWEP(WepMapEntry& wepe, std::unique_lock<std::mutex>& schedulerLock) {};
|
||||
virtual void _unregisterWEP(WepMapEntry& wepe, std::unique_lock<std::mutex>& schedulerLock) {}
|
||||
virtual void _notifyWEPUpdate(WepMapEntry& wepe, std::set<wep::AtomicWepNode*> readyToExecute, std::unique_lock<std::mutex>& schedulerLock) {}
|
||||
virtual void _notifySchedulingDecisionStatusUpdate(WepMapEntry& wepe, std::shared_ptr<SchedulingDecision> sd, std::unique_lock<std::mutex>& schedulerLock) {}
|
||||
|
||||
// Convenience functions for passing a scheduling decision to the execution layer.
|
||||
bool executeSchedulingDecision(WepMapEntry& wepe, std::shared_ptr<SchedulingDecision> sd, std::unique_lock<std::mutex>& schedulerLock) noexcept;
|
||||
|
||||
public:
|
||||
SchedulerBase();
|
||||
virtual ~SchedulerBase() noexcept;
|
||||
|
||||
// From AbstractScheduler class
|
||||
virtual void registerWEP(wep::WorkflowExecutionPlan& wep, enactment::EnactmentEngine& ee) noexcept override;
|
||||
virtual void unregisterWEP(wep::WorkflowExecutionPlan& wep) noexcept override;
|
||||
virtual void notifyWEPUpdate(wep::WorkflowExecutionPlan& wep, std::set<wep::AtomicWepNode*> readyToExecute) noexcept override;
|
||||
virtual void notifySchedulingDecisionStatusUpdate(std::shared_ptr<SchedulingDecision> wep) noexcept override;
|
||||
virtual double getCummulativePredictionTime() noexcept override { return cummulativePredictionTime; }
|
||||
};
|
||||
|
||||
|
||||
} /* namespace scheduling */
|
||||
} /* namespace wfr */
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
namespace wfr {
|
||||
namespace scheduling {
|
||||
|
||||
class AbstractScheduler;
|
||||
|
||||
class SchedulerManager {
|
||||
private:
|
||||
static SchedulerManager* singleton;
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, std::function<AbstractScheduler*()>> factoryMap_t;
|
||||
std::string defaultScheduler;
|
||||
factoryMap_t schedulerFactories;
|
||||
|
||||
private:
|
||||
SchedulerManager(std::string defaultScheduler);
|
||||
|
||||
public:
|
||||
static void init(int argc, char** argv);
|
||||
|
||||
static void finish();
|
||||
|
||||
static SchedulerManager& getInstance();
|
||||
|
||||
public:
|
||||
~SchedulerManager() {}
|
||||
|
||||
AbstractScheduler* getDefaultScheduler();
|
||||
|
||||
AbstractScheduler* getSchedulerByName(std::string& name);
|
||||
|
||||
void markSchedulerForDeletion(AbstractScheduler* scheduler);
|
||||
};
|
||||
|
||||
} /* namespace scheduling */
|
||||
} /* namespace wfr */
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/scheduling/AbstractScheduler.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wep {
|
||||
class AtomicWepNode;
|
||||
class WEPnode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace scheduling {
|
||||
|
||||
class DummyScheduler: public wfr::scheduling::SchedulerBase {
|
||||
private:
|
||||
resource::ResourceManager& resourceManager;
|
||||
prediction::PredictionManager& predictionManager;
|
||||
|
||||
public:
|
||||
DummyScheduler(resource::ResourceManager& resourceManager, prediction::PredictionManager& predictionManager)
|
||||
: resourceManager(resourceManager), predictionManager(predictionManager) {}
|
||||
|
||||
virtual void _notifyWEPUpdate(SchedulerBase::WepMapEntry& wepe, std::set<wep::AtomicWepNode*> readyToExecute, std::unique_lock<std::mutex>& schedulerLock);
|
||||
};
|
||||
|
||||
} /* namespace scheduling */
|
||||
} /* namespace wfr */
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/scheduling/AbstractScheduler.h>
|
||||
#include <wfr/prediction/PredictionManager.h>
|
||||
#include <wfr/common/resource/Resource.h>
|
||||
#include <wfr/common/resource/ResourceManager.h>
|
||||
#include <wfr/common/types/WfrTypes.h>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace wfr {
|
||||
|
||||
namespace wfs {
|
||||
class AtomicActivityInstance;
|
||||
}
|
||||
|
||||
namespace wep {
|
||||
class AtomicWepNode;
|
||||
class AbstractWepNode;
|
||||
}
|
||||
namespace resource {
|
||||
class ResourceManager;
|
||||
}
|
||||
namespace prediction {
|
||||
class PredictionManager;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace scheduling {
|
||||
|
||||
|
||||
|
||||
|
||||
class HEFTScheduler: public scheduling::SchedulerBase {
|
||||
protected:
|
||||
struct InstanceUserData {
|
||||
bool isComplete = false;
|
||||
bool isScheduled = false;
|
||||
NumericalMeasurement rank;
|
||||
NumericalMeasurement averageComputingCost;
|
||||
// resourceName => (fastest implementation, prediction);
|
||||
std::map<resource::ComputingResourceType*, std::tuple<wfs::AtomicActivityImplementation*, prediction::ExecutionTimeResult>> predictions;
|
||||
};
|
||||
struct SchedulingQueueEntry {
|
||||
InstanceUserData* instanceData = nullptr;
|
||||
wfs::AtomicActivityInstance* instance = nullptr;
|
||||
wep::AbstractWepNode* node = nullptr;
|
||||
};
|
||||
struct _SchedulingQueueEntryComparison {
|
||||
bool operator()(const SchedulingQueueEntry& e1, const SchedulingQueueEntry& e2) {
|
||||
if (e1.instanceData && !e2.instanceData) {
|
||||
return false;
|
||||
} else if (!e1.instanceData && e2.instanceData) {
|
||||
return true;
|
||||
} else if (e1.instanceData && e2.instanceData) {
|
||||
return e1.instanceData->rank.getValue() < e2.instanceData->rank.getValue();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
std::priority_queue<SchedulingQueueEntry, std::vector<SchedulingQueueEntry>, _SchedulingQueueEntryComparison> schedulingPriorityQueue;
|
||||
|
||||
|
||||
|
||||
resource::ResourceManager& resourceManager;
|
||||
prediction::PredictionManager& predictionManager;
|
||||
|
||||
std::vector<std::string> debugLines;
|
||||
wfr_size_t debugIteration = 0;
|
||||
|
||||
|
||||
|
||||
NumericalMeasurement getRank(wfs::AtomicActivityInstance& ai, InstanceUserData* instanceData, const std::vector<resource::ComputingResourceType*>& resourceTypes, const std::vector<resource::ComputingResource*>& resources);
|
||||
NumericalMeasurement getAverageExecutionCost(wfs::AtomicActivityInstance& ai, InstanceUserData* instanceData, const std::vector<resource::ComputingResourceType*>& resources);
|
||||
NumericalMeasurement getMaxSuccValue(wfs::AtomicActivityInstance& ai, InstanceUserData* instanceData, const std::vector<resource::ComputingResourceType*>& resourceTypes, const std::vector<resource::ComputingResource*>& resources);
|
||||
|
||||
public:
|
||||
HEFTScheduler(resource::ResourceManager& resourceManager, prediction::PredictionManager& predictionManager)
|
||||
: resourceManager(resourceManager), predictionManager(predictionManager) {}
|
||||
|
||||
~HEFTScheduler() {
|
||||
/*for (auto s : debugLines) {
|
||||
std::cout << s << std::endl;
|
||||
}*/
|
||||
}
|
||||
|
||||
virtual void _notifyWEPUpdate(SchedulerBase::WepMapEntry& wepe, std::set<wep::AtomicWepNode*> readyToExecute, std::unique_lock<std::mutex>& schedulerLock);
|
||||
};
|
||||
|
||||
} /* namespace scheduling */
|
||||
} /* namespace wfr */
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/scheduling/AbstractScheduler.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wep {
|
||||
class AtomicWepNode;
|
||||
class WEPnode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace scheduling {
|
||||
|
||||
class JustInTimeScheduler: public wfr::scheduling::SchedulerBase {
|
||||
private:
|
||||
resource::ResourceManager& resourceManager;
|
||||
prediction::PredictionManager& predictionManager;
|
||||
std::set<wep::AtomicWepNode*> nodeQueue;
|
||||
|
||||
public:
|
||||
JustInTimeScheduler(resource::ResourceManager& resourceManager, prediction::PredictionManager& predictionManager)
|
||||
: resourceManager(resourceManager), predictionManager(predictionManager) {}
|
||||
|
||||
virtual void _notifyWEPUpdate(SchedulerBase::WepMapEntry& wepe, std::set<wep::AtomicWepNode*> readyToExecute, std::unique_lock<std::mutex>& schedulerLock);
|
||||
};
|
||||
|
||||
} /* namespace scheduling */
|
||||
} /* namespace wfr */
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/scheduling/AbstractScheduler.h>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wep {
|
||||
class AtomicWepNode;
|
||||
class WEPnode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace scheduling {
|
||||
|
||||
class RandomScheduler: public wfr::scheduling::SchedulerBase {
|
||||
private:
|
||||
resource::ResourceManager& resourceManager;
|
||||
prediction::PredictionManager& predictionManager;
|
||||
std::set<wep::AtomicWepNode*> nodeQueue;
|
||||
|
||||
public:
|
||||
RandomScheduler(resource::ResourceManager& resourceManager, prediction::PredictionManager& predictionManager)
|
||||
: resourceManager(resourceManager), predictionManager(predictionManager) {}
|
||||
|
||||
virtual void _notifyWEPUpdate(SchedulerBase::WepMapEntry& wepe, std::set<wep::AtomicWepNode*> readyToExecute, std::unique_lock<std::mutex>& schedulerLock);
|
||||
};
|
||||
|
||||
} /* namespace scheduling */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
|
||||
namespace wfr {
|
||||
namespace wep {
|
||||
|
||||
// Forward declarations
|
||||
class WorkflowExecutionPlan;
|
||||
class AbstractWepNode;
|
||||
|
||||
// main namespace
|
||||
namespace utils {
|
||||
|
||||
|
||||
class WepDotFileWriter {
|
||||
|
||||
// Invariant properties that can be accessed directly.
|
||||
public:
|
||||
typedef std::set<AbstractWepNode*> visitedNodes_t;
|
||||
const std::shared_ptr<WorkflowExecutionPlan> wep;
|
||||
const std::string workflowName;
|
||||
|
||||
// Non-Public functions
|
||||
private:
|
||||
void writeWepNodeAndEdges(std::ofstream& outfile, AbstractWepNode* node, visitedNodes_t& visitedNodes);
|
||||
|
||||
std::string getNodeType(AbstractWepNode* node);
|
||||
std::string getNodeLabel(AbstractWepNode* node);
|
||||
std::string getNodeID(AbstractWepNode* node);
|
||||
std::string getNodeShape(AbstractWepNode* node);
|
||||
std::string getNodeStatus(AbstractWepNode* node);
|
||||
std::string getNodeVisitationCount(AbstractWepNode* node);
|
||||
|
||||
public:
|
||||
WepDotFileWriter(const std::shared_ptr<WorkflowExecutionPlan>& wep) noexcept;
|
||||
|
||||
void printToFile();
|
||||
void printToFile(const std::string fileName);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} /* namespace utils */
|
||||
} /* namespace wep */
|
||||
} /* namespace wfr */
|
||||
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace wfr {
|
||||
namespace wep {
|
||||
class AbstractWepNode;
|
||||
}
|
||||
|
||||
namespace utils {
|
||||
namespace wep {
|
||||
|
||||
|
||||
|
||||
template<typename VisitType>
|
||||
void wepDepthFirstSearch(wfr::wep::AbstractWepNode* startNode, const VisitType& visitFunction,
|
||||
std::set<wfr::wep::AbstractWepNode*>& visitedNodes = std::set<wfr::wep::AbstractWepNode*>()) {
|
||||
visitedNodes.insert(startNode);
|
||||
if (visitFunction(startNode)) {
|
||||
for (auto c : startNode->getSuccessors()) {
|
||||
if (visitedNodes.find(c) == visitedNodes.end()) {
|
||||
wepDepthFirstSearch(c, visitFunction, visitedNodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename VisitType>
|
||||
void wepBreadthFirstSearch(wfr::wep::AbstractWepNode* startNode, const VisitType& visitFunction) {
|
||||
std::vector<wfr::wep::AbstractWepNode*> nodeQueue;
|
||||
std::set<wfr::wep::AbstractWepNode*> visitedNodes;
|
||||
nodeQueue.push_back(startNode);
|
||||
while (!nodeQueue.empty()) {
|
||||
auto cn = nodeQueue.front();
|
||||
visitedNodes.insert(cn);
|
||||
nodeQueue.erase(nodeQueue.begin());
|
||||
if (visitFunction(cn)) {
|
||||
for (auto c : cn->getSuccessors()) {
|
||||
if (visitedNodes.find(c) == visitedNodes.end()) {
|
||||
bool isInQueue = false;
|
||||
for (auto e : nodeQueue) {
|
||||
if (c == e) {
|
||||
isInQueue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isInQueue) {
|
||||
nodeQueue.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename VisitType>
|
||||
void wepBreadthFirstReverseSearch(wfr::wep::AbstractWepNode* startNode, const VisitType& visitFunction) {
|
||||
std::vector<wfr::wep::AbstractWepNode*> nodeQueue;
|
||||
std::set<wfr::wep::AbstractWepNode*> visitedNodes;
|
||||
nodeQueue.push_back(startNode);
|
||||
while (!nodeQueue.empty()) {
|
||||
auto cn = nodeQueue.front();
|
||||
visitedNodes.insert(cn);
|
||||
nodeQueue.erase(nodeQueue.begin());
|
||||
if (visitFunction(cn)) {
|
||||
for (auto c : cn->getPredecessors()) {
|
||||
if (visitedNodes.find(c) == visitedNodes.end()) {
|
||||
bool isInQueue = false;
|
||||
for (auto e : nodeQueue) {
|
||||
if (c == e) {
|
||||
isInQueue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isInQueue) {
|
||||
nodeQueue.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <wfr/WorkflowRuntime.h>
|
||||
|
||||
#include <wfr/common/types/LwdTypes.h>
|
||||
#include <wfr/common/types/WfsTypes.h>
|
||||
|
||||
#include <wfr/common/wfs/WorkflowTemplate.h>
|
||||
#include <wfr/common/wfs/Workflow.h>
|
||||
#include <wfr/common/wfs/ActivityTemplate.h>
|
||||
#include <wfr/common/wfs/Activity.h>
|
||||
#include <wfr/common/wfs/ActivityInstance.h>
|
||||
#include <wfr/common/wfs/AtomicActivityImplementation.h>
|
||||
#include <wfr/common/wfs/instances/AssignActivityInstance.h>
|
||||
#include <wfr/common/wfs/instances/AtomicActivityInstance.h>
|
||||
#include <wfr/common/wfs/instances/ContainerActivityInstance.h>
|
||||
#include <wfr/common/wfs/instances/ConditionalActivityInstance.h>
|
||||
#include <wfr/common/wfs/instances/ForLoopActivityInstance.h>
|
||||
#include <wfr/common/wfs/instances/WhileLoopActivityInstance.h>
|
||||
#include <wfr/common/wfs/AtomicActivityType.h>
|
||||
|
||||
#include <wfr/common/macros/lwdmacros.h>
|
||||
#include <wfr/common/utils/utils.h>
|
||||
#include <wfr/common/utils/filesystem.h>
|
||||
|
||||
using namespace wfr;
|
||||
|
||||
/*
|
||||
#include <wfr/utils/lwd/DataBufferUtils.h>
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user