Model Workflow

Introduction

The APP4MC AMALTHEA platform provides the option to define a workflow on a model with different steps. AMALTHEA provides a simple API for implementing such a workflow. The definition of the workflow can be done either in plain Java or any other language, which is able to access Java classes.
The EASE framework provides a scripting environment inside of Eclipse with different script engines like Rhino (JavaScript), Jython or Groovy. AMALTHEA provides a sample and some convenient helpers based on EASE to define and execute such a workflow.
As an alternative APP4MC provides also an implementation for the Modeling Workflow Engine 2 (MWE2), coming from the Xtext framework. The definition of the workflow can be done in a textual syntax from MWE2, containing different components which are working on the given model.
AMALTHEA provides several plugins for this purpose:

org.eclipse.app4mc.amalthea.workflow.core
Includes basic API and some predefined workflow components, which can be used independent from any framework.
org.eclipse.app4mc.amalthea.workflow.ease
Provides some helper modules for EASE
org.eclipse.app4mc.amalthea.workflow.base
Provides basic classes for usage with MWE2

General Structure

The plugin org.eclipse.app4mc.amalthea.workflow.core provides a general abstract class org.eclipse.app4mc.amalthea.workflow.core.WorkflowComponent which can be used to extend in the case to provide or implement an own workflow step.

It provides the following features:

The interface org.eclipse.app4mc.amalthea.workflow.core.Context provides convenient methods to store and retrieve data in a org.eclipse.app4mc.amalthea.workflow.core.WorkflowComponent.

The class org.eclipse.app4mc.amalthea.workflow.core.DefaultContext is a default implementation using an internal java.util.HashMap to store the data.

A sample workflow implementation with two components WorkfklowComponent1 and WorkflowComponent2 can look like the following structure.

Both classes are extending org.eclipse.app4mc.amalthea.workflow.core.WorkflowComponent.

The next step is to create a WorkflowDefinition, which needs to do the following steps:

  1. Create an instance of a org.eclipse.app4mc.amalthea.workflow.core.Context using the org.eclipse.app4mc.amalthea.workflow.core.DefaultContext
  2. Create an instance of WorkfklowComponent1 and configure it if needed with the proper setter methods
  3. Call the run method of WorkfklowComponent1 and pass the context
  4. Create an instance of WorkfklowComponent2 and configure it if needed with the proper setter methods
  5. Call the run method of WorkfklowComponent2 and pass the context

Therefore using the context, data can be shared between the different workflow component implementations.
The following diagram is showing this flow in more detail:

Available Basic Components

The APP4MC AMALTHEA platform ships with some available workflow steps, which can be used out of the box.

Model Reader

The component org.eclipse.app4mc.amalthea.workflow.component.ModelReader reads a given list of files containing AMALTHEA models. The result model is stored in the AMALTHEA_SLOT as default. Please refer the JavaDoc for more details.

Simple configuration inside of a workflow can look like the following:

ModelReader reader = new ModelReader();
reader.addFileName("path to file");
reader.run(ctx);

Model Writer

The component org.eclipse.app4mc.amalthea.workflow.component.ModelWriter writes a given AMALTHEA model to either one file or several files. As default the current available model in the AMALTHEA_SLOT is taken.
The following parameters are available to set:

Sample configuration inside of a workflow:

ModelWriter writer = new ModelWriter();
writer.setOutputDir("path to dir");
writer.setFileName("output.amxmi");
writer.run(ctx);

Add Schedule Points

The component org.eclipse.app4mc.amalthea.workflow.component.AddSchedulePoints modifies a given model (default in the AMALTHEA_SLOT) in that way, that in the org.eclipse.app4mc.amalthea.model.sw.SWModel the contained org.eclipse.app4mc.amalthea.model.sw.Task elements are checked if the preemption is set to cooperative. If this is the case, it will add between the elements of the org.eclipse.app4mc.amalthea.model.sw.CallGraph new elements of type org.eclipse.app4mc.amalthea.model.sw.SchedulePoint.

Sample configuration inside of a workflow:

AddSchedulePoints addSchedulePoints = new AddSchedulePoints();
addSchedulePoints.run(ctx);

Other Components

Create Tasks

The component org.eclipse.app4mc.multicore.openmapping.workflow.CreateTasks from the plugin org.eclipse.app4mc.multicore.openmapping is the corresponding workflow element for the Task creation example. It takes a copy of a given model (defaults to AMALTHEA_SLOT) and performs the action org.eclipse.app4mc.multicore.openmapping.algorithms.taskgen.pragmatic.PragmaticTaskCreator. The result of this action is stored as default in the model slot createtasks.

Sample configuration inside of a workflow:

CreateTasks ct = new CreateTasks();
ct.run(ctx);

Generate Mapping

