Versions Compared

Key

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

The information on this page is not complete

Section
Column

Ways to modify OpenIFS

We do not recommend that the source code in the oifs/src directory is edited directly as this can make it difficult to track changes and update to new versions. We recommend all code changes are maintained outside the main src directory. There are several ways in which code changes to OpenIFS could be managed:

Copy entire source

Copy the entire oifs/src to (for example) oifs/mysrc and work on the copy. The build configuration files can also be copied if required to, say, oifs/mymake. For instance you might make a new version of oifs/make/fcmcfg/oifs.cfg for your own changes or new compiler configurations files.

Multiple copies of the src directory could be used for different experiments.  The use of a version control system is recommended to track changes. The difficulty with this approach is the full source needs to be copied which makes integrating changes different and changed files are hard to see.

Copy only changed/new source

Leave code in oifs/src 'as-is' and place only modified or new code in separate directories but link to pre-compiled code in oifs/make.  This has the advantage that multiple code developments can be maintained in separate directories; code changes are easy to see and integrating new versions of the model source straightforward. A version control system can also be used.

This makes use of a facility provided by the FCM build software called 'inherited builds'. This is explained below in a series of examples.

Column
width250px

 

 

Panel
bgColorwhite
titleBGColorlightlightgrey
titleOn this page
Table of Contents
maxLevel3
indent4px
stylesquare
Panel
bgColorlightcyan
titleBGColorlightskyblue
titleDownload examples

 The files for these examples can be downloaded from....

...

Code Block
titleCreate some new code...
% mkdir mysrc/newnewsrc
% cd mysrc/newnewsrc
% cat > newsub.F90 << EOF
subroutine newsub
print *,'hello openifs'
end subroutine
EOF
% cd ../ifs/control
% vi cnt0.F90
Edit cnt0.F90 and add 'call newsub' to the start of the executable code.

...

Code Block
use = ../make
build.source = $HERE/../mysrc
build.ns-incl = newnewsrc algor ifsaux ifs surf trans openifs programs/master.F90
build.prop{fc.flags}[ifs/control/cnt0.F90] = -g -O1 -fcheck=bounds

The statement build.ns-incl lists the directories under mysrc (and the original src) that FCM is allowed to analyse and compile code. The new directory we created needs to be added to this list. Compare it with the same statement in the default configuration file: oifs/make/fcmcfg/oifs.cfg. Without this addition, the command 'fcm make' would result in an undefined reference to the subroutine newsub as it will not have compiled the code.

With this additional line, when we compile we get:

Code Block
titleFCM output (shortened)
% fcm make -v -f new-src.cfg 
[init] make
[init] make config-parse
[info] config-file=/openifs/inherit_tests/oifs/mymake/new-src.cfg
[done] make dest-init
[init] make build
[info] analyse  0.0 newsrc/newsub.F90
[info] analyse  0.0 ifs/module/yemct0.F90
[info] analyse  0.0 ifs/control/cnt0.F90
[info] sources: total=2193, analysed=3, elapsed-time=0.5s, total-time=0.0s
[info] target-tree-analysis: elapsed-time=13.2s
[info] compile    0.0 M yemct0.o             <- ifs/module/yemct0.F90
[info] compile+   0.0 M yemct0.mod           <- ifs/module/yemct0.F90
[info] ext-iface  0.0 U cnt3.intfb.h         <- ifs/control/cnt3.F90
[info] compile    0.0 U cnt2.o               <- ifs/control/cnt2.F90
[info] ext-iface  0.0 U cnt0.intfb.h         <- ifs/control/cnt0.F90
[info] compile    0.1 U cnt3.o               <- ifs/control/cnt3.F90
[info] compile    0.1 M cnt0.o               <- ifs/control/cnt0.F90
[FAIL] make build          # 25.4s
[FAIL] make                # 25.6s
[FAIL] mpif90 -obin/master.exe /media/hugetmp/Backedup/openifs/inherit_tests/oifs/make/build/o/master.o -L/var/tmp/tmpdir/nagc/jtmp.6858/LvpNtq0TxD -lmaster -fopenmp /home/rd/openifs/software/grib_api/1.9.18/grib_api-gcc-4.5.0/lib/libgrib_api_f90.a /home/rd/openifs/software/grib_api/1.9.18/grib_api-gcc-4.5.0/lib/libgrib_api.a -L/usr/local/apps/lapack/3.4.1/LP64 -llapack -lblas -lm # rc=1
[FAIL] /var/tmp/tmpdir/nagc/jtmp.6858/LvpNtq0TxD/libmaster.a(cnt0.o): In function `cnt0':
[FAIL] /media/hugetmp/Backedup/openifs/inherit_tests/oifs/mysrc3/ifs/control/cnt0.F90:101: undefined reference to `newsub_'
[FAIL] collect2: ld returned 1 exit status

FCM correctly analysed the new code now that the configuration file lists the directory containing it, but FCM failed to compile the file newsrc/newsub.F90.

Why?  The reason is that the code does not have enough information to determine where the subroutine 'newsub' comes from. As it's not a module (no USE statement), nor has an explicit interface (no #include "newsub.intfb.h") FCM will assume it comes from an external library.

We can correct the problem in two ways. The preferred way is to add an explicit interface for the subroutine call making it clear the source code is not from an external library. This also has the advantage that the compiler can check arguments passed to the subroutine are correct.  Interface files for subroutines are generated automatically by FCM and do not need to be created by the user.

Code Block
titleEdit mysrc/ifs/control/cnt0.F90 to add the new interface statement:
#include "su0yoma.intfb.h"
#include "su0yomb.intfb.h"
#include "newsub.intfb.h"
!     ------------------------------------------------------------------
call newsub

 

 

 

HTML
<script type="text/javascript" src="https://software.ecmwf.int/issues/s/en_UKet2vtj/787/12/1.2.5/_/download/batch/com.atlassian.jira.collector.plugin.jira-issue-collector-plugin:issuecollector/com.atlassian.jira.collector.plugin.jira-issue-collector-plugin:issuecollector.js?collectorId=5fd84ec6"></script>

...