This document is based on material provided by Yann Frauel and describes how to make your C++ code ITM compliant and how to turn it into a Kepler actor .
You must include the header file UALClasses.h:
#include "UALClasses.h"The function arguments that are arrays or strings must be declared as pointers, as usual. All other arguments must be passed by reference (i.e. they must be declared with an ampersand):
void mycppfunction(double * vector, char * string, int & scalar)The function arguments that are CPOs must be declared with types ItmNs::Itm::cpo_type or ItmNs::Itm::cpo_typeArray. The first form is for time-independent CPOs or a single slice of a time-dependent CPO. The latter is for a complete time-dependent CPO. Note that in all cases, the CPO is considered as a single object, not an array, so it must be passed by reference as mentioned above:
void mycppfunction( ItmNs::Itm::limiter & lim, ItmNs::Itm::coreimpur & cor, ItmNs::Itm::ironmodelArray & iron)The syntax is identical for input and output arguments. For output CPOs, do not forget to use the usual methods to assign strings and allocate arrays:
lim.datainfo.dataprovider.assign("test_limiter"); iron.array.resize(3); iron.array(j).desc_iron.geom_iron.npoints.resize(3);Otherwise, the content of CPOs is accessed as usual:
cout << lim.datainfo.dataprovider << endl; cout << iron.array(j).desc_iron.geom_iron.npoints(i);
The code parameters are passed as the last argument with ItmNs::codeparam_t& type:
void mycppfunction(..., ItmNs::codeparam_t & codeparam)Each field of the param structure is a vector of 132-byte strings, not necessarily terminated by 0-character! (This does not follow C/C++ standards and should be changed in the future.)
You need to include the header directories for the UAL and Blitz:
-I$(UAL)/include -I$(UAL)/lowlevel -I$(UAL)/cppinterface/ -I/afs/efda- itm.eu/project/switm/blitz/blitz-0.9/include/Same for linking:
-L$(UAL)/lib -lUALCPPInterface -lUALLowLevel -L/afs/efda- itm.eu/project/switm/blitz/blitz-0.9/lib -lblitzAdditionally, you must compile with the -fPIC option.
We want to generate an actor that has three different types of actors as
inputs and three
different types of actors as output. Additionally, we have an integer as
input/output, a vector
of doubles as output and a string as output. We also want to use code
parameters.
Content of mycppfunction.cpp:
#include "UALClasses.h" typedef struct { char **parameters; char **default_param; char **schema; } param; void mycppfunction( ItmNs::Itm::summary & sum, ItmNs::Itm::antennas & ant, ItmNs::Itm::equilibriumArray & eq, int & x, ItmNs::Itm::limiter & lim, ItmNs::Itm::coreimpur & cor, ItmNs::Itm::ironmodelArray & iron, double * y, char * str, param & codeparam) { /* display first line of parameters */ cout << codeparam.parameters[0] << endl; cout << codeparam.default_param[0] << endl; cout << codeparam.schema[0] << endl; /* display content of inputs */ cout << "x=" << x << endl; cout << sum.time << endl; cout << sum.datainfo.dataprovider << endl; cout << ant.datainfo.dataprovider << endl; cout << eq.array(0).datainfo.dataprovider << endl; for (int k=0; k<3; k++) { for (int i=0; i<4; i++) { cout << eq.array(k).profiles_1d.psi(i)<< " "; } cout << endl; } /* fill limiter CPO */ lim.datainfo.dataprovider.assign("test_limiter"); lim.position.r.resize(5); // allocate vector for (int i=0; i<5; i++) { lim.position.r(i)=(i+1); } /* fill coreimpur CPO */ cor.datainfo.dataprovider.assign("test_coreimpur"); cor.flag.resize(3); // allocate vector for (int i=0; i<3; i++) { cor.flag(i)=(i+1)*10; } cor.time=0; // don't forget to fill time for time-dependent CPOs /* fill ironmodel CPO */ iron.array.resize(3); // allocate slices for (int j=0; j<3; j++) { char s[255]; sprintf(s,"test_ironmodel%d",j); iron.array(j).datainfo.dataprovider.assign(s); // allocate vector iron.array(j).desc_iron.geom_iron.npoints.resize(3); for (int i=0; i<3; i++) { iron.array(j).desc_iron.geom_iron.npoints(i)=j*i; } iron.array(j).time=j; // fill time for time-dependent CPOs } /* assign value to non CPO outputs */ x=5; for (int i=0; i<10; i++) { y[i]=i; } strcpy(str,"This is a test string"); }
CXXFLAGS=-g -fPIC -I$(UAL)/include -I$(UAL)/lowlevel -I$(UAL)/cppinterface/ -I$SWITMDIR/blitz/blitz-0.9/include/ LDFLAGS=-L$(UAL)/lib -lUALCPPInterface -lUALLowLevel -L/afs/efda- itm.eu/project/switm/blitz/blitz-0.9/lib -lblitz libmycppfunction.a: mycppfunction.o ar -rvs libmycppfunction.a mycppfunction.o mycppfunction.o: mycppfunction.cpp clean: rm mycppfunction.o libmycppfunction.a
First tab (Argument):
The fields Kepler, Ptolemy, and UAL are automatically filled with the values which you set by running the ITMv1 script.
Second tab (HasReturn):
Third tab (HasParameters):
For information on code specific parameters, please see How to handle code specific parameters.
Fourth tab (Source):