1.1.1. 4.3.1 Generating Python code

Whenever Kepler actor is created, associated Python actor is generated inside $HOME/kepler/itm/python directory. You can use this code inside your Python based workflow. However, there are few things to remember.

Make sure to use:

ITMIMAS

Most recent PyUAL release

module load pyual/rc

Most recent PyUAL release

Make sure to import module from

/work/imas/core/pyual

Make sure to use most recent release of FC2K.

 

In case you can't use most recent release of FC2K,

the lowest version that supports Python code generation is: R3.0.16

module switch fc2k/R3.0.16

Make sure to use most recent release of FC2K.


In case you can't use most recent release of FC2K,

the lowest version that supports Python code generation is: 4.2.6

module switch fc2k/4.2.6 # at ITER

module switch imas-fc2k/4.2.6 # at Gateway

 

1.1.2. 4.3.2 Sample code

Make sure to check how to generate actor, based on compiled library. You can find this information here:

 

1.1.3. 4.3.3 How to use generated code

After generating the code, you can use it inside your Python workflow.

Let's take a simple case

subroutine nocpoparam(in_input, out_output, user_in_codeparamstruct)
  use euitm_schemas, only: type_param
  use itm_types
  use xml2eg_mdl
  use string_manipulation_tools
  use euitm_xml_parser, only: element, tree, find_parameter, euitm_xml_parse
  implicit none
  integer, intent(in)     ::      in_input
  integer, intent(out)    ::      out_output
  integer                 ::      int_value
  type(type_param) :: user_in_codeparamstruct
  type(tree) :: parameter_list
  type(element), pointer :: temp_pointer => null()
  character(len = 132) :: code_param_name
  character(len = 132) :: parameter_value
  integer(itm_i4) :: nparm
  call euitm_xml_parse(user_in_codeparamstruct, nparm, parameter_list)
  temp_pointer => parameter_list%first
  ! this is the place where we define the name of the parameter (case sensitive)
  code_param_name = 'parameters/i'
  ! this is the place where we look for the parameter value
  call find_parameter(code_param_name, parameter_value, temp_pointer)
  if (len(trim(parameter_value)).ge.1) then
    ! here comes the code that interprets the parameter
    call char2int(str2char(parameter_value), int_value)
    write (*,*) 'Value of parameters/i: ', int_value
  end if
  out_output = in_input + int_value
  return
end subroutine

You can compile it using following Makefile

F90      =ifort
COPTS    = -g -O0 -assume no2underscore -fPIC -shared-intel
LIBS     = $(shell eval-pkg-config --libs itmtypes-$(ITM_INTEL_OBJECTCODE) ual-$(ITM_INTEL_OBJECTCODE) xmllib-$(ITM_INTEL_OBJECTCODE) )
INCLUDES = $(shell eval-pkg-config --cflags itmtypes-$(ITM_INTEL_OBJECTCODE) ual-$(ITM_INTEL_OBJECTCODE) xmllib-$(ITM_INTEL_OBJECTCODE) )
all: libnocpoparamopt.a libnocpoparamdef.a
libnocpoparamopt.a: nocpo_param.o
        ar -rvs $@ $^
libnocpoparamdef.a: nocpo_param.o
        ar -rvs $@ $^
nocpo_param.o: nocpo_param.f90
        $(F90) $(COPTS) -c -o $@ $^ ${INCLUDES}
clean:
        rm -f *.o *.a

And then, after generating FC2K actor, you can access actor following way from the Python

# the name of the actor (defined in fc2k)
from actors import nocpoparam, nocpoparam_raw

def test_actor():
    # inputs
    in_input = -5
    # code parameters
    codeparams = '<?xml version="1.0"?>\n\n<parameters>\n  <r> 3.141592 </r>\n  <i> 2 </i>\n  <boolean> True False </boolean>\n  <realVec> 2.7e2  4.0 </realVec>\n  <intVec> 13 7 </intVec>\n  <booleanVec> True False </booleanVec>\n</parameters>\n'
    # run the actor
    out_output = nocpoparam(in_input, codeparams=codeparams)
    # test the results
    assert out_output == 2 + in_input
def test_actor_raw():
    # inputs
    in_input = -5
    # code parameters
    codeparams = '<?xml version="1.0"?>\n\n<parameters>\n  <r> 3.141592 </r>\n  <i> 2 </i>\n  <boolean> True False </boolean>\n  <realVec> 2.7e2  4.0 </realVec>\n  <intVec> 13 7 </intVec>\n  <booleanVec> True False </booleanVec>\n</parameters>\n'
    # run the actor
    out_output = nocpoparam_raw(in_input, codeparams=codeparams)
    # test the results
    assert out_output == 2 + in_input

if __name__ == '__main__':
    test_actor()

 

 

 

  • No labels