Newer
Older
#!/bin/bash
#set -x
set -e
#This script:
# - compiles the AROME model using a specific commit for the externalised physics
# - runs a small 3D case and checks if results are identical to a given version
#small_3D_np2: on only 2 procs
#small_3D_alt1: options around time-step dependency, CFRAC_ICE_*='T', CSEDIM='SPLI', LSEDIM_AFTER=.T.
#small_3D_alt2: CCLOUD='OLD3'
#small_3D_alt3: PRFR
#small_3D_alt4: small_3D_alt1 + CSNOWRIMING='OLD'
#small_3D_alt5: CCLOUD='ICE4'
#small_3D_alt6: CMF_UPDRAFT='RAHA', CMF_CLOUD='BIGA'

RIETTE Sébastien
committed
#small_3D_alt7: CMF_CLOUD='STAT', LOSIGMAS=.FALSE. #Needs 2 corrections in original cycle 48
#small_3D_alt8: CMF_UPDRAFT='RHCJ'
#small_3D_alt9: CCLOUD='OLD3', OCND2=.T.
#The small_3D_alt7 needed a correction in apl_arome which has been introduced in d37dd1f. But the reference pack has been modified
# afterwards to enable this test case to be run (documented in INSTALL_pack_ial.md). In consequence, the reference
# to use is the same as for the other test cases and this case cannot be run for commit before d37dd1f (20 April 2022).
#The small_3D_alt8 is not included in the list of available tests because it needs to be compared against a special commit.
# Indeed, on 3 February 2022 (commit 907e906) the mesonh version of compute_updraft_rhcj.F90 has been put in the common directory.
# The reference is
# the commit 907e906 when running in 48t1
# the commit d10ed48 when running in 48t3
# Indeed, it was checked that edc3f88 (last commit in 48t1) is identical to 907e906.
# Between edc3f88 and d10ed48 only the reference change, physics source code is identical.
#The small_3D_alt9 is not included in the list of available tests because it needs to be compared against a special commit.
# Indeed, some pieces are missing in the reference pack. Theses pieces have been added in commit edc3f88 during phasing with 48t3.
# The reference is
# the commit edc3f88 (21 September 2022) when running in 48t1
# the commit d10ed48 in 48t3 (29 september 2022) when running in 48t3
# Between edc3f88 and d10ed48 only the reference change, physics source code is identical.
#Special pack names:
# - recompil: original source code (everything under mpa)
# - split_48t1: original 48t1 source code but with physics source code under phyex directory
# - split_48t3: same as split_48t1 but for the 48t3 cycle
# - split: symbolic link to split_48t1 (backward compatibility)
specialPack="ori split split_48t1 split_48t3 recompil"
availTests="small_3D,small_3D_np2,small_3D_alt1,small_3D_alt2,small_3D_alt3,small_3D_alt4,small_3D_alt5,small_3D_alt6,small_3D_alt7"
separator='_' #- be carrefull, gmkpack (at least on belenos) has multiple allergies (':', '.', '@')
#- seprator must be in sync with prep_code.sh separator
PHYEXTOOLSDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
dirpack=$PHYEXTOOLSDIR/pack
dirconf=$PHYEXTOOLSDIR/conf_tests
if [ $(hostname | cut -c 1-7) == 'belenos' -o $(hostname | cut -c 1-7) == 'taranis' ]; then
HPC=1
gmkpack_l=MIMPIIFC1805
gmkpack_o=2y
defaultMainPackVersion=01
defaultRef='split_${cycle}'
else
HPC=0
gmkpack_l=MPIGFORTRAN920DBL
gmkpack_o=xfftw
defaultMainPackVersion=01
defaultRef='split_${cycle}'
fi
mainPackVersion=${mainPackVersion:-${defaultMainPackVersion}}
extraCompilationCheck=1
function usage {
echo "Usage: $0 [-h] [-c] [-r] [-C] [-s] [-f] [--noexpand] [-t test] commit reference"
echo "commit commit hash (or a directory, or among $specialPack) to test"
echo "reference commit hash (or a directory, or among $specialPack) REF to use as a reference"
echo "-s suppress compilation pack"
echo "-c performs compilation"
echo "-r runs the tests"
echo "-C checks the result against the reference"
echo "-t comma separated list of tests to execute"
echo " or ALL to execute all tests"
echo "--noexpand do not use mnh_expand (code will be in array-syntax)"
echo "-f full compilation (do not use pre-compiled pack)"
echo "--cycle CYCLE to force using CYCLE"

RIETTE Sébastien
committed
echo "--repo-user user hosting the PHYEX repository on github,"
echo " defaults to the env variable PHYEXREOuser (=$PHYEXREOuser)"
echo "--repo-protocol protocol (https or ssh) to reach the PHYEX repository on github,"
echo " defaults to the env variable PHYEXREOprotocol (=$PHYEXREOprotocol)"
echo ""
echo "If nothing is asked (compilation, running, check) everything is done"
echo
echo "With the special reference REF commit, a suitable reference is guessed"
echo
echo "If no test is aked for, the default one ($defaultTest) is executed"
echo
echo "The directory (for commit only, not ref) can take the form server:directory"
echo
echo "If using a directory (for commit or reference) it must contain at least one '/'"
echo
echo "The cycle will be guessed from the source code"
}
compilation=0
run=0
check=0
commit=""
reference=""
tests=""
suppress=0
useexpand=1
fullcompilation=0
cycle=""
while [ -n "$1" ]; do
case "$1" in
'-h') usage;;
'-s') suppress=1;;
'-c') compilation=1;;
'-r') run=$(($run+1));;
'-C') check=1;;
'-t') tests="$2"; shift;;
'--noexpand') useexpand=0;;
'-f') fullcompilation=1;;
'--cycle') cycle="$2"; shift;;

