Nic Hannah
ARC CoE Climate System Science
Breakaway Labs
It depends! Probably determined by the user rather than the developer. I imagine high quality software to have few serious bugs, be reliable, easy to maintain, efficient/fast, also easy to test and understand.
Apart from performance measuring quality is very difficult. Perhaps we can start by comparing between models or versions.
* I think GFDL does particularly well in this respect, however there's more to do within the community. GFDL is in a good position to lead the way here.
$ forchk -f90 src/MOM6/src/*/*.F90
333 if (h0+h1==0. .or. h1+h2==0. .or. h2+h3==0.) then
(file: src/MOM6/src/ALE/regrid_edge_values.F90, line: 333)
h0+h1==0.
**[342 I] eq.or ineq. comparison of floating point data with zero constant
37 logical :: boundary_extrapolation = .true.
(file: src/MOM6/src/ALE/MOM_remapping.F90, line: 37)
= .true.
**[274 E] initialization of component or field not allowed
(Initialization of components is supported from Fortran 95 on)
(file: src/MOM6/src/parameterizations/vertical/MOM_vert_friction.F90, line: 1128)
VISC
**[557 I] dummy argument not used
(file: src/MOM6/src/ice_shelf/MOM_ice_shelf.F90, line: 526)
**[ 53 W] tab(s) used
$ mpirun -wdir /short/v45/nah599/access/work/cm_360x300-valgrind/atmosphere -np 32 \
-x LD_PRELOAD=/home/599/nah599/usr/local/lib/valgrind/libmpiwrap-amd64-linux.so \
/home/599/nah599/usr/local/bin/valgrind --main-stacksize=2000000000 \
--max-stackframe=2000000000 --error-limit=no --gen-suppressions=all \
--suppressions=/home/599/nah599/more_home/access-tests/valgrind_suppressions.txt \
/short/v45/nah599/access/bin/um7.3.dbg.exe
An example command line:
1 IF (GID == GCG__ALLGROUP) THEN
2 IGID = GC__MY_MPI_COMM_WORLD
3 ELSE
4 IGID = GID
5 ENDIF
6 ISTAT = GCG__MPI_RANK(SEND, IGID)
7 IF (ISTAT == -1) RETURN
8 RANK = ISTAT
9 CALL MPL_BCAST(SARR, 8_GC_REAL_KIND*LEN, MPL_BYTE, RANK, &
IGID, ISTAT)
==16086== Conditional jump or move depends on uninitialised value(s)
==16086== at 0x1A3ED83: gcg_rbcast_ (gcg_rbcast.f90:150)
==16086== by 0x10DEEBA: interpolation_multi_ (interpolation_multi.f90:1490)
==16086== by 0xB79F66: sl_thermo_ (sl_thermo.f90:1497)
==16086== by 0x88F11E: ni_sl_thermo_ (ni_sl_thermo.f90:768)
==16086== by 0x503DC7: atm_step_ (atm_step.f90:10389)
==16086== by 0x4757CD: u_model_ (in /short/v45/nah599/access/bin/um_hg3_dbg.exe)
==16086== by 0x4420FA: um_shell_ (um_shell.f90:3939)
==16086== by 0x43BA26: MAIN__ (flumeMain.f90:36)
==16086== by 0x43B935: main (in /short/v45/nah599/access/bin/um_hg3_dbg.exe)
Stack trace to bad variable access:
Code in question:
Unit test example: since MOM_EOS_Wright.F90 is very modular it's easy to call from Python and compare to the TEOS-10 package.
>>> import random
>>> def check_units():
... s = 2.0**random.randint(1, 100)
... m = 2.0**random.randint(1, 100)
... cm = m / 100.0
... nm = m*1e-9
... mL = cm**3
... # Assign variable x a value of 5 mL
... x = 5*mL
... print('x expressed as cm cubed: {}'.format(x / cm**3))
... print('x expressed as nm cubed: {}'.format(x / nm**3))
... print('x expressed as seconds: {}'.format(x / s))
...
>>> check_units()
x expressed as cm cubed: 5.0
x expressed as nm cubed: 5e+21
x expressed as seconds: 5.02168138831e+53
>>> check_units()
x expressed as cm cubed: 5.0
x expressed as nm cubed: 5e+21
x expressed as seconds: 90071992547.4