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
Executable
+96
View File
@@ -0,0 +1,96 @@
project(WFR-lib C CXX)
cmake_minimum_required(VERSION 2.8)
# cmake options
OPTION(BUILD_WFR_SHARED "Build libwfr as shared library" ON)
# Compiler flags
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -DNDEBUG -Wall")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -DNDEBUG -Wall")
#set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall")
#set(CMAKE_C_FLAGS_RELEASE "-O3 -Wall")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELEASE}")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_RELEASE}")
# Initialize variables
set(WFR_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(WFR_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(WFR_LIBRARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
set(wfr_add_include_dirs "")
set(wfr_cpp_files "")
# Check whether we are called by another script
get_directory_property(hasParent PARENT_DIRECTORY)
# Override default libs install directory
if (NOT hasParent)
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/dist")
endif()
endif()
# Include third-party stuff
include(third-party/cmake.inc)
# Include wfr source code
include(src/cmake.inc)
# Set include dir and compiler command line options for compiling
include_directories(${WFR_INCLUDE_DIR} ${Libodb_common_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${Libodb_sqlite_INCLUDE_DIR} ${Rapidjson_INCLUDE_DIR} ${wfr_add_include_dirs})
ADD_DEFINITIONS(
-std=c++11
-Wno-unknown-pragmas
)
# Add wfr library
if (BUILD_WFR_SHARED)
add_library(wfr_lib SHARED ${wfr_cpp_files})
set(WFR_LIBRARY_EXTENSION ".so")
else()
add_library(wfr_lib STATIC ${wfr_cpp_files})
set(WFR_LIBRARY_EXTENSION ".a")
endif()
add_dependencies(wfr_lib libodb sqlite3 Boost)
set_target_properties(wfr_lib PROPERTIES OUTPUT_NAME wfr)
# Set variables
set(WFR_LIBRARIES
wfr_lib
"${Boost_LIBRARIES}"
"${Libodb_sqlite_LIBRARIES}"
"${Libodb_common_LIBRARIES}"
"${Sqlite3_LIBRARIES}"
pthread
dl
)
message("WFR_LIBRARIES: ${WFR_LIBRARIES}")
message("Boost_LIBRARIES: ${Boost_LIBRARIES}")
message("Libodb_sqlite_LIBRARIES: ${Libodb_sqlite_LIBRARIES}")
message("Libodb_common_LIBRARIES: ${Libodb_common_LIBRARIES}")
message("Sqlite3_LIBRARIES: ${Sqlite3_LIBRARIES}")
# Where to install the wfr stuff
install(DIRECTORY ${WFR_INCLUDE_DIR} DESTINATION ${CMAKE_INSTALL_PREFIX})
install(TARGETS wfr_lib DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/wfr-config.cmake DESTINATION ${CMAKE_INSTALL_PREFIX})
# Provide some variables to parent script
if(hasParent)
set(WFR_FOUND "TRUE" PARENT_SCOPE)
set(WFR_DIR "${WFR_DIR}" PARENT_SCOPE)
set(WFR_INCLUDE_DIR "${WFR_INCLUDE_DIR}" PARENT_SCOPE)
set(WFR_LIBRARY_DIR "${WFR_LIBRARY_DIR}" PARENT_SCOPE)
set(WFR_LIBRARIES ${WFR_LIBRARIES} PARENT_SCOPE)
endif()
+18
View File
@@ -0,0 +1,18 @@
Directory Layout:
=================
common: Objects used by all other modules.
enactment: Enactment Engine
eventsystem: Global Event System
execution: ExecutionLayer
wfr.h: Contains all includes needed for a workflow program
NameSpace Layout:
=================
wfr: NameSpace containing all "visible" (visible to a workflow program) objects
wfr::wfs: Workflow Structure Objects
wfr::wep: Workflow Executionplan Objects
wfri: Internal Objects
+25
View File
@@ -0,0 +1,25 @@
set(SELF_DIR ${CMAKE_CURRENT_LIST_DIR})
# Where to find WFR
if (NOT WFR_DIR)
set(WFR_DIR "${SELF_DIR}")
endif()
set(WFR_INCLUDE_DIR "${WFR_DIR}/include")
set(WFR_LIBRARY_DIR "${WFR_DIR}/lib")
# WFR requires C++11
ADD_DEFINITIONS( -std=c++11 )
# Search for required libraries (prefer static over shared)
set(wfr_lib_paths ${WFR_LIBRARY_DIR}) # Where to search
find_library(wfr_lib NAMES libwfr.a wfr PATHS ${wfr_lib_paths})
find_library(boost_program_options_lib NAMES libboost_program_options.a boost_program_options PATHS ${wfr_lib_paths})
find_library(boost_system_lib NAMES libboost_system.a boost_system PATHS ${wfr_lib_paths})
find_library(boost_filesystem_lib NAMES libboost_filesystem.a boost_filesystem PATHS ${wfr_lib_paths})
find_library(odb_lib NAMES libodb.a odb PATHS ${wfr_lib_paths})
find_library(odb_sqlite_lib NAMES libodb-sqlite.a odb-sqlite PATHS ${wfr_lib_paths})
find_library(sqlite_lib NAMES libsqlite3.a sqlite3 PATHS ${wfr_lib_paths})
# Store required libraries into single variable
set(WFR_LIBRARIES ${wfr_lib} ${boost_system_lib} ${boost_program_options_lib} ${boost_filesystem_lib} ${odb_sqlite_lib} ${odb_lib} ${sqlite_lib} pthread dl)
+95
View File
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="workflowstructure" nsURI="http://workflowstructure/1.0" nsPrefix="workflowstructure">
<eClassifiers xsi:type="ecore:EClass" name="WorkflowTemplate">
<eOperations name="execute"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="workflowName"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="topLevelActivity"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="activityTemplate" lowerBound="1"
upperBound="-1" eType="#//ActivityTemplate" containment="true" eOpposite="#//ActivityTemplate/workflowTemplate"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ActivityTemplate">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="activityName"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="activityType"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="branchID"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="functionHooks"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="workflowTemplate" lowerBound="1"
eType="#//WorkflowTemplate" eOpposite="#//WorkflowTemplate/activityTemplate"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="successor" upperBound="-1"
eType="#//ActivityTemplate" eOpposite="#//ActivityTemplate/predecessor"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="predecessor" upperBound="-1"
eType="#//ActivityTemplate" eOpposite="#//ActivityTemplate/successor"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="parent" eType="#//ActivityTemplate"
eOpposite="#//ActivityTemplate/children"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="children" upperBound="-1"
eType="#//ActivityTemplate" eOpposite="#//ActivityTemplate/parent"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Workflow">
<eOperations name="execute"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="workflowID"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="workflowStatus"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="baseTemplate" lowerBound="1"
eType="#//WorkflowTemplate"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="activities" lowerBound="1"
upperBound="-1" eType="#//Activity" containment="true" eOpposite="#//Activity/workflow"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Activity">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="activityID"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="workflow" lowerBound="1"
eType="#//Workflow" eOpposite="#//Workflow/activities"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="activityType"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="activityStatus"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="instances" upperBound="-1"
eType="#//ActivityInstance" containment="true" eOpposite="#//ActivityInstance/baseActivity"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="baseTemplate" lowerBound="1"
eType="#//ActivityTemplate"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="successor" upperBound="-1"
eType="#//Activity" eOpposite="#//Activity/predecessor"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="predecessor" upperBound="-1"
eType="#//Activity" eOpposite="#//Activity/successor"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="parent" eType="#//Activity"
eOpposite="#//Activity/children"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="children" upperBound="-1"
eType="#//Activity" eOpposite="#//Activity/parent"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ActivityInstance">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="instanceID"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="activityType"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="instanceState"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="baseActivity" lowerBound="1"
eType="#//Activity" eOpposite="#//Activity/instances"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="portData (input/output/...)"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="successor" upperBound="-1"
eType="#//ActivityInstance" eOpposite="#//ActivityInstance/predecessor"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="predecessor" upperBound="-1"
eType="#//ActivityInstance" eOpposite="#//ActivityInstance/successor"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="parent" eType="#//ActivityInstance"
eOpposite="#//ActivityInstance/children"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="children" upperBound="-1"
eType="#//ActivityInstance" eOpposite="#//ActivityInstance/parent"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="LoopInstance" eSuperTypes="#//ActivityInstance">
<eStructuralFeatures xsi:type="ecore:EReference" name="iterations" upperBound="-1"
containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="WorkflowExecutionPlan">
<eStructuralFeatures xsi:type="ecore:EReference" name="nodes" lowerBound="1" upperBound="-1"
eType="#//WEPnode" containment="true" eOpposite="#//WEPnode/executionPlan"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="WEPnode">
<eStructuralFeatures xsi:type="ecore:EReference" name="executionPlan" lowerBound="1"
eType="#//WorkflowExecutionPlan" eOpposite="#//WorkflowExecutionPlan/nodes"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="successors" upperBound="-1"
eType="#//WEPnode" eOpposite="#//WEPnode/predecessors"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="predecessors" upperBound="-1"
eType="#//WEPnode" eOpposite="#//WEPnode/successors"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="associated Activity" eType="#//ActivityInstance"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="nodeType"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="WEPnodeAtomic" eSuperTypes="#//WEPnode"/>
<eClassifiers xsi:type="ecore:EClass" name="WEPnodeHole" eSuperTypes="#//WEPnode"/>
<eClassifiers xsi:type="ecore:EClass" name="..." eSuperTypes="#//WEPnode"/>
<eClassifiers xsi:type="ecore:EClass" name="ActivityContainerInstance" eSuperTypes="#//ActivityInstance"/>
<eClassifiers xsi:type="ecore:EClass" name="..." eSuperTypes="#//ActivityInstance"/>
<eClassifiers xsi:type="ecore:EClass" name="ActivityAtomicInstance" eSuperTypes="#//ActivityInstance"/>
</ecore:EPackage>
+721
View File
@@ -0,0 +1,721 @@
<?xml version="1.0" encoding="UTF-8"?>
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmi:id="_mHvoMIzFEeO4Eau2KiDmqg" type="EcoreTools" name="WorkflowStructure" measurementUnit="Pixel">
<children xmi:type="notation:Node" xmi:id="_nZ0UEIzFEeO4Eau2KiDmqg" type="1001">
<children xmi:type="notation:Node" xmi:id="_nZ07IIzFEeO4Eau2KiDmqg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_nZ1iMIzFEeO4Eau2KiDmqg" type="5001">
<children xmi:type="notation:Node" xmi:id="_1cTXYIzFEeO4Eau2KiDmqg" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//WorkflowTemplate/workflowName"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_1cTXYYzFEeO4Eau2KiDmqg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_3ESB0IzFEeO4Eau2KiDmqg" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//WorkflowTemplate/topLevelActivity"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_3ESB0YzFEeO4Eau2KiDmqg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_nZ1iMYzFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_nZ1iMozFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_nZ1iM4zFEeO4Eau2KiDmqg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_nZ1iNIzFEeO4Eau2KiDmqg" type="5002">
<children xmi:type="notation:Node" xmi:id="_5YNzUIzFEeO4Eau2KiDmqg" type="2002">
<element xmi:type="ecore:EOperation" href="WorkflowStructure.ecore#//WorkflowTemplate/execute"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_5YNzUYzFEeO4Eau2KiDmqg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_nZ1iNYzFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_nZ1iNozFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_nZ2JQIzFEeO4Eau2KiDmqg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_nZ0UEYzFEeO4Eau2KiDmqg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//WorkflowTemplate"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_nZ0UEozFEeO4Eau2KiDmqg" x="55" y="75"/>
</children>
<children xmi:type="notation:Node" xmi:id="_oihBgIzFEeO4Eau2KiDmqg" type="1001">
<children xmi:type="notation:Node" xmi:id="_oihokIzFEeO4Eau2KiDmqg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_oihokYzFEeO4Eau2KiDmqg" type="5001">
<children xmi:type="notation:Node" xmi:id="_9SJSQIzFEeO4Eau2KiDmqg" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//ActivityTemplate/activityName"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_9SJSQYzFEeO4Eau2KiDmqg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_Dr6QsIzGEeO4Eau2KiDmqg" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//ActivityTemplate/activityType"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_Dr6QsYzGEeO4Eau2KiDmqg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_z7BUYIzREeO4Eau2KiDmqg" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//ActivityTemplate/branchID"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_z7BUYYzREeO4Eau2KiDmqg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_HEkOkIzGEeO4Eau2KiDmqg" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//ActivityTemplate/functionHooks"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_HEkOkYzGEeO4Eau2KiDmqg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_oihokozFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_oihok4zFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_oiholIzFEeO4Eau2KiDmqg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_oiholYzFEeO4Eau2KiDmqg" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_oiholozFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_oihol4zFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_oihomIzFEeO4Eau2KiDmqg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_oihBgYzFEeO4Eau2KiDmqg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//ActivityTemplate"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_oihBgozFEeO4Eau2KiDmqg" x="365" y="45"/>
</children>
<children xmi:type="notation:Node" xmi:id="_qSg_gIzFEeO4Eau2KiDmqg" type="1001">
<children xmi:type="notation:Node" xmi:id="_qShmkIzFEeO4Eau2KiDmqg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_qShmkYzFEeO4Eau2KiDmqg" type="5001">
<children xmi:type="notation:Node" xmi:id="_Uzrp8IzGEeO4Eau2KiDmqg" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//Workflow/workflowID"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_Uzrp8YzGEeO4Eau2KiDmqg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_b-uUUIzGEeO4Eau2KiDmqg" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//Workflow/workflowStatus"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_b-uUUYzGEeO4Eau2KiDmqg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_qShmkozFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_qShmk4zFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_qShmlIzFEeO4Eau2KiDmqg"/>
<layoutConstraint xmi:type="notation:Ratio" xmi:id="_vUxYcIzFEeO4Eau2KiDmqg" value="0.3"/>
</children>
<children xmi:type="notation:Node" xmi:id="_qShmlYzFEeO4Eau2KiDmqg" type="5002">
<children xmi:type="notation:Node" xmi:id="_jzzaMIzGEeO4Eau2KiDmqg" type="2002">
<element xmi:type="ecore:EOperation" href="WorkflowStructure.ecore#//Workflow/execute"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_jz0BQIzGEeO4Eau2KiDmqg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_qShmlozFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_qShml4zFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_qShmmIzFEeO4Eau2KiDmqg"/>
<layoutConstraint xmi:type="notation:Ratio" xmi:id="_vUx_gIzFEeO4Eau2KiDmqg" value="0.3"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_qSg_gYzFEeO4Eau2KiDmqg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//Workflow"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_qSg_gozFEeO4Eau2KiDmqg" x="50" y="265"/>
</children>
<children xmi:type="notation:Node" xmi:id="_ryzGgIzFEeO4Eau2KiDmqg" type="1001">
<children xmi:type="notation:Node" xmi:id="_ryzGg4zFEeO4Eau2KiDmqg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_ryzGhIzFEeO4Eau2KiDmqg" type="5001">
<children xmi:type="notation:Node" xmi:id="_tx6CEIzGEeO4Eau2KiDmqg" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//Activity/activityID"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_tx6CEYzGEeO4Eau2KiDmqg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_AxYDII9AEeO9s7Q_fmy5EA" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//Activity/activityType"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_AxYDIY9AEeO9s7Q_fmy5EA"/>
</children>
<children xmi:type="notation:Node" xmi:id="_UXUgQIzVEeOfspFKg5o4YA" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//Activity/activityStatus"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_UXUgQYzVEeOfspFKg5o4YA"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_ryzGhYzFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_ryzGhozFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_ryzGh4zFEeO4Eau2KiDmqg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_ryztkIzFEeO4Eau2KiDmqg" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_ryztkYzFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_ryztkozFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_ryztk4zFEeO4Eau2KiDmqg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_ryzGgYzFEeO4Eau2KiDmqg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//Activity"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_ryzGgozFEeO4Eau2KiDmqg" x="370" y="255"/>
</children>
<children xmi:type="notation:Node" xmi:id="_taVFAIzFEeO4Eau2KiDmqg" type="1001">
<children xmi:type="notation:Node" xmi:id="_taVFA4zFEeO4Eau2KiDmqg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_taVFBIzFEeO4Eau2KiDmqg" type="5001">
<children xmi:type="notation:Node" xmi:id="_3OvY0IzaEeOfspFKg5o4YA" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//ActivityInstance/instanceID"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_3OvY0YzaEeOfspFKg5o4YA"/>
</children>
<children xmi:type="notation:Node" xmi:id="_zdvNYI9AEeO9s7Q_fmy5EA" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//ActivityInstance/activityType"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_zdvNYY9AEeO9s7Q_fmy5EA"/>
</children>
<children xmi:type="notation:Node" xmi:id="_34ZZ0IzaEeOfspFKg5o4YA" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//ActivityInstance/instanceState"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_34ZZ0YzaEeOfspFKg5o4YA"/>
</children>
<children xmi:type="notation:Node" xmi:id="_10fpYI9AEeO9s7Q_fmy5EA" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//ActivityInstance/portData%20(input%2Foutput%2F...)"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_10fpYY9AEeO9s7Q_fmy5EA"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_taVFBYzFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_taVFBozFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_taVFB4zFEeO4Eau2KiDmqg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_taVsEIzFEeO4Eau2KiDmqg" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_taVsEYzFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_taVsEozFEeO4Eau2KiDmqg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_taVsE4zFEeO4Eau2KiDmqg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_taVFAYzFEeO4Eau2KiDmqg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//ActivityInstance"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_taVFAozFEeO4Eau2KiDmqg" x="330" y="455"/>
</children>
<children xmi:type="notation:Node" xmi:id="_SWGMMI9CEeO9s7Q_fmy5EA" type="1001">
<children xmi:type="notation:Node" xmi:id="_SWGzQI9CEeO9s7Q_fmy5EA" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_SWGzQY9CEeO9s7Q_fmy5EA" type="5001">
<styles xmi:type="notation:DrawerStyle" xmi:id="_SWGzQo9CEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_SWGzQ49CEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_SWGzRI9CEeO9s7Q_fmy5EA"/>
</children>
<children xmi:type="notation:Node" xmi:id="_SWHaUI9CEeO9s7Q_fmy5EA" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_SWHaUY9CEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_SWHaUo9CEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_SWHaU49CEeO9s7Q_fmy5EA"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_SWGMMY9CEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//WorkflowExecutionPlan"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_SWGMMo9CEeO9s7Q_fmy5EA" x="775" y="85"/>
</children>
<children xmi:type="notation:Node" xmi:id="_Wz8QgI9CEeO9s7Q_fmy5EA" type="1001">
<children xmi:type="notation:Node" xmi:id="_Wz83kI9CEeO9s7Q_fmy5EA" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_Wz83kY9CEeO9s7Q_fmy5EA" type="5001">
<children xmi:type="notation:Node" xmi:id="_Afs88I9DEeO9s7Q_fmy5EA" type="2001">
<element xmi:type="ecore:EAttribute" href="WorkflowStructure.ecore#//WEPnode/nodeType"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_Afs88Y9DEeO9s7Q_fmy5EA"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_Wz83ko9CEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_Wz83k49CEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_Wz83lI9CEeO9s7Q_fmy5EA"/>
</children>
<children xmi:type="notation:Node" xmi:id="_Wz83lY9CEeO9s7Q_fmy5EA" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_Wz83lo9CEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_Wz83l49CEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_Wz83mI9CEeO9s7Q_fmy5EA"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_Wz8QgY9CEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//WEPnode"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Wz8Qgo9CEeO9s7Q_fmy5EA" x="805" y="230"/>
</children>
<children xmi:type="notation:Node" xmi:id="_yByFYI9DEeO9s7Q_fmy5EA" type="1001">
<children xmi:type="notation:Node" xmi:id="_yByscI9DEeO9s7Q_fmy5EA" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_yByscY9DEeO9s7Q_fmy5EA" type="5001">
<styles xmi:type="notation:DrawerStyle" xmi:id="_yBysco9DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_yBysc49DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_yBysdI9DEeO9s7Q_fmy5EA"/>
</children>
<children xmi:type="notation:Node" xmi:id="_yBysdY9DEeO9s7Q_fmy5EA" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_yBysdo9DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_yBysd49DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_yByseI9DEeO9s7Q_fmy5EA"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_yByFYY9DEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//WEPnodeAtomic"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_yByFYo9DEeO9s7Q_fmy5EA" x="675" y="355"/>
</children>
<children xmi:type="notation:Node" xmi:id="_25fbMI9DEeO9s7Q_fmy5EA" type="1001">
<children xmi:type="notation:Node" xmi:id="_25gCQI9DEeO9s7Q_fmy5EA" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_25gCQY9DEeO9s7Q_fmy5EA" type="5001">
<styles xmi:type="notation:DrawerStyle" xmi:id="_25gCQo9DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_25gCQ49DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_25gCRI9DEeO9s7Q_fmy5EA"/>
</children>
<children xmi:type="notation:Node" xmi:id="_25gpUI9DEeO9s7Q_fmy5EA" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_25gpUY9DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_25gpUo9DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_25gpU49DEeO9s7Q_fmy5EA"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_25fbMY9DEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//WEPnodeHole"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_25fbMo9DEeO9s7Q_fmy5EA" x="805" y="355"/>
</children>
<children xmi:type="notation:Node" xmi:id="__OPfoI9DEeO9s7Q_fmy5EA" type="1001">
<children xmi:type="notation:Node" xmi:id="__OPfo49DEeO9s7Q_fmy5EA" type="4001"/>
<children xmi:type="notation:Node" xmi:id="__OPfpI9DEeO9s7Q_fmy5EA" type="5001">
<styles xmi:type="notation:DrawerStyle" xmi:id="__OPfpY9DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="__OPfpo9DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="__OPfp49DEeO9s7Q_fmy5EA"/>
</children>
<children xmi:type="notation:Node" xmi:id="__OPfqI9DEeO9s7Q_fmy5EA" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="__OPfqY9DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="__OPfqo9DEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="__OPfq49DEeO9s7Q_fmy5EA"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="__OPfoY9DEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//..."/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="__OPfoo9DEeO9s7Q_fmy5EA" x="920" y="355"/>
</children>
<children xmi:type="notation:Node" xmi:id="_YbM3UI9EEeO9s7Q_fmy5EA" type="1001">
<children xmi:type="notation:Node" xmi:id="_YbNeYI9EEeO9s7Q_fmy5EA" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_YbNeYY9EEeO9s7Q_fmy5EA" type="5001">
<styles xmi:type="notation:DrawerStyle" xmi:id="_YbNeYo9EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_YbNeY49EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_YbNeZI9EEeO9s7Q_fmy5EA"/>
</children>
<children xmi:type="notation:Node" xmi:id="_YbNeZY9EEeO9s7Q_fmy5EA" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_YbNeZo9EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_YbNeZ49EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_YbNeaI9EEeO9s7Q_fmy5EA"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_YbM3UY9EEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//ActivityContainerInstance"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_YbM3Uo9EEeO9s7Q_fmy5EA" x="185" y="625"/>
</children>
<children xmi:type="notation:Node" xmi:id="_aq7eQI9EEeO9s7Q_fmy5EA" type="1001">
<children xmi:type="notation:Node" xmi:id="_aq7eQ49EEeO9s7Q_fmy5EA" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_aq7eRI9EEeO9s7Q_fmy5EA" type="5001">
<styles xmi:type="notation:DrawerStyle" xmi:id="_aq7eRY9EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_aq8FUI9EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_aq8FUY9EEeO9s7Q_fmy5EA"/>
<layoutConstraint xmi:type="notation:Ratio" xmi:id="_gkQCEI9EEeO9s7Q_fmy5EA" value="0.3"/>
</children>
<children xmi:type="notation:Node" xmi:id="_aq8FUo9EEeO9s7Q_fmy5EA" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_aq8FU49EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_aq8FVI9EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_aq8FVY9EEeO9s7Q_fmy5EA"/>
<layoutConstraint xmi:type="notation:Ratio" xmi:id="_gkQCEY9EEeO9s7Q_fmy5EA" value="0.3"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_aq7eQY9EEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//....1"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_aq7eQo9EEeO9s7Q_fmy5EA" x="550" y="625"/>
</children>
<children xmi:type="notation:Node" xmi:id="_eS2nMI9EEeO9s7Q_fmy5EA" type="1001">
<children xmi:type="notation:Node" xmi:id="_eS2nM49EEeO9s7Q_fmy5EA" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_eS2nNI9EEeO9s7Q_fmy5EA" type="5001">
<styles xmi:type="notation:DrawerStyle" xmi:id="_eS2nNY9EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_eS2nNo9EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_eS2nN49EEeO9s7Q_fmy5EA"/>
<layoutConstraint xmi:type="notation:Ratio" xmi:id="_fogykI9EEeO9s7Q_fmy5EA" value="0.3"/>
</children>
<children xmi:type="notation:Node" xmi:id="_eS3OQI9EEeO9s7Q_fmy5EA" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_eS3OQY9EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_eS3OQo9EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_eS3OQ49EEeO9s7Q_fmy5EA"/>
<layoutConstraint xmi:type="notation:Ratio" xmi:id="_fogykY9EEeO9s7Q_fmy5EA" value="0.3"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_eS2nMY9EEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="WorkflowStructure.ecore#//ActivityAtomicInstance"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_eS2nMo9EEeO9s7Q_fmy5EA" x="375" y="625"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_52ilsI9EEeO9s7Q_fmy5EA" type="Note" fontName="Sans Serif" description="No Specialisations with this class because we want them all the same size to be able to store them in a static table." fillColor="13369343" transparency="0" lineColor="6737151" lineWidth="1">
<children xmi:type="notation:BasicDecorationNode" xmi:id="_52jMwI9EEeO9s7Q_fmy5EA" type="DiagramName">
<element xsi:nil="true"/>
</children>
<children xmi:type="notation:BasicDecorationNode" xmi:id="_52jMwY9EEeO9s7Q_fmy5EA" type="Description">
<element xsi:nil="true"/>
</children>
<styles xmi:type="notation:TextStyle" xmi:id="_52ilsY9EEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:LineTypeStyle" xmi:id="_52ilso9EEeO9s7Q_fmy5EA"/>
<element xsi:nil="true"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_52ils49EEeO9s7Q_fmy5EA" x="75" y="-15" width="276"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_cwlGsI9FEeO9s7Q_fmy5EA" type="Note" fontName="Sans Serif" description="No Specialisations with this class because it only acts as a container for the instances." fillColor="13369343" transparency="0" lineColor="6737151" lineWidth="1">
<children xmi:type="notation:BasicDecorationNode" xmi:id="_cwltwI9FEeO9s7Q_fmy5EA" type="DiagramName">
<element xsi:nil="true"/>
</children>
<children xmi:type="notation:BasicDecorationNode" xmi:id="_cwltwY9FEeO9s7Q_fmy5EA" type="Description">
<element xsi:nil="true"/>
</children>
<styles xmi:type="notation:TextStyle" xmi:id="_cwlGsY9FEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:LineTypeStyle" xmi:id="_cwlGso9FEeO9s7Q_fmy5EA"/>
<element xsi:nil="true"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_cwlGs49FEeO9s7Q_fmy5EA" x="100" y="345" width="187"/>
</children>
<styles xmi:type="notation:DiagramStyle" xmi:id="_mHvoMYzFEeO4Eau2KiDmqg"/>
<element xmi:type="ecore:EPackage" href="WorkflowStructure.ecore#/"/>
<edges xmi:type="notation:Edge" xmi:id="_JklUQIzGEeO4Eau2KiDmqg" type="3002" source="_nZ0UEIzFEeO4Eau2KiDmqg" target="_oihBgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_Jkl7UIzGEeO4Eau2KiDmqg" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_Jkl7UYzGEeO4Eau2KiDmqg" x="-32" y="-10"/>
</children>
<children xmi:type="notation:Node" xmi:id="_JkmiYIzGEeO4Eau2KiDmqg" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_JkmiYYzGEeO4Eau2KiDmqg" x="10" y="10"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_JklUQYzGEeO4Eau2KiDmqg" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_JklUQozGEeO4Eau2KiDmqg" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//WorkflowTemplate/activityTemplate"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_JklUQ4zGEeO4Eau2KiDmqg" points="[3, -2, -183, 0]$[184, -2, -2, 0]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_aqWW0I9BEeO9s7Q_fmy5EA" id="(0.9924812030075187,0.3055555555555556)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_aqWW0Y9BEeO9s7Q_fmy5EA" id="(0.024,0.6082474226804123)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_dxjj4IzGEeO4Eau2KiDmqg" type="3002" source="_qSg_gIzFEeO4Eau2KiDmqg" target="_nZ0UEIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_dxjj5IzGEeO4Eau2KiDmqg" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_dxjj5YzGEeO4Eau2KiDmqg" x="1" y="-51"/>
</children>
<children xmi:type="notation:Node" xmi:id="_dxkK8IzGEeO4Eau2KiDmqg" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_dxkK8YzGEeO4Eau2KiDmqg" x="2" y="15"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_dxjj4YzGEeO4Eau2KiDmqg" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_dxjj4ozGEeO4Eau2KiDmqg" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//Workflow/baseTemplate"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_dxjj44zGEeO4Eau2KiDmqg" points="[2, -31, -4, 130]$[11, -126, 5, 35]"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_2PWIcIzGEeO4Eau2KiDmqg" type="3002" source="_qSg_gIzFEeO4Eau2KiDmqg" target="_ryzGgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_2PWIdIzGEeO4Eau2KiDmqg" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_2PWIdYzGEeO4Eau2KiDmqg" x="-10" y="-10"/>
</children>
<children xmi:type="notation:Node" xmi:id="_2PWIdozGEeO4Eau2KiDmqg" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_2PWId4zGEeO4Eau2KiDmqg" x="10" y="10"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_2PWIcYzGEeO4Eau2KiDmqg" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_2PWIcozGEeO4Eau2KiDmqg" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//Workflow/activities"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_2PWIc4zGEeO4Eau2KiDmqg" points="[9, 0, -217, 11]$[222, -11, -4, 0]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_9jQ5oIzUEeOfspFKg5o4YA" id="(0.9603174603174603,0.375)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_9jRgsIzUEeOfspFKg5o4YA" id="(0.08823529411764706,0.40816326530612246)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_6aTtAIzGEeO4Eau2KiDmqg" type="3002" source="_ryzGgIzFEeO4Eau2KiDmqg" target="_qSg_gIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_6aTtBIzGEeO4Eau2KiDmqg" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_6aTtBYzGEeO4Eau2KiDmqg" x="2" y="-26"/>
</children>
<children xmi:type="notation:Node" xmi:id="_6aTtBozGEeO4Eau2KiDmqg" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_6aTtB4zGEeO4Eau2KiDmqg" x="-4" y="3"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_6aTtAYzGEeO4Eau2KiDmqg" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_6aTtAozGEeO4Eau2KiDmqg" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//Activity/workflow"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_6aTtA4zGEeO4Eau2KiDmqg" points="[-4, 0, 222, -11]$[-217, 11, 9, 0]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_Io7toI_iEeOcvcNiiq9Ujg" id="(0.08823529411764706,0.40816326530612246)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_Io7toY_iEeOcvcNiiq9Ujg" id="(0.9603174603174603,0.375)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_XSfQ4IzVEeOfspFKg5o4YA" type="3002" source="_ryzGgIzFEeO4Eau2KiDmqg" target="_taVFAIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_XSf38IzVEeOfspFKg5o4YA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_XSf38YzVEeOfspFKg5o4YA" x="-10" y="38"/>
</children>
<children xmi:type="notation:Node" xmi:id="_XSgfAIzVEeOfspFKg5o4YA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_XSgfAYzVEeOfspFKg5o4YA" x="5" y="17"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_XSfQ4YzVEeOfspFKg5o4YA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_XSfQ4ozVEeOfspFKg5o4YA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//Activity/instances"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_XSfQ44zVEeOfspFKg5o4YA" points="[8, 32, 2, -71]$[8, 99, 2, -4]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_50K4EIzcEeOfspFKg5o4YA" id="(0.4406779661016949,0.8024691358024691)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XSiUMIzVEeOfspFKg5o4YA" id="(0.5087719298245614,0.041379310344827586)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_iAVToIzVEeOfspFKg5o4YA" type="3002" source="_ryzGgIzFEeO4Eau2KiDmqg" target="_oihBgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_iAV6sIzVEeOfspFKg5o4YA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_iAV6sYzVEeOfspFKg5o4YA" x="-5" y="-47"/>
</children>
<children xmi:type="notation:Node" xmi:id="_iAV6sozVEeOfspFKg5o4YA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_iAV6s4zVEeOfspFKg5o4YA" x="-5" y="8"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_iAVToYzVEeOfspFKg5o4YA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_iAVToozVEeOfspFKg5o4YA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//Activity/baseTemplate"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_iAVTo4zVEeOfspFKg5o4YA" points="[9, -10, 26, 127]$[45, -132, 62, 5]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_iAXv4IzVEeOfspFKg5o4YA" id="(0.4576271186440678,0.16923076923076924)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_hP9icIzcEeOfspFKg5o4YA" type="3002" source="_oihBgIzFEeO4Eau2KiDmqg" target="_nZ0UEIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_hP-JgIzcEeOfspFKg5o4YA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_hP-JgYzcEeOfspFKg5o4YA" x="-26" y="-28"/>
</children>
<children xmi:type="notation:Node" xmi:id="_hP-JgozcEeOfspFKg5o4YA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_hP-Jg4zcEeOfspFKg5o4YA" x="10" y="10"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_hP9icYzcEeOfspFKg5o4YA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_hP9icozcEeOfspFKg5o4YA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//ActivityTemplate/workflowTemplate"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_hP9ic4zcEeOfspFKg5o4YA" points="[-2, 0, 184, -2]$[-183, 0, 3, -2]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_HYTMMI_iEeOcvcNiiq9Ujg" id="(0.024,0.6082474226804123)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_HYTMMY_iEeOcvcNiiq9Ujg" id="(0.9924812030075187,0.3055555555555556)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_2DGaMIzcEeOfspFKg5o4YA" type="3002" source="_taVFAIzFEeO4Eau2KiDmqg" target="_ryzGgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_2DGaNIzcEeOfspFKg5o4YA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_2DGaNYzcEeOfspFKg5o4YA" x="16" y="-45"/>
</children>
<children xmi:type="notation:Node" xmi:id="_2DGaNozcEeOfspFKg5o4YA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_2DGaN4zcEeOfspFKg5o4YA" x="-5" y="9"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_2DGaMYzcEeOfspFKg5o4YA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_2DGaMozcEeOfspFKg5o4YA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//ActivityInstance/baseActivity"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_2DGaM4zcEeOfspFKg5o4YA" points="[2, -4, 8, 99]$[2, -71, 8, 32]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_KSmaII_iEeOcvcNiiq9Ujg" id="(0.5087719298245614,0.041379310344827586)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_KSmaIY_iEeOcvcNiiq9Ujg" id="(0.4406779661016949,0.8024691358024691)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_lZLqUI88EeO9s7Q_fmy5EA" type="3002" source="_oihBgIzFEeO4Eau2KiDmqg" target="_oihBgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_lZM4cI88EeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_lZNfgI88EeO9s7Q_fmy5EA" x="-3" y="8"/>
</children>
<children xmi:type="notation:Node" xmi:id="_lZNfgY88EeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_lZNfgo88EeO9s7Q_fmy5EA" x="13" y="-12"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_lZLqUY88EeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_lZLqUo88EeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//ActivityTemplate/successor"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_lZLqU488EeO9s7Q_fmy5EA" points="[5, 14, -9, 27]$[5, 51, -9, 64]$[74, 51, 60, 64]$[74, -7, 60, 6]$[26, -7, 12, 6]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_BJiL0I89EeO9s7Q_fmy5EA" id="(0.8,0.8827586206896552)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_BJiL0Y89EeO9s7Q_fmy5EA" id="(0.9142857142857143,0.7586206896551724)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_olZusI88EeO9s7Q_fmy5EA" type="3002" source="_oihBgIzFEeO4Eau2KiDmqg" target="_oihBgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_olZutI88EeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_olZutY88EeO9s7Q_fmy5EA" x="-14" y="36"/>
</children>
<children xmi:type="notation:Node" xmi:id="_olaVwI88EeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_olaVwY88EeO9s7Q_fmy5EA" x="17" y="16"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_olZusY88EeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_olZuso88EeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//ActivityTemplate/predecessor"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_olZus488EeO9s7Q_fmy5EA" points="[12, 6, 26, -7]$[60, 6, 74, -7]$[60, 64, 74, 51]$[-9, 64, 5, 51]$[-9, 27, 5, 14]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_olbj4I88EeO9s7Q_fmy5EA" id="(0.9142857142857143,0.7586206896551724)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_olbj4Y88EeO9s7Q_fmy5EA" id="(0.8,0.8827586206896552)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_C76IYI89EeO9s7Q_fmy5EA" type="3002" source="_oihBgIzFEeO4Eau2KiDmqg" target="_oihBgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_C76IZI89EeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_C76IZY89EeO9s7Q_fmy5EA" x="19" y="24"/>
</children>
<children xmi:type="notation:Node" xmi:id="_C76IZo89EeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_C76IZ489EeO9s7Q_fmy5EA" x="18" y="-17"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_C76IYY89EeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_C76IYo89EeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//ActivityTemplate/parent"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_C76IY489EeO9s7Q_fmy5EA" points="[19, 1, 33, 22]$[63, 1, 77, 22]$[63, -57, 77, -36]$[-9, -57, 5, -36]$[-9, -21, 5, 0]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_Z-63YI9FEeO9s7Q_fmy5EA" id="(0.8473282442748091,0.23008849557522124)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_Z-63YY9FEeO9s7Q_fmy5EA" id="(0.732824427480916,0.008849557522123894)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_F_bjwI89EeO9s7Q_fmy5EA" type="3002" source="_oihBgIzFEeO4Eau2KiDmqg" target="_oihBgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_F_cK0I89EeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_F_cK0Y89EeO9s7Q_fmy5EA" y="-12"/>
</children>
<children xmi:type="notation:Node" xmi:id="_F_cK0o89EeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_F_cK0489EeO9s7Q_fmy5EA" x="10" y="10"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_F_bjwY89EeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_F_bjwo89EeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//ActivityTemplate/children"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_F_bjw489EeO9s7Q_fmy5EA" points="[5, 0, -9, -21]$[5, -36, -9, -57]$[77, -36, 63, -57]$[77, 22, 63, 1]$[33, 22, 19, 1]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_F_dY8I89EeO9s7Q_fmy5EA" id="(0.732824427480916,0.008849557522123894)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_F_dY8Y89EeO9s7Q_fmy5EA" id="(0.8473282442748091,0.23008849557522124)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_kOtl0I89EeO9s7Q_fmy5EA" type="3002" source="_ryzGgIzFEeO4Eau2KiDmqg" target="_ryzGgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_kOuM4I89EeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_kOuM4Y89EeO9s7Q_fmy5EA" x="-49" y="-19"/>
</children>
<children xmi:type="notation:Node" xmi:id="_kOuM4o89EeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_kOuM4489EeO9s7Q_fmy5EA" x="10" y="-11"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_kOtl0Y89EeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_kOtl0o89EeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//Activity/successor"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_kOtl0489EeO9s7Q_fmy5EA" points="[-8, 2, -25, 17]$[-8, 35, -25, 50]$[68, 35, 51, 50]$[68, -18, 51, -3]$[24, -18, 7, -3]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_MMJvQI8-EeO9s7Q_fmy5EA" id="(0.7964071856287425,0.9734513274336283)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_MMJvQY8-EeO9s7Q_fmy5EA" id="(0.9461077844311377,0.7345132743362832)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_mDD4UI89EeO9s7Q_fmy5EA" type="3002" source="_ryzGgIzFEeO4Eau2KiDmqg" target="_ryzGgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_mDEfYI89EeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_mDEfYY89EeO9s7Q_fmy5EA" x="-40" y="-13"/>
</children>
<children xmi:type="notation:Node" xmi:id="_mDEfYo89EeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_mDEfY489EeO9s7Q_fmy5EA" x="-14" y="18"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_mDD4UY89EeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_mDD4Uo89EeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//Activity/predecessor"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_mDD4U489EeO9s7Q_fmy5EA" points="[7, -3, 24, -18]$[51, -3, 68, -18]$[51, 50, 68, 35]$[-25, 50, -8, 35]$[-25, 17, -8, 2]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_mDFtgI89EeO9s7Q_fmy5EA" id="(0.9461077844311377,0.7345132743362832)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_mDFtgY89EeO9s7Q_fmy5EA" id="(0.7964071856287425,0.9734513274336283)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_yUemoI89EeO9s7Q_fmy5EA" type="3002" source="_ryzGgIzFEeO4Eau2KiDmqg" target="_ryzGgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_yUfNsI89EeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_yUfNsY89EeO9s7Q_fmy5EA" x="-17" y="13"/>
</children>
<children xmi:type="notation:Node" xmi:id="_yUfNso89EeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_yUfNs489EeO9s7Q_fmy5EA" x="-13" y="-12"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_yUemoY89EeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_yUemoo89EeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//Activity/parent"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_yUemo489EeO9s7Q_fmy5EA" points="[3, -2, 31, 20]$[45, -2, 73, 20]$[45, -42, 73, -20]$[-18, -42, 10, -20]$[-18, -23, 10, -1]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_SLr94I9AEeO9s7Q_fmy5EA" id="(0.9760479041916168,0.2920353982300885)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_SLr94Y9AEeO9s7Q_fmy5EA" id="(0.7365269461077845,0.017699115044247787)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_zWjHoI89EeO9s7Q_fmy5EA" type="3002" source="_ryzGgIzFEeO4Eau2KiDmqg" target="_ryzGgIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_zWjHpI89EeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_zWjHpY89EeO9s7Q_fmy5EA" x="-2" y="-10"/>
</children>
<children xmi:type="notation:Node" xmi:id="_zWjusI89EeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_zWjusY89EeO9s7Q_fmy5EA" x="4" y="11"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_zWjHoY89EeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_zWjHoo89EeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//Activity/children"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_zWjHo489EeO9s7Q_fmy5EA" points="[10, -1, -18, -23]$[10, -20, -18, -42]$[73, -20, 45, -42]$[73, 20, 45, -2]$[31, 20, 3, -2]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_zWk80I89EeO9s7Q_fmy5EA" id="(0.7365269461077845,0.017699115044247787)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_1QnnoI89EeO9s7Q_fmy5EA" id="(0.9760479041916168,0.2920353982300885)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="__Ov9UI9AEeO9s7Q_fmy5EA" type="3002" source="_taVFAIzFEeO4Eau2KiDmqg" target="_taVFAIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="__Ov9VI9AEeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="__Ov9VY9AEeO9s7Q_fmy5EA" x="-11" y="-8"/>
</children>
<children xmi:type="notation:Node" xmi:id="__Ov9Vo9AEeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="__Ov9V49AEeO9s7Q_fmy5EA" x="8" y="7"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="__Ov9UY9AEeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="__Ov9Uo9AEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//ActivityInstance/successor"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="__Ov9U49AEeO9s7Q_fmy5EA" points="[0, 8, 26, 31]$[0, 26, 26, 49]$[-56, 26, -30, 49]$[-56, -17, -30, 6]$[-26, -17, 0, 6]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_e32AEI9DEeO9s7Q_fmy5EA" id="(0.1377551020408163,0.9175257731958762)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_e32AEY9DEeO9s7Q_fmy5EA" id="(0.00510204081632653,0.6804123711340206)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_BFh4wI9BEeO9s7Q_fmy5EA" type="3002" source="_taVFAIzFEeO4Eau2KiDmqg" target="_taVFAIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_BFh4xI9BEeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_BFh4xY9BEeO9s7Q_fmy5EA" x="-18" y="9"/>
</children>
<children xmi:type="notation:Node" xmi:id="_BFh4xo9BEeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_BFh4x49BEeO9s7Q_fmy5EA" x="-11" y="-11"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_BFh4wY9BEeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_BFh4wo9BEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//ActivityInstance/predecessor"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_BFh4w49BEeO9s7Q_fmy5EA" points="[0, 6, -26, -17]$[-30, 6, -56, -17]$[-30, 49, -56, 26]$[26, 49, 0, 26]$[26, 31, 0, 8]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_BFjG4I9BEeO9s7Q_fmy5EA" id="(0.00510204081632653,0.6804123711340206)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_BFjG4Y9BEeO9s7Q_fmy5EA" id="(0.1377551020408163,0.9175257731958762)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_JICWoI9BEeO9s7Q_fmy5EA" type="3002" source="_taVFAIzFEeO4Eau2KiDmqg" target="_taVFAIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_JICWpI9BEeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_JICWpY9BEeO9s7Q_fmy5EA" x="-18" y="-9"/>
</children>
<children xmi:type="notation:Node" xmi:id="_JIC9sI9BEeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_JIC9sY9BEeO9s7Q_fmy5EA" x="-12" y="16"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_JICWoY9BEeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_JICWoo9BEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//ActivityInstance/parent"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_JICWo49BEeO9s7Q_fmy5EA" points="[-4, -6, -17, 19]$[-44, -6, -57, 19]$[-44, -51, -57, -26]$[10, -51, -3, -26]$[10, -27, -3, -2]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_Vo9Ooo9DEeO9s7Q_fmy5EA" id="(0.025510204081632654,0.28865979381443296)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_Vo9Oo49DEeO9s7Q_fmy5EA" id="(0.09183673469387756,0.030927835051546393)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_J9mssI9BEeO9s7Q_fmy5EA" type="3002" source="_taVFAIzFEeO4Eau2KiDmqg" target="_taVFAIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_J9mstI9BEeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_J9mstY9BEeO9s7Q_fmy5EA" x="-1" y="11"/>
</children>
<children xmi:type="notation:Node" xmi:id="_J9nTwI9BEeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_J9nTwY9BEeO9s7Q_fmy5EA" x="10" y="-9"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_J9mssY9BEeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_J9msso9BEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//ActivityInstance/children"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_J9mss49BEeO9s7Q_fmy5EA" points="[-3, -2, 10, -27]$[-3, -26, 10, -51]$[-57, -26, -44, -51]$[-57, 19, -44, -6]$[-17, 19, -4, -6]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_LYn5MI9BEeO9s7Q_fmy5EA" id="(0.09183673469387756,0.030927835051546393)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_LYn5MY9BEeO9s7Q_fmy5EA" id="(0.025510204081632654,0.28865979381443296)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_ZBY_gI9CEeO9s7Q_fmy5EA" type="3002" source="_SWGMMI9CEeO9s7Q_fmy5EA" target="_Wz8QgI9CEeO9s7Q_fmy5EA">
<children xmi:type="notation:Node" xmi:id="_ZBZmkI9CEeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_ZBZmkY9CEeO9s7Q_fmy5EA" x="-12" y="26"/>
</children>
<children xmi:type="notation:Node" xmi:id="_ZBZmko9CEeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_ZBZmk49CEeO9s7Q_fmy5EA" x="3" y="19"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_ZBY_gY9CEeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_ZBY_go9CEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//WorkflowExecutionPlan/nodes"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZBY_g49CEeO9s7Q_fmy5EA" points="[1, 20, -13, -140]$[15, 165, 1, 5]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_LpMZoI_iEeOcvcNiiq9Ujg" id="(0.4695121951219512,0.8571428571428571)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_LpMZoY_iEeOcvcNiiq9Ujg" id="(0.5,0.8809523809523809)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_e3X7cI9CEeO9s7Q_fmy5EA" type="3002" source="_Wz8QgI9CEeO9s7Q_fmy5EA" target="_SWGMMI9CEeO9s7Q_fmy5EA">
<children xmi:type="notation:Node" xmi:id="_e3X7dI9CEeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_e3X7dY9CEeO9s7Q_fmy5EA" x="13" y="-54"/>
</children>
<children xmi:type="notation:Node" xmi:id="_e3X7do9CEeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_e3X7d49CEeO9s7Q_fmy5EA" x="-4" y="7"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_e3X7cY9CEeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_e3X7co9CEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//WEPnode/executionPlan"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_e3X7c49CEeO9s7Q_fmy5EA" points="[1, 5, 15, 165]$[-13, -140, 1, 20]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_Os9FkI_iEeOcvcNiiq9Ujg" id="(0.5,0.8809523809523809)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_Os9FkY_iEeOcvcNiiq9Ujg" id="(0.4695121951219512,0.8571428571428571)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_mKNP4I9CEeO9s7Q_fmy5EA" type="3002" source="_Wz8QgI9CEeO9s7Q_fmy5EA" target="_Wz8QgI9CEeO9s7Q_fmy5EA">
<children xmi:type="notation:Node" xmi:id="_mKNP5I9CEeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_mKNP5Y9CEeO9s7Q_fmy5EA" x="-10" y="-10"/>
</children>
<children xmi:type="notation:Node" xmi:id="_mKNP5o9CEeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_mKNP549CEeO9s7Q_fmy5EA" x="10" y="10"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_mKNP4Y9CEeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_mKNP4o9CEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//WEPnode/successors"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_mKNP449CEeO9s7Q_fmy5EA" points="[9, -2, 35, -20]$[9, -37, 35, -55]$[79, -37, 105, -55]$[79, 18, 105, 0]$[24, 18, 50, 0]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_s2Q4Mo9CEeO9s7Q_fmy5EA" id="(0.7647058823529411,0.07142857142857142)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_s2Q4M49CEeO9s7Q_fmy5EA" id="(0.5,0.5)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_oZRIcI9CEeO9s7Q_fmy5EA" type="3002" source="_Wz8QgI9CEeO9s7Q_fmy5EA" target="_Wz8QgI9CEeO9s7Q_fmy5EA">
<children xmi:type="notation:Node" xmi:id="_oZRIdI9CEeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_oZRvgI9CEeO9s7Q_fmy5EA" x="-16" y="-38"/>
</children>
<children xmi:type="notation:Node" xmi:id="_oZRvgY9CEeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_oZRvgo9CEeO9s7Q_fmy5EA" x="10" y="10"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_oZRIcY9CEeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_oZRIco9CEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//WEPnode/predecessors"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_oZRIc49CEeO9s7Q_fmy5EA" points="[50, 0, 24, 18]$[105, 0, 79, 18]$[105, -55, 79, -37]$[35, -55, 9, -37]$[35, -20, 9, -2]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_puKe0I9CEeO9s7Q_fmy5EA" id="(0.5,0.5)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_puKe0Y9CEeO9s7Q_fmy5EA" id="(0.7647058823529411,0.07142857142857142)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_ysj9MI9CEeO9s7Q_fmy5EA" type="3002" source="_Wz8QgI9CEeO9s7Q_fmy5EA" target="_taVFAIzFEeO4Eau2KiDmqg">
<children xmi:type="notation:Node" xmi:id="_yskkQI9CEeO9s7Q_fmy5EA" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_yskkQY9CEeO9s7Q_fmy5EA" x="6" y="9"/>
</children>
<children xmi:type="notation:Node" xmi:id="_yskkQo9CEeO9s7Q_fmy5EA" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_yskkQ49CEeO9s7Q_fmy5EA" x="56" y="-12"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_ysj9MY9CEeO9s7Q_fmy5EA" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_ysj9Mo9CEeO9s7Q_fmy5EA" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="WorkflowStructure.ecore#//WEPnode/associated%20Activity"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ysj9M49CEeO9s7Q_fmy5EA" points="[-12, 6, 285, -251]$[-157, 6, 140, -251]$[-157, 257, 140, 0]$[-293, 257, 4, 0]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_yslyYI9CEeO9s7Q_fmy5EA" id="(0.12745098039215685,0.40476190476190477)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_0Br9EI9CEeO9s7Q_fmy5EA" id="(0.9795918367346939,0.5463917525773195)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_G68FkI9EEeO9s7Q_fmy5EA" type="3003" source="_yByFYI9DEeO9s7Q_fmy5EA" target="_Wz8QgI9CEeO9s7Q_fmy5EA">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_G68FkY9EEeO9s7Q_fmy5EA" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_G68Fko9EEeO9s7Q_fmy5EA" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_G68Fk49EEeO9s7Q_fmy5EA" points="[29, -8, -112, 102]$[29, -33, -112, 77]$[146, -33, 5, 77]$[146, -86, 5, 24]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_LrBJYI9EEeO9s7Q_fmy5EA" id="(0.32,0.21428571428571427)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_Ha1GkI9EEeO9s7Q_fmy5EA" type="3003" source="_25fbMI9DEeO9s7Q_fmy5EA" target="_Wz8QgI9CEeO9s7Q_fmy5EA">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_Ha1GkY9EEeO9s7Q_fmy5EA" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_Ha1Gko9EEeO9s7Q_fmy5EA" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Ha1Gk49EEeO9s7Q_fmy5EA" points="[1, -20, 4, 102]$[1, -98, 4, 24]"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_H0YPAI9EEeO9s7Q_fmy5EA" type="3003" source="__OPfoI9DEeO9s7Q_fmy5EA" target="_Wz8QgI9CEeO9s7Q_fmy5EA">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_H0YPAY9EEeO9s7Q_fmy5EA" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_H0YPAo9EEeO9s7Q_fmy5EA" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_H0YPA49EEeO9s7Q_fmy5EA" points="[-64, -16, 116, 88]$[-64, -41, 116, 63]$[-153, -41, 27, 63]$[-153, -94, 27, 10]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NdcwUI9EEeO9s7Q_fmy5EA" id="(0.9313725490196079,0.40476190476190477)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_O1ao0I9EEeO9s7Q_fmy5EA" id="(0.28431372549019607,0.7959183673469388)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_pKZ_kI9EEeO9s7Q_fmy5EA" type="3003" source="_YbM3UI9EEeO9s7Q_fmy5EA" target="_taVFAIzFEeO4Eau2KiDmqg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_pKZ_kY9EEeO9s7Q_fmy5EA" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_pKZ_ko9EEeO9s7Q_fmy5EA" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_pKZ_k49EEeO9s7Q_fmy5EA" points="[53, -15, -164, 123]$[53, -45, -164, 93]$[240, -45, 23, 93]$[240, -90, 23, 48]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_pKamoI9EEeO9s7Q_fmy5EA" id="(0.14207650273224043,0.38095238095238093)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_pdPcAI9EEeO9s7Q_fmy5EA" type="3003" source="_eS2nMI9EEeO9s7Q_fmy5EA" target="_taVFAIzFEeO4Eau2KiDmqg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_pdPcAY9EEeO9s7Q_fmy5EA" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_pdPcAo9EEeO9s7Q_fmy5EA" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_pdPcA49EEeO9s7Q_fmy5EA" points="[-6, -20, 24, 123]$[-37, -95, -7, 48]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ssDhYI9EEeO9s7Q_fmy5EA" id="(0.46987951807228917,0.14285714285714285)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ra40cI9EEeO9s7Q_fmy5EA" id="(0.6224489795918368,0.9484536082474226)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_p1DfEI9EEeO9s7Q_fmy5EA" type="3003" source="_aq7eQI9EEeO9s7Q_fmy5EA" target="_taVFAIzFEeO4Eau2KiDmqg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_p1DfEY9EEeO9s7Q_fmy5EA" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_p1DfEo9EEeO9s7Q_fmy5EA" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_p1DfE49EEeO9s7Q_fmy5EA" points="[-13, -14, 88, 97]$[-13, -49, 88, 62]$[-126, -49, -25, 62]$[-126, -89, -25, 22]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_p1EtMI9EEeO9s7Q_fmy5EA" id="(0.8725490196078431,0.30952380952380953)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_p1EtMY9EEeO9s7Q_fmy5EA" id="(0.5918367346938775,0.8247422680412371)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_KttXII9FEeO9s7Q_fmy5EA" type="NoteAttachment" source="_52ilsI9EEeO9s7Q_fmy5EA" target="_oihBgIzFEeO4Eau2KiDmqg" lineWidth="1">
<styles xmi:type="notation:ArrowStyle" xmi:id="_KttXIY9FEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:LineTypeStyle" xmi:id="_KttXIo9FEeO9s7Q_fmy5EA"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_KttXI49FEeO9s7Q_fmy5EA" points="[-1, -1, -33, -66]$[33, 47, 1, -18]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_KtulQI9FEeO9s7Q_fmy5EA" id="(0.21739130434782608,1.0)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_KtulQY9FEeO9s7Q_fmy5EA" id="(0.224,0.1958762886597938)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_iEJ5II9FEeO9s7Q_fmy5EA" type="NoteAttachment" source="_ryzGgIzFEeO4Eau2KiDmqg" target="_cwlGsI9FEeO9s7Q_fmy5EA" lineWidth="1">
<styles xmi:type="notation:ArrowStyle" xmi:id="_iEJ5IY9FEeO9s7Q_fmy5EA"/>
<styles xmi:type="notation:LineTypeStyle" xmi:id="_iEJ5Io9FEeO9s7Q_fmy5EA"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_iEJ5I49FEeO9s7Q_fmy5EA" points="[-58, -1, 83, -52]$[-151, 54, -10, 3]"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_iELHQI9FEeO9s7Q_fmy5EA" id="(1.0,0.0)"/>
</edges>
</notation:Diagram>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

+74
View File
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="classdiagram" nsURI="http://classdiagram/1.0" nsPrefix="classdiagram">
<eClassifiers xsi:type="ecore:EClass" name="Workflow">
<eStructuralFeatures xsi:type="ecore:EReference" name="activities" lowerBound="1"
upperBound="-1" eType="#//WorkflowActivity" eOpposite="#//WorkflowActivity/workflow"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="status"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="WorkflowActivity">
<eStructuralFeatures xsi:type="ecore:EReference" name="workflow" lowerBound="1"
eType="#//Workflow" eOpposite="#//Workflow/activities"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="Status"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="successor" upperBound="-1"
eType="#//WorkflowActivity" eOpposite="#//WorkflowActivity/predecessor"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="predecessor" upperBound="-1"
eType="#//WorkflowActivity" eOpposite="#//WorkflowActivity/successor"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="InputPorts"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="OutputPorts"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="Name"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EDataType" name="LightWeightDataStructure" instanceTypeName="sdsdsdsd"/>
<eClassifiers xsi:type="ecore:EClass" name="AtomicActivity" eSuperTypes="#//WorkflowActivity">
<eOperations name="InputHook"/>
<eOperations name="ExecutionHook"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="ActivityType"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="BlockScope" eSuperTypes="#//WorkflowActivity">
<eOperations name="InputHook"/>
<eOperations name="OutputHook"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="IfActivity" eSuperTypes="#//WorkflowActivity">
<eOperations name="InputHook"/>
<eOperations name="BranchHook"/>
<eOperations name="OutputHook"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="Conditions"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="Branches"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="WhileActivity" eSuperTypes="#//WorkflowActivity">
<eOperations name="InputHook"/>
<eOperations name="ConditionHook"/>
<eOperations name="OutputHook"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="LoopPorts"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="UnionPorts"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="Condition"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ForActivity" eSuperTypes="#//WorkflowActivity">
<eOperations name="InputHook"/>
<eOperations name="counterHook"/>
<eOperations name="OutputHook"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="LoopPorts"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="UnionPorts"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="LoopCounter"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ForEachActivity" eSuperTypes="#//WorkflowActivity">
<eOperations name="InputHook"/>
<eOperations name="CounterHook"/>
<eOperations name="OutputHook"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="LoopPorts"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="UnionPorts"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="LoopElementPorts"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="pForActivity" eSuperTypes="#//WorkflowActivity">
<eOperations name="InputHook"/>
<eOperations name="CounterHook"/>
<eOperations name="OutputHook"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="LoopCounter"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="pForEachActivity" eSuperTypes="#//WorkflowActivity">
<eOperations name="InputHook"/>
<eOperations name="CounterHook"/>
<eOperations name="OutputHook"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="LoopElementPorts"/>
</eClassifiers>
</ecore:EPackage>
+443
View File
@@ -0,0 +1,443 @@
<?xml version="1.0" encoding="UTF-8"?>
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmi:id="_u4HeAH3lEeOAl9i6j131Rg" type="EcoreTools" name="classdiagram" measurementUnit="Pixel">
<children xmi:type="notation:Node" xmi:id="_-Nj-AH3lEeOAl9i6j131Rg" type="1001">
<children xmi:type="notation:Node" xmi:id="_-NlMIH3lEeOAl9i6j131Rg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_-NlzMH3lEeOAl9i6j131Rg" type="5001">
<children xmi:type="notation:Node" xmi:id="_M9FCQH3tEeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//Workflow/status"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_M9FCQX3tEeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_-NmaQH3lEeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_-NmaQX3lEeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_-NmaQn3lEeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_-NmaQ33lEeOAl9i6j131Rg" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_-NmaRH3lEeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_-NmaRX3lEeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_-NmaRn3lEeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_-Nj-AX3lEeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="classdiagram.ecore#//Workflow"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_-Nj-An3lEeOAl9i6j131Rg" x="70" y="75"/>
</children>
<children xmi:type="notation:Node" xmi:id="_Aahk0H3mEeOAl9i6j131Rg" type="1001">
<children xmi:type="notation:Node" xmi:id="_AaiL4n3mEeOAl9i6j131Rg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_AaiL433mEeOAl9i6j131Rg" type="5001">
<children xmi:type="notation:Node" xmi:id="_OPBLQH3tEeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//WorkflowActivity/Status"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_OPBLQX3tEeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_j-SsYH3zEeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//WorkflowActivity/InputPorts"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_j-SsYX3zEeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_krhl0H3zEeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//WorkflowActivity/OutputPorts"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_krhl0X3zEeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_onvjwH3zEeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//WorkflowActivity/Name"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_onvjwX3zEeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_AaiL5H3mEeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_AaiL5X3mEeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_AaiL5n3mEeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_Aaiy8H3mEeOAl9i6j131Rg" type="5002">
<styles xmi:type="notation:DrawerStyle" xmi:id="_Aaiy8X3mEeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_Aaiy8n3mEeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_Aaiy833mEeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_AaiL4H3mEeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="classdiagram.ecore#//WorkflowActivity"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_AaiL4X3mEeOAl9i6j131Rg" x="300" y="100"/>
</children>
<children xmi:type="notation:Node" xmi:id="_w9gU0H3zEeOAl9i6j131Rg" type="1001">
<children xmi:type="notation:Node" xmi:id="_w9g74H3zEeOAl9i6j131Rg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_w9g74X3zEeOAl9i6j131Rg" type="5001">
<children xmi:type="notation:Node" xmi:id="_zdj2wH3zEeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//AtomicActivity/ActivityType"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_zdj2wX3zEeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_w9g74n3zEeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_w9g7433zEeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_w9g75H3zEeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_w9g75X3zEeOAl9i6j131Rg" type="5002">
<children xmi:type="notation:Node" xmi:id="_1EVnUH3zEeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//AtomicActivity/InputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_1EVnUX3zEeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_36vzwH3zEeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//AtomicActivity/ExecutionHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_36vzwX3zEeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_w9g75n3zEeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_w9g7533zEeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_w9g76H3zEeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_w9gU0X3zEeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="classdiagram.ecore#//AtomicActivity"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_w9gU0n3zEeOAl9i6j131Rg" x="10" y="310"/>
</children>
<children xmi:type="notation:Node" xmi:id="_71iOUH3zEeOAl9i6j131Rg" type="1001">
<children xmi:type="notation:Node" xmi:id="_71i1YH3zEeOAl9i6j131Rg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_71i1YX3zEeOAl9i6j131Rg" type="5001">
<styles xmi:type="notation:DrawerStyle" xmi:id="_71i1Yn3zEeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_71i1Y33zEeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_71i1ZH3zEeOAl9i6j131Rg"/>
<layoutConstraint xmi:type="notation:Ratio" xmi:id="_8t-5QH3zEeOAl9i6j131Rg" value="0.3"/>
</children>
<children xmi:type="notation:Node" xmi:id="_71i1ZX3zEeOAl9i6j131Rg" type="5002">
<children xmi:type="notation:Node" xmi:id="_-ZoiwH3zEeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//BlockScope/InputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_-ZoiwX3zEeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_CKygMH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//BlockScope/OutputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_CKygMX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_71i1Zn3zEeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_71i1Z33zEeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_71i1aH3zEeOAl9i6j131Rg"/>
<layoutConstraint xmi:type="notation:Ratio" xmi:id="_8t-5QX3zEeOAl9i6j131Rg" value="0.3"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_71iOUX3zEeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="classdiagram.ecore#//BlockScope"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_71iOUn3zEeOAl9i6j131Rg" x="165" y="310"/>
</children>
<children xmi:type="notation:Node" xmi:id="_FQVU0H30EeOAl9i6j131Rg" type="1001">
<children xmi:type="notation:Node" xmi:id="_FQV74H30EeOAl9i6j131Rg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_FQV74X30EeOAl9i6j131Rg" type="5001">
<children xmi:type="notation:Node" xmi:id="_GtKfMH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//IfActivity/Conditions"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_GtKfMX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_IuGcMH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//IfActivity/Branches"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_IuGcMX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_FQV74n30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_FQV74330EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_FQV75H30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_FQV75X30EeOAl9i6j131Rg" type="5002">
<children xmi:type="notation:Node" xmi:id="_Kbz7MH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//IfActivity/InputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_Kbz7MX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_LjmpsH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//IfActivity/BranchHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_LjmpsX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_NSAFMH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//IfActivity/OutputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_NSAFMX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_FQV75n30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_FQV75330EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_FQV76H30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_FQVU0X30EeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="classdiagram.ecore#//IfActivity"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_FQVU0n30EeOAl9i6j131Rg" x="305" y="310"/>
</children>
<children xmi:type="notation:Node" xmi:id="_QP6AwH30EeOAl9i6j131Rg" type="1001">
<children xmi:type="notation:Node" xmi:id="_QP6Aw330EeOAl9i6j131Rg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_QP6AxH30EeOAl9i6j131Rg" type="5001">
<children xmi:type="notation:Node" xmi:id="_SOsosH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//WhileActivity/LoopPorts"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_SOsosX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_TIcUIH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//WhileActivity/UnionPorts"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_TIcUIX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_UFLpMH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//WhileActivity/Condition"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_UFLpMX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_QP6AxX30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_QP6Axn30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_QP6Ax330EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_QP6n0H30EeOAl9i6j131Rg" type="5002">
<children xmi:type="notation:Node" xmi:id="_V2P-MH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//WhileActivity/InputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_V2P-MX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_WjCLsH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//WhileActivity/ConditionHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_WjCLsX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_aJWyIH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//WhileActivity/OutputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_aJWyIX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_QP6n0X30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_QP6n0n30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_QP6n0330EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_QP6AwX30EeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="classdiagram.ecore#//WhileActivity"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_QP6Awn30EeOAl9i6j131Rg" x="455" y="310"/>
</children>
<children xmi:type="notation:Node" xmi:id="_cIexQH30EeOAl9i6j131Rg" type="1001">
<children xmi:type="notation:Node" xmi:id="_cIexQ330EeOAl9i6j131Rg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_cIexRH30EeOAl9i6j131Rg" type="5001">
<children xmi:type="notation:Node" xmi:id="_dpDMIH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//ForActivity/LoopPorts"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_dpDMIX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_e7XvoH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//ForActivity/UnionPorts"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_e7XvoX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_ftM1MH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//ForActivity/LoopCounter"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_ftM1MX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_cIexRX30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_cIexRn30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_cIexR330EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_cIexSH30EeOAl9i6j131Rg" type="5002">
<children xmi:type="notation:Node" xmi:id="_hZ6OoH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//ForActivity/InputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_hZ6OoX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_h63moH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//ForActivity/counterHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_h63moX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_jJOQIH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//ForActivity/OutputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_jJOQIX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_cIexSX30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_cIexSn30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_cIexS330EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_cIexQX30EeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="classdiagram.ecore#//ForActivity"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_cIexQn30EeOAl9i6j131Rg" x="790" y="310"/>
</children>
<children xmi:type="notation:Node" xmi:id="_m_R7sH30EeOAl9i6j131Rg" type="1001">
<children xmi:type="notation:Node" xmi:id="_m_SiwH30EeOAl9i6j131Rg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_m_SiwX30EeOAl9i6j131Rg" type="5001">
<children xmi:type="notation:Node" xmi:id="_o_ccoH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//ForEachActivity/LoopPorts"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_o_ccoX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_qmNmIH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//ForEachActivity/UnionPorts"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_qmNmIX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_rYpIoH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//ForEachActivity/LoopElementPorts"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_rYpIoX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_m_Siwn30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_m_Siw330EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_m_SixH30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_m_SixX30EeOAl9i6j131Rg" type="5002">
<children xmi:type="notation:Node" xmi:id="_s7-joH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//ForEachActivity/InputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_s7-joX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_t808oH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//ForEachActivity/CounterHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_t808oX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_vDaKMH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//ForEachActivity/OutputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_vDaKMX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_m_Sixn30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_m_Six330EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_m_SiyH30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_m_R7sX30EeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="classdiagram.ecore#//ForEachActivity"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_m_R7sn30EeOAl9i6j131Rg" x="620" y="310"/>
</children>
<children xmi:type="notation:Node" xmi:id="_2PO3sH30EeOAl9i6j131Rg" type="1001">
<children xmi:type="notation:Node" xmi:id="_2PO3s330EeOAl9i6j131Rg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_2PPewH30EeOAl9i6j131Rg" type="5001">
<children xmi:type="notation:Node" xmi:id="_4aOIkH30EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//pForActivity/LoopCounter"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_4aOIkX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_2PPewX30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_2PPewn30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_2PPew330EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_2PPexH30EeOAl9i6j131Rg" type="5002">
<children xmi:type="notation:Node" xmi:id="_7HGlkH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//pForActivity/InputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_7HGlkX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_8fYAEH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//pForActivity/CounterHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_8fYAEX30EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_9fAREH30EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//pForActivity/OutputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_9fAREX30EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_2PPexX30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_2PPexn30EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_2PPex330EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_2PO3sX30EeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="classdiagram.ecore#//pForActivity"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_2PO3sn30EeOAl9i6j131Rg" x="935" y="310"/>
</children>
<children xmi:type="notation:Node" xmi:id="_BS2WIH31EeOAl9i6j131Rg" type="1001">
<children xmi:type="notation:Node" xmi:id="_BS29MH31EeOAl9i6j131Rg" type="4001"/>
<children xmi:type="notation:Node" xmi:id="_BS29MX31EeOAl9i6j131Rg" type="5001">
<children xmi:type="notation:Node" xmi:id="_DDX4kH31EeOAl9i6j131Rg" type="2001">
<element xmi:type="ecore:EAttribute" href="classdiagram.ecore#//pForEachActivity/LoopElementPorts"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_DDX4kX31EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_BS29Mn31EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_BS29M331EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_BS29NH31EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_BS29NX31EeOAl9i6j131Rg" type="5002">
<children xmi:type="notation:Node" xmi:id="_ES8DAH31EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//pForEachActivity/InputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_ES8DAX31EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_FjXJEH31EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//pForEachActivity/CounterHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_FjXJEX31EeOAl9i6j131Rg"/>
</children>
<children xmi:type="notation:Node" xmi:id="_HFZjkH31EeOAl9i6j131Rg" type="2002">
<element xmi:type="ecore:EOperation" href="classdiagram.ecore#//pForEachActivity/OutputHook"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_HFZjkX31EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:DrawerStyle" xmi:id="_BS29Nn31EeOAl9i6j131Rg"/>
<styles xmi:type="notation:SortingStyle" xmi:id="_BS29N331EeOAl9i6j131Rg"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_BS29OH31EeOAl9i6j131Rg"/>
</children>
<styles xmi:type="notation:ShapeStyle" xmi:id="_BS2WIX31EeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
<element xmi:type="ecore:EClass" href="classdiagram.ecore#//pForEachActivity"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_BS2WIn31EeOAl9i6j131Rg" x="1085" y="310"/>
</children>
<styles xmi:type="notation:DiagramStyle" xmi:id="_u4HeAX3lEeOAl9i6j131Rg"/>
<element xmi:type="ecore:EPackage" href="classdiagram.ecore#/"/>
<edges xmi:type="notation:Edge" xmi:id="_Pg_NoH3mEeOAl9i6j131Rg" type="3002" source="_-Nj-AH3lEeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<children xmi:type="notation:Node" xmi:id="_Pg_0sH3mEeOAl9i6j131Rg" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_Pg_0sX3mEeOAl9i6j131Rg" x="-16" y="-13"/>
</children>
<children xmi:type="notation:Node" xmi:id="_PhAbwH3mEeOAl9i6j131Rg" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_PhAbwX3mEeOAl9i6j131Rg" x="10" y="10"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_Pg_NoX3mEeOAl9i6j131Rg" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_Pg_Non3mEeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="classdiagram.ecore#//Workflow/activities"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Pg_No33mEeOAl9i6j131Rg" points="[0, 20, -184, -54]$[0, 74, -184, 0]$[180, 74, -4, 0]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_eQZBUH3mEeOAl9i6j131Rg" id="(0.5,0.5)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_eQZBUX3mEeOAl9i6j131Rg" id="(0.04132231404958678,0.6190476190476191)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_V9sLUH3mEeOAl9i6j131Rg" type="3002" source="_Aahk0H3mEeOAl9i6j131Rg" target="_-Nj-AH3lEeOAl9i6j131Rg">
<children xmi:type="notation:Node" xmi:id="_V9syY33mEeOAl9i6j131Rg" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_V9syZH3mEeOAl9i6j131Rg" x="23" y="-34"/>
</children>
<children xmi:type="notation:Node" xmi:id="_V9syZX3mEeOAl9i6j131Rg" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_V9syZn3mEeOAl9i6j131Rg" x="10" y="10"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_V9syYH3mEeOAl9i6j131Rg" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_V9syYX3mEeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="classdiagram.ecore#//WorkflowActivity/workflow"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_V9syYn3mEeOAl9i6j131Rg" points="[-4, 0, 180, 74]$[-184, 0, 0, 74]$[-184, -54, 0, 20]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_V9unkH3mEeOAl9i6j131Rg" id="(0.04132231404958678,0.6190476190476191)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_YhngoH3mEeOAl9i6j131Rg" id="(0.5,0.5)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_QLEoQH3tEeOAl9i6j131Rg" type="3002" source="_Aahk0H3mEeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<children xmi:type="notation:Node" xmi:id="_QLFPUH3tEeOAl9i6j131Rg" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_QLFPUX3tEeOAl9i6j131Rg" x="-20" y="12"/>
</children>
<children xmi:type="notation:Node" xmi:id="_QLFPUn3tEeOAl9i6j131Rg" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_QLFPU33tEeOAl9i6j131Rg" x="10" y="21"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_QLEoQX3tEeOAl9i6j131Rg" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_QLEoQn3tEeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="classdiagram.ecore#//WorkflowActivity/successor"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_QLEoQ33tEeOAl9i6j131Rg" points="[5, 9, 30, -8]$[36, 9, 61, -8]$[36, 56, 61, 39]$[-19, 56, 6, 39]$[-19, 21, 6, 4]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_eeS2QH3tEeOAl9i6j131Rg" id="(0.9586776859504132,0.5714285714285714)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_eeS2QX3tEeOAl9i6j131Rg" id="(0.7520661157024794,0.9183673469387755)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_S8FXUH3tEeOAl9i6j131Rg" type="3002" source="_Aahk0H3mEeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<children xmi:type="notation:Node" xmi:id="_S8FXVH3tEeOAl9i6j131Rg" type="4011">
<layoutConstraint xmi:type="notation:Location" xmi:id="_S8FXVX3tEeOAl9i6j131Rg" x="-55" y="-12"/>
</children>
<children xmi:type="notation:Node" xmi:id="_S8F-YH3tEeOAl9i6j131Rg" type="4012">
<layoutConstraint xmi:type="notation:Location" xmi:id="_S8F-YX3tEeOAl9i6j131Rg" x="10" y="10"/>
</children>
<styles xmi:type="notation:ConnectorStyle" xmi:id="_S8FXUX3tEeOAl9i6j131Rg" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_S8FXUn3tEeOAl9i6j131Rg" fontColor="4210752" fontName="Sans Serif" fontHeight="10"/>
<element xmi:type="ecore:EReference" href="classdiagram.ecore#//WorkflowActivity/predecessor"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_S8FXU33tEeOAl9i6j131Rg" points="[6, 4, -19, 21]$[6, 39, -19, 56]$[61, 39, 36, 56]$[61, -8, 36, 9]$[30, -8, 5, 9]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_S8HMgH3tEeOAl9i6j131Rg" id="(0.7520661157024794,0.9183673469387755)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_S8HMgX3tEeOAl9i6j131Rg" id="(0.9586776859504132,0.5714285714285714)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_yGmq4H3zEeOAl9i6j131Rg" type="3003" source="_w9gU0H3zEeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_yGmq4X3zEeOAl9i6j131Rg" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_yGmq4n3zEeOAl9i6j131Rg" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_yGmq433zEeOAl9i6j131Rg" points="[13, -1, -249, 163]$[13, -71, -249, 93]$[263, -71, 1, 93]$[263, -116, 1, 48]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_QECSgH31EeOAl9i6j131Rg" id="(0.6544117647058824,0.027777777777777776)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_RcFDgH31EeOAl9i6j131Rg" id="(0.06611570247933884,0.9587628865979382)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_SHW1IH31EeOAl9i6j131Rg" type="3003" source="_71iOUH3zEeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_SHW1IX31EeOAl9i6j131Rg" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_SHW1In31EeOAl9i6j131Rg" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_SHW1I331EeOAl9i6j131Rg" points="[18, -31, -118, 163]$[18, -71, -118, 123]$[102, -71, -34, 123]$[102, -146, -34, 48]"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_S3uiIH31EeOAl9i6j131Rg" type="3003" source="_FQVU0H30EeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_S3uiIX31EeOAl9i6j131Rg" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_S3uiIn31EeOAl9i6j131Rg" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_S3uiI331EeOAl9i6j131Rg" points="[8, -22, -34, 163]$[8, -137, -34, 48]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_S3vJMH31EeOAl9i6j131Rg" id="(0.1092436974789916,0.22115384615384615)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_TVPkkH31EeOAl9i6j131Rg" type="3003" source="_QP6AwH30EeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_TVPkkX31EeOAl9i6j131Rg" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_TVPkkn31EeOAl9i6j131Rg" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_TVPkk331EeOAl9i6j131Rg" points="[53, -33, 155, 139]$[53, -73, 155, 99]$[-144, -73, -42, 99]$[-144, -148, -42, 24]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_TVQysH31EeOAl9i6j131Rg" id="(0.11194029850746269,0.2833333333333333)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_TVQysX31EeOAl9i6j131Rg" id="(0.5702479338842975,0.7525773195876289)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_ZYW9kH31EeOAl9i6j131Rg" type="3003" source="_m_R7sH30EeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_ZYW9kX31EeOAl9i6j131Rg" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_ZYW9kn31EeOAl9i6j131Rg" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZYW9k331EeOAl9i6j131Rg" points="[-26, -18, 379, 187]$[-26, -58, 379, 147]$[-395, -58, 10, 147]$[-395, -133, 10, 72]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZYYLsH31EeOAl9i6j131Rg" id="(0.6891891891891891,0.15833333333333333)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZYYLsX31EeOAl9i6j131Rg" id="(0.1322314049586777,0.24742268041237114)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_ZxAHEH31EeOAl9i6j131Rg" type="3003" source="_cIexQH30EeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_ZxAHEX31EeOAl9i6j131Rg" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_ZxAHEn31EeOAl9i6j131Rg" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZxAHE331EeOAl9i6j131Rg" points="[1, -59, 515, 191]$[1, -99, 515, 151]$[-525, -99, -11, 151]$[-525, -174, -11, 76]"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZxBVMH31EeOAl9i6j131Rg" id="(0.30578512396694213,0.20618556701030927)"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_bBuIEH31EeOAl9i6j131Rg" type="3003" source="_2PO3sH30EeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_bBuIEX31EeOAl9i6j131Rg" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_bBuIEn31EeOAl9i6j131Rg" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_bBuIE331EeOAl9i6j131Rg" points="[1, -43, 638, 163]$[1, -83, 638, 123]$[-671, -83, -34, 123]$[-671, -158, -34, 48]"/>
</edges>
<edges xmi:type="notation:Edge" xmi:id="_bgUIkH31EeOAl9i6j131Rg" type="3003" source="_BS2WIH31EeOAl9i6j131Rg" target="_Aahk0H3mEeOAl9i6j131Rg">
<styles xmi:type="notation:ConnectorStyle" xmi:id="_bgUIkX31EeOAl9i6j131Rg" routing="Rectilinear" lineColor="4210752"/>
<styles xmi:type="notation:FontStyle" xmi:id="_bgUIkn31EeOAl9i6j131Rg" fontName="Sans Serif"/>
<element xsi:nil="true"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_bgUIk331EeOAl9i6j131Rg" points="[1, -43, 800, 163]$[1, -83, 800, 123]$[-833, -83, -34, 123]$[-833, -158, -34, 48]"/>
</edges>
</notation:Diagram>
+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>
*/
+74
View File
@@ -0,0 +1,74 @@
#include <wfr/WorkflowRuntime.h>
#include <wfr/common/wfs/Workflow.h>
#include <wfr/execution/ExecutionManager.h>
#include <wfr/prediction/PredictionManager.h>
#include <wfr/common/resource/ResourceManager.h>
#include <wfr/common/eventsystem/EventSystem.h>
#include <wfr/common/eventsystem/Event.h>
#include <wfr/enactment/EnactmentEngine.h>
#include <wfr/scheduling/SchedulerManager.h>
#include <boost/program_options.hpp>
#include <iostream>
namespace wfr {
std::map<std::string, WorkflowRuntime::ConfigEntry> WorkflowRuntime::globalConfig;
std::default_random_engine WorkflowRuntime::randomEngine;
std::unordered_set<std::shared_ptr<wfs::Workflow>> WorkflowRuntime::workflowInstances;
void WorkflowRuntime::init(int argc, char** argv) {
bool isHelp = false;
boost::program_options::options_description opts("Global Options");
opts.add_options()
("help", "Print help message.")
("sim-mode", "Enable simulation-mode.");
boost::program_options::variables_map vm;
auto parsed = boost::program_options::command_line_parser(argc, argv).options(opts).allow_unregistered().run();
boost::program_options::store(parsed, vm);
boost::program_options::notify(vm);
if (vm.count("help")) {
std::cerr << opts << std::endl;
isHelp = true;
}
if (vm.count("sim-mode")) {
setGlobalConfig("sim-mode", true);
}
wfr::eventsystem::EventSystem::init(argc, argv);
wfr::resource::ResourceManager::init(argc, argv);
wfr::enactment::EnactmentEngine::init(argc, argv);
wfr::prediction::PredictionManager::init(argc, argv);
wfr::execution::ExecutionManager::init(argc, argv);
wfr::scheduling::SchedulerManager::init(argc, argv);
if (isHelp) exit(0);
}
void WorkflowRuntime::finish() {
wfr::scheduling::SchedulerManager::finish();
wfr::execution::ExecutionManager::finish();
wfr::prediction::PredictionManager::finish();
wfr::enactment::EnactmentEngine::finish();
wfr::resource::ResourceManager::finish();
wfr::eventsystem::EventSystem::finish();
if (workflowInstances.size() == 1) {
(*workflowInstances.begin())->printStatistics();
} else if (workflowInstances.size() > 1) {
std::cerr << "ERROR: Print statistics for more than one workflow instance not implemented." << std::endl;
}
}
void WorkflowRuntime::logMessage(std::string message, const wfr_timestamp_sc_t& timestamp, bool noLocking) {
wfr::eventsystem::GeneralLoggingEvent::fireEvent(message, timestamp, noLocking);
}
} /* namespace wfr */
Executable
+13
View File
@@ -0,0 +1,13 @@
set(wfr_cpp_files "${wfr_cpp_files}"
src/WorkflowRuntime.cpp
)
include(src/common/cmake.inc)
include(src/eventsystem/cmake.inc)
include(src/enactment/cmake.inc)
include(src/wep/cmake.inc)
include(src/utils/cmake.inc)
include(src/prediction/cmake.inc)
include(src/scheduling/cmake.inc)
include(src/execution/cmake.inc)
+4
View File
@@ -0,0 +1,4 @@
include(src/common/wfs/cmake.inc)
include(src/common/wep/cmake.inc)
include(src/common/resource/cmake.inc)
+155
View File
@@ -0,0 +1,155 @@
#include <wfr/common/resource/Resource.h>
#include <wfr/common/wfs/AtomicActivityImplementation.h>
#include <algorithm>
namespace wfr {
namespace resource {
bool AbstractResourceType::hasCapability(const RequiredResourceCapability& type) const noexcept {
for (auto& cap : capabilities) {
if (cap == type) {
return true;
}
}
return false;
}
bool AbstractResourceType::hasCapability(wfr::resource::ResourceCapabilityType type) const noexcept {
for (auto& cap : capabilities) {
if (cap.type == type) {
return true;
}
}
return false;
}
std::vector<std::string> AbstractResourceType::getPropertyKeys() const noexcept {
std::vector<std::string> retval;
for (auto i : properties) {
retval.push_back(i.first);
}
return retval;
}
std::string AbstractResourceType::getProperty(const std::string& key) const noexcept {
auto i = properties.find(key);
if (i != properties.end()) {
return i->second;
} else {
return std::string();
}
}
std::map<std::string, ComputingDeviceClass> registeredDeviceTypes = {
{"cpu", ComputingDeviceClass::CPU},
{"gpu", ComputingDeviceClass::GPU}
};
std::map<std::string, ResourceCapabilityType> registeredDeviceCapabilityTypes = {
{"genericcpu", ResourceCapabilityType::GenericCPU},
{"cuda", ResourceCapabilityType::CUDA},
{"opencl", ResourceCapabilityType::OpenCL}
};
ComputingDeviceClass parseComputingDeviceType(const std::string& type) {
ComputingDeviceClass retval = ComputingDeviceClass::Unknown;
std::string tmp(type);
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
auto item = registeredDeviceTypes.find(tmp);
if (item != registeredDeviceTypes.end()) {
retval = item->second;
}
return retval;
}
std::string getComputingDeviceTypeString(const ComputingDeviceClass& type) {
std::string retval;
for (auto& item : registeredDeviceTypes) {
if (item.second == type) {
retval = item.first;
break;
}
}
return retval;
}
ResourceCapabilityType parseResourceCapabilityType(const std::string& type) {
ResourceCapabilityType retval = ResourceCapabilityType::Unknown;
std::string tmp(type);
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
auto item = registeredDeviceCapabilityTypes.find(tmp);
if (item != registeredDeviceCapabilityTypes.end()) {
retval = item->second;
}
return retval;
}
std::string getResourceCapabilityTypeString(const ResourceCapabilityType& type) {
std::string retval;
for (auto& item : registeredDeviceCapabilityTypes) {
if (item.second == type) {
retval = item.first;
break;
}
}
return retval;
}
bool ComputingResource::reserveSlots(const wfr_size_t& slots) noexcept {
if (slots <= getFreeSlotCount()) {
reservedSlots += slots;
return true;
} else {
return false;
}
}
bool ComputingResource::markReservedSlotsBusy(const wfr_size_t& slots) noexcept {
if (slots <= reservedSlots) {
reservedSlots -= slots;
busySlots += slots;
return true;
} else {
return false;
}
}
bool ComputingResource::markFreeSlotsBusy(const wfr_size_t& slots) noexcept {
if (slots <= getFreeSlotCount()) {
busySlots += slots;
return true;
} else {
return false;
}
}
bool ComputingResource::releaseBusySlots(const wfr_size_t& slots) noexcept {
if (slots <= busySlots) {
busySlots -= slots;
return true;
} else {
return false;
}
}
} /* namespace resource */
} /* namespace wfr */
+372
View File
@@ -0,0 +1,372 @@
#include <wfr/common/resource/ResourceManager.h>
#include <wfr/common/exceptions/exceptions.h>
#include <wfr/common/types/ResourceTypes.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <thread>
#include <chrono>
#include <thread>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
#include <wfr/common/resource/Resource.h>
#include <wfr/common/resource/ResourceReservation.h>
namespace wfr {
namespace resource {
ResourceManager* ResourceManager::singleton = nullptr;
void ResourceManager::init(int argc, char** argv) {
std::string resourceConfigFile;
bool cpuAutoConfig = true;
bool printResourceTable = false;
boost::program_options::options_description opts("ResourceManager Options");
opts.add_options()
("help", "Print help message.")
("no-cpu-autoconfig", "Disable CPU auto-configuration.")
("print-resource-table", "Print resource table.")
("resource-config-file", boost::program_options::value<std::string>(), "Set resource config file.");
boost::program_options::variables_map vm;
auto parsed = boost::program_options::command_line_parser(argc, argv).options(opts).allow_unregistered().run();
boost::program_options::store(parsed, vm);
boost::program_options::notify(vm);
if (vm.count("help")) {
std::cerr << opts << std::endl;
return;
}
if (vm.count("no-cpu-autoconfig")) {
cpuAutoConfig = false;
}
if (vm.count("print-resource-table")) {
printResourceTable = true;
}
if (vm.count("resource-config-file")) {
resourceConfigFile = vm["resource-config-file"].as<std::string>();
boost::filesystem::path resourceConfigFilePath(resourceConfigFile);
if (boost::filesystem::is_regular_file(resourceConfigFilePath)) {
std::cerr << "Resource config file is set to \""<< resourceConfigFile << "\"." << std::endl;
} else {
throw wfr::exception::wfr_illegal_argument((boost::format("%1% does not exist or is not a file.") % resourceConfigFile).str());
}
}
singleton = new ResourceManager(resourceConfigFile, cpuAutoConfig, printResourceTable);
}
void ResourceManager::finish() noexcept {
if (singleton != nullptr) {
delete singleton;
singleton = nullptr;
}
}
ResourceManager& ResourceManager::getInstance() noexcept {
if (singleton == nullptr) {
throw wfr::exception::wfr_missing_instance("ResourceManager instance not found.");
}
return *singleton;
}
ResourceManager::ResourceManager(std::string resourceConfigFile, bool cpuAutoConfig, bool printResourceTable) {
if (cpuAutoConfig) {
unsigned threadCount = std::thread::hardware_concurrency();
ComputingResourceType* resType = new ComputingResourceType("CPU", ComputingDeviceClass::CPU, threadCount, {{ResourceCapabilityType::GenericCPU, 0, 0}});
std::string tmp(resType->resourceTypeName);
computingResourceTypes.insert({tmp, resType});
ComputingResource* dev = new ComputingResource("cpu0", *resType);
computingResources.insert({dev->resourceIdentifier, dev});
}
if (!resourceConfigFile.empty()) {
readConfigFile(resourceConfigFile);
}
if (printResourceTable) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
this->printResourceTable(std::cout);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void ResourceManager::readConfigFile(std::string resourceConfigFile) {
std::ifstream configFile(resourceConfigFile);
std::string configContent((std::istreambuf_iterator<char>(configFile)), std::istreambuf_iterator<char>());
rapidjson::Document configDocument;
if (!configDocument.Parse(configContent.c_str()).HasParseError()) {
if (!configDocument.IsObject()) {
throw wfr::exception::wfr_fatal_error("Resource config file: toplevel item is not an object.");
}
if (!configDocument.HasMember("devicetypes")) {
throw wfr::exception::wfr_fatal_error("Resource config file: No devicetypes item found.");
}
auto& types = configDocument["devicetypes"];
if (!types.IsObject()) {
throw wfr::exception::wfr_fatal_error("Resource config file: devicetypes item is not an object.");
}
// Iterate over device types
for(rapidjson::Value::ConstMemberIterator it=types.MemberBegin(); it != types.MemberEnd(); it++) {
auto& type = *it;
if (!type.value.IsObject()) {
throw wfr::exception::wfr_fatal_error("Resource config file: type item is not an object.");
}
std::string resourceName = type.name.GetString();
ComputingDeviceClass computingDeviceClass = ComputingDeviceClass::Unknown;
if (!type.value.HasMember("deviceClass")) {
throw wfr::exception::wfr_fatal_error((boost::format("Resource config file: device type \"%1%\" has no deviceClass property.") % resourceName).str());
}
if (!type.value["deviceClass"].IsString()) {
throw wfr::exception::wfr_fatal_error("Resource config file: device type property \"deviceClass\" has wrong type.");
}
std::string classStr = type.value["deviceClass"].GetString();
if (classStr.compare("CPU") == 0) {
computingDeviceClass = ComputingDeviceClass::CPU;
} else if (classStr.compare("GPU") == 0) {
computingDeviceClass = ComputingDeviceClass::GPU;
} else {
computingDeviceClass = ComputingDeviceClass::Unknown;
}
if (computingDeviceClass == ComputingDeviceClass::Unknown) {
throw wfr::exception::wfr_fatal_error((boost::format("Resource config file: unknown device type class \"%1%\".") % classStr).str());
}
wfr_size_t deviceSlots = 1;
if (type.value.HasMember("slots")) {
if (!type.value["slots"].IsUint()) {
throw wfr::exception::wfr_fatal_error("Resource config file: device type property \"slots\" has wrong type.");
}
deviceSlots = type.value["slots"].GetUint();
}
std::set<ResourceCapability> capabilities = std::set<ResourceCapability>();
if (type.value.HasMember("capabilities")) {
if (!type.value["capabilities"].IsArray()) {
throw wfr::exception::wfr_fatal_error("Resource config file: device type property \"capabilities\" has wrong type.");
}
auto& caps = type.value["capabilities"];
for(rapidjson::Value::ConstValueIterator it2=caps.Begin(); it2 != caps.End(); it2++) {
auto& cap = *it2;
if (!cap.IsArray()) {
throw wfr::exception::wfr_fatal_error("Resource config file: capability has wrong type.");
}
if (!cap[0].IsString()) {
throw wfr::exception::wfr_fatal_error("Resource config file: capability param 0 has wrong type.");
}
if (!cap[1].IsInt()) {
throw wfr::exception::wfr_fatal_error("Resource config file: capability param 1 has wrong type.");
}
if (!cap[2].IsInt()) {
throw wfr::exception::wfr_fatal_error("Resource config file: capability param 2 has wrong type.");
}
std::string capname = cap[0].GetString();
ResourceCapabilityType captype = ResourceCapabilityType::Unknown;
if (capname.compare("GenericCPU") == 0) {
captype = ResourceCapabilityType::GenericCPU;
} else if (capname.compare("OpenCL") == 0) {
captype = ResourceCapabilityType::OpenCL;
} else if (capname.compare("CUDA") == 0) {
captype = ResourceCapabilityType::CUDA;
} else {
throw wfr::exception::wfr_fatal_error((boost::format("Resource config file: unknown capability \"%1%\".") % capname).str());
}
wfr_size_t minVersion = cap[1].GetInt();
wfr_size_t maxVersion = cap[2].GetInt();
capabilities.insert({captype, minVersion, maxVersion});
}
}
std::map<std::string, std::string> properties = std::map<std::string, std::string>();
if (type.value.HasMember("properties")) {
if (!type.value["properties"].IsArray()) {
throw wfr::exception::wfr_fatal_error("Resource config file: device type property \"properties\" has wrong type.");
}
auto& props = type.value["properties"];
for(rapidjson::Value::ConstValueIterator it2=props.Begin(); it2 != props.End(); it2++) {
auto& prop = *it2;
if (!prop.IsArray()) {
throw wfr::exception::wfr_fatal_error("Resource config file: property has wrong type.");
}
if (!prop[0].IsString()) {
throw wfr::exception::wfr_fatal_error("Resource config file: property name has wrong type.");
}
if (!prop[1].IsString()) {
throw wfr::exception::wfr_fatal_error("Resource config file: property value has wrong type.");
}
properties.insert({prop[0].GetString(), prop[1].GetString()});
}
}
ComputingResourceType* resType = new ComputingResourceType(resourceName, computingDeviceClass, deviceSlots, capabilities, properties);
computingResourceTypes.insert({resourceName, resType});
}
if (!configDocument.HasMember("devices")) {
throw wfr::exception::wfr_fatal_error("Resource config file: No devices item found.");
}
auto& devices = configDocument["devices"];
if (!devices.IsObject()) {
throw wfr::exception::wfr_fatal_error("Resource config file: devices item is not an object.");
}
// Iterate over devices
for(rapidjson::Value::ConstMemberIterator it2=devices.MemberBegin(); it2 != devices.MemberEnd(); it2++) {
auto& dev = *it2;
if (!dev.value.IsString()) {
throw wfr::exception::wfr_fatal_error("Resource config file: device item is not a string.");
}
std::string devName = dev.name.GetString();
std::string devTypeName = dev.value.GetString();
auto devType = computingResourceTypes.find(devTypeName);
if (devType == computingResourceTypes.end()) {
throw wfr::exception::wfr_fatal_error((boost::format("Resource config file: unknown device type \"%1%\".") % devTypeName).str());
}
ComputingResource* device = new ComputingResource(devName, *(*devType).second);
computingResources.insert({device->resourceIdentifier, device});
}
} else {
rapidjson::ParseErrorCode e = configDocument.GetParseError();
size_t o = configDocument.GetErrorOffset();
std::stringstream ss;
ss << "Error during parsing resource config file: \"" << rapidjson::GetParseError_En(e) << "\"";
ss << " at offset " << o << " near '" << configContent.substr(o, 10) << "...'" << std::endl;
throw wfr::exception::wfr_fatal_error(ss.str());
}
}
std::vector<ComputingResource*> ResourceManager::getComputingResources() const noexcept {
std::vector<ComputingResource*> retval;
for (auto dev : computingResources) {
retval.push_back(dev.second);
}
return retval;
}
ComputingResource* ResourceManager::getComputingResource(std::string identifier) const noexcept {
std::vector<ComputingResource*> retval;
for (auto dev : computingResources) {
if (dev.second->resourceIdentifier.compare(identifier) == 0) {
return dev.second;
}
}
return nullptr;
}
std::vector<ComputingResource*> ResourceManager::filterComputingResources(std::vector<RequiredResourceCapability> filter) const noexcept {
std::vector<ComputingResource*> retval;
for (auto dev : computingResources) {
for (auto cap : filter) {
if (dev.second->hasCapability(cap)) {
retval.push_back(dev.second);
}
}
}
return retval;
}
ComputingResourceReservation ResourceManager::reserveComputingResource(ComputingResource* device, const wfr_size_t& slots) noexcept {
if (device->getFreeSlotCount() >= slots) {
if (device->reserveSlots(slots)) {
return ComputingResourceReservation(device, slots);
}
}
return ComputingResourceReservation();
}
std::vector<ComputingResourceType*> ResourceManager::getComputingResourceTypes() const noexcept {
std::vector<ComputingResourceType*> retval;
for (auto i : computingResourceTypes) {
retval.push_back(i.second);
}
return retval;
}
ComputingResourceType* ResourceManager::getComputingResourceType(std::string name) const noexcept {
return computingResourceTypes.at(name);
}
ResourceManager::~ResourceManager() {
for (auto dev : computingResources) {
delete dev.second;
}
computingResources.clear();
for (auto type : computingResourceTypes) {
delete type.second;
}
computingResourceTypes.clear();
}
void ResourceManager::printResourceTable(std::ostream& out) const noexcept {
out << "======= Computing Resource Type Table ========" << std::endl;
for (auto& res : computingResourceTypes) {
out << "ResourceType: \"" << res.first << "\":" << std::endl;
std::string deviceClassStr;
switch (res.second->computingDeviceClass) {
case ComputingDeviceClass::CPU:
deviceClassStr = "CPU";
break;
case ComputingDeviceClass::GPU:
deviceClassStr = "GPU";
break;
default:
deviceClassStr = "Unknown";
break;
}
out << "\tDeviceClass: " << deviceClassStr << std::endl;
out << "\tSlots: " << res.second->maxSlots << std::endl;
out << "\tCapabilities: " << std::endl;
auto& caps = res.second->getCapabilities();
if (caps.size() > 0) {
for (auto& cap : caps) {
std::string capName;
switch (cap.type) {
case ResourceCapabilityType::GenericCPU:
capName = "GenericCPU";
break;
case ResourceCapabilityType::CUDA:
capName = "CUDA";
break;
case ResourceCapabilityType::OpenCL:
capName = "OpenCL";
break;
default:
capName = "Unknown";
break;
}
out << "\t\t" << capName << " (Min: " << cap.minorVersion << ", Max: " << cap.majorVersion << ")" << std::endl;
}
} else {
out << "\t\tNone" << std::endl;
}
out << "\tProperties: " << std::endl;
auto& props = res.second->getProperties();
if (props.size() > 0) {
for (auto& prop : props) {
out << "\t\t" << prop.first << " = " << prop.second << std::endl;
}
} else {
out << "\t\tNone" << std::endl;
}
}
out << "===== Computing Resource Type Table End ======" << std::endl;
out << "======= Computing Resource Table ========" << std::endl;
for (auto& res : computingResources) {
out << "Resource: \"" << res.second->resourceIdentifier << "\":" << std::endl;
out << "\tResourceType: \"" << res.second->resourceType.resourceTypeName << "\"" << std::endl;
}
out << "===== Computing Resource Table End ======" << std::endl;
}
} /* namespace resource */
} /* namespace wfr */
+5
View File
@@ -0,0 +1,5 @@
set(wfr_cpp_files "${wfr_cpp_files}"
src/common/resource/Resource.cpp
src/common/resource/ResourceManager.cpp
)
+15
View File
@@ -0,0 +1,15 @@
#include <wfr/common/wep/AbstractWepNode.h>
namespace wfr {
namespace wep {
std::atomic<wfr_id_t> AbstractWepNode::nextWepNodeID = ATOMIC_VAR_INIT(1);
} /* namespace wep */
} /* namespace wfr */
+26
View File
@@ -0,0 +1,26 @@
#include <wfr/common/wep/ActivityWepNode.h>
#include <wfr/common/wfs/ActivityInstance.h>
namespace wfr {
namespace wep {
ActivityWepNode::ActivityWepNode(WepNodeType nodeType, wfs::ActivityInstance& activity) noexcept
: AbstractWepNode(nodeType, true), lastKnownActivityStatus(activity.getInstanceStatus()), activity(activity) {}
void ActivityWepNode::updateInstanceStatus() {
lastKnownActivityStatus = activity.getInstanceStatus();
}
void ActivityWepNode::addToVisitationCount(uint64_t val) noexcept {
visitationCount += val;
activity.addToVisitationCount(val);
}
} /* namespace wep */
} /* namespace wfr */
+36
View File
@@ -0,0 +1,36 @@
#include <wfr/common/wep/WorkflowExecutionPlan.h>
#include <wfr/common/wep/AbstractWepNode.h>
#include <set>
#include <queue>
namespace wfr {
namespace wep {
std::atomic<wfr_id_t> WorkflowExecutionPlan::nextWepID = ATOMIC_VAR_INIT(1);
WorkflowExecutionPlan::~WorkflowExecutionPlan() noexcept {
if (startNode) {
std::set<AbstractWepNode*> visitedNodes;
std::queue<AbstractWepNode*> nodeQueue;
nodeQueue.push(startNode);
visitedNodes.insert(startNode);
do {
auto node = nodeQueue.front();
nodeQueue.pop();
for (auto s : node->getSuccessors()) {
if (visitedNodes.find(s) == visitedNodes.end()) {
nodeQueue.push(s);
visitedNodes.insert(s);
}
}
delete node;
} while (!nodeQueue.empty());
}
}
} /* namespace wep */
} /* namespace wfr */
+22
View File
@@ -0,0 +1,22 @@
#include <wfr/common/wep/activities/IterationEndWepNode.h>
#include <wfr/common/wep/activities/IterationStartWepNode.h>
namespace wfr {
namespace wep {
void IterationEndWepNode::updateInstanceStatus() {
startNode->updateInstanceStatus();
}
wfs::ActivityInstanceStatus IterationEndWepNode::getLastKnownInstanceStatus() const noexcept {
return startNode->getLastKnownInstanceStatus();
}
} /* namespace wep */
} /* namespace wfr */
+16
View File
@@ -0,0 +1,16 @@
#include <wfr/common/wep/activities/IterationStartWepNode.h>
namespace wfr {
namespace wep {
void IterationStartWepNode::updateInstanceStatus() {
}
} /* namespace wep */
} /* namespace wfr */
+8
View File
@@ -0,0 +1,8 @@
set(wfr_cpp_files "${wfr_cpp_files}"
src/common/wep/AbstractWepNode.cpp
src/common/wep/ActivityWepNode.cpp
src/common/wep/WorkflowExecutionPlan.cpp
src/common/wep/activities/IterationStartWepNode.cpp
src/common/wep/activities/IterationEndWepNode.cpp
)
+183
View File
@@ -0,0 +1,183 @@
#include <wfr/common/wfs/Activity.h>
#include <wfr/common/wfs/ActivityTemplate.h>
#include <wfr/common/wfs/ActivityInstance.h>
#include <wfr/common/wfs/Workflow.h>
#include <wfr/common/wfs/instances/AtomicActivityInstance.h>
#include <wfr/common/wfs/instances/AssignActivityInstance.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/templates/ForLoopActivityTemplate.h>
#include <wfr/common/wfs/instances/WhileLoopActivityInstance.h>
#include <wfr/common/eventsystem/Event.h>
#include <boost/format.hpp>
namespace wfr {
namespace wfs {
std::atomic<wfr_id_t> Activity::nextActivityID = ATOMIC_VAR_INIT(1);
Activity::Activity( Workflow& workflow, ActivityTemplate& baseTemplate )
: status(ActivityStatus::Unknown),
activityID(getNextActivityID()),
workflow(workflow),
baseTemplate(baseTemplate) {
setActivityStatus(ActivityStatus::Created);
}
Activity::~Activity() {
for (auto i : instanceList) {
if (i) delete i;
}
instanceList.clear();
}
ActivityType Activity::activityType() const noexcept {
return baseTemplate.activityType;
}
bool Activity::isCompositeActivity() const noexcept {
return baseTemplate.isCompositeActivity;
}
bool Activity::isLoop() const noexcept {
return baseTemplate.isLoop;
}
bool Activity::isConditional() const noexcept {
return baseTemplate.isConditional;
}
wfr_size_t Activity::getChildrenCount(wfr_id_t branchID) const noexcept {
wfr_size_t retval = 0;
for (auto i : workflow.getActivities()) {
if (i->parent && i->parent->activityID == activityID && i->baseTemplate.branchID == branchID) {
retval++;
}
}
return retval;
}
std::vector<Activity*> Activity::getChildren(wfr_id_t branchID) const noexcept {
std::vector<Activity*> retval;
for (auto i : workflow.getActivities()) {
if (i->parent && i->parent->activityID == activityID && i->baseTemplate.branchID == branchID) {
retval.push_back(i);
}
}
return retval;
}
bool Activity::isSuccessor(wfr_id_t aid) const noexcept {
for (auto i : successors) {
if (i->activityID == aid) {
return true;
}
}
return false;
}
bool Activity::isSuccessor(Activity& act) const noexcept {
for (auto i : successors) {
if (i == &act) {
return true;
}
}
return false;
}
bool Activity::isPredecessor(wfr_id_t aid) const noexcept {
for (auto i : predecessors) {
if (i->activityID == aid) {
return true;
}
}
return false;
}
bool Activity::isPredecessor(Activity& act) const noexcept {
for (auto i : predecessors) {
if (i == &act) {
return true;
}
}
return false;
}
void Activity::setActivityStatus(ActivityStatus status) {
if (status != this->status) {
if (this->status > status) {
throw exception::wfr_exception((boost::format("Illegal state change in activity with id %1%.") % activityID).str());
}
ActivityStatus oldStatus = this->status;
this->status = status;
wfr::eventsystem::ActivityStatusEvent::fireEvent(*this, oldStatus, status);
}
}
void Activity::initActivity() {
// Retrieve parent activity
if (baseTemplate.parentActivityID > 0) {
parent = workflow.getActivityByTemplateID(baseTemplate.parentActivityID);
assert(parent);
}
// Retrieve successors
for (auto i : baseTemplate.succRawList) {
auto tmp = workflow.getActivityByTemplateID(i);
assert(tmp);
successors.push_back(tmp);
}
// Retrieve predecessors
for (auto i : baseTemplate.predRawList) {
auto tmp = workflow.getActivityByTemplateID(i);
assert(tmp);
predecessors.push_back(tmp);
}
setActivityStatus(ActivityStatus::Initialized);
}
ActivityInstance* Activity::createNewInstance(wfr_id_t iterationID) {
ActivityInstance* retval = nullptr;
switch (activityType()) {
case ActivityType::Atomic:
retval = new AtomicActivityInstance(*this, iterationID);
break;
case ActivityType::Assign:
retval = new AssignActivityInstance(*this, iterationID);
break;
case ActivityType::Conditional:
retval = new ConditionalActivityInstance(*this, iterationID);
break;
case ActivityType::Container:
retval = new ContainerActivityInstance(*this, iterationID);
break;
case ActivityType::ForLoop:
retval = new ForLoopActivityInstance(*this, baseTemplate.as<ForLoopActivityTemplate>().isParallel, iterationID);
break;
case ActivityType::WhileLoop:
retval = new WhileLoopActivityInstance(*this, iterationID);
break;
default:
throw wfr::exception::wfr_fatal_error("Unknown instance type encountered.");
}
if (retval != nullptr) {
instanceList.push_back(retval);
}
return retval;
}
} /* namespace wfs */
} /* namespace wfr */
+176
View File
@@ -0,0 +1,176 @@
/*
* ActivityInstance.cpp
*
* Created on: 06.02.2014
* Author: matthias
*/
#include <wfr/common/wfs/ActivityInstance.h>
#include <wfr/common/wfs/ActivityTemplate.h>
#include <wfr/common/wfs/instances/CompositeActivityInstance.h>
#include <wfr/common/wfs/Activity.h>
#include <wfr/common/wfs/Workflow.h>
#include <wfr/common/eventsystem/Event.h>
#include <wfr/common/eventsystem/EventSystem.h>
#include <wfr/common/exceptions/exceptions.h>
#include <wfr/common/scheduling/SchedulingDecision.h>
#include <wfr/WorkflowRuntime.h>
#include <boost/format.hpp>
#include <chrono>
namespace wfr {
namespace wfs {
std::atomic<wfr_id_t>ActivityInstance::nextInstanceID = ATOMIC_VAR_INIT(1);
wfr_id_t ActivityInstance::getNextInstanceID() {
return nextInstanceID.fetch_add(1);
}
ActivityInstance::ActivityInstance(Activity& baseActivity, const wfr_id_t& iterationID) noexcept
: status(ActivityInstanceStatus::Unknown),
instanceID(getNextInstanceID()),
baseActivity(baseActivity),
iterationID(iterationID) {
setInstanceStatus(ActivityInstanceStatus::Created);
}
ActivityType ActivityInstance::activityType() const noexcept {
return baseActivity.baseTemplate.activityType;
}
bool ActivityInstance::isCompositeActivity() const noexcept {
return baseActivity.baseTemplate.isCompositeActivity;
}
bool ActivityInstance::isLoop() const noexcept {
return baseActivity.baseTemplate.isLoop;
}
bool ActivityInstance::isConditional() const noexcept {
return baseActivity.baseTemplate.isConditional;
}
void ActivityInstance::setInstanceStatus(const ActivityInstanceStatus& status) {
if (status != this->status) {
if (this->status > status) {
throw wfr::exception::wfr_fatal_error((boost::format("Illegal activity instance state change in activity instance with id %1%.") % instanceID).str());
}
ActivityInstanceStatus oldStatus = this->status;
this->status = status;
switch (status) {
case wfr::wfs::ActivityInstanceStatus::ReadyForExecution:
readyTime = std::chrono::system_clock::now();
break;
case wfr::wfs::ActivityInstanceStatus::Running:
startTime = std::chrono::system_clock::now();
break;
case wfr::wfs::ActivityInstanceStatus::Finished:
endTime = std::chrono::system_clock::now();
/*if (parentActivity) {
if (parentActivity->isCompositeActivity()) {
wfr::wfs::CompositeActivityInstance& composite = parentActivity->as<wfs::CompositeActivityInstance>();
composite.notifyChildHasFinished(*this);
} else {
throw wfr::exception::wfr_fatal_error("Non-Composite activity cannot be a parent.");
}
}*/
break;
case wfr::wfs::ActivityInstanceStatus::Error:
endTime = std::chrono::system_clock::now();
break;
default:
break;
}
eventsystem::ActivityInstanceStatusEvent::fireEvent(*this, oldStatus, status);
#ifdef WFR_ENABLE_STATISTICS
switch (activityType()) {
case ActivityType::Atomic:
switch (status) {
case wfr::wfs::ActivityInstanceStatus::Created:
baseActivity.workflow.addToCreatedAtomicInstanceCount();
break;
case wfr::wfs::ActivityInstanceStatus::Running:
baseActivity.workflow.addToCumulaticeAtomicReadyWaitingDuration(startTime-readyTime);
break;
case wfr::wfs::ActivityInstanceStatus::Finished:
baseActivity.workflow.addToFinishedAtomicInstanceCount();
baseActivity.workflow.addToCumulaticeAtomicRunningDuration(endTime-startTime);
break;
case wfr::wfs::ActivityInstanceStatus::Error:
baseActivity.workflow.addToErrorAtomicInstanceCount();
baseActivity.workflow.addToCumulaticeAtomicRunningDuration(endTime-startTime);
break;
default:
break;
}
break;
default:
switch (status) {
case wfr::wfs::ActivityInstanceStatus::Created:
baseActivity.workflow.addToCreatedCompositeInstanceCount();
break;
case wfr::wfs::ActivityInstanceStatus::Finished:
baseActivity.workflow.addToFinishedCompositeInstanceCount();
break;
case wfr::wfs::ActivityInstanceStatus::Error:
baseActivity.workflow.addToErrorCompositeInstanceCount();
break;
default:
break;
}
break;
}
#endif
}
}
void ActivityInstance::setErrorState(std::exception_ptr exception) noexcept {
errorCause = exception;
setInstanceStatus(ActivityInstanceStatus::Error);
}
void ActivityInstance::executeSimMode() noexcept {
if (WorkflowRuntime::getGlobalConfig<bool>("sim-mode")) {
if (schedulingDecision) {
std::cout << "Simulating execution ... " << std::endl;
auto prediction = schedulingDecision->getPrediction();
if (prediction) {
auto& predTime = prediction.getExecutionTime();
double time = WorkflowRuntime::getRandomNumber(predTime.getValue() - predTime.getDeviation(), predTime.getValue() + predTime.getDeviation());
std::cout << "Sleeping for " << time << " seconds." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds((long int)(time * 1000)));
/*std::cout << "Doing stuff for " << time << " seconds." << std::endl;
std::chrono::system_clock::time_point endtime = std::chrono::system_clock::now() + std::chrono::milliseconds((long int)(time * 1000));
while (true) {
if (std::chrono::system_clock::now() >= endtime) {
break;
} else {
volatile int i = 0;
for (int t = 0; t < 1000; t++) {
i++;
}
}
}*/
} else {
std::cout << "Warning: No valid prediction found" << std::endl;
}
} else {
throw exception::wfr_fatal_error("No scheduling decision found.");
}
}
}
} /* namespace wfs */
} /* namespace wfr */
+181
View File
@@ -0,0 +1,181 @@
#include <wfr/common/wfs/ActivityTemplate.h>
#include <wfr/common/wfs/Activity.h>
#include <wfr/common/wfs/WorkflowTemplate.h>
#include <wfr/common/exceptions/exceptions.h>
#include <wfr/common/wfs/templates/AtomicActivityTemplate.h>
#include <wfr/common/wfs/templates/AssignActivityTemplate.h>
#include <wfr/common/wfs/templates/ContainerActivityTemplate.h>
#include <wfr/common/wfs/templates/ForLoopActivityTemplate.h>
#include <wfr/common/wfs/templates/WhileLoopActivityTemplate.h>
#include <wfr/common/wfs/templates/ConditionalActivityTemplate.h>
#include <boost/format.hpp>
#include <iostream>
namespace wfr {
namespace wfs {
ActivityTemplate::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
: succRawList(succList), predRawList(predList), templateID(id), activityName(name), activityType(type), parentActivityID(parentID),
branchID(branchID), isCompositeActivity(isCompositeActivity), isLoop(isLoop), isConditional(isConditional) {
if (id == 0) {
throw exception::wfr_fatal_error((boost::format("ID of Activity template \"%1%\" must be greater than 0.") % activityName).str());
}
}
void ActivityTemplate::initActivityTemplate(WorkflowTemplate& parentWorkflow) {
this->parentWorkflow = &parentWorkflow;
if (parentActivityID > 0) {
this->parentActivity = parentWorkflow.getActivityByID(parentActivityID);
if (!this->parentActivity) {
throw exception::wfr_fatal_error((boost::format("Activity template \"%1%\" has invalid parent activity id.") % activityName).str());
}
}
for (auto i : succRawList) {
auto act = parentWorkflow.getActivityByID(i);
if (!act) {
throw exception::wfr_fatal_error((boost::format("Activity template \"%1%\" has invalid successor id %2%.") % activityName % i).str());
} else {
successors.push_back(act);
}
}
for (auto i : predRawList) {
auto act = parentWorkflow.getActivityByID(i);
if (!act) {
throw exception::wfr_fatal_error((boost::format("Activity template \"%1%\" has invalid predecessor id %2%.") % activityName % i).str());
} else {
predecessors.push_back(act);
}
}
}
void ActivityTemplate::checkStructure() {
// Check parent activity
if (parentActivity) {
if (!parentActivity->isCompositeActivity) {
throw exception::wfr_fatal_error((boost::format("Parent \"%1%\" of activity template \"%2%\" is is not a composite activity.") % parentActivity->activityName % activityName).str());
}
}
// Check that every successor has this activity as predecessor
for (auto i : successors) {
if (!i->isPredecessor(*this)) {
throw exception::wfr_fatal_error((boost::format("Activity template \"%2%\" is a successor of \"%1%\", but \"%1%\" is not a predecessor of \"%2%\".") % activityName % i->activityName).str());
}
}
// Check that every predecessor has this activity as successor
for (auto i : predecessors) {
if (!i->isSuccessor(*this)) {
throw exception::wfr_fatal_error((boost::format("Activity template \"%2%\" is a predecessor of \"%1%\", but \"%1%\" is not a successor of \"%2%\".") % activityName % i->activityName).str());
}
}
}
Activity* ActivityTemplate::createActivityFromTemplate(wfr::wfs::Workflow& workflow) {
return new Activity(workflow, *this);
}
ActivityTemplate* 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 ) {
return new AtomicActivityTemplate(id, name, parentID, branchID, succList, predList, inputHook, atomicActivityType);
}
ActivityTemplate* 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 ) {
return new AssignActivityTemplate(id, name, parentID, branchID, succList, predList, inputHook, execHook);
}
ActivityTemplate* 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 ) {
return new ContainerActivityTemplate(id, name, parentID, branchID, succList, predList, inputHook, outputHook);
}
ActivityTemplate* 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 ) {
return new ForLoopActivityTemplate(id, name, parentID, branchID, succList, predList, inputFuncHook, outputFuncHook, counterFuncHook, iterationFuncHook, isParallel);
}
ActivityTemplate* 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 ) {
return new WhileLoopActivityTemplate(id, name, parentID, branchID, succList, predList, inputFuncHook, outputFuncHook, conditionFuncHook, iterationFuncHook);
}
ActivityTemplate* 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 ) {
return new ConditionalActivityTemplate(id, name, parentID, branchID, succList, predList, inputFuncHook, outputFuncHook, branchFuncHook);
}
} /* namespace wfs */
} /* namespace wfr */
+100
View File
@@ -0,0 +1,100 @@
#include <wfr/common/wfs/AtomicActivityImplementation.h>
#include <wfr/common/wfs/implementations/PThreadActivityImplementation.h>
#include <wfr/common/wfs/implementations/OpenCLActivityImplementation.h>
#include <wfr/common/wfs/implementations/CUDAActivityImplementation.h>
#include <sstream>
#include <iostream>
namespace wfr {
namespace wfs {
std::atomic<wfr_id_t> AtomicActivityImplementation::nextImplementationID = ATOMIC_VAR_INIT(1);
AtomicActivityImplementation*
AtomicActivityImplementation::PThread( const ExecutionHookFunc& executionFuncHook,
const std::string& name,
utils::PropertyList properties,
resource::RequiredCapabilityList capabilities ) noexcept {
std::vector<resource::RequiredResourceCapability> caps(capabilities);
caps.push_back(wfr::resource::RequiredResourceCapability::GenericCPU());
return new PThreadActivityImplementation(executionFuncHook, caps, properties, name);
}
AtomicActivityImplementation*
AtomicActivityImplementation::OpenCL( const ExecutionHookFunc& executionFuncHook,
const std::string& name,
std::initializer_list<wfr_size_t> minVersion,
std::initializer_list<wfr_size_t> maxVersion,
utils::PropertyList properties,
resource::RequiredCapabilityList capabilities ) noexcept {
std::vector<resource::RequiredResourceCapability> caps(capabilities);
wfr_size_t minVersion1 = 0, minVersion2 = 0, maxVersion1 = 0, maxVersion2 = 0;
wfr_size_t versionCount = 0;
for (auto i : minVersion) {
if (versionCount == 0) {
minVersion1 = i;
} else if (versionCount == 1) {
minVersion2 = i;
} else {
break;
}
versionCount++;
}
versionCount = 0;
for (auto i : maxVersion) {
if (versionCount == 0) {
maxVersion1 = i;
} else if (versionCount == 1) {
maxVersion2 = i;
} else {
break;
}
versionCount++;
}
caps.push_back(wfr::resource::RequiredResourceCapability::OpenCL(minVersion1, minVersion2, maxVersion1, maxVersion2));
return new OpenCLActivityImplementation(executionFuncHook, capabilities, properties, name);
}
AtomicActivityImplementation*
AtomicActivityImplementation::CUDA( const ExecutionHookFunc& executionFuncHook,
const std::string& name,
std::initializer_list<wfr_size_t> minVersion,
std::initializer_list<wfr_size_t> maxVersion,
utils::PropertyList properties,
resource::RequiredCapabilityList capabilities ) noexcept {
std::vector<resource::RequiredResourceCapability> caps(capabilities);
wfr_size_t minVersion1 = 0, minVersion2 = 0, maxVersion1 = 0, maxVersion2 = 0;
wfr_size_t versionCount = 0;
for (auto i : minVersion) {
if (versionCount == 0) {
minVersion1 = i;
} else if (versionCount == 1) {
minVersion2 = i;
} else {
break;
}
versionCount++;
}
versionCount = 0;
for (auto i : maxVersion) {
if (versionCount == 0) {
maxVersion1 = i;
} else if (versionCount == 1) {
maxVersion2 = i;
} else {
break;
}
versionCount++;
}
caps.push_back(wfr::resource::RequiredResourceCapability::CUDA(minVersion1, minVersion2, maxVersion1, maxVersion2));
return new CUDAActivityImplementation(executionFuncHook, capabilities, properties, name);
}
} /* namespace execution */
} /* namespace wfr */

Some files were not shown because too many files have changed in this diff Show More