Back to Documentation

Tutorial 4: Running external tasks

Until now we only presented the way to run Groovy tasks. It is very exciting, but you would be also able to run your favourite java or C programs by the means of a workflow. That is all the purpose of this tutorial!

Introduction

In OpenMOLE, a generic task named ExternalTask offers to run external code. Of course some conditions of portability have to be satisfied. For this, the best choice is Java, since it has been designed to be portable. Other codes can also be embed like. For instance C or C++ programs can also be embed if only they can be statically compiled.

Running a C program

Running a C program through OpenMOLE is easy. All you need to do is to compile your code and to link it statically, so that it is simple to embed it.

A C Program

Let us consider the simple code hello.c:

#include <stdio.h>
 
int main(int argc,char* argv[])
{
if (argc > 1)   
        printf("Hello from C! %s\n",argv[1]);
return 0;
}

Let us compile it statically:

>> gcc -static -o hello hello.c

Note that the system command file gives a couple of information about the compilation of af binary file, namely the type of linkage and the architecture type:

>> file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.15, not stripped

Note: For complex projects you might be interrested in using CDE instead of static compilation.

A workflow executing it

In the following script, a exploration sampler is executed. Each task runs the previous C code with generated arguments:

import org.openmole.core.implementation.data.*
import org.openmole.plugin.domain.range.*
import org.openmole.plugin.sampling.complete.*
import org.openmole.core.implementation.sampling.*
import org.openmole.core.implementation.task.*
import org.openmole.core.implementation.capsule.*
import org.openmole.core.implementation.transition.*
import org.openmole.core.implementation.capsule.*
import org.openmole.plugin.task.systemexec.*
import org.openmole.core.implementation.mole.*

proto1 = new Prototype("proto1", Integer)
plan = new CompleteSampling(new Factor(proto1, new IntegerRange("0","10","1")))

exploT = new ExplorationTask("exploT",plan)
exploTC = new ExplorationCapsule(exploT)

//Defines the SystemExecTask as a launcher of the hello executable
CTask = new SystemExecTask("CTask",
                            'HelloC/hello "${proto1}"')

// Adds the HelloC path in context
CTask.addResource("/home/mathieu/Work/OpenMole/scripts/data/HelloC")

CTask.addInput(proto1)
CTaskC = new Capsule(CTask)

new ExplorationTransition(exploTC,CTaskC)

exC = new MoleExecution(new Mole(exploTC))
exC.start()

The output:

Hello from C! 0
Hello from C! 1
Hello from C! 2
Hello from C! 3
Hello from C! 4
Hello from C! 5
Hello from C! 6
Hello from C! 7
Hello from C! 8
Hello from C! 9
Hello from C! 10

Running a Java program

In the same way, a java program can be encapsulated in a task of a workflow. To achieve this, a jar archive of the program should be given to a Groovy Task.

The Java Program

Let us consider the simple code Hello.java in a directory named hello (package structure):

package hello;

public class Hello {
    public static void main(String[] args) {
        if (args.length == 1)
                System.out.println("Hello from Java! "+args[0]);
    }
}

Let us compile it and generate the jar file:

>> mkdir hello
>> mv Hello.java hello
>> cd hello
>> javac Hello.java
>> cd ..
>> jar cvf Hello.jar hello

A workflow executing the jar inside OpenMOLE runtime

Now, we will run the java program inside the OpenMOLE runtime with the following script:

import org.openmole.core.implementation.data.*
import org.openmole.plugin.domain.range.*
import org.openmole.plugin.sampling.complete.*
import org.openmole.core.implementation.sampler.*
import org.openmole.core.implementation.task.*
import org.openmole.core.implementation.capsule.*
import org.openmole.core.implementation.transition.*
import org.openmole.core.implementation.capsule.*
import org.openmole.plugin.task.groovy.*
import org.openmole.core.implementation.mole.*

proto1 = new Prototype("proto1", Integer)
sampling = new CompleteSampling(new Factor(proto1, new IntegerRange("0","10","1")))

exploT = new ExplorationTask("exploT", sampling)
exploTC = new ExplorationCapsule(exploT)

//Defines the GroovyTask as a launcher of the hello executable
JavaTask = new GroovyTask("JavaTask")
JavaTask.addLib("/home/mathieu/Work/OpenMole/scripts/data/HelloJava/Hello.jar")
JavaTask.addImport("hello.Hello")
JavaTask.setCode("Hello.main([proto1] as String[])")
JavaTask.addInput(proto1)
JavaTaskC = new Capsule(JavaTask)

new ExplorationTransition(exploTC,JavaTaskC)

exJ = new MoleExecution(new Mole(exploTC))
exJ.start()

The output:

Hello from Java! 0
Hello from Java! 1
Hello from Java! 2
Hello from Java! 3
Hello from Java! 4
Hello from Java! 5
Hello from Java! 6
Hello from Java! 7
Hello from Java! 8
Hello from Java! 9
Hello from Java! 10

Running a NetLogo program

NetLogo is a simulation platform written in Java; so that it has been easy to extend a NetLogo task as a plugin to run headless Netlogo scripts. A NetLogoTask provides the headlesse script as well as all the required commands to run it.
Let us consider the following nlogo script. This script is one of the provided example scripts on the NetLogo website.

The following script enables to run this script through an OpenMOLE workflow:

import org.openmole.core.implementation.data.*
import org.openmole.core.implementation.task.*
import org.openmole.core.implementation.capsule.*
import org.openmole.plugin.task.systemexec.*
import org.openmole.core.implementation.mole.*
import org.openmole.plugin.task.netlogo.*
import org.openmole.plugin.task.groovy.*
import org.openmole.core.implementation.transition.*

output = new Prototype("output", Double)

cmds = ["set density 62","random-seed 10","setup","repeat 50 [ go ]"]

// NetLogoTask constructor, which contains:
// - the path to the nlogo scripts and resources,
// - the command list
netLogoT = new NetLogoTask("NetLogoTask",
                           "/home/mathieu/Work/OpenMole/scripts/data/",
                           "Fire.nlogo",
                           cmds)
netLogoT.addOutput("burned-trees",output)
netLogoTC = new TaskCapsule(netLogoT)

displayT = new GroovyTask("displayT")
displayT.setCode("println 'burned-trees: ' + output")
displayT.addInput(output)
displayTC = new Capsule(displayT)

new Transition(netLogoTC,displayTC)

exG = new MoleExecution(new Mole(netLogoTC))
exG.start()

The output:

burned-trees: 4065.0

logo cemagref

logo iscpif

logo lifegrid

logo region auvergne

logo patres project