Run your own Python model

Most of the time, model code is not designed to be portable. For now, OpenMOLE handles Java, Scala, NetLogo and R (in the near future) via specific Tasks, but it is still far from covering the languages used to develop models around the world.

Meanwhile, you have to package your code using CARE, as explained in the Native Packaging section. The following contents expose how to handle your packaged model within OpenMOLE.

Embedding a Python script

The toy Python script for this test case is:
import sys
f = open(sys.argv[2], 'w')

We save this to hello.py. It does nothing but printing its first argument to the file passed as a second argument.

To call this script from the command line you should type: python hello.py 42 test.txt considering you have python installed on your system.

Once the script is up and running, remember that the first step to run it from OpenMOLE is to package it. This is done using CARE on your system.
care -r ~ -o python.tgz.bin python hello.py 42 test.txt

Notice how the command line is identical to the original one. The call to the python script remains unchanged, as CARE and its options are inserted at the beginning of the command line.

The result of the previous command line is a file named python.tgz.bin. It is an archive containing a portable version of your execution. It can be extracted and executed on any other Linux platform.

The method described here packages everything including python itself! Therefore there is no need to install python on the target execution machine. All that is needed is for the remote execution host to run Linux, which is the case for the vast majority of (decent) high performance computing environments.

Packaging an application is done once and for all by running the original application against CARE. CARE's re-execution mechanisms allows you to change the original command line when re-running your application. This way you can update the parameters passed on the command line and the re-execution will be impacted accordingly. As long as all the configuration files, libraries, ... were used during the original execution, there is no need to package the application multiple times with different input parameters.

You can now upload this archive to your OpenMOLE workspace and run it using the following script:
// Declare the variable
val arg = Val[Int]
val output = Val[File]

// python task
val pythonTask =
  CARETask(workDirectory / "hello.tgz.bin", "python hello.py ${arg} output.txt") set (
    inputs += arg,
    outputFiles += ("output.txt", output),
    outputs += arg

val exploration = ExplorationTask(arg in (0 to 10))

val copy = CopyFileHook(output, workDirectory / "hello${arg}.txt")
val env = LocalEnvironment(4)
exploration -< (pythonTask hook copy on env by 2)

Notions from OpenMOLE are reused in this example. If you're not too familiar with Environments, Groupings, Hooks or Samplings, check the relevant sections of the documentation.

Two things should be noted from this example:
  • The procedure to package an application is always the same, regardless of the underlying programming language / framework used.
  • The CARETask is not different from the SystemExecTask to the extent of the archive given as a first parameter.
  • These two aspects make it really easy to embed native applications in OpenMOLE. You can also read more about packaging your native models for OpenMOLE in the dedicated section.