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.
#include <iostream>
#include <sstream>
#include <fstream>
double* model_computation(double param1, double param2, double output[]){
std::cout << "model computation with parameters " << param1 << " and " << param2 << " \n" ;
output[0] = param1 * 10 ;
output[1] = param2 * 20 ;
return output ;
}
int main(int argc , char* argv[]){
// extract args from command line
std::istringstream iss1 (argv[1]) ;
std::istringstream iss2 (argv[2]) ;
double val1 ;
double val2 ;
double output[2];
if (iss1 >> val1 && iss2 >> val2 ){
double* result = model_computation(val1, val2, output) ; //model computation call
std::cout << "log : compute first result "<< result[0] << '\n' ;
std::cout << "log : compute second result " << result[1] << '\n' ;
//CSV file dump
std::ofstream myfile;
myfile.open ("results.txt");
myfile << result[0] << ','<< result[1]<< "\n";
myfile.close();
return 0;
}
else{
std::cout << "Wrong arg : not a double " ;
return -1;
}
}
> g++ hello_world.cpp
> ./a.out 12.24 24
model computation with parameters 12.24 and 24
log : compute first result 122.4
log : compute second result 480
care-x86_64 -o ./cpp.tgz.bin -r ~ ./a.out 12.24 24
Please see the Native packaging page for more details.
The packaging step produces the following output:
care info: concealed path: $HOME /home/paul
care info: concealed path: /tmp
care info: revealed path: $PWD /home/paul/dev/cppExampleDocOpenMOLE
care info: revealed path: /home/paul/dev/cppExampleDocOpenMOLE/a.out
care info: revealed path: /home/paul
care info: ----------------------------------------------------------------------
main function call
model computation with parameters 12.34 and 24
log : compute first result 122.4
log : compute second result 480
care info: ----------------------------------------------------------------------
care info: Hints:
care info: - search for "conceal" in `care -h` if the execution didn't go as expected.
care info: - run `././cpp.tgz.bin` or `care -x ./cpp.tgz.bin` to extract the output archive correctly.
cpp.tgz.bin
and results.txt
, respectively the CARE archive and the results file.ExplorationTask
to run the model several times with different input values, with this script:
// Declare the variables (from the OpenMOLE point of view)
val arg1 = Val[Double]
val arg2 = Val[Double]
val output = Val[File]
// exploration of the inputs range
val exploration = ExplorationTask(
(arg1 in (0.0 to 5.0 by 1.0)) x
(arg2 in (0.0 until 4.0 by 1.0))
)
// the care task for our archive
val cppTask =
CARETask(workDirectory / "cpp.tgz.bin", "./a.out ${arg1} ${arg2}") set (
inputs += (arg1, arg2),
outputFiles += ("results.txt", output),
outputs += (arg1, arg2)
)
// we fetch the data via a CopyFileHook, for each input combination
val copy = CopyFileHook(output, workDirectory / "cpp${arg1}${arg2}.txt")
// we run that locally , on 4 cores
val env = LocalEnvironment(4)
// the workflow
exploration -< (cppTask hook copy on env)
This script uses a Hook
to catch the output file, check the dedicated page for more details.
Let's try this example on your own machine:
model computation with parameters 4and 2
log : compute first result 40
log : compute second result 40
model computation with parameters 3and 9
log : compute first result 30
log : compute second result 180
cpp2.01.0.txt
, are located in the directory where we uploaded our CARE packaged code.
This is not a smart move if you have a lot of file to manage, so we should put them in a result dedicated directory, in order to compress the whole thing at the end of the experiment and download the resulting archive.
To do that, let's replace the CopyFileHook
line by the following:
val copy = CopyFileHook(output, workDirectory /"results/cpp${arg1}${arg2}.txt")