Initial commit

This commit is contained in:
Matthias
2017-04-11 15:49:21 +02:00
commit ec80b339e2
2081 changed files with 968992 additions and 0 deletions
+208
View File
@@ -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 */
+276
View File
@@ -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
View File
@@ -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 */
+85
View File
@@ -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 */
+74
View File
@@ -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
+836
View File
@@ -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;
+20
View File
@@ -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 */
+174
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+233
View File
@@ -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
+36
View File
@@ -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
+22
View File
@@ -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 */
+93
View File
@@ -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
+137
View File
@@ -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
+55
View File
@@ -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 */
+28
View File
@@ -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
+268
View File
@@ -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 */
+216
View File
@@ -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
+79
View File
@@ -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 */
+43
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+36
View File
@@ -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
View File
@@ -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 */
+40
View File
@@ -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 */
+209
View File
@@ -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 */
+282
View File
@@ -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 */
+257
View File
@@ -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
View File
@@ -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 */
+68
View File
@@ -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 */
+260
View File
@@ -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 */
+102
View File
@@ -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 */
+29
View File
@@ -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 */
+33
View File
@@ -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 */
+50
View File
@@ -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
View File
@@ -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 */
+37
View File
@@ -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 */
+37
View File
@@ -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 */
+42
View File
@@ -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 */
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#define WFR_ENABLE_STATISTICS
#define WFR_ENABLE_WEPDOTWRITER
#define WFR_ENABLE_PERFDATABASE
#define WFR_ENABLE_STDLOGGER
+66
View File
@@ -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 */
+85
View File
@@ -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 */
+32
View File
@@ -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 */
+105
View File
@@ -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
View File
@@ -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_ */
+49
View File
@@ -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 */
+59
View File
@@ -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 */
+57
View File
@@ -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
View File
@@ -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 */
+108
View File
@@ -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 */
+31
View File
@@ -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 */
+141
View File
@@ -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 */
+44
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+34
View File
@@ -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 */
+53
View File
@@ -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 */
+94
View File
@@ -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);
}
}
}
}
}
}
}
}
}
+33
View File
@@ -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>
*/