Run your Python model

Suggest edits
Documentation > Run > Package Native Code

Contents

Most of the time, model code is not designed to be portable. OpenMOLE handles natively Java, Scala, NetLogo and R via specific Tasks. However, if no specific task has yet been designed for the language/platform you can still embed you code into OpenMOLE using:

Embedding a Python script 🔗

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

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 copy = CopyFileHook(output, workDirectory / "hello${arg}.txt")
val env = LocalEnvironment(4)

DirectSampling(
  evaluation = pythonTask hook copy on env by 2,
  sampling = arg in (0 to 10)
)

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.