The component org.eclipse.app4mc.multicore.openmapping.workflow.GenerateMapping from the plugin org.eclipse.app4mc.multicore.openmapping is the corresponding workflow element for the Mapping example. It takes a copy of a given model (defaults to AMALTHEA_SLOT) and performs one of the actions org.eclipse.app4mc.multicore.openmapping.algorithms.heuristic.lb.LoadBalancingDFG or org.eclipse.app4mc.multicore.openmapping.algorithms.ilp.lb.ILPBasedLoadBalancing or org.eclipse.app4mc.multicore.openmapping.algorithms.ilp.energyminimization.EnergyMinimization or org.eclipse.app4mc.multicore.openmapping.algorithms.ga.lb.GABasedLoadBalancing depending on the parameter mappingAlg. The result of this action is stored as default in the model slot mapping.
Parameter:

Sample configuration inside of a workflow:

GenerateMapping mappingDfg = new GenerateMapping();
mappingDfg.setModelSlot("createtasks");
mappingDfg.setMappingAlg("dfg");
mappingDfg.setEnableLog(true);
mappingDfg.run(ctx);

EASE modules

The purpose of using EASE is to provide one way to define and run a workflow for a model.
Therefore APP4MC provides some helper methods to be used in the EASE scripting environment.
The modules are provided by the plugin org.eclipse.app4mc.amalthea.workflow.ease.

Workflow Module

The workflow module provides some helpers regarding running a APP4MC workflow definition based on EASE.
The general module can be loaded with the following line:

loadModule('/APP4MC/Workflow')

EASE opens an own Eclipse console by default to show the output of the executed script when using right click and Run as -> EASE Script. Therefore if you are using Log4J for your logging, you can use the following provided methods to configure dedicated Log4J Loggers to use also the EASE console for output.

The following overview gives an overview about the available helper methods:

Method Params Description
addLoggerToConsole String loggerName Adds a Log4J logger to the output of the current used output of the EASE script engine.
addLoggerToConsole String loggerName, String pattern Adds a Log4J logger to the output of the current used output of the EASE script engine with a given pattern, see org.apache.log4j.PatternLayout for more details
endWorkflow - Basic finish actions to be performed, should be called at the end

MWE2 Workflow

The plugin org.eclipse.app4mc.amalthea.workflow.base provides a general class org.eclipse.app4mc.amalthea.workflow.base.AmaltheaWorkflow which can be used to extend in the case to provide or implement an own workflow step based on Modeling Workflow Engine 2 (MWE2).
It provides the following features:

To use the AMALTHEA model workflow component, currently the following dependencies are needed in addition to the AMALTHEA model plugins:

MWE2 Components

The APP4MC AMALTHEA platform ships with some available workflow steps for usage together with MWE2.
Note: To use the components below as shown in the corresponding configurations, the classes must be imported!

Reader

The component org.eclipse.app4mc.amalthea.workflow.util.AmaltheaReader reads a given list of files containing AMALTHEA models. The result model is stored in the AMALTHEA_SLOT as default.

Sample configuration inside of a workflow:

component = AmaltheaReader {
	fileName = "${base}/model/AMALTHEA_Democar_MappingExample.amxmi"
	fileName = "${base}/model/AMALTHEA_Democar_MappingExample-hw.amxmi"
}
Writer

The component org.eclipse.app4mc.amalthea.workflow.util.AmaltheaWriter writes a given AMALTHEA model to either one file or several files. As default the current available model in the AMALTHEA_SLOT is taken.
The following parameters are available to set:

Sample configuration inside of a workflow:

component = AmaltheaWriter {
	fileName = "createtasks"
	singleFile = true
	outputDir = "${base}/workflow-output"
}
Add Schedule Points

The component org.eclipse.app4mc.amalthea.workflow.util.AddSchedulePoints modifies a given model (default in the AMALTHEA_SLOT) in that way, that in the org.eclipse.app4mc.amalthea.model.SWModel the contained org.eclipse.app4mc.amalthea.model.Task elements are checked if the preemption is set to cooperative. If this is the case, it will add between the elements of the org.eclipse.app4mc.amalthea.model.CallGraph new elements of type org.eclipse.app4mc.amalthea.model.SchedulePoint.

Sample configuration inside of a workflow:

component = AddSchedulePoints {
}

Current Limitations / Open Points

As there are two options available (Basic Java/EASE and MWE2 based) for running a workflow, there are currently also some limitations existent. The following table should help you to chose the right base:

Use Case Supported in MWE2 Supported in EASE Reason
Loading of AMALTHEA model files (with cross document references) using workflow/script file no yes
  • MWE2: Separate Java runtime is started by MWE2, Sphinx relies in running Eclipse instance
  • EASE: Makes use of the runtime from runtime workbench
Using workflow components which are available in the runtime (i.e. workflow component classes which are already available in plugins as a part of the runtime product) yes yes
  • MWE2: Separate runtime is started by MWE2 and if plugin (containing workflow component) is added as dependency then its classes are loaded
  • EASE: Makes use of the runtime from runtime workbench and has access to all classes
Defining custom workflow components (Java classes) and using them in the workflow/script file located in the same workspace yes yes
  • MWE2: Custom workflow component objects can be directly created in MWE2 script file(as in Java) and there is no restriction [irrespective of whether there is constructor]
  • EASE: As the runtime from the launched workbench (runtime workbench) is used, custom Java classes available in the workspace are not part of the classpath. For creation of objects of custom workflow components (Java classes): EASE JVM module createInstance API should be used by specifying the absolute path of the Java class
