diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..739870bd4e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + target-branch: "master" diff --git a/.github/workflows/containerized-ci.yml b/.github/workflows/containerized-ci.yml new file mode 100644 index 0000000000..afdfe6bc16 --- /dev/null +++ b/.github/workflows/containerized-ci.yml @@ -0,0 +1,138 @@ +name: Continuous integration in containers +on: [push, pull_request, workflow_dispatch] + +jobs: + Containerized-CI: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + compiler: [ifort, ifx] + include: + # Flags and KGOs for Intel Fortran Compiler Classic + - compiler: ifort + fcflags: -m64 -g -traceback -heap-arrays -assume realloc_lhs -extend-source 132 -check bounds,uninit,pointers,stack -stand f08 + gdkgo1: https://docs.google.com/uc?export=download&id=1TpXY-vXkwAnym9nNjzUxt1q_8c8T7X8T + gdkgo2: https://docs.google.com/uc?export=download&id=1ic-2B3dIx1kIoi-Nd1ndLbLAe_LIWDGP + # Flags and KGOs for Intel Fortran Compiler + - compiler: ifx + fcflags: -debug -traceback -O0 -heap-arrays -assume realloc_lhs -extend-source 132 -stand f08 + gdkgo1: https://docs.google.com/uc?export=download&id=19N7wXou-2Zv0oVAnwn4Ucs8Ghr-C0SMt + gdkgo2: https://docs.google.com/uc?export=download&id=1EUO6C_v0rq0NMXkLGqZDKX99kknnMRQN + # Set container images + - compiler: ifort + image: ghcr.io/earth-system-radiation/rte-rrtmgp-ci:oneapi + - compiler: ifx + image: ghcr.io/earth-system-radiation/rte-rrtmgp-ci:oneapi + container: + image: ${{ matrix.image }} + env: + F90: ${{ matrix.compiler }} + FC: ${{ matrix.compiler }} + F90FLAGS: ${{ matrix.fcflags }} + # Make variables: + NFHOME: /opt/netcdf-fortran + # KGO tests variables + ATOL: 0.0 + RTOL: 0.0 + KGO_VERSION: v002 + GDKGO1: ${{ matrix.gdkgo1 }} + GDKGO2: ${{ matrix.gdkgo2 }} + steps: + # + # Checks-out repository under $GITHUB_WORKSPACE + # + - uses: actions/checkout@v4 + + ############################################################################### + # Build COSP and retrieve input and test files + ############################################################################### + # Build COSP2 driver. Intel Fortran stores automatic arrays in the stack + # by default, whereas GNU Fortran stores them in the heap. This can cause + # segmentation faults with ifort, especially in memory-intensive applications + # like COSP. We tell ifort to use heap arrays. + - name: Build driver + run: | + ${F90} --version + cd build + make -j driver + # Retrieve and expand large data files + - name: Retrieve input files + run: | + GDFILE='https://docs.google.com/uc?export=download&id=17eK4_DVEvFOE9Uf6siXJDpWZJKT1aqkU' + OUTPATH=driver/data/inputs/UKMO/cosp_input.um_global.nc.gz + curl -sSfL -o $OUTPATH $GDFILE + gunzip ${OUTPATH} + cd driver/data/inputs/UKMO + md5sum -c cosp_input.um_global.nc.md5 + - name: Retrieve KGOs for basic test + run: | + cd ${GITHUB_WORKSPACE} + OUTPATH=driver/data/outputs/UKMO/cosp2_output_um.$F90.kgo.$KGO_VERSION.nc.gz + curl -sSfL -o $OUTPATH $GDKGO1 + gunzip ${OUTPATH} + cd driver/data/outputs/UKMO + # md5sum -c cosp2_output_um.${F90}.kgo.$KGO_VERSION.nc.md5 + - name: Retrieve KGOs for global test + run: | + cd ${GITHUB_WORKSPACE} + OUTPATH=driver/data/outputs/UKMO/cosp2_output.um_global.${F90}.kgo.$KGO_VERSION.nc.gz + curl -sSfL -o $OUTPATH $GDKGO2 + gunzip ${OUTPATH} + cd driver/data/outputs/UKMO + # md5sum -c cosp2_output.um_global.${F90}.kgo.$KGO_VERSION.nc.md5 + ############################################################################### + # Run COSP2 tests. Basic test and UM global snapshot + ############################################################################### + - name: Basic test and UM global snapshot + run: | + cd driver/run + ./cosp2_test cosp2_input_nl.txt + ./cosp2_test cosp2_input_nl.um_global.txt + ############################################################################### + # Compare results against known good outputs. As above, + # we split it in as many steps as tests. + ############################################################################### + # 1. Basic test + - name: Basic against known good output (KGO) + run: | + cd driver + KGO=data/outputs/UKMO/cosp2_output_um.${F90}.kgo.$KGO_VERSION.nc + TST=data/outputs/UKMO/cosp2_output_um.nc + python compare_to_kgo.py ${KGO} ${TST} --atol=${ATOL} --rtol=${RTOL} + # 2. UM global snapshot. + - name: UM global against known good output (KGO) + run: | + cd driver + KGO=data/outputs/UKMO/cosp2_output.um_global.${F90}.kgo.$KGO_VERSION.nc + TST=data/outputs/UKMO/cosp2_output.um_global.nc + python compare_to_kgo.py ${KGO} ${TST} --atol=${ATOL} --rtol=${RTOL} + ############################################################################### + # Produce plots when it fails during global snapshot tests, + # and create a tarball with outputs. + ############################################################################### + - name: Produce plots and create tarball + if: failure() + run: | + TST_MLEV=data/outputs/UKMO/cosp2_output.um_global_model_levels.nc + cd driver + if [[ -e data/outputs/UKMO/cosp2_output.um_global.nc ]]; then + python plot_test_outputs.py + fi + if [[ -e data/outputs/UKMO/cosp2_output.um_global_model_levels.nc ]]; then + python plot_test_outputs.py --tst_file=$TST_MLEV + fi + cd data/outputs/UKMO + tar --ignore-failed-read -czf outputs.UKMO.tgz cosp2_output.um_global.nc \ + cosp2_output_um.nc cosp2_output.um_global_model_levels.nc *.png \ + cosp2_output.um_global.out + ls -lh + ############################################################################### + # Make output files available if any test fails + ############################################################################### + - name: Upload output file if test fails + if: failure() + uses: actions/upload-artifact@v1.0.0 + with: + name: outputs.UKMO.tgz + path: driver/data/outputs/UKMO/outputs.UKMO.tgz diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 4652b5d4b5..1f028fcbe2 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -26,216 +26,115 @@ # THE POSSIBILITY OF SUCH DAMAGE. # Workflow for continuous integration tests -name: CI -on: [push, pull_request] +name: Continuous integration gfortran compilers +on: [push, pull_request, workflow_dispatch] jobs: - # This workflow contains a single job called "test" - test: + # This workflow contains a single job called "ci_gfortran" + ci_gfortran: # The type of runner that the job will run on - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: + fail-fast: false matrix: - fortran-compiler: [gfortran, gfortran-8, gfortran-7, ifort] + compiler: [gfortran-10, gfortran-11, gfortran-12] + python-version: [3.11] + defaults: + run: + shell: bash -el {0} env: - F90: ${{ matrix.fortran-compiler }} - FC: ${{ matrix.fortran-compiler }} + F90: ${{ matrix.compiler }} + FC: ${{ matrix.compiler }} F90FLAGS: "-O3 -ffree-line-length-none -fcheck=bounds -finit-real=nan" + NFHOME: /usr ATOL: 0.0 RTOL: 0.0 KGO_VERSION: v002 - NFHOME: /home/runner/netcdf-fortran - LD_LIBRARY_PATH: /home/runner/netcdf-fortran/lib + GDKGO1: https://docs.google.com/uc?export=download&id=11dKcIL3EQr7s6jbo4f9GsoW0SufesGbq + GDKGO2: https://docs.google.com/uc?export=download&id=1s5Ha6Hqnv_hWbRUs8KQpJ4Lxy8uvJDar + GDKGO3: https://docs.google.com/uc?export=download&id=1kY1lRgzd0UhDiQef2u-VgTQql_iut3U2 + F90_SHORT_NAME: gfortran # Sequence of tasks that will be executed as part of the job steps: - # Checks-out repository under $GITHUB_WORKSPACE - - uses: actions/checkout@v2 ############################################################################### # Initial steps ############################################################################### - # Set up Python and install dependencies - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: 3.7 - - name: Setup conda - uses: s-weigand/setup-conda@v1 - with: - python-version: 3.7 - - name: Install python packages - run: conda install --yes cartopy matplotlib netcdf4 - # Update system packages - - name: Update system packages - run: sudo apt-get update - # Non compiler-specific environment - - name: Non compiler-specific environment - run: export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${NFHOME}/lib - ############################################################################### - # FORTRAN compilers - ############################################################################### - # - # Install gfortran compiler - # - - name: Install gfortran compiler - if: contains(matrix.fortran-compiler, 'gfortran') - run: sudo apt-get install ${{ matrix.fortran-compiler }} - # - # Intel compilers - # - - name: cache-intel-compilers - id: cache-intel-compilers - if: contains(matrix.fortran-compiler, 'ifort') - uses: actions/cache@v2 - with: - path: /opt/intel - key: intel-${{ runner.os }}-compilers-b - - # https://software.intel.com/content/www/us/en/develop/articles/installing-intel-oneapi-toolkits-via-apt.html - # List of packages from Docler file at - # https://github.com/intel/oneapi-containers/blob/master/images/docker/hpckit-devel-ubuntu18.04/Dockerfile - - name: Install Intel compilers and libraries - if: contains(matrix.fortran-compiler, 'ifort') && steps.cache-intel-compilers.outputs.cache-hit != 'true' - run: | - wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB - sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB - sudo add-apt-repository "deb https://apt.repos.intel.com/oneapi all main" - sudo apt-get update - sudo apt-get install intel-hpckit-getting-started intel-oneapi-clck intel-oneapi-common-licensing intel-oneapi-common-vars - sudo apt-get install intel-oneapi-dev-utilities intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic intel-oneapi-compiler-fortran intel-oneapi-itac - - # - # Nvidia compilers - # - - name: cache-nvidia-compilers - id: cache-nvidia-compilers - if: contains(matrix.fortran-compiler, 'nvfortran') - uses: actions/cache@v2 + # Checks-out repository under $GITHUB_WORKSPACE + - uses: actions/checkout@v4 + # Set up conda environment + - name: Setup conda environment + uses: conda-incubator/setup-miniconda@v3.0.3 with: - path: /opt/nvidia/hpc_sdk/ - key: nvhpc-${{ runner.os }}-2020-20.7 - - - name: Nvidia setup compilers - if: contains(matrix.fortran-compiler, 'nvfortran') && steps.cache-nvidia-compilers.outputs.cache-hit != 'true' - env: - NVCOMPILERS: /opt/nvidia/hpc_sdk - run: | - wget -q https://developer.download.nvidia.com/hpc-sdk/nvhpc-20-7_20.7_amd64.deb https://developer.download.nvidia.com/hpc-sdk/nvhpc-2020_20.7_amd64.deb - sudo apt-get install ./nvhpc-20-7_20.7_amd64.deb ./nvhpc-2020_20.7_amd64.deb - ############################################################################### - # Compiler-specific environment - ############################################################################### - # Environments for ifort and nvidia compilers - - name: Environment for ifort compiler - if: contains(matrix.fortran-compiler, 'ifort') - run: | - echo "CC=icx" > $GITHUB_ENV - echo "FC=ifort" > $GITHUB_ENV - echo "F90FLAGS=-O3 -heap-arrays" > $GITHUB_ENV - - name: Environment for nvfortran compiler - env: - NVCOMPILERS: /opt/nvidia/hpc_sdk - if: contains(matrix.fortran-compiler, 'nvfortran') - run: | - echo "CC=nvc" > $GITHUB_ENV - echo "FC=nvfortran" > $GITHUB_ENV - echo "F90FLAGS=-Mallocatable=03 -Mstandard -Mbounds -Mchkptr -Kieee -Mchkstk" > $GITHUB_ENV - echo "${NVCOMPILERS}/Linux_x86_64/20.7/compilers/bin" >> $GITHUB_PATH - ############################################################################### + auto-update-conda: true + activate-environment: ci-env + environment-file: build/environment.yml + python-version: ${{ matrix.python-version }} + auto-activate-base: false # NetCDF C and FORTRAN libraries - ############################################################################### - # NetCDF C library - name: Install NetCDF library - run: sudo apt-get install libnetcdf-dev - - # Cache netcdf FORTRAN library - - name: cache-netcdf-fortran - id: cache-netcdf-fortran - uses: actions/cache@v2 - with: - path: /home/runner/netcdf-fortran - key: netcdf-fortran-4.4.4a-${{ runner.os }}-${{ matrix.fortran-compiler }}-v02 - - # Build NetCDF FORTRAN library for current compiler - - name: Build NetCDF FORTRAN library - env: - FCFLAGS: -fPIC - if: steps.cache-netcdf-fortran.outputs.cache-hit != 'true' run: | - source /opt/intel/oneapi/setvars.sh || true - ${F90} --version - git clone https://github.com/Unidata/netcdf-fortran.git --branch v4.4.4 - cd netcdf-fortran - ./configure --prefix=${NFHOME} - make -j - sudo make install + sudo apt-get update + sudo apt-get install libnetcdff-dev + ############################################################################### # Build COSP and retrieve input and test files ############################################################################### - # Build COSP2 driver. Intel Fortran stores automatic arrays in the stack - # by default, whereas GNU Fortran stores them in the heap. This can cause - # segmentation faults with ifort, especially in memory-intensive applications - # like COSP. We tell ifort to use heap arrays. + # Build COSP2 driver. - name: Build driver run: | - source /opt/intel/oneapi/setvars.sh || true ${F90} --version cd build make -j driver # Retrieve and expand large data files - - name: Retrieve data files + - name: Retrieve input files run: | GDFILE='https://docs.google.com/uc?export=download&id=17eK4_DVEvFOE9Uf6siXJDpWZJKT1aqkU' OUTPATH=driver/data/inputs/UKMO/cosp_input.um_global.nc.gz - wget --no-check-certificate $GDFILE -O $OUTPATH + curl -sSfL -o $OUTPATH $GDFILE gunzip ${OUTPATH} cd driver/data/inputs/UKMO md5sum -c cosp_input.um_global.nc.md5 + - name: Retrieve KGOs for basic test + run: | cd ${GITHUB_WORKSPACE} - GDFILE='https://docs.google.com/uc?export=download&id=1s5Ha6Hqnv_hWbRUs8KQpJ4Lxy8uvJDar' - OUTPATH=driver/data/outputs/UKMO/cosp2_output.um_global.gfortran.kgo.$KGO_VERSION.nc.gz - wget --no-check-certificate $GDFILE -O $OUTPATH + OUTPATH=driver/data/outputs/UKMO/cosp2_output_um.${F90_SHORT_NAME}.kgo.$KGO_VERSION.nc.gz + curl -sSfL -o $OUTPATH $GDKGO1 gunzip ${OUTPATH} cd driver/data/outputs/UKMO - md5sum -c cosp2_output.um_global.gfortran.kgo.$KGO_VERSION.nc.md5 + md5sum -c cosp2_output_um.${F90_SHORT_NAME}.kgo.$KGO_VERSION.nc.md5 + - name: Retrieve KGOs for global test + run: | cd ${GITHUB_WORKSPACE} - GDFILE='https://docs.google.com/uc?export=download&id=11dKcIL3EQr7s6jbo4f9GsoW0SufesGbq' - OUTPATH=driver/data/outputs/UKMO/cosp2_output_um.gfortran.kgo.$KGO_VERSION.nc.gz - wget --no-check-certificate $GDFILE -O $OUTPATH + OUTPATH=driver/data/outputs/UKMO/cosp2_output.um_global.${F90_SHORT_NAME}.kgo.$KGO_VERSION.nc.gz + curl -sSfL -o $OUTPATH $GDKGO2 gunzip ${OUTPATH} cd driver/data/outputs/UKMO - md5sum -c cosp2_output_um.gfortran.kgo.$KGO_VERSION.nc.md5 + md5sum -c cosp2_output.um_global.${F90_SHORT_NAME}.kgo.$KGO_VERSION.nc.md5 + cd ${GITHUB_WORKSPACE} + - name: Retrieve KGOs for global test with outputs on model levels + run: | cd ${GITHUB_WORKSPACE} - GDFILE='https://docs.google.com/uc?export=download&id=1kY1lRgzd0UhDiQef2u-VgTQql_iut3U2' - OUTPATH=driver/data/outputs/UKMO/cosp2_output.um_global_model_levels.gfortran.kgo.$KGO_VERSION.nc.gz - wget --no-check-certificate $GDFILE -O $OUTPATH + OUTPATH=driver/data/outputs/UKMO/cosp2_output.um_global_model_levels.${F90_SHORT_NAME}.kgo.$KGO_VERSION.nc.gz + curl -sSfL -o $OUTPATH $GDKGO3 gunzip ${OUTPATH} cd driver/data/outputs/UKMO - md5sum -c cosp2_output.um_global_model_levels.gfortran.kgo.$KGO_VERSION.nc.md5 + md5sum -c cosp2_output.um_global_model_levels.${F90_SHORT_NAME}.kgo.$KGO_VERSION.nc.md5 ############################################################################### # Run COSP2 tests. We could run both tests in one step, but # doing it this way the output is easier to interpret. ############################################################################### # 1. Basic test - - name: Basic test + - name: Basic test, UM global snapshot run: | source /opt/intel/oneapi/setvars.sh || true cd driver/run ./cosp2_test cosp2_input_nl.txt - # 2. UM global snapshot - - name: UM global snapshot - run: | - source /opt/intel/oneapi/setvars.sh || true - cd driver/run ./cosp2_test cosp2_input_nl.um_global.txt - # 3. UM global snapshot. Diagnostics on model levels. + # 2. UM global snapshot. Diagnostics on model levels. - name: UM global snapshot. Diagnostics on model levels. run: | - if [[ "${F90}" = 'gfortran' ]]; then - cd driver/run - ./cosp2_test cosp2_input_nl.um_global_model_levels.txt cosp2_output_nl.um_global_model_levels.txt - else - echo "Test is only run for gfortran compiler." - fi + cd driver/run + ./cosp2_test cosp2_input_nl.um_global_model_levels.txt cosp2_output_nl.um_global_model_levels.txt ############################################################################### # Compare results against known good outputs. As above, # we split it in as many steps as tests. @@ -243,44 +142,24 @@ jobs: # 1. Basic test - name: Basic against known good output (KGO) run: | - if [[ "${F90}" != 'gfortran' ]]; then - ATOL=1.0e-20 - RTOL=0.0006 - fi cd driver - KGO=data/outputs/UKMO/cosp2_output_um.gfortran.kgo.$KGO_VERSION.nc + KGO=data/outputs/UKMO/cosp2_output_um.${F90_SHORT_NAME}.kgo.$KGO_VERSION.nc TST=data/outputs/UKMO/cosp2_output_um.nc python compare_to_kgo.py ${KGO} ${TST} --atol=${ATOL} --rtol=${RTOL} - # 2. UM global snapshot. The approach used for the basic test would needed - # large tolerances for the ifort compiler. We keep tolerances small for ifort, - # and then we test against the output table. + # 2. UM global snapshot. - name: UM global against known good output (KGO) run: | cd driver - KGO=data/outputs/UKMO/cosp2_output.um_global.gfortran.kgo.$KGO_VERSION.nc + KGO=data/outputs/UKMO/cosp2_output.um_global.${F90_SHORT_NAME}.kgo.$KGO_VERSION.nc TST=data/outputs/UKMO/cosp2_output.um_global.nc - if [[ "${F90}" = 'gfortran' ]]; then - python compare_to_kgo.py ${KGO} ${TST} --atol=${ATOL} --rtol=${RTOL} - else - ATOL=1.0e-20 - RTOL=0.0006 - OUTTST=data/outputs/UKMO/cosp2_output.um_global.out - OUTKGO=data/outputs/UKMO/cosp2_output.um_global.${F90}.kgo.${KGO_VERSION}.out - python compare_to_kgo.py ${KGO} ${TST} --atol=${ATOL} --rtol=${RTOL} \ - --noerror=True --stats_file=${OUTTST} - diff ${OUTKGO} ${OUTTST} - fi - # 3. UM global snapshot. Diagnostics on model levels. Only gfortran. + python compare_to_kgo.py ${KGO} ${TST} --atol=${ATOL} --rtol=${RTOL} + # 3. UM global snapshot. Diagnostics on model levels. - name: UM global on model levels against known good output (KGO) run: | cd driver - KGO=data/outputs/UKMO/cosp2_output.um_global_model_levels.gfortran.kgo.$KGO_VERSION.nc + KGO=data/outputs/UKMO/cosp2_output.um_global_model_levels.${F90_SHORT_NAME}.kgo.$KGO_VERSION.nc TST=data/outputs/UKMO/cosp2_output.um_global_model_levels.nc - if [[ "${F90}" = 'gfortran' ]]; then python compare_to_kgo.py ${KGO} ${TST} --atol=${ATOL} --rtol=${RTOL} - else - echo "Test only run for gfortran compiler." - fi ############################################################################### # Produce plots when it fails during global snapshot tests, # and create a tarball with outputs. diff --git a/build/Makefile.conf b/build/Makefile.conf index 7c6e79379b..508f04a27a 100644 --- a/build/Makefile.conf +++ b/build/Makefile.conf @@ -1,6 +1,6 @@ #F90 = gfortran #F90FLAGS = -O3 -ffree-line-length-none -fcheck=bounds -finit-real=nan -F90_LIB = /home/runner/netcdf-fortran -NC_INC = -I$(F90_LIB)/include -NC_LIB = -L$(F90_LIB)/lib +F90_LIB = ${NFHOME} +NC_INC = -I$(NFHOME)/include +NC_LIB = -L$(NFHOME)/lib diff --git a/build/environment.yml b/build/environment.yml new file mode 100644 index 0000000000..276287783e --- /dev/null +++ b/build/environment.yml @@ -0,0 +1,8 @@ +name: ci-env +channels: + - conda-forge + - defaults +dependencies: + - cartopy + - matplotlib + - netcdf4 diff --git a/driver/data/outputs/UKMO/cosp2_output.um_global.ifort.kgo.v002.nc.md5 b/driver/data/outputs/UKMO/cosp2_output.um_global.ifort.kgo.v002.nc.md5 new file mode 100644 index 0000000000..9a8c3d0ee0 --- /dev/null +++ b/driver/data/outputs/UKMO/cosp2_output.um_global.ifort.kgo.v002.nc.md5 @@ -0,0 +1 @@ +c8c21f8d4cf8de96e7e2db0bc93d0f3e cosp2_output.um_global.ifort.kgo.v002.nc diff --git a/driver/data/outputs/UKMO/cosp2_output.um_global.ifx.kgo.v002.nc.md5 b/driver/data/outputs/UKMO/cosp2_output.um_global.ifx.kgo.v002.nc.md5 new file mode 100644 index 0000000000..c7de89c4fd --- /dev/null +++ b/driver/data/outputs/UKMO/cosp2_output.um_global.ifx.kgo.v002.nc.md5 @@ -0,0 +1 @@ +bed330b229dbdd674a11e0f8c65f011f cosp2_output.um_global.ifx.kgo.v002.nc diff --git a/driver/data/outputs/UKMO/cosp2_output_um.ifort.kgo.v002.nc.md5 b/driver/data/outputs/UKMO/cosp2_output_um.ifort.kgo.v002.nc.md5 new file mode 100644 index 0000000000..b997cc786f --- /dev/null +++ b/driver/data/outputs/UKMO/cosp2_output_um.ifort.kgo.v002.nc.md5 @@ -0,0 +1 @@ +fb0ba88dc9df95bf67d06442c3a85394 cosp2_output_um.ifort.kgo.v002.nc diff --git a/driver/data/outputs/UKMO/cosp2_output_um.ifx.kgo.v002.nc.md5 b/driver/data/outputs/UKMO/cosp2_output_um.ifx.kgo.v002.nc.md5 new file mode 100644 index 0000000000..60366f0b0e --- /dev/null +++ b/driver/data/outputs/UKMO/cosp2_output_um.ifx.kgo.v002.nc.md5 @@ -0,0 +1 @@ +23b30d93bafd5942c7b70f034885eeec cosp2_output_um.ifx.kgo.v002.nc