From 74a0e098b2163425e4b5466c2dfcf8ae26d560a5 Mon Sep 17 00:00:00 2001 From: Robert Pincus Date: Tue, 10 Jan 2023 10:58:46 -0500 Subject: [PATCH] Updated SW cloud optics data, finalization routines for RRTMGP, overhauled CI (#204) Spectral ordering of SW cloud optics data is corrected leading to differences in fluxes as large as a few W/m2. New inquiry and finalization routines are added for ty_gas_optics_rrtmgp. Continuous integration is overhauled to be more compact and lightweight by @skosukhin. Co-authored-by: Sergey Kosukhin --- .github/workflows/containerized-ci.yml | 142 +++++++------ .github/workflows/continuous-integration.yml | 197 +++++++----------- .github/workflows/doc-deployment.yml | 64 +++--- .github/workflows/module_switcher | 146 +++++++++++++ .github/workflows/self-hosted-ci.yml | 155 +++++++------- Contributing.md | 6 +- environment-noplots.yml | 11 + environment.yml | 2 +- examples/all-sky/Makefile | 2 +- examples/all-sky/compare-to-reference.py | 2 +- examples/all-sky/run-allsky-example.py | 2 +- .../rfmip-clear-sky/compare-to-reference.py | 66 +++--- ...rrtmgp-cloud-optics-coeffs-reordered-sw.nc | Bin 0 -> 29380 bytes .../rrtmgp-cloud-optics-coeffs-sw.nc | Bin 28888 -> 0 bytes rrtmgp/mo_gas_optics_rrtmgp.F90 | 77 ++++++- tests/validation-plots.py | 11 +- 16 files changed, 554 insertions(+), 329 deletions(-) create mode 100644 .github/workflows/module_switcher create mode 100644 environment-noplots.yml create mode 100644 extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-reordered-sw.nc delete mode 100644 extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-sw.nc diff --git a/.github/workflows/containerized-ci.yml b/.github/workflows/containerized-ci.yml index ea481926a..629b1ee6e 100644 --- a/.github/workflows/containerized-ci.yml +++ b/.github/workflows/containerized-ci.yml @@ -1,84 +1,102 @@ name: Continuous integration in a box -on: - push: - branches-ignore: - - documentation - pull_request: - branches-ignore: - - documentation +on: + push: + branches-ignore: + - documentation + pull_request: + branches-ignore: + - documentation jobs: Containerized-CI: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: + fortran-compiler: [ifort, ifx, nvfortran] rte-kernels: [default, openacc] - container: ["earthsystemradiation/rte-rrtmgp-ci:ifort","earthsystemradiation/rte-rrtmgp-ci:nvfortran"] + include: + - fortran-compiler: ifort + fcflags: "-m64 -g -traceback -heap-arrays -assume realloc_lhs -extend-source 132 -check bounds,uninit,pointers,stack -stand f08" + image: "earthsystemradiation/rte-rrtmgp-ci:ifort" + - fortran-compiler: ifx + fcflags: "-m64 -g -traceback -heap-arrays -assume realloc_lhs -extend-source 132 -check bounds,uninit,pointers,stack -stand f08" + image: "earthsystemradiation/rte-rrtmgp-ci:ifort" + - fortran-compiler: nvfortran + fcflags: "-Mallocatable=03 -Mstandard -Mbounds -Mchkptr -Kieee -Mchkstk" + image: "earthsystemradiation/rte-rrtmgp-ci:nvfortran" container: - image: ${{ matrix.container }} + image: ${{ matrix.image }} env: - NCHOME: /home/runner/netcdf-c - NFHOME: /home/runner/netcdf-fortran - RFMIP_DIR: /home/runner/rfmip-files + # Core variables: + FC: ${{ matrix.fortran-compiler }} + FCFLAGS: ${{ matrix.fcflags }} + # Make variables: + NCHOME: /dummy + NFHOME: /opt/netcdf-fortran + RRTMGP_ROOT: ${{ github.workspace }} + RTE_KERNELS: ${{ matrix.rte-kernels }} + RUN_CMD: + # Auxiliary variables: + RFMIP_CACHEDIR: /home/runner/rfmip-files steps: - ############################################################################ - # Checks out repository under $GITHUB_WORKSPACE - - name: Check out code - uses: actions/checkout@v3 - - name: Environmental variables - # This might be able to be set in the ENV section above - run: echo "RRTMGP_ROOT=${GITHUB_WORKSPACE}" >> $GITHUB_ENV - - name: Environmental variables - ifort - if: contains(matrix.container, 'ifort') - run: echo "FCFLAGS=-m64 -g -traceback -heap-arrays -assume realloc_lhs -extend-source 132 -check bounds,uninit,pointers,stack -stand f08" >> $GITHUB_ENV - - name: Environmental variables - nvfortran - if: contains(matrix.container, 'nvfortran') - run: echo "FCFLAGS=-Mallocatable=03 -Mstandard -Mbounds -Mchkptr -Kieee -Mchkstk" >> $GITHUB_ENV - - - name: Make library, examples, tests - shell: bash - env: - RTE_KERNELS: ${{ matrix.rte-kernels }} - run: | - source /opt/intel/oneapi/setvars.sh || true - cd ${RRTMGP_ROOT} - ${FC} --version - make libs - make -C build separate-libs - ############################################################################ + # + # Checks-out repository under $GITHUB_WORKSPACE + # + - uses: actions/checkout@v3 + # + # Cache RFMIP files + # - name: Cache RFMIP files - id: cache-rfmip-files uses: actions/cache@v3 with: - path: /home/runner/rfmip-files # Same as #{RFMIP_DIR} + path: ${{ env.RFMIP_CACHEDIR }} key: rfmip-files - + # + # Stage RFMIP files + # - name: Stage RFMIP files - if: steps.cache-rfmip-files.outputs.cache-hit != 'true' run: | - mkdir -p ${RFMIP_DIR} - cd ${RFMIP_DIR} - python ${RRTMGP_ROOT}/examples/rfmip-clear-sky/stage_files.py - ############################################################################ - - name: Run examples, tests - shell: bash - env: - LD_LIBRARY_PATH: /home/runner/netcdf-c/lib + if test ! -d "${RFMIP_CACHEDIR}"; then + mkdir -p "${RFMIP_CACHEDIR}" && cd "${RFMIP_CACHEDIR}" + python "${GITHUB_WORKSPACE}/examples/rfmip-clear-sky/stage_files.py" + fi + for file in "${RFMIP_CACHEDIR}"/*; do + if test ! -d "${file}"; then + echo "copying '${file}'..." + cp "${file}" "${GITHUB_WORKSPACE}/examples/rfmip-clear-sky/" + fi + done + # + # Build libraries, examples and tests + # + - name: Build libraries, examples and tests run: | - source /opt/intel/oneapi/setvars.sh || true - export LD_LIBRARY_PATH=${NFHOME}/lib:${LD_LIBRARY_PATH} - make tests - - name: Comparison + $FC --version + make libs + make -C build separate-libs + # + # Run examples and tests + # + - name: Run examples and tests + run: make tests + # + # Compare the results + # + - name: Compare the results run: make check - ############################################################################ - - name: Validation plots - if: contains(matrix.container, 'ifort') && contains(matrix.rte-kernels, 'default') - run: | - cd ${RRTMGP_ROOT}/tests - python validation-plots.py - - name: Upload plots - if: contains(matrix.container, 'ifort') && contains(matrix.rte-kernels, 'default') + # + # Generate validation plots + # + - name: Generate validation plots + if: matrix.fortran-compiler == 'ifort' && matrix.rte-kernels == 'default' + working-directory: tests + run: python validation-plots.py + # + # Upload validation plots + # + - name: Upload validation plots + if: matrix.fortran-compiler == 'ifort' && matrix.rte-kernels == 'default' uses: actions/upload-artifact@v3 with: name: valdiation-plot diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 7cb2ef664..50ab6aca3 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -1,150 +1,111 @@ name: Continuous Integration -on: - push: - branches-ignore: - - documentation - pull_request: - branches-ignore: - - documentation +on: + push: + branches-ignore: + - documentation + pull_request: + branches-ignore: + - documentation + +defaults: + run: + # Enable Conda environment by using the login shell: + shell: bash -leo pipefail {0} jobs: CI: - runs-on: ubuntu-20.04 - defaults: - run: - shell: bash -l {0} + runs-on: ubuntu-22.04 strategy: + fail-fast: false matrix: - fortran-compiler: [gfortran-9, gfortran-10] + fortran-compiler: [gfortran-10, gfortran-11, gfortran-12] rte-kernels: [default, openacc] env: + # Core variables: FC: ${{ matrix.fortran-compiler }} FCFLAGS: "-ffree-line-length-none -m64 -std=f2008 -march=native -fbounds-check -finit-real=nan -g -DRTE_USE_CBOOL" - CC: gcc - NCHOME: /home/runner/netcdf-c - NFHOME: /home/runner/netcdf-fortran - RFMIP_DIR: /home/runner/rfmip-files + # Make variables: + NCHOME: /dummy + NFHOME: /usr + RRTMGP_ROOT: ${{ github.workspace }} + RTE_KERNELS: ${{ matrix.rte-kernels }} + RUN_CMD: + # Auxiliary variables: + RFMIP_CACHEDIR: /home/runner/rfmip-files steps: - - name: Update system packages - run: sudo apt-get update - ############################################################################ # - # Compilers.... + # Checks-out repository under $GITHUB_WORKSPACE # - # Gfortran 10 not available in Github CI stack, so install + - uses: actions/checkout@v3 # - - name: gfortran-10 setup compiler - if: contains(matrix.fortran-compiler, 'gfortran-10') - run: | - sudo apt-get install gfortran-10 gcc-10 - echo "CC=gcc-10" >> $GITHUB_ENV - - ############################################################################ + # Synchronize the package index # - # Netcdf C and Fortran + - name: Synchronize the package index + run: sudo apt-get update # - - name: Install HDF5 library - run: | - sudo apt-get install libhdf5-dev libcurl4-gnutls-dev hdf5-helpers - dpkg -L libhdf5-dev - - # Skipping this for now - netCDF configure doesn't see the HDF libararies - - name: cache-netcdf-c - id: cache-netcdf-c - uses: actions/cache@v3 - with: - path: /home/runner/netcdf-c - key: netcdf-c-4.7.4a-${{ runner.os }}-${{ matrix.fortran-compiler }} - - - name: Install netcdf C library from source - if: steps.cache-netcdf-c.outputs.cache-hit != 'true' - env: - CPPFLAGS: -I/usr/include/hdf5/serial - LDFLAGS: -L/usr/lib/x86_64-linux-gnu/hdf5/serial/ - run: | - ${CC} --version - git clone https://github.com/Unidata/netcdf-c.git --branch v4.7.4 - cd netcdf-c - ls /usr/include - ./configure --prefix=${NCHOME} - make -j - sudo make install - - # Would be great to encode version info - - name: cache-netcdf-fortran - id: cache-netcdf-fortran + # Install NetCDF-Fortran (compatible with all compilers) + # + - name: Install NetCDF-Fortran + run: sudo apt-get install libnetcdff-dev + # + # Cache Conda packages + # + - name: Cache Conda packages uses: actions/cache@v3 with: - path: /home/runner/netcdf-fortran - key: netcdf-fortran-4.5.3-${{ runner.os }}-${{ matrix.fortran-compiler }} - - - name: Build NetCDF Fortran library - # Here too it would be nice to use the environment to specify netcdf-c location - env: - CPPFLAGS: -I/home/runner/netcdf-c/include - LDFLAGS: -L/home/runner/netcdf-c/lib - LD_LIBRARY_PATH: /home/runner/netcdf-c/lib - FCFLAGS: -fPIC - if: steps.cache-netcdf-fortran.outputs.cache-hit != 'true' - run: | - echo ${TEST} - ${FC} --version - git clone https://github.com/Unidata/netcdf-fortran.git --branch v4.5.3 - cd netcdf-fortran - echo ${CPPFLAGS} - ./configure --prefix=${NFHOME} - make -j - sudo make install - ############################################################################ - # Checks out repository under $GITHUB_WORKSPACE - - name: Check out code - uses: actions/checkout@v3 - - - name: Environmental variables - run: echo "RRTMGP_ROOT=${GITHUB_WORKSPACE}" >> $GITHUB_ENV - - - name: Make library, examples, tests - env: - RTE_KERNELS: ${{ matrix.rte-kernels }} - run: | - cd ${RRTMGP_ROOT} - ${FC} --version - make libs - make -C build separate-libs - - ############################################################################ - # Set up Python and packages + path: ~/conda_pkgs_dir + key: conda-pkgs + # + # Set up Conda # - - name: Setup conda + - name: Set up Conda uses: conda-incubator/setup-miniconda@v2 with: miniforge-version: latest activate-environment: rte_rrtmgp_test - environment-file: environment.yml + environment-file: environment-noplots.yml python-version: 3.9 auto-activate-base: false - ############################################################################ + # Use the cache properly: + use-only-tar-bz2: true + # + # Cache RFMIP files + # - name: Cache RFMIP files - id: cache-rfmip-files uses: actions/cache@v3 with: - path: /home/runner/rfmip-files # Same as #{RFMIP_DIR} + path: ${{ env.RFMIP_CACHEDIR }} key: rfmip-files - + # + # Stage RFMIP files + # - name: Stage RFMIP files - if: steps.cache-rfmip-files.outputs.cache-hit != 'true' run: | - mkdir -p ${RFMIP_DIR} - cd ${RFMIP_DIR} - python ${RRTMGP_ROOT}/examples/rfmip-clear-sky/stage_files.py - ############################################################################ - # Would be great to encode version info - - name: Run examples, tests - env: - LD_LIBRARY_PATH: /home/runner/netcdf-c/lib - run: | - export LD_LIBRARY_PATH=${NFHOME}/lib:${LD_LIBRARY_PATH} - make tests - - name: Comparison + if test ! -d "${RFMIP_CACHEDIR}"; then + mkdir -p "${RFMIP_CACHEDIR}" && cd "${RFMIP_CACHEDIR}" + python "${GITHUB_WORKSPACE}/examples/rfmip-clear-sky/stage_files.py" + fi + for file in "${RFMIP_CACHEDIR}"/*; do + if test ! -d "${file}"; then + echo "copying '${file}'..." + cp "${file}" "${GITHUB_WORKSPACE}/examples/rfmip-clear-sky/" + fi + done + # + # Build libraries, examples and tests + # + - name: Build libraries, examples and tests run: | - make check + $FC --version + make libs + make -C build separate-libs + # + # Run examples and tests + # + - name: Run examples and tests + run: make tests + # + # Compare the results + # + - name: Compare the results + run: make check diff --git a/.github/workflows/doc-deployment.yml b/.github/workflows/doc-deployment.yml index 7c4d03972..b61edd538 100644 --- a/.github/workflows/doc-deployment.yml +++ b/.github/workflows/doc-deployment.yml @@ -1,54 +1,64 @@ name: Build and Deploy Documentation and Website - on: push: - branches: - - main - - documentation + branches: + - main + - documentation jobs: Build: runs-on: ubuntu-22.04 - - env: - FC: gfortran - GCC_V: 12 - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Install Dependencies Ubuntu + # + # Checks-out repository under $GITHUB_WORKSPACE + # + - uses: actions/checkout@v3 + # + # Synchronize the package index + # + - name: Synchronize the package index + run: sudo apt-get update + # + # Install dependencies + # + - name: Install dependencies run: | - sudo apt-get update - sudo apt install -y gfortran-${GCC_V} python3-dev graphviz - sudo pip install ford - - # Install ruby - - uses: ruby/setup-ruby@v1 + sudo apt-get install graphviz + sudo pip install 'markdown<3.4' ford + # + # Install Ruby + # + - name: Install Ruby + uses: ruby/setup-ruby@v1 with: ruby-version: 3.1 - - # Setup Jekyll - - name: Setup Jekyll + # + # Install Jekyll + # + - name: Install Jekyll run: | cd doc/jekyll_site sudo gem install bundler jekyll bundle update - + # # Build documentation + # - name: Build Documentation run: | cd doc ./build_documentation.sh -ci - + # + # Upload documentation + # - name: Upload Documentation uses: actions/upload-artifact@v3 with: name: documentation path: public/ if-no-files-found: error - + # + # Check broken links + # - name: Broken Link Check if: ${{ github.ref == 'refs/heads/main'}} uses: technote-space/broken-link-checker-action@v2 @@ -56,7 +66,9 @@ jobs: TARGET: file://${{ github.workspace }}/doc/ford_site/pages/index.html RECURSIVE: true ASSIGNEES: ${{ github.actor }} - + # + # Deploy documentation + # - name: Deploy API Documentation uses: JamesIves/github-pages-deploy-action@v4.4.1 if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} diff --git a/.github/workflows/module_switcher b/.github/workflows/module_switcher new file mode 100644 index 000000000..3037308c0 --- /dev/null +++ b/.github/workflows/module_switcher @@ -0,0 +1,146 @@ +# +# Accepts a list of environment modules and makes sure that they are +# loaded/unloaded. The function makes it easier to manipulate modules in +# non-interactive shell mode while transparently accounting for several common +# defects in the configuration of the environment module system: +# +# 1) if a module's name is prepended with the exclamation mark ('!') on the +# argument list, the module is unloaded using the 'make unload' command +# (helps in preparing the environment using a single command); +# +# 2) if a module is already loaded, it does not get reloaded (some +# environments, e.g. Cray, are sensitive to the undocumented order of the +# loaded modules and keeping an already loaded module instead of reloading +# it is often safer); +# +# 3) if a module conflicts exactly one already loaded module, it gets loaded +# using the 'module switch' command (this is often the only tested and +# functional way to load a required module in some environments, e.g +# PrgEnv-* modules on Cray); +# +# 4) if a module is in conflict with several already loaded modules, all +# conflicting modules get unloaded first using the 'module unload' command +# and then the required module is loaded using the 'module load' command; +# +# 5) if a module's name starts with 'PrgEnv-', it is considered to be in +# conflict with any other module that has that prefix (on a Cray system, it +# is important that only one PrgEnv module is loaded at a time, which is +# normally covered with the mutual conflict statements in the respective +# module files, however, that is not always the case). +# +switch_for_module () +{ + for sfm_module in "$@"; do + case $sfm_module in + !*) + sfm_module=`echo $sfm_module | cut -c2-` + sfm_cmd="module unload $sfm_module" + echo "$sfm_cmd" + eval "$sfm_cmd" + continue ;; + esac + + sfm_module_full= + sfm_module_short= + case $sfm_module in + */*) + # The module is provided with the version part: + sfm_module_full=$sfm_module + sfm_module_short=`echo $sfm_module | sed 's%/[^/]*$%%'` ;; + *) + # Only the name of the module is provided, get the default version: + sfm_module_full=`module show $sfm_module 2>&1 | sed -n "s%^[^ \t]*/\\($sfm_module.*\\):%\\1%p"` + sfm_module_short=$sfm_module ;; + esac + + # A space-separated list of modules that are already loaded: + sfm_loaded_full=`module -t list 2>&1 | tr '\n' ' ' | sed 's/^.*Modulefiles://' | sed 's/(default)//g'` + + # Check whether the requested module if already loaded: + if test -n "$sfm_module_full"; then + case " $sfm_loaded_full " in + *" $sfm_module_full "*) + echo "module $sfm_module is already loaded" + continue ;; + esac + fi + + # A list of modules in conflict: + sfm_conflicts=`module show $sfm_module 2>&1 | sed -n 's/^conflict\(.*\)/\1/p' | tr '\n\t' ' '` + + # A list of loaded modules without version parts: + sfm_loaded_short=`echo "$sfm_loaded_full" | sed 's%\([^ ][^ ]*\)/[^ ]*%\1%g'` + + # Add the short name of the module to the list of conflicts: + sfm_conflicts="$sfm_conflicts $sfm_module_short" + + # On a Cray system, it is important that only one PrgEnv module is loaded at + # a time. This is normally covered with the mutual conflict statements in + # the respective module files. However, that is not always the case, + # therefore we introduce an additional protection against two or more PrgEnv + # modules being loaded simultaneously: if the module we are asked to switch + # for starts with PrgEnv-, each of the loaded modules that starts with + # PrgEnv- too is added to the list of conflicts: + case $sfm_module_short in + PrgEnv-*) + for sfm_loaded in $sfm_loaded_short; do + case $sfm_loaded in + PrgEnv-*) + sfm_conflicts="$sfm_conflicts $sfm_loaded" ;; + *) ;; + esac + done + ;; + *) ;; + esac + + # A list of loaded modules that are in conflict with the requested module: + sfm_loaded_conflicts= + for sfm_conflict in $sfm_conflicts""; do + sfm_loaded_list= + case $sfm_conflict in + */*) + # The conflict is specified with the version part: + sfm_loaded_list=$sfm_loaded_full ;; + *) + # The conflict is specified without the version part: + sfm_loaded_list=$sfm_loaded_short ;; + esac + + # Check that the conflicted module is loaded: + case " $sfm_loaded_list " in + *" $sfm_conflict "*) + # The conflict is loaded, check whether it is already added to the + # list: + case " $sfm_loaded_conflicts " in + *" $sfm_conflict "*) ;; + *) + # The conflict is not in the list, append: + sfm_loaded_conflicts="$sfm_loaded_conflicts $sfm_conflict" ;; + esac + ;; + esac + done + + # Calculate the number of modules that must be unloaded to before loading + # the requested module: + sfm_loaded_conflicts_count=`echo $sfm_loaded_conflicts | wc -w` + + case $sfm_loaded_conflicts_count in + 0) + # None of the conflicting modules is loaded: + sfm_cmd="module load $sfm_module" ;; + 1) + # There is only one module that must be unloaded, use switch command: + sfm_cmd="module switch $sfm_loaded_conflicts $sfm_module" ;; + *) + # There is more than one module that must be unloaded, unload all of + # them and then load the requested one: + sfm_cmd="module unload $sfm_loaded_conflicts && module load $sfm_module" ;; + esac + + echo "$sfm_cmd" + eval "$sfm_cmd" + done +} + diff --git a/.github/workflows/self-hosted-ci.yml b/.github/workflows/self-hosted-ci.yml index 8261c324e..5977da2e4 100644 --- a/.github/workflows/self-hosted-ci.yml +++ b/.github/workflows/self-hosted-ci.yml @@ -1,101 +1,94 @@ name: Self-hosted CI +on: + push: + branches-ignore: + - documentation + pull_request: + branches-ignore: + - documentation -on: - push: - branches-ignore: - - documentation - pull_request: - branches-ignore: - - documentation +defaults: + run: + shell: bash jobs: CI: runs-on: daint + continue-on-error: ${{ matrix.experimental }} strategy: fail-fast: false matrix: include: - - config_name: nvidia_default_gpu - cdt_version: cdt-cuda/21.09 - compiler_base: nvidia - compiler_module: nvidia - accel_module: craype-accel-nvidia60 + - config-name: nvidia-gpu-acc + rte-kernels: openacc + compiler-modules: "PrgEnv-nvidia nvidia craype-accel-nvidia60 cdt-cuda/21.09 !cray-libsci_acc" # Generic accelerator flag - FCFLAGS: "-O3 -acc -Mallocatable=03 -gopt" - RTE_KERNELS: openacc - - config_name: cce-cpu-icon-production - cdt_version: cdt-cuda/22.05 - compiler_base: cray - compiler_module: cce - accel_module: "" + fcflags: "-O3 -acc -Mallocatable=03 -gopt" + experimental: false + - config-name: cce-cpu-icon-production + rte-kernels: default + compiler-modules: "PrgEnv-cray" # Production flags for Icon model - RTE_KERNELS: default - FCFLAGS: "-hadd_paren -r am -Ktrap=divz,ovf,inv -hflex_mp=intolerant -hfp1 -hnoacc -O1,cache0" - - config_name: cce-openmp - cdt_version: cdt-cuda/22.05 - compiler_base: cray - compiler_module: cce - accel_module: craype-accel-nvidia60 + fcflags: "-hadd_paren -r am -Ktrap=divz,ovf,inv -hflex_mp=intolerant -hfp1 -hnoacc -O1,cache0" + experimental: false + - config-name: cce-gpu-openmp + rte-kernels: openacc + compiler-modules: "PrgEnv-cray craype-accel-nvidia60 cdt-cuda/22.05" # OpenMP flags from Nichols Romero (Argonne) - FCFLAGS: "-hnoacc -homp -O0" - RTE_KERNELS: openacc + fcflags: "-hnoacc -homp -O0" + experimental: true env: - FCFLAGS: ${{ matrix.FCFLAGS }} - RTE_KERNELS: ${{ matrix.RTE_KERNELS }} + # Core variables: + FC: ftn + FCFLAGS: ${{ matrix.fcflags }} + # Make variables: + NCHOME: /dummy + NFHOME: /dummy + RRTMGP_ROOT: ${{ github.workspace }} + RTE_KERNELS: ${{ matrix.rte-kernels }} RUN_CMD: "srun -C gpu -A d56 -p cscsci -t 15:00" steps: - - name: Check out code - uses: actions/checkout@v3 - - name: Create module environment + # + # Checks-out repository under $GITHUB_WORKSPACE + # + - uses: actions/checkout@v3 + # + # Finalize build environment + # + - name: Finalize build environment run: | - set -e - echo ' - module load daint-gpu - module load ${{ matrix.cdt_version }} - export PATH=$CRAY_BINUTILS_BIN:$PATH - module swap PrgEnv-cray PrgEnv-${{ matrix.compiler_base }} - module swap ${{ matrix.compiler_base }} ${{ matrix.compiler_module }} - module load ${{ matrix.accel_module }} - module load cray-netcdf cray-hdf5 - module rm cray-libsci_acc - export LD_LIBRARY_PATH=$CRAY_LD_LIBRARY_PATH:$LD_LIBRARY_PATH - export CUDA_HOME=$CUDATOOLKIT_HOME - echo Compiler Environment: - module list - echo LD_LIBRARY_PATH is: - echo $LD_LIBRARY_PATH - ' > compiler_modules - - name: Stage files + # There are significant limitations on what can go into ${GITHUB_ENV}, + # therefore, we use ${BASH_ENV} but only when necessary: + BASH_ENV="${GITHUB_WORKSPACE}/.bash" + echo "source '${GITHUB_WORKSPACE}/.github/workflows/module_switcher'" >> "${BASH_ENV}" + echo "switch_for_module daint-gpu ${{ matrix.compiler-modules }} cray-netcdf cray-hdf5" >> "${BASH_ENV}" + # Use custom Python environment: + # The environment can be re-generated as follows: + # module load cray-python + # python3 -m venv /scratch/snx3000/rpincus/rte-rrtmgp-python + # /scratch/snx3000/rpincus/rte-rrtmgp-python/bin/pip3 install --upgrade pip + # /scratch/snx3000/rpincus/rte-rrtmgp-python/bin/pip3 install dask[array] netCDF4 numpy xarray + echo "PATH=\"/scratch/snx3000/rpincus/rte-rrtmgp-python/bin:\${PATH}\"" >> "${BASH_ENV}" + # Make bash run the above on startup: + echo "BASH_ENV=${BASH_ENV}" >> "${GITHUB_ENV}" + # Compiler needs more temporary space than normally available: + tmpdir='${{ github.workspace }}/tmp' + mkdir "${tmpdir}" && echo "TMPDIR=${tmpdir}" >> "${GITHUB_ENV}" + # + # Build libraries, examples and tests + # + - name: Build libraries, examples and tests run: | - set -e - cd examples/rfmip-clear-sky - source ./stage_files.sh - - name: Make - run: | - set -e - source compiler_modules - export RRTMGP_ROOT=$PWD - export FC=ftn - # Compiler needs more temporary space than normally available - mkdir -p $PWD/tmp - export TMPDIR=$PWD/tmp - make clean + $FC --version make libs make -C build separate-libs - - name: Run - run: | - set -e - export TMPDIR=$PWD/tmp - source compiler_modules - module load cray-python - export RRTMGP_ROOT=$PWD - make tests - - name: Check results - run: | - set -e - module load daint-gpu - export RRTMGP_ROOT=$PWD - # This module will unload some of the build modules, so do the checks separately - module load netcdf4-python - . /scratch/snx3000/rpincus/netcdf-env/bin/activate - make check + # + # Run examples and tests + # + - name: Run examples and tests + run: make tests + # + # Compare the results + # + - name: Compare the results + run: make check diff --git a/Contributing.md b/Contributing.md index e5a81aaa0..0531ed768 100644 --- a/Contributing.md +++ b/Contributing.md @@ -2,11 +2,11 @@ Thanks for considering making a contribution to RTE+RRTMGP. -The code in this repository is intended to work with compilers supporting the Fortran 2008 standard. It is also expected to run end-to-end on GPUs when compiled with OpenACC. Commits are tested with [Travis](https://travis-ci.com) against gfortran versions 8 and 9 and against various versions > 19.9 of the PGI compiler using resources provided by the [Swiss Supercomputing Center](https://cscs.ch). The testing uses two general codes in `examples/`for which results are compared against existing implemetations, and custom codes in tests/ intended to excercise all code options. +The code in this repository is intended to work with compilers supporting the Fortran 2008 standard. It is also expected to run end-to-end on GPUs when compiled with OpenACC or OpenMP (though OpenMP is still unreliable). Commits are tested automatically against a range of compilers using Github Actions and also resources provided by the [Swiss Supercomputing Center](https://cscs.ch). The testing uses two general codes in `examples/`for which results are compared against existing implemetations, and custom codes in `tests/` intended to excercise all code options. ##### Did you find a bug? -Please file an issue on the [Github page](https://github.com/RobertPincus/rte-rrtmgp/issues). +Please file an issue on the [Github page](https://github.com/RobertPincus/rte-rrtmgp/issues). Please include a minimal reproducer of the bug it at all possible. ##### Did you write a patch that fixes a bug? @@ -14,6 +14,6 @@ Please fork this repository, branch from `develop`, make your changes, and open ##### Did you add functionality? -Please fork this repository, branch from `develop`, make your changes, and open a Github [pull request](https://github.com/RobertPincus/rte-rrtmgp/pulls) against branch `develop`, adding a new regression test or comparison against the reference in `tests/verification.py` or `tests/validation-plots.py` as appropriate. +Please fork this repository, branch from `develop`, make your changes, and open a Github [pull request](https://github.com/RobertPincus/rte-rrtmgp/pulls) against branch `develop`, adding a new regression test or comparison against the reference in `tests/verification.py` or `tests/validation-plots.py` as appropriate. Add the test to the `tests` target in `tests/Makefile`. RTE+RRTMGP is intended to be a core that users can extend with custom code to suit their own needs. \ No newline at end of file diff --git a/environment-noplots.yml b/environment-noplots.yml new file mode 100644 index 000000000..7b29fc6bf --- /dev/null +++ b/environment-noplots.yml @@ -0,0 +1,11 @@ +# +# Python modules below are needed to run tests and check results +# +name: rte_rrtmgp_test_noplots + +dependencies: + - conda-forge::python=3.9 + - conda-forge::netcdf4 + - conda-forge::xarray + - conda-forge::dask + - conda-forge::numpy diff --git a/environment.yml b/environment.yml index a6d800170..c595faa38 100644 --- a/environment.yml +++ b/environment.yml @@ -1,5 +1,5 @@ # -# Python modules below are needed to run tests and check results +# Python modules below are needed to run tests, check results and generate validation plots # name: rte_rrtmgp_test diff --git a/examples/all-sky/Makefile b/examples/all-sky/Makefile index 1d58ddc76..3f7ee7724 100644 --- a/examples/all-sky/Makefile +++ b/examples/all-sky/Makefile @@ -48,7 +48,7 @@ mo_load_cloud_coefficients.o: mo_simple_netcdf.o mo_cloud_optics.o mo_load_cloud tests: cp garand-atmos-1.nc rrtmgp-allsky.nc $(RUN_CMD) ./rrtmgp_allsky rrtmgp-allsky.nc ${RRTMGP_ROOT}/rrtmgp/data/rrtmgp-data-lw-g256-2018-12-04.nc ${RRTMGP_ROOT}/extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-lw.nc 128 - $(RUN_CMD) ./rrtmgp_allsky rrtmgp-allsky.nc ${RRTMGP_ROOT}/rrtmgp/data/rrtmgp-data-sw-g224-2018-12-04.nc ${RRTMGP_ROOT}/extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-sw.nc 128 + $(RUN_CMD) ./rrtmgp_allsky rrtmgp-allsky.nc ${RRTMGP_ROOT}/rrtmgp/data/rrtmgp-data-sw-g224-2018-12-04.nc ${RRTMGP_ROOT}/extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-reordered-sw.nc 128 check: python ./compare-to-reference.py diff --git a/examples/all-sky/compare-to-reference.py b/examples/all-sky/compare-to-reference.py index aebeafa6a..e26d27b73 100644 --- a/examples/all-sky/compare-to-reference.py +++ b/examples/all-sky/compare-to-reference.py @@ -39,7 +39,7 @@ if args.download_reference or not os.path.exists(ref_file): os.makedirs(args.ref_dir, exist_ok=True) urllib.request.urlretrieve( - "ftp://ftp.ldeo.columbia.edu/pub/robertp/rte-rrtmgp/continuous-integration/rrtmgp-allsky.nc", + "ftp://ftp.ldeo.columbia.edu/pub/robertp/rte-rrtmgp/continuous-integration/rrtmgp-allsky-2023-01-04.nc", ref_file) tst = xr.open_dataset(tst_file) ref = xr.open_dataset(ref_file) diff --git a/examples/all-sky/run-allsky-example.py b/examples/all-sky/run-allsky-example.py index af84a7077..fd4a5f507 100644 --- a/examples/all-sky/run-allsky-example.py +++ b/examples/all-sky/run-allsky-example.py @@ -23,7 +23,7 @@ "rrtmgp-cloud-optics-coeffs-lw.nc") sw_clouds_coeff_file = os.path.join(rte_rrtmgp_dir, "extensions", "cloud_optics", - "rrtmgp-cloud-optics-coeffs-sw.nc") + "rrtmgp-cloud-optics-coeffs-reordered-sw.nc") # In the local directory all_sky_exe_name = os.path.join(all_sky_dir, "rrtmgp_allsky") diff --git a/examples/rfmip-clear-sky/compare-to-reference.py b/examples/rfmip-clear-sky/compare-to-reference.py index 710c673d5..526e5cba5 100755 --- a/examples/rfmip-clear-sky/compare-to-reference.py +++ b/examples/rfmip-clear-sky/compare-to-reference.py @@ -12,39 +12,24 @@ tst_dir = "." rrtmgp_suffix = "_Efx_RTE-RRTMGP-181204_rad-irf_r1i1p1f1_gn.nc" - - -def construct_esgf_remote_name(var): - # - # For a given variable name, provide the OpenDAP URL for the RTE+RRTMGP - # RFMIP results - # This doesn't seem to work on CSCS Piz Daint within the netcdf-python - # module - # - esgf_url_base = ("http://esgf3.dkrz.de/thredds/dodsC/" - "cmip6/RFMIP/RTE-RRTMGP-Consortium/RTE-RRTMGP-181204/" - "rad-irf/r1i1p1f1/Efx/") - # DKRZ server has been unstable - better to try the other if one fails - esgf_url_base = ("http://esgf-data1.llnl.gov/thredds/dodsC/css03_data/" - "CMIP6/RFMIP/RTE-RRTMGP-Consortium/RTE-RRTMGP-181204/" - "rad-irf/r1i1p1f1/Efx/") - esgf_url_ver = "gn/v20191007/" - return os.path.join(esgf_url_base, var, esgf_url_ver, var + rrtmgp_suffix) +max_dwd_attempts = 3 # -# Construct URL for RTE+RRTMGP results for RFMIP from ESGF +# Construct a list of possible URLs for RTE+RRTMGP results for RFMIP from ESGF # -def construct_esgf_file(var): - esgf_url_base = ("http://esgf3.dkrz.de/thredds/fileServer/" - "cmip6/RFMIP/RTE-RRTMGP-Consortium/RTE-RRTMGP-181204/" - "rad-irf/r1i1p1f1/Efx/") - # DKRZ node goes down frequently - esgf_url_base = ("http://esgf-data1.llnl.gov/thredds/fileServer/css03_data/" - "CMIP6/RFMIP/RTE-RRTMGP-Consortium/RTE-RRTMGP-181204/" - "rad-irf/r1i1p1f1/Efx/") +def construct_esgf_files(var): + esgf_url_bases = [ + "http://esgf-data1.llnl.gov/thredds/fileServer/css03_data/" + "CMIP6/RFMIP/RTE-RRTMGP-Consortium/RTE-RRTMGP-181204/" + "rad-irf/r1i1p1f1/Efx/", + "http://esgf3.dkrz.de/thredds/fileServer/" + "cmip6/RFMIP/RTE-RRTMGP-Consortium/RTE-RRTMGP-181204/" + "rad-irf/r1i1p1f1/Efx/" + ] esgf_url_ver = "gn/v20191007/" - return os.path.join(esgf_url_base, var, esgf_url_ver, var + rrtmgp_suffix) + return [os.path.join(esgf_url_base, var, esgf_url_ver, var+rrtmgp_suffix) + for esgf_url_base in esgf_url_bases] # @@ -75,9 +60,28 @@ def construct_esgf_file(var): print("Downloading reference data") os.makedirs(args.ref_dir, exist_ok=True) for v in variables: - urllib.request.urlretrieve(construct_esgf_file(v), - os.path.join(args.ref_dir, - v + rrtmgp_suffix)) + filename = v + rrtmgp_suffix + possible_urls = construct_esgf_files(v) + dwd_attempt_num = 1 + dwd_success = False + while dwd_attempt_num <= max_dwd_attempts: + print("{0} (attempt {1})".format(filename, dwd_attempt_num)) + for url in possible_urls: + print('\tfrom {0}...'.format(url[:73])) + try: + urllib.request.urlretrieve(url, os.path.join(args.ref_dir, filename)) + dwd_success = True + break + except: + pass + + if dwd_success: + break + + dwd_attempt_num += 1 + + if not dwd_success: + raise Exception("Failed to download {0}".format(filename)) tst = xr.open_mfdataset(os.path.join(tst_dir, "r??" + rrtmgp_suffix), combine='by_coords') diff --git a/extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-reordered-sw.nc b/extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-reordered-sw.nc new file mode 100644 index 0000000000000000000000000000000000000000..2a98593aa110cb81621bbf18f09fb3e15a42a4df GIT binary patch literal 29380 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 N@hcZ|&))ye{|j&^va0|9 literal 0 HcmV?d00001 diff --git a/extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-sw.nc b/extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-sw.nc deleted file mode 100644 index 890621100077f2f8151ce9c0f9dd20df5f4da2ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28888 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 load_int, load_ext procedure, public :: source_is_internal procedure, public :: source_is_external + procedure, public :: is_loaded + procedure, public :: finalize procedure, public :: get_ngas procedure, public :: get_gases procedure, public :: get_press_min @@ -465,7 +467,7 @@ function compute_gas_taus(this, & use_rayl = allocated(this%krayl) error_msg = '' ! Check for initialization - if (.not. this%is_initialized()) then + if (.not. this%is_loaded()) then error_msg = 'ERROR: spectral configuration not loaded' return end if @@ -967,6 +969,7 @@ function load_int(this, available_gases, gas_names, key_species, & character(len = 128) :: err_message ! ---- !$acc enter data copyin(this) + call this%finalize() err_message = init_abs_coeffs(this, & available_gases, & gas_names, key_species, & @@ -1075,6 +1078,7 @@ function load_ext(this, available_gases, gas_names, key_species, & integer :: ngpt ! ---- !$acc enter data copyin(this) + call this%finalize() err_message = init_abs_coeffs(this, & available_gases, & gas_names, key_species, & @@ -1702,6 +1706,77 @@ subroutine create_idx_minor_scaling(gas_names, & idx_minor_scaling_atm(imnr) = string_loc_in_array(scaling_gas_atm(imnr), gas_names) enddo end subroutine create_idx_minor_scaling + !-------------------------------------------------------------------------------------------------------------------- + ! Is the object ready to use? + ! + pure function is_loaded(this) + class(ty_gas_optics_rrtmgp), intent(in) :: this + logical(wl) :: is_loaded + + is_loaded = allocated(this%kmajor) + end function is_loaded + !-------------------------------------------------------------------------------------------------------------------- + ! + ! Reset the object to un-initialized state + ! + subroutine finalize(this) + class(ty_gas_optics_rrtmgp), intent(inout) :: this + real(wp), dimension(:), allocatable :: press_ref, press_ref_log, temp_ref + + if(this%is_loaded()) then + !$acc exit data delete(this%gas_names, this%vmr_ref, this%flavor) & + !$acc delete(this%gpoint_flavor, this%kmajor) & + !$acc delete(this%minor_limits_gpt_lower) & + !$acc delete(this%minor_scales_with_density_lower, this%scale_by_complement_lower) & + !$acc delete(this%idx_minor_lower, this%idx_minor_scaling_lower) & + !$acc delete(this%kminor_start_lower, this%kminor_lower) & + !$acc delete(this%minor_limits_gpt_upper) & + !$acc delete(this%minor_scales_with_density_upper, this%scale_by_complement_upper) & + !$acc delete(this%idx_minor_upper, this%idx_minor_scaling_upper) & + !$acc delete(this%kminor_start_upper, this%kminor_upper) + !$omp target exit data map(release:this%gas_names, this%vmr_ref, this%flavor) & + !$omp map(release:this%gpoint_flavor, this%kmajor) & + !$omp map(release:this%minor_limits_gpt_lower) & + !$omp map(release:this%minor_scales_with_density_lower, this%scale_by_complement_lower) & + !$omp map(release:this%idx_minor_lower, this%idx_minor_scaling_lower) & + !$omp map(release:this%kminor_start_lower, this%kminor_lower) & + !$omp map(release:this%minor_limits_gpt_upper) & + !$omp map(release:this%minor_scales_with_density_upper, this%scale_by_complement_upper) & + !$omp map(release:this%idx_minor_upper, this%idx_minor_scaling_upper) & + !$omp map(release:this%kminor_start_upper, this%kminor_upper) + deallocate(this%gas_names, this%vmr_ref, this%flavor, this%gpoint_flavor, this%kmajor) + deallocate(this%minor_limits_gpt_lower, & + this%minor_scales_with_density_lower, this%scale_by_complement_lower, & + this%idx_minor_lower, this%idx_minor_scaling_lower, this%kminor_start_lower, this%kminor_lower) + deallocate(this%minor_limits_gpt_upper, & + this%minor_scales_with_density_upper, this%scale_by_complement_upper, & + this%idx_minor_upper, this%idx_minor_scaling_upper, this%kminor_start_upper, this%kminor_upper) + + if(allocated(this%krayl)) then + !$acc exit data delete(this%krayl) + !$omp target exit data map(release:this%krayl) + deallocate(this%krayl) + end if + + if(allocated(this%planck_frac)) then + !$acc exit data delete(this%planck_frac, this%totplnk, this%optimal_angle_fit) + !$omp target exit data map(release:this%planck_frac, this%totplnk, this%optimal_angle_fit) + deallocate(this%planck_frac, this%totplnk, this%optimal_angle_fit) + end if + + if(allocated(this%solar_source)) then + !$acc exit data delete(this%solar_source, this%solar_source_quiet) & + !$acc delete(this%solar_source_facular,this%solar_source_sunspot) + !$omp target exit data map(release:this%solar_source, this%solar_source_quiet) + !$omp map(release:this%solar_source_facular,this%solar_source_sunspot) + deallocate(this%solar_source, & + this%solar_source_quiet, this%solar_source_facular, this%solar_source_sunspot) + end if + !$acc exit data delete(this) + !$omp target exit data map(release:this) + end if + + end subroutine finalize ! --------------------------------------------------------------------------------------- subroutine create_key_species_reduce(gas_names,gas_names_red, & key_species,key_species_red,key_species_present_init) diff --git a/tests/validation-plots.py b/tests/validation-plots.py index 8f630e554..1c55383b8 100644 --- a/tests/validation-plots.py +++ b/tests/validation-plots.py @@ -67,9 +67,14 @@ def construct_lbl_esgf_name(var, esgf_node="llnl"): gp['lw_flux_up_from_deriv'] = gp.lw_flux_up + gp.lw_jaco_up gp.lw_flux_up_from_deriv.attrs = { "description": "LW flux up, surface T+1K, computed from Jacobian"} - lbl = xr.open_mfdataset( - [construct_lbl_esgf_name(v, esgf_node="dkrz") for v in ["rsd", "rsu", "rld", "rlu"]], - combine="by_coords").sel(expt=0) + try: + lbl = xr.open_mfdataset([construct_lbl_esgf_name(v, esgf_node="dkrz") + for v in ["rsd", "rsu", "rld", "rlu"]], + combine="by_coords").sel(expt=0) + except: + lbl = xr.open_mfdataset([construct_lbl_esgf_name(v, esgf_node="llnl") + for v in ["rsd", "rsu", "rld", "rlu"]], + combine="by_coords").sel(expt=0) ######################################################################## # # The RFMIP cases are on an irregular pressure grid so we can't compute