Using Java classes (available in the runtime workspace from other plugins --> these classes are not part of runtime workbench) inside custom workflow component Java classes yes yes
  • MWE2: works perfectly (just like native)
  • EASE: works, for creation of object from custom Java classes, EASE JVM module is used, which compiles the used Java classes and creates objects of them
Using classes (API) from 3rd party libraries (added in the classpath of the plugin)inside custom workflow component java classes yes no(*)
  • MWE2: As new Java runtime is created, all the required plugins & jars are added in the classpath
  • EASE: In the current implementation only the runtime from workbench is considered, jars from the classpath of a plugin (created newly in the runtime workbench) are not loaded in the runtime of EASE. Due to this reason, execution of the script fails with an exception java.lang.NoClassDefFoundError: <your used class from 3rd party lib>

*: This feature is already available in the master branch of EASE. Consider to update it to an newer version than 0.3.0 if it is needed.

Sample for using EASE JVM module to load a class from the same workspace:

var labelsCreationComponent = createInstance("workspace://com.ease.example/src/org/eclipse/app4mc/amalthea/example/workflow/components/CreateLabelsComponent.java")

Overall Sample

A sample workflow is available in the AMALTHEA example projects inside of org.eclipse.app4mc.amalthea.example.democar.mapping/workflow/sample_workflow.js. In general this workflow contains all steps as shown in the AMALTHEA examples tutorial Task creation and Mapping example, but it can be executed in one script. Execute it by doing a right click and then Run As -> EASE Script.
The following steps are performed in the sample configuration:

  1. Read the files AMALTHEA_Democar_MappingExample.amxmi and AMALTHEA_Democar_MappingExample-hw.amxmi inside if the model folder. Result model is saved in the default AMALTHEA_SLOT.
  2. Perform the Create Tasks component
  3. Write the result model available in the createtasks model slot to a single model file createtasks in the directory workflow-output.
  4. Perform the Generate Mapping component with the dfg algorithm on the result of the Create Tasks component. This is done by specifying modelSlot = "createtasks".
  5. Write the result model available in the mapping model slot to a single model file mapping_dfg in the directory workflow-output.
  6. Perform the Generate Mapping component with the ilp algorithm on the result of the Create Tasks component. This is done by specifying modelSlot = "createtasks". In addition the result slot is overwritten by resultSlot = "mappingilp", as the previous run of Generate Mapping is already stored in the mapping slot.
  7. Write the result model available in the mapping_ilp model slot to a single model file mapping_ilp in the directory workflow-output.

The following diagram shows a snippet of this workflow:

Adding a new workflow component

Below you will find a sample how to add and implement a new workflow component.

Create project

  1. Add a new plugin project with the name my.sample.workflow
  2. Open the MANIFEST.MF in the META-INF folder.
  3. Switch to the tab Dependencies to add the following plugin dependencies: org.eclipse.app4mc.amalthea.workflow.core
  4. Add a new class my.sample.workflow.HelloWorld, which is extending org.eclipse.app4mc.amalthea.workflow.core.WorkflowComponent.
  5. Implement something in the runInternal(Context ctx) throws WorkflowException method (see sample below).
@Override
protected void runInternal(Context ctx) throws WorkflowException {
	// some checking if sw model is available
	if (null == getAmaltheaModel(ctx).getSwModel()) {
		throw new WorkflowException("No proper SWModel available!");
	}
	this.log.info("Number of tasks in model: " + getAmaltheaModel(ctx).getSwModel().getTasks().size());
}

Execute the new component in the available sample

The previous created class my.sample.workflow.HelloWorld should be added to a workflow.
Therefore we are using the provided sample project from APP4MC org.eclipse.app4mc.amalthea.example.democar.mapping.
Before starting with the next steps, we need to start a new runtime from the existing workspace, so that the plugin my.sample.workflow is already loaded.

Note: If you want to use the classes from the plugin my.sample.workflow in a EASE script located in the same workspace, you can create an instance of it at runtime using the JVM module of EASE. Please consider the EASE documentation for more details.

  1. Add the AMALTHEA democar samples to your workspace (File – New – Example – Democar Examples)
  2. Go to the project org.eclipse.app4mc.amalthea.example.democar.mapping.
  3. Open the sample_workflow.js located in the workflow folder.
  4. Add to the imports: importPackage(my.sample.workflow)
  5. Add to the logger configs: addLoggerToConsole("my.sample.workflow")
  6. Add the First snippet below after the first AmaltheaReader component and before the CreateTasks component.
  7. Run the script by doing a right click -> Run As -> EASE Script
var ctx = new DefaultContext()

//Reader
var reader = new ModelReader()
reader.addFileName(MODEL_LOCATION1)
reader.addFileName(MODEL_LOCATION2)
reader.run(ctx)

var hw = new HelloWorld()
hw.run(ctx)

//create tasks based on initial model
//result is saved in modelslot createtasks
var createTasks = new CreateTasks()
createTasks.run(ctx)