RIETTE Sébastien
committed
'--repo-user') export PHYEXREPOuser=$2; shift;;
'--repo-protocol') export PHYEXREPOprotocol=$2; shift;;
#--) shift; break ;;
*) if [ -z "${commit-}" ]; then
commit=$1
else
reference=$1
else
echo "Only two commit hash allowed on command line"
exit 1
fi
fi;;
esac
shift
done
HOMEPACK=${HOMEPACK:=$HOME/pack}
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
function exescript () {
#usage: exescript <output file> <script> [arg [arg ...]]
output=$1
shift
if [ $HPC -eq 1 ]; then
sbatch --wait -o $output $@
cat $output
else
$@ 2>&1 | tee $output
fi
}
if [ -z "${tests-}" ]; then
tests=$defaultTest
elif [ $tests == 'ALL' ]; then
tests=$availTests
fi
if [ $compilation -eq 0 -a \
$run -eq 0 -a \
$check -eq 0 ]; then
compilation=1
run=1
check=1
fi
if [ -z "${commit-}" ]; then
echo "At least one commit hash must be provided on command line"
exit 2
fi
if [ $check -eq 1 -a -z "${reference-}" ]; then
echo "To perform a comparison two commit hashes are mandatory on the command line"
exit 3
fi

RIETTE Sébastien
committed
function apl_arome_content2cycle {
# variable content_apl_arome must contain the source code of apl_arome.F90
if grep CPG_DYN_TYPE <(echo $content_apl_arome) > /dev/null; then
echo 48t3
else
echo 48t1
fi
}

RIETTE Sébastien
committed
function ial_version_content2cycle {
# variable content_ial_version must contain the source code of ial_version.json
content_ial_version=$content_ial_version python3 -c "import json; import os; print(json.loads(os.environ['content_ial_version'])['cycle'])"
}
#Name is choosen such as it can be produced with a main pack: PHYEX/${cycle}_XXXXXXXXX.01.${gmkpack_l}.${gmkpack_o}
fromdir=''
if echo $commit | grep '/' > /dev/null; then
fromdir=$commit
if [ "$cycle" == "" ]; then

