Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Main purpose of FC2K is to embed native code inside Kepler workflow. This way, you are able to connect various, physics based, calculations into chain of execution. There are few rules you have to follow while embedding native code inside Kepler:

  • your Your routine signature must be exactly the same as one suggested by FC2K
  • in In order to access IDSes, you have to use IMAS based modules inside your Fortran code
  • you You can pass data into and outside of the code in the form of:
    • primitive Primitive types
    • IDSes
    • code Code parameters
  • you You should avoid accessing external files unless it's really impossible to run the simulation without external source of data
  • all All physics related information should be exchanged only via IDSes

...

Warning
titlesource code

Source code for this sample can be found at following location

/afs/gw/swimas/resources/tutorials/2019-10-PSNC/FC2K/simple_IMAS_code Note that workflow is running such way it reads data from pulse file of user g2michal - it means you don't have to copy input data into your public/imasdb  folder. However, you are still obliged to use imasdb  in order to set location for temporary databases.


info
Info

Make sure to initialise your environment. Follow the steps here: 00. Initial setup or here: 05.3. IMAS - basic topics - environment set-up(POZ'19Oct)

Make sure to initialise test database - it will be used for temporary files

Code Block
> imasdb test


Preparing the code

First of all, we need simple code that will read data. In this sample, we will use very simple code that reads distribution IDS, shows some info, and output scalar value

Let's say we will retrieve the first time index (as integer) from the array of all times. Remember, this is just an exercise where we want to make all things work together. Don't pay attention to whether it's something meaningful or not. Let's say our actor is supposed to retrieve first time index in the IDS.

Code Block
IDS -> actor code [we treat the actor as a black box] -> integer

...

Code Block
subroutine distributiondisp(distributionin, output)

  use ids_schemas

  implicit none
 
  type (ids_distribution_sources) :: distributionin
  integer, intent(out)            :: output
 
  output = int( distributionin%time(1) )  ! we are reading data from the IDS and return it back to Kepler
 
  return

end subroutine

As you can see, we don't even access input data, yet. All we have, so far, is the API of the native code.

...

As you recall from previous session (dedicated to FC2K) we have to have library that contains native code we are supposed to run.Image Removed


Let's prepare it. We will do it, by creating Makefile  project - library will be called libdistribution_disp.a 

Code Block
# In this sample I will use ifort
# However, depending on target system (where IMAS is installed)
# it might be you have other options as well - e.g.: gfortran, pgi, NAG, etc.

F90      = ifort
COPTS    = -g -O0 -assume no2underscore -fPIC -shared-intel

# Note that you should _always_ use pkg-config to obtain
# flags for compiler and linker
# do not pass hardcoded locations unless it's really unavoidable!

LIBS     = `pkg-config --libs imas-ifort imas-lowlevel`
INCLUDES = `pkg-config --cflags imas-ifort imas-lowlevel`

# It is little bit messy here, but we need two different targets
# for the purpose of the tutorial
# first  - builds very basic code that doesn't touch IDSes data
# second - builds the code that will read IDSed data
#

first: distribution_disp.o libdistribution_disp.a

second: distribution_disp_2.o all: libdistribution_disp_2.a

libdistribution_disp.a: distribution_disp.o
  	ar -rvs libdistribution_disp.a $^

libdistribution_disp_2.a: distribution_disp_2.o
  ar -rvs libdistribution_disp.a $^

distribution_disp.o: distribution_disp.f90
  $(F90) $(COPTS) -c -o $@ $^ ${INCLUDES} $(LIBS)

distribution_disp_2.o: distribution_disp_2.f90
  	$(F90) $(COPTS) -c -o $@ $^ ${INCLUDES} $(LIBS)

# try to provide _clean_ target, so you can easily
# cleanup source tree

clean:
  rm -f *.o *.a

Once we run make we can use library inside the project

Code Block
> make first
ifort -g -O0 -assume no2underscore -fPIC -shared-intel -c -o distribution_disp.o distribution_disp.f90 `pkg-config --cflags imas-ifortifort` imas-lowlevel` `pkg-config --libs imas-ifort imas-lowlevel`ifort`
ar -rvs libdistribution_disp.a distribution_disp.o
ar: creating libdistribution_disp.a
a - distribution_disp.o

...