RIETTE Sébastien
committed
content_ial_version=$(scp $commit/src/arome/ial_version.json /dev/stdout 2>/dev/null || echo "")
if [ "$content_ial_version" == "" ]; then
content_apl_arome=$(scp $commit/src/arome/ext/apl_arome.F90 /dev/stdout)
cycle=$(apl_arome_content2cycle)
else
cycle=$(ial_version_content2cycle)
fi
fi
packBranch=$(echo $commit | sed 's/\//'${separator}'/g' | sed 's/:/'${separator}'/g' | sed 's/\./'${separator}'/g')
name="PHYEX/${cycle}_${packBranch}.01.${gmkpack_l}.${gmkpack_o}"
[ $suppress -eq 1 -a -d $HOMEPACK/$name ] && rm -rf $HOMEPACK/$name
elif echo $specialPack | grep -w $commit > /dev/null; then
name="PHYEX/$commit"
if [ $commit == split_48t3 ]; then
cycle=48t3
else
cycle=48t1
fi
if [ "$cycle" == "" ]; then
if [[ $commit == arome${separator}* ]]; then
apl_arome_file="ext/apl_arome.F90"
ial_version_file="ext/ial_version.json"
else
apl_arome_file="src/arome/ext/apl_arome.F90"
ial_version_file="src/arome/ial_version.json"
fi
content_ial_version=$(wget --no-check-certificate https://raw.githubusercontent.com/$PHYEXREPOuser/PHYEX/${commit}/$ial_version_file -O - 2>/dev/null || echo "")

RIETTE Sébastien
committed
if [ "$content_ial_version" == "" ]; then
content_apl_arome=$(wget --no-check-certificate https://raw.githubusercontent.com/$PHYEXREPOuser/PHYEX/${commit}/$apl_arome_file -O - 2>/dev/null)

RIETTE Sébastien
committed
cycle=$(apl_arome_content2cycle)
else
cycle=$(ial_version_content2cycle)
fi
fi
name="PHYEX/${cycle}_${packBranch}.01.${gmkpack_l}.${gmkpack_o}"
[ $suppress -eq 1 -a -d $HOMEPACK/$name ] && rm -rf $HOMEPACK/$name
fi
if [ ! -z "${reference-}" ]; then
[ $reference == 'REF' ] && reference=$(eval echo $defaultRef) #echo to replace ${cycle} by value
reffromdir=''
if echo $reference | grep '/' > /dev/null; then
reffromdir=$reference
refname="PHYEX/*_$(echo $reference | sed 's/\//'${separator}'/g' | sed 's/:/'${separator}'/g' | sed 's/\./'${separator}'/g').01.${gmkpack_l}.${gmkpack_o}"
elif echo $specialPack | grep -w $reference > /dev/null; then
refname="PHYEX/$reference"
else
refname="PHYEX/*_COMMIT${reference}.01.${gmkpack_l}.${gmkpack_o}"
fi
fi
if [ $compilation -eq 1 ]; then
echo "### Compilation of commit $commit"
if echo $specialPack | grep -w $commit > /dev/null; then
echo "Special commit '$commit' cannot be compiled with this script"
exit 4
fi
if [ -d $HOMEPACK/$name ]; then
echo "Pack already exists ($HOMEPACK/$name), suppress it to be able to compile it again (or use the -s option to automatically suppress it)"
exit 5
fi
export GMKTMP=/dev/shm
if [ $fullcompilation == 0 ]; then
basepack=${cycle}_main.01.${gmkpack_l}.${gmkpack_o}
#[ $HPC -eq 0 -a ! -d $ROOTPACK/$basepack ] && getpack $basepack
gmkpack -r ${cycle} -b phyex -v $mainPackVersion -l ${gmkpack_l} -o ${gmkpack_o} -p masterodb \
-f $dirpack/ \
-u $name
reftree='main'
else
#Create main pack
gmkpack -a -r ${cycle} -b ${packBranch} -n 01 -l ${gmkpack_l} -o ${gmkpack_o} -p masterodb -h $HOMEPACK/PHYEX
#Populate (we keep everything from the official source code except internals and module subdirectories of mpa)
cd $HOMEPACK/$name/src/local/
ssh sxphynh.cnrm.meteo.fr "wget http://anonymous:mto@webdav.cnrm.meteo.fr/public/algo/khatib/src/${cycle}_main.01.tgz -O -" > ${cycle}_main.01.tgz
wget http://anonymous:mto@webdav.cnrm.meteo.fr/public/algo/khatib/src/${cycle}_main.01.tgz
tar xf ${cycle}_main.01.tgz
rm -f ${cycle}_main.01.tgz
for rep in turb micro conv; do
mkdir -p phyex/$rep
rm -rf mpa/$rep/internals mpa/$rep/module
done
if [ -f /cnrm/algo/khatib/drhook.c_for_ubuntu.tar ]; then
#If file exists it means that we are running on a CTI computer, so we are using ubuntu
tar xf /cnrm/algo/khatib/drhook.c_for_ubuntu.tar
fi
#Special modification of the compilation configuration file and script
sed -i 's/-ftree-vectorize//' $HOMEPACK/$name/.gmkfile/${gmkpack_l}.*
sed -i "/MACROS_FRT/s/$/ -DREPRO48/" $HOMEPACK/$name/.gmkfile/${gmkpack_l}.*
#sed -i "s/PHYEX\/${cycle}_$$.01.${gmkpack_l}.${gmkpack_o}/$(echo $name | sed 's/\//\\\//')/" $HOMEPACK/$name/ics_masterodb #this line could be used if pack was renamed before compilation but it does not work on belenos
resetpack -f #Is it really useful?
reftree='local'
fi
MNH_EXPAND_DIR=$PHYEXTOOLSDIR/mnh_expand
export PATH=$MNH_EXPAND_DIR/filepp:$MNH_EXPAND_DIR/MNH_Expand_Array:$PATH
if [ $useexpand == 1 ]; then
expand_options="-D MNH_EXPAND -D MNH_EXPAND_LOOP"
else
expand_options=""
fi
subs="-s gmkpack_ignored_files -s turb -s micro -s aux -s ext -s conv -s externals" #externals is the old name for aux/ext
prep_code=$PHYEXTOOLSDIR/prep_code.sh
if [ "$fromdir" == '' ]; then
echo "Clone repository, and checkout commit $commit (using prep_code.sh)"
if [[ $commit == arome${separator}* ]]; then
$prep_code -c $commit PHYEX #This commit is ready for inclusion
else
$prep_code -c $commit $expand_options $subs -m arome PHYEX
fi
else
echo "Copy $fromdir"
mkdir PHYEX
scp -q -r $fromdir/src PHYEX/
$prep_code $expand_options $subs -m arome PHYEX
fi
find PHYEX -type f -exec touch {} \; #to be sure a recompilation occurs
for rep in turb micro conv aux; do
[ -d PHYEX/$rep ] && mv PHYEX/$rep .
done
if [ -f PHYEX/gmkpack_ignored_files ]; then
#gmkpack_ignored_files contains a list of file, present in the reference pack, that is not used anymore
#and must be excluded from compilation (in case of a full comilation) or from re-compilation (in case of a non-full
#compilation).
if [ $fullcompilation == 0 ]; then
#Content is added in the ics_masterodb script
sed -i "/^end_of_ignored_files/i $(first=1; for line in $(cat PHYEX/gmkpack_ignored_files); do echo -n $(test $first -ne 1 && echo \\n)${line}; first=0; done)" $HOMEPACK/$name/ics_masterodb
else
#Files must be suppressed (non phyex files)
for file in $(cat PHYEX/gmkpack_ignored_files); do
[ -f $HOMEPACK/$name/src/local/$file ] && rm -f $HOMEPACK/$name/src/local/$file
done
fi
EXT=PHYEX/ext
[ ! -d $EXT ] && EXT=PHYEX/externals #old name for ext/aux
if [ -d $EXT ]; then
#Move manually files outside of mpa (a find on the whole repository would take too much a long time)
[ -f $EXT/yomparar.F90 ] && mv $EXT/yomparar.F90 ../arpifs/module/
[ -f $EXT/namparar.nam.h ] && mv $EXT/namparar.nam.h ../arpifs/namelist
[ -f $EXT/suparar.F90 ] && mv $EXT/suparar.F90 ../arpifs/phys_dmn/
[ -f $EXT/apl_arome.F90 ] && mv $EXT/apl_arome.F90 ../arpifs/phys_dmn/
[ -f $EXT/suphmpa.F90 ] && mv $EXT/suphmpa.F90 ../arpifs/phys_dmn/
[ -f $EXT/vdfhghtnhl.F90 ] && mv $EXT/vdfhghtnhl.F90 ../arpifs/phys_dmn/
#Special mpa case
[ -f $EXT/modd_spp_type.F90 ] && mv $EXT/modd_spp_type.F90 ../mpa/micro/externals/
[ -f $EXT/spp_mod_type.F90 ] && mv $EXT/spp_mod_type.F90 ../mpa/micro/externals/
[ -d $EXT/dead_code ] && rm -rf $EXT/dead_code/
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
if [ $EXT == "PHYEX/externals" ]; then
mv $EXT .
else
#Move automatically all codes under mpa
for file in $EXT/*; do
extname=`basename $file`
loc=`find ../../$reftree/mpa/ -name $extname | sed "s/\/$reftree\//\/local\//g"`
nb=`echo $loc | wc -w`
if [ $nb -ne 1 ]; then
echo "Don't know where $file must be moved, none or several places found!"
exit 9
fi
mv $file $loc
done
fi
fi
rm -rf PHYEX
cd $HOMEPACK/$name
sed -i 's/GMK_THREADS=1/GMK_THREADS=10/' ics_masterodb
cleanpack -f
exescript Output_compilation ics_masterodb
if [ $extraCompilationCheck -eq 1 -a \
-f bin/MASTERODB \
-a $(grep Error Output_compilation | \
grep -v TestErrorHandler | \
grep -v "'Error" | \
grep -v "'CPLNG: Error" | \
grep -v '"Error' | \
grep -v "'*** Error" | wc -l) -ne 0 ]; then
echo "MASTERODB was produced but errors occured during compilation:"
grep Error Output_compilation | \
grep -v TestErrorHandler | \
grep -v "'Error" | \
grep -v "'CPLNG: Error" | \
grep -v '"Error' | \
grep -v "'*** Error"
echo "MASTERODB suppressed!"
rm -f bin/MASTERODB
fi
fi
if [ $run -ge 1 ]; then
echo "### Running of commit $commit"
if [ ! -f $HOMEPACK/$name/bin/MASTERODB ]; then
echo "Pack does not exist ($HOMEPACK/$name) or compilation has failed, please check"
exit 6
fi
#Cleaning to suppress old results that may be confusing in case of a crash during the run
for t in $(echo $tests | sed 's/,/ /g'); do
cd $HOMEPACK/$name
if [ -d conf_tests/$t ]; then
rm -rf conf_tests/$t
fi
done
#Run the tests one after the other
for t in $(echo $tests | sed 's/,/ /g'); do
cd $HOMEPACK/$name
mkdir -p conf_tests/$t
cd conf_tests/$t
MYLIB=$name TESTDIR=$dirconf/$t exescript Output_run $dirconf/$t/aro${cycle}.sh
done
fi
if [ $check -eq 1 ]; then
echo "### Check commit $commit against commit $reference"
allt=0
message=""
filestocheck=""
for t in $(echo $tests | sed 's/,/ /g'); do
if echo $t | grep 'small' > /dev/null; then
filestocheck="$filestocheck ${t},conf_tests/$t/ICMSHFPOS+0002:00 ${t},conf_tests/$t/DHFDLFPOS+0002"
else
filestocheck="$filestocheck ${t},conf_tests/$t/NODE.001_01"
fi
done
for tag_file in $filestocheck; do
tag=$(echo $tag_file | cut -d, -f1)
file=$(echo $tag_file | cut -d, -f2)
file1=$HOMEPACK/$name/$file
file2=$(echo $HOMEPACK/$refname/$file) #echo to enable shell substitution
mess=""
t=0
if [ ! -f "$file1" ]; then
mess="Result ($file1) for commit $commit does not exist, please run the simulation"
t=1
fi
if [ ! -f "$file2" ]; then
mess2="Result ($file2) for commit $reference does not exist, please run the simulation"
t=1
mess=$mess2
else
mess="$mess and $mess2"
fi
fi
if [ $t -eq 0 ]; then
if [ $(basename $file) == ICMSHFPOS+0002:00 ]; then
#historic files
cmd="cmp $file1 $file2 256 256"
output='stderr'
elif [ $(basename $file) == DHFDLFPOS+0002 ]; then
#DDH files
ddh_images="$HOMEPACK/$name/ddh_diff_${tag}.png"
if [ `hostname` == 'sxphynh' ]; then
[ ! -d /d0/images/$USER ] && mkdir /d0/images/$USER
ddh_images="$ddh_images /d0/images/$USER/ddh_diff_${tag}.png"
fi
cmd="$PHYEXTOOLSDIR/comp_DDH.py"
if [ ! -x $cmd ]; then
echo "Command not found: \"$cmd\""
exit 10
fi
cmd="$cmd $file1 $file2 $ddh_images"
output='stdout'
elif [ $(basename $file) == NODE.001_01 ]; then
#Output listing
cmd="$PHYEXTOOLSDIR/diffNODE.001_01"
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
if [ ! -x $cmd ]; then
echo "Command not found: \"$cmd\""
exit 11
fi
cmd="$cmd $file1 $file2 --norm-max-diff=0."
output='stdout'
else
cmd="cmp $file1 $file2"
output='stderr'
fi
set +e
if [ $output == 'stderr' ]; then
mess=$($cmd 2>&1)
else
mess=$($cmd 2>/dev/null)
fi
t=$?
set -e
fi
[ $t -ne 0 ] && message="$message $file : $mess \n"
allt=$(($allt+$t))
done
if [ $allt -eq 0 ]; then
echo "SUCCESS, files are (nearly) identical"
else
echo "*************** Files are different *******************"
echo -e "$message"
fi
fi