diff --git a/.ci/bb/breeze-mpim/test.all.clang b/.ci/bb/breeze-mpim/test.all.clang new file mode 100755 index 0000000000000000000000000000000000000000..5047123ae0923edda3abb004ec63861d24dac3bd --- /dev/null +++ b/.ci/bb/breeze-mpim/test.all.clang @@ -0,0 +1,40 @@ +#!/bin/bash + +set -eu +set -o pipefail + +script_dir=$(cd "$(dirname "$0")"; pwd) +top_srcdir=$(cd "${script_dir}/../../.."; pwd) + +. "${script_dir}/utils.sh" +init_clang1201 + +# Check the formatting. Note that git-clang-format might keep redundant blank +# lines. Therefore, we use clang-format: +find src app \ + -name '*.h' -o -name '*.hpp' -o -name '*.c' -o -name '*.cpp' | \ + xargs -n 1 -P 8 clang-format --Werror --dry-run --verbose + +test -f "${top_srcdir}/configure" || "${top_srcdir}/autogen.sh" + +"${top_srcdir}/configure" \ +--disable-maintainer-mode \ +--enable-cf-interface \ +--enable-iso-c-interface \ +--enable-mpi \ +--enable-option-checking=fatal \ +--with-eccodes="${ECCODES_ROOT}" \ +--with-netcdf="${NETCDF_ROOT}" \ +CC="${MPICC}" \ +CPPFLAGS="-I${UUID_ROOT}/include" \ +FC="${MPIFC}" \ +F77="${MPIFC}" \ +LDFLAGS="-I${UUID_ROOT}/lib" \ +MPI_LAUNCH="${MPI_LAUNCH}" \ +PKG_CONFIG_PATH="${YAXT_ROOT}/lib/pkgconfig:${PPM_ROOT}/lib/pkgconfig" + +make -j8 + +make -j8 check | tee tests/test-suite.log + +check_all_tests_passed tests/test-suite.log diff --git a/.ci/bb/breeze-mpim/test.all.nag b/.ci/bb/breeze-mpim/test.all.nag new file mode 100755 index 0000000000000000000000000000000000000000..7f467bfdea3be4ce28232e90d4387dff834b6016 --- /dev/null +++ b/.ci/bb/breeze-mpim/test.all.nag @@ -0,0 +1,58 @@ +#!/bin/bash + +set -eu +set -o pipefail + +script_dir=$(cd "$(dirname "$0")"; pwd) +top_srcdir=$(cd "${script_dir}/../../.."; pwd) + +. "${script_dir}/utils.sh" +init_nag626223 + +test -f "${top_srcdir}/configure" || "${top_srcdir}/autogen.sh" + +# Create a distribution file with minimalistic configuration: +"${top_srcdir}/configure" +make -j1 dist + +# Create a subdirectory for further testing and switch to it: +mkdir check_dist && cd check_dist + +# Move the distribution file to the test directory and unpack it: +mv ../cdi-*.tar.gz ./ +tar xf cdi-*.tar.gz + +# Create a subdirectory for building and switch to it: +mkdir build && cd build + +# Use GCC from the path when compiling/linking Fortran code: +FCFLAGS="-O2 -g -Wc=$(which gcc)" + +# Create an out-of-source configuration: +../cdi-*/configure \ +--disable-maintainer-mode \ +--enable-cf-interface \ +--enable-iso-c-interface \ +--enable-mpi \ +--enable-option-checking=fatal \ +--with-eccodes="${ECCODES_ROOT}" \ +--with-netcdf="${NETCDF_ROOT}" \ +CC="${MPICC}" \ +CPPFLAGS="-I${UUID_ROOT}/include" \ +F77="${MPIFC}" \ +FC="${MPIFC}" \ +FCFLAGS="${FCFLAGS}" \ +FFLAGS="${FCFLAGS}" \ +LDFLAGS="-I${UUID_ROOT}/lib" \ +MPI_LAUNCH="${MPI_LAUNCH}" \ +PKG_CONFIG_PATH="${YAXT_ROOT}/lib/pkgconfig:${PPM_ROOT}/lib/pkgconfig" + +make -j8 + +make -j8 check | tee tests/test-suite.log + +check_all_tests_passed tests/test-suite.log + +make -j8 distclean + +check_no_files_in_cwd diff --git a/.ci/bb/breeze-mpim/test.all.nv b/.ci/bb/breeze-mpim/test.all.nv new file mode 100755 index 0000000000000000000000000000000000000000..786ff18324a3a4ba029ffe9b0d9a1039575b23a7 --- /dev/null +++ b/.ci/bb/breeze-mpim/test.all.nv @@ -0,0 +1,55 @@ +#!/bin/bash + +set -eu +set -o pipefail + +script_dir=$(cd "$(dirname "$0")"; pwd) +top_srcdir=$(cd "${script_dir}/../../.."; pwd) + +. "${script_dir}/utils.sh" +init_nv2130 + +# We want to check with the Debian version of Libtool, which is patched to avoid +# overlinking: +( export PATH="/usr/bin:${PATH-}" + export ACLOCAL_PATH="/usr/share/aclocal:${ACLOCAL_PATH-}" + module unload automake/1.16.1 + module load automake/1.16.1 + "${top_srcdir}/autogen.sh" ) + +"${top_srcdir}/configure" \ +--disable-maintainer-mode \ +--enable-cf-interface \ +--enable-iso-c-interface \ +--enable-mpi \ +--enable-option-checking=fatal \ +--with-eccodes="${ECCODES_ROOT}" \ +--with-netcdf="${NETCDF_ROOT}" \ +CC="${MPICC}" \ +CPPFLAGS="-I${UUID_ROOT}/include" \ +F77="${MPIFC}" \ +FC="${MPIFC}" \ +FCFLAGS='-g -fPIC' \ +LDFLAGS="-I${UUID_ROOT}/lib" \ +MPI_LAUNCH="${MPI_LAUNCH}" \ +PKG_CONFIG_PATH="${YAXT_ROOT}/lib/pkgconfig:${PPM_ROOT}/lib/pkgconfig" + +make -j8 + +make -j8 check | tee tests/test-suite.log + +check_all_tests_passed tests/test-suite.log + +# Check that an executable is not overlinked to libscalesppmcore.so: +tested_file='./examples/pio/.libs/collectData' +invalid_needed=`readelf -d "${tested_file}" | sed -E -n '/\(NEEDED\).*libscalesppmcore\.so/p'` || { + echo "ERROR: failed to check '${tested_file}' for ELF NEEDED entries" >&2 + exit 1 +} +if test -n "${invalid_needed}"; then + { + echo "ERROR: '${tested_file}' has excessive ELF NEEDED entries:" >&2 + echo "${invalid_needed}" >&2 + } >&2 + exit 1 +fi diff --git a/.ci/bb/breeze-mpim/test.ru-py.gcc b/.ci/bb/breeze-mpim/test.ru-py.gcc new file mode 100755 index 0000000000000000000000000000000000000000..20d8a9a4584849af49f5ea271f983a50a39990ad --- /dev/null +++ b/.ci/bb/breeze-mpim/test.ru-py.gcc @@ -0,0 +1,33 @@ +#!/bin/bash + +set -eu +set -o pipefail + +script_dir=$(cd "$(dirname "$0")"; pwd) +top_srcdir=$(cd "${script_dir}/../../.."; pwd) + +. "${script_dir}/utils.sh" +init_gcc630 + +test -f "${top_srcdir}/configure" || "${top_srcdir}/autogen.sh" + +"${top_srcdir}/configure" \ +--disable-maintainer-mode \ +--enable-option-checking=fatal \ +--enable-python \ +--enable-ruby \ +--enable-swig \ +--with-eccodes="${ECCODES_ROOT}" \ +--with-netcdf="${NETCDF_ROOT}" \ +CC="${CC}" \ +CPPFLAGS="-I${UUID_ROOT}/include" \ +CXX="${CXX}" \ +LDFLAGS="-L${UUID_ROOT}/lib" + +make -j8 + +# Test the interfaces: +LD_LIBRARY_PATH="${NETCDF_ROOT}/lib:${LD_LIBRARY_PATH}" make -j8 -C interfaces test +(cd interfaces && ./CdiInfo) + +make -j8 check diff --git a/.ci/bb/breeze-mpim/utils.sh b/.ci/bb/breeze-mpim/utils.sh new file mode 100644 index 0000000000000000000000000000000000000000..61868dab965ce979be23f8722e117da5b7fad95f --- /dev/null +++ b/.ci/bb/breeze-mpim/utils.sh @@ -0,0 +1,259 @@ +# +# Accepts a list of environment modules and loads them witch conflict +# resolution. +# +switch_for_module () +{ + for sfm_module in "$@"; do + 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" + + # 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 +} + +# +# Initializes the environment. +# +init_env () +{ + saved_set=$- + set +eu + . /etc/profile.d/mpim.sh + set -${saved_set} + switch_for_module automake/1.16.1 + + # Use non-Debian libtool by default: + LIBTOOL_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/libtool-2.4.6-qdyaqqw' + export PATH="${LIBTOOL_ROOT}/bin:${PATH-}" + export ACLOCAL_PATH="${LIBTOOL_ROOT}/share/aclocal:${ACLOCAL_PATH-}" + + SWIG_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/swig-4.0.2-busrrtn' + RUBY_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/ruby-3.0.2-stqm2vj' + PYTHON_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/python-2.7.18-zqrnwom' + + export PATH="${RUBY_ROOT}/bin:${PYTHON_ROOT}/bin:${SWIG_ROOT}/bin:${PATH-}" +} + +# +# Sets variables for tests with GCC 6.3.0. +# +init_gcc630 () +{ + init_env + switch_for_module gcc/6.3.0 + + CC=gcc + CXX=g++ + FC=gfortran + + ECCODES_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/eccodes-2.21.0-3sdngaq' + NETCDF_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/netcdf-c-4.8.0-fzupaca' + UUID_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/libuuid-1.0.3-rm4kv2o' + + # Here we fix a never-ending story with Libtool overlinkning, absence of + # '*.la' files when they could help, and '-Wl,--disable/enable-new-dtags': + HDF5_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/hdf5-1.10.7-4l3frcp' + export LD_LIBRARY_PATH="${ECCODES_ROOT}/lib:${HDF5_ROOT}/lib:${LD_LIBRARY_PATH-}" +} + +# +# Sets variables for tests with NVHPC 21.3.0. +# +init_nv2130 () +{ + init_env + switch_for_module gcc/6.3.0 + + export NVHPC='/data/mpi/sclab/sip/m300488/nvhpc' + export NVLOCALRC="${NVHPC}/Linux_x86_64/21.3/compilers/bin/localrc.60300" + export PATH="${NVHPC}/Linux_x86_64/21.3/compilers/bin:${PATH-}" + + CC=nvc + CXX=nvc++ + FC=nvfortran + + export PATH="/data/mpi/sclab/sip/m300488/libcdi-ci-sw/nvhpc-21.3-sandybridge/mpich-3.4.2-sfxulsj/bin:${PATH-}" + MPICC=mpicc + MPIFC=mpif90 + MPI_LAUNCH="$(which mpirun)" + + ECCODES_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/eccodes-2.21.0-3sdngaq' + NETCDF_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/nvhpc-21.3-sandybridge/netcdf-c-4.8.0-vjppuov' + PPM_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/nvhpc-21.3-sandybridge/scales-ppm-1.0.7-uy4z72r' + YAXT_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/nvhpc-21.3-sandybridge/yaxt-0.9.2.1-lbqqemx' + UUID_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/libuuid-1.0.3-rm4kv2o' + + # Here we fix a never-ending story with Libtool overlinkning, absence of + # '*.la' files when they could help, and '-Wl,--disable/enable-new-dtags': + HDF5_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/nvhpc-21.3-sandybridge/hdf5-1.10.7-h7pvthl' + export LD_LIBRARY_PATH="${ECCODES_ROOT}/lib:${HDF5_ROOT}/lib:${LD_LIBRARY_PATH-}" +} + +# +# Sets variables for tests with Clang 12.0.1. +# +init_clang1201 () +{ + init_env + switch_for_module gcc/6.3.0 + + export PATH="/data/mpi/sclab/sip/m300488/clang/12.0.1/bin:${PATH-}" + # Clang does not inject RPATHs to the standard library in use: + export LD_LIBRARY_PATH="/sw/stretch-x64/gcc/gcc-6.3.0/lib64:${LD_LIBRARY_PATH-}" + + CC=clang + CXX=clang++ + FC=gfortran + + export PATH="/data/mpi/sclab/sip/m300488/libcdi-ci-sw/clang-12.0.1-sandybridge/openmpi-4.1.1-6ydagyy/bin:${PATH-}" + MPICC=mpicc + MPIFC=mpif90 + MPI_LAUNCH="$(which mpirun) --oversubscribe" + + ECCODES_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/eccodes-2.21.0-3sdngaq' + NETCDF_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/clang-12.0.1-sandybridge/netcdf-c-4.8.0-z6r5guk' + PPM_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/clang-12.0.1-sandybridge/scales-ppm-1.0.7-5mhatgx' + YAXT_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/clang-12.0.1-sandybridge/yaxt-0.9.2.1-cj2nf5j' + UUID_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/libuuid-1.0.3-rm4kv2o' + + # Here we fix a never-ending story with Libtool overlinkning, absence of + # '*.la' files when they could help, and '-Wl,--disable/enable-new-dtags': + HDF5_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/clang-12.0.1-sandybridge/hdf5-1.10.7-4y54xnh' + export LD_LIBRARY_PATH="${ECCODES_ROOT}/lib:${HDF5_ROOT}/lib:${LD_LIBRARY_PATH-}" +} + +# +# Sets variables for tests with NAG 6.2.6223. +# +init_nag626223 () +{ + init_env + switch_for_module gcc/6.3.0 nag/6.2 + + CC=gcc + CXX=g++ + FC=nagfor + + export PATH="/data/mpi/sclab/sip/m300488/libcdi-ci-sw/nag-6.2-sandybridge/mpich-3.4.2-fzsvtw2/bin:${PATH-}" + MPICC=mpicc + MPIFC=mpif90 + MPI_LAUNCH="$(which mpirun)" + + ECCODES_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/eccodes-2.21.0-3sdngaq' + NETCDF_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/nag-6.2-sandybridge/netcdf-c-4.8.0-ogawg3w' + PPM_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/nag-6.2-sandybridge/scales-ppm-1.0.7-5kdlwzv' + YAXT_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/nag-6.2-sandybridge/yaxt-0.9.2.1-rhq2ysn' + UUID_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/gcc-6.3.0-sandybridge/libuuid-1.0.3-rm4kv2o' + + # Here we fix a never-ending story with Libtool overlinkning, absence of + # '*.la' files when they could help, and '-Wl,--disable/enable-new-dtags': + HDF5_ROOT='/data/mpi/sclab/sip/m300488/libcdi-ci-sw/nag-6.2-sandybridge/hdf5-1.10.7-pltg3k4' + export LD_LIBRARY_PATH="${ECCODES_ROOT}/lib:${HDF5_ROOT}/lib:${LD_LIBRARY_PATH-}" +} + +# +# Accepts a path to a file containing the testsuite summary (either the +# 'test-suite.log' or the standard output of the 'make check' command) and +# checks whether all tests were run and passed. +# +check_all_tests_passed () +{ + awk '/SKIP: /{ + print "ERROR: the total number of tests is not equal to the number of passed tests"; + exit 1; + }' $1 >&2 +} + +# +# Checks whether the current working directory or any of its subdirectories +# contain a file and fails with an error message if that is the case. +# +check_no_files_in_cwd () +{ + cnfic_files=`find . -type f 2>/dev/null` + if test -n "$cnfic_files"; then + { + echo "ERROR: the current working directory contains undeleted files:" + echo "$cnfic_files" + } >&2 + exit 1 + fi +} diff --git a/.ci/bb/daint-cscs/test.all.cray b/.ci/bb/daint-cscs/test.all.cray new file mode 100755 index 0000000000000000000000000000000000000000..85a961807cafca02e810076cffb4b6c446fd1f68 --- /dev/null +++ b/.ci/bb/daint-cscs/test.all.cray @@ -0,0 +1,53 @@ +#!/bin/bash + +set -eu +set -o pipefail + +script_dir=$(cd "$(dirname "$0")"; pwd) +top_srcdir=$(cd "${script_dir}/../../.."; pwd) + +. "${script_dir}/utils.sh" +init_cray1203 + +# Save time for the person running this script manually: +if test "x${PE_NETCDF_MODULE_NAME}" = 'xcray-netcdf'; then + case $top_srcdir in + "${HOME}/"*) + echo "ERROR: parallel NetCDF4 tests are known to fail when CDI is built in the user home directory and linked against NetCDF that does not support MPI parallel invocations" >&2 + exit 1 + esac +fi + +test -f "${top_srcdir}/configure" || "${top_srcdir}/autogen.sh" + +# The configure script does not check the 'lib64' subdirectory, therefore we +# run it with '--with-eccodes' and the following flags. Note that fixing this +# in the configure script might be tricky: the 'lib64' subdirectory should be +# checked first but if it does not exist or does not contain the library, we +# might end up linking to a library from the linker's default search path +# (e.g. /usr/lib) instead of the one from "$with_eccodes/lib" because +# "-L${with_eccodes}/lib64" would be ignored in that case: +CPPFLAGS="-I${ECCODES_ROOT}/include" +LDFLAGS="-L${ECCODES_ROOT}/lib64" + +"${top_srcdir}/configure" \ +--disable-maintainer-mode \ +--enable-cf-interface \ +--enable-iso-c-interface \ +--enable-mpi \ +--enable-option-checking=fatal \ +--with-eccodes \ +--with-netcdf \ +CC="${CC}" \ +CPPFLAGS="${CPPFLAGS}" \ +F77="${FC}" \ +FC="${FC}" \ +LDFLAGS="${LDFLAGS}" \ +MPI_LAUNCH="${MPI_LAUNCH}" \ +PKG_CONFIG_PATH="${YAXT_ROOT}/lib/pkgconfig:${PPM_ROOT}/lib/pkgconfig:${PKG_CONFIG_PATH}" + +make -j8 + +make -j8 check | tee tests/test-suite.log + +check_all_tests_passed tests/test-suite.log diff --git a/.ci/bb/daint-cscs/test.all.pgi b/.ci/bb/daint-cscs/test.all.pgi new file mode 100755 index 0000000000000000000000000000000000000000..c6d02c8521a455ba7a41f151a28964cc9b57e8cc --- /dev/null +++ b/.ci/bb/daint-cscs/test.all.pgi @@ -0,0 +1,56 @@ +#!/bin/bash + +set -eu +set -o pipefail + +script_dir=$(cd "$(dirname "$0")"; pwd) +top_srcdir=$(cd "${script_dir}/../../.."; pwd) + +. "${script_dir}/utils.sh" +init_pgi2011 + +# Save time for the person running this script manually: +if test "x${PE_NETCDF_MODULE_NAME}" = 'xcray-netcdf'; then + case $top_srcdir in + "${HOME}/"*) + echo "ERROR: parallel NetCDF4 tests are known to fail when CDI is built in the user home directory and linked against NetCDF that does not support MPI parallel invocations" >&2 + exit 1 + esac +fi + +test -f "${top_srcdir}/configure" || "${top_srcdir}/autogen.sh" + +# The configure script does not check the 'lib64' subdirectory, therefore we +# run it with '--with-eccodes' and the following flags. Note that fixing this +# in the configure script might be tricky: the 'lib64' subdirectory should be +# checked first but if it does not exist or does not contain the library, we +# might end up linking to a library from the linker's default search path +# (e.g. /usr/lib) instead of the one from "$with_eccodes/lib" because +# "-L${with_eccodes}/lib64" would be ignored in that case: +CPPFLAGS="-I${ECCODES_ROOT}/include" +LDFLAGS="-L${ECCODES_ROOT}/lib64" + +"${top_srcdir}/configure" \ +--disable-maintainer-mode \ +--enable-cf-interface \ +--enable-iso-c-interface \ +--enable-mpi \ +--enable-option-checking=fatal \ +--with-eccodes \ +--with-netcdf \ +CC="${CC}" \ +CFLAGS='-g -O1' \ +CPPFLAGS="${CPPFLAGS}" \ +F77="${FC}" \ +FC="${FC}" \ +FCFLAGS='-g -fPIC' \ +LDFLAGS="${LDFLAGS}" \ +MPI_LAUNCH="${MPI_LAUNCH}" \ +PKG_CONFIG_PATH="${YAXT_ROOT}/lib/pkgconfig:${PPM_ROOT}/lib/pkgconfig:${PKG_CONFIG_PATH}" \ +PTHREAD_LIBS='-lpthread' + +make -j8 + +make -j8 check | tee tests/test-suite.log + +check_all_tests_passed tests/test-suite.log diff --git a/.ci/bb/daint-cscs/utils.sh b/.ci/bb/daint-cscs/utils.sh new file mode 100644 index 0000000000000000000000000000000000000000..7fa5f17d9036a6016258c28485bb4122dcf60e7c --- /dev/null +++ b/.ci/bb/daint-cscs/utils.sh @@ -0,0 +1,182 @@ +# +# Accepts a list of environment modules and loads them witch conflict +# resolution. +# +switch_for_module () +{ + for sfm_module in "$@"; do + 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" + + # 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 +} + +# +# Initializes the environment. +# +init_env () +{ + AUTOMAKE_ROOT='/project/d56/libcdi-ci-sw/gcc-11.2.0-haswell/automake-1.16.3-46gthis' + export PATH="${AUTOMAKE_ROOT}/bin:${PATH-}" + # Tell the custom installation of Automake where the libtool macros are: + export ACLOCAL_PATH="/usr/share/aclocal:${ACLOCAL_PATH-}" +} + +# +# Sets variables for tests with Cray 12.0.3. +# +init_cray1203 () +{ + init_env + switch_for_module craype PrgEnv-cray cce/12.0.3 cray-mpich + + # Build and test against NetCDF that does not support MPI parallel invocations + # (parallel NetCDF4 tests are known to fail in this case when run from the + # user home directory on Daint): + switch_for_module cray-netcdf + + # Uncomment the following line to test against MPI-capable NetCDF: + # switch_for_module cray-netcdf-hdf5parallel cray-hdf5-parallel + + CC=cc + CXX=CC + FC=ftn + MPI_LAUNCH="$(which srun) -p cscsci -C gpu -A d56 -t 05:00" + + ECCODES_ROOT='/project/d56/libcdi-ci-sw/cce-12.0.3-haswell/eccodes-2.24.2-o2a4fw3' + PPM_ROOT='/project/d56/libcdi-ci-sw/cce-12.0.3-haswell/scales-ppm-1.0.8-44zlrlu' + YAXT_ROOT='/project/d56/libcdi-ci-sw/cce-12.0.3-haswell/yaxt-0.9.2.1-enz3pcz' + + # Here we fix a never-ending story with Libtool overlinkning, absence of + # '*.la' files when they could help, and '-Wl,--disable/enable-new-dtags': + export LD_LIBRARY_PATH="${ECCODES_ROOT}/lib64:${PPM_ROOT}/lib:${YAXT_ROOT}/lib:${LD_LIBRARY_PATH-}" +} + +# +# Sets variables for tests with PGI 20.1.1. +# +init_pgi2011 () +{ + init_env + # We use deprecated versions (the most recent compatible with PGI though) of + # the Cray packages and have to make sure that the default versions are + # unloaded (otherwise, we get various warnings and errors): + module unload cray-mpich cray-netcdf cray-netcdf-hdf5parallel cray-hdf5 cray-hdf5-parallel + switch_for_module craype PrgEnv-pgi/6.0.8 pgi/20.1.1 cray-mpich/7.7.15 + + # Build and test against NetCDF that does not support MPI parallel invocations + # (parallel NetCDF4 tests are known to fail in this case when run from the + # user home directory on Daint): + switch_for_module cray-netcdf/4.7.4.0 cray-hdf5/1.12.0.0 + + # Uncomment the following line to test against MPI-capable NetCDF: + # switch_for_module cray-netcdf-hdf5parallel/4.7.4.0 cray-hdf5-parallel/1.12.0.0 + + CC=cc + CXX=CC + FC=ftn + MPI_LAUNCH="$(which srun) -p cscsci -C gpu -A d56 -t 05:00" + + ECCODES_ROOT='/project/d56/libcdi-ci-sw/pgi-20.1.1-haswell/eccodes-2.24.2-hwtl5nr' + PPM_ROOT='/project/d56/libcdi-ci-sw/pgi-20.1.1-haswell/scales-ppm-1.0.8-z2nxqya' + YAXT_ROOT='/project/d56/libcdi-ci-sw/pgi-20.1.1-haswell/yaxt-0.9.2.1-3orop7g' + + # The deprecated versions of the Cray packages are not in the default linker + # search path: + export LD_LIBRARY_PATH="${MPICH_DIR}/lib:${NETCDF_DIR}/lib:${HDF5_DIR}/lib:${LD_LIBRARY_PATH-}" + + # Here we fix a never-ending story with Libtool overlinkning, absence of + # '*.la' files when they could help, and '-Wl,--disable/enable-new-dtags': + export LD_LIBRARY_PATH="${ECCODES_ROOT}/lib64:${PPM_ROOT}/lib:${YAXT_ROOT}/lib:${LD_LIBRARY_PATH-}" +} + +# +# Accepts a path to a file containing the testsuite summary (either the +# 'test-suite.log' or the standard output of the 'make check' command) and +# checks whether all tests were run and passed. +# +check_all_tests_passed () +{ + awk '/SKIP: /{ + print "ERROR: the total number of tests is not equal to the number of passed tests"; + exit 1; + }' $1 >&2 +} diff --git a/.ci/bb/levante-dkrz/install_prerequisites.sh b/.ci/bb/levante-dkrz/install_prerequisites.sh new file mode 100755 index 0000000000000000000000000000000000000000..7b9d22858ab02f3e3299a8454c80fd514c43250e --- /dev/null +++ b/.ci/bb/levante-dkrz/install_prerequisites.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +set -eu +unset CDPATH + +module purge +module load git + +install_dir='/work/mh0287/m300488/libcdi-ci-sw/install' +work_dir="$(pwd)/build" +make_cmd='make -j22' + +mkdir -p "${work_dir}" && cd "${work_dir}" + +# Get PPM 1.0.8: +wget https://swprojects.dkrz.de/redmine/attachments/download/517/ppm-1.0.8.tar.gz +tar xvf ppm-1.0.8.tar.gz +ppm_src_dir="${work_dir}/ppm-1.0.8" +ppm_name_tag='ppm-1.0.8' +ppm_config_args='--enable-MPI --disable-netcdf --disable-hdf5 --disable-parmetis --disable-metis --disable-crypto' + +# Get YAXT 0.9.3: +git clone --depth=1 -b release-0.9.3 https://gitlab.dkrz.de/dkrz-sw/yaxt.git +yaxt_src_dir="${work_dir}/yaxt" +yaxt_name_tag='yaxt-0.9.3' +yaxt_config_args='' + +export CC='mpicc' +export FC='mpif90' + +# Install for GCC 11.2.0: +compiler_name_tag='gcc-11.2.0' +module load openmpi/4.1.2-gcc-11.2.0 + +# Install PPM: +build_dir="${ppm_name_tag}-${compiler_name_tag}" +mkdir "${build_dir}" +( cd "${build_dir}" + "${ppm_src_dir}/configure" ${ppm_config_args} --prefix="${install_dir}/${ppm_name_tag}-${compiler_name_tag}" + $make_cmd + $make_cmd check + $make_cmd install ) + +# Install YAXT: +build_dir="${yaxt_name_tag}-${compiler_name_tag}" +mkdir "${build_dir}" +( cd "${build_dir}" + "${yaxt_src_dir}/configure" ${yaxt_config_args} --prefix="${install_dir}/${yaxt_name_tag}-${compiler_name_tag}" + $make_cmd + $make_cmd check + $make_cmd install ) + +module unload openmpi/4.1.2-gcc-11.2.0 + +# Install for Intel Classic 2021.5.0: +compiler_name_tag='intel-classic-2021.5.0' +module load openmpi/4.1.2-intel-2021.5.0 + +# Install PPM: +build_dir="${ppm_name_tag}-${compiler_name_tag}" +mkdir "${build_dir}" +( cd "${build_dir}" + "${ppm_src_dir}/configure" ${ppm_config_args} --prefix="${install_dir}/${ppm_name_tag}-${compiler_name_tag}" + $make_cmd + $make_cmd check + $make_cmd install ) + +# Install YAXT: +build_dir="${yaxt_name_tag}-${compiler_name_tag}" +mkdir "${build_dir}" +( cd "${build_dir}" + "${yaxt_src_dir}/configure" ${yaxt_config_args} --prefix="${install_dir}/${yaxt_name_tag}-${compiler_name_tag}" + $make_cmd + $make_cmd check + $make_cmd install ) + +module unload openmpi/4.1.2-intel-2021.5.0 diff --git a/.ci/bb/levante-dkrz/test.all.gcc b/.ci/bb/levante-dkrz/test.all.gcc new file mode 100755 index 0000000000000000000000000000000000000000..a114e52c7f04cbc7978957a774498ab6acbd6238 --- /dev/null +++ b/.ci/bb/levante-dkrz/test.all.gcc @@ -0,0 +1,47 @@ +#!/bin/bash + +set -eu +set -o pipefail + +script_dir=$(cd "$(dirname "$0")"; pwd) +top_srcdir=$(cd "${script_dir}/../../.."; pwd) + +. "${script_dir}/utils.sh" +init_gcc1120 + +test -f "${top_srcdir}/configure" || "${top_srcdir}/autogen.sh" + +# The configure script does not check the 'lib64' subdirectory, therefore we +# run it with '--with-eccodes' and the following flags. Note that fixing this +# in the configure script might be tricky: the 'lib64' subdirectory should be +# checked first but if it does not exist or does not contain the library, we +# might end up linking to a library from the linker's default search path +# (e.g. /usr/lib) instead of the one from "$with_eccodes/lib" because +# "-L${with_eccodes}/lib64" would be ignored in that case: +CPPFLAGS="-I${ECCODES_ROOT}/include" +LDFLAGS="-L${ECCODES_ROOT}/lib64" + +# We expect --enable-cf-interface and --enable-ppm-dist-array to be set to +# 'yes' automatically because of --enable-mpi. Function +# 'check_all_tests_passed' that we run at the end makes sure that the options +# have been enabled and the corresponding tests have not been skipped. +"${top_srcdir}/configure" \ +--disable-maintainer-mode \ +--enable-iso-c-interface \ +--enable-mpi \ +--enable-option-checking=fatal \ +--with-eccodes \ +--with-netcdf="${NETCDF_ROOT}" \ +CC="${MPICC}" \ +CPPFLAGS="${CPPFLAGS}" \ +F77="${MPIFC}" \ +FC="${MPIFC}" \ +LDFLAGS="${LDFLAGS}" \ +MPI_LAUNCH="${MPI_LAUNCH}" \ +PKG_CONFIG_PATH="${YAXT_ROOT}/lib/pkgconfig:${PPM_ROOT}/lib/pkgconfig" + +make -j8 + +make -j8 check | tee tests/test-suite.log + +check_all_tests_passed tests/test-suite.log diff --git a/.ci/bb/levante-dkrz/test.all.intel-classic b/.ci/bb/levante-dkrz/test.all.intel-classic new file mode 100755 index 0000000000000000000000000000000000000000..21c9e889d07941490439fe53b631531375a9f5c8 --- /dev/null +++ b/.ci/bb/levante-dkrz/test.all.intel-classic @@ -0,0 +1,51 @@ +#!/bin/bash + +set -eu +set -o pipefail + +script_dir=$(cd "$(dirname "$0")"; pwd) +top_srcdir=$(cd "${script_dir}/../../.."; pwd) + +. "${script_dir}/utils.sh" +init_intelclassic202150 + +test -f "${top_srcdir}/configure" || "${top_srcdir}/autogen.sh" + +# Create a subdirectory for building and switch to it: +mkdir build && cd build + +# The configure script does not check the 'lib64' subdirectory, therefore we +# run it with '--with-eccodes' and the following flags. Note that fixing this +# in the configure script might be tricky: the 'lib64' subdirectory should be +# checked first but if it does not exist or does not contain the library, we +# might end up linking to a library from the linker's default search path +# (e.g. /usr/lib) instead of the one from "$with_eccodes/lib" because +# "-L${with_eccodes}/lib64" would be ignored in that case: +CPPFLAGS="-I${ECCODES_ROOT}/include" +LDFLAGS="-L${ECCODES_ROOT}/lib64" + +"${top_srcdir}/configure" \ +--disable-maintainer-mode \ +--enable-cf-interface \ +--enable-iso-c-interface \ +--enable-mpi \ +--enable-option-checking=fatal \ +--with-eccodes \ +--with-netcdf="${NETCDF_ROOT}" \ +CC="${MPICC}" \ +CPPFLAGS="${CPPFLAGS}" \ +F77="${MPIFC}" \ +FC="${MPIFC}" \ +LDFLAGS="${LDFLAGS}" \ +MPI_LAUNCH="${MPI_LAUNCH}" \ +PKG_CONFIG_PATH="${YAXT_ROOT}/lib/pkgconfig:${PPM_ROOT}/lib/pkgconfig" + +make -j8 + +make -j8 check | tee tests/test-suite.log + +check_all_tests_passed tests/test-suite.log + +make -j8 distclean + +check_no_files_in_cwd diff --git a/.ci/bb/levante-dkrz/test.icon-pio.intel-classic b/.ci/bb/levante-dkrz/test.icon-pio.intel-classic new file mode 100755 index 0000000000000000000000000000000000000000..b99b4bb9ba71c84cf583cdacf69ff9b6b1846b11 --- /dev/null +++ b/.ci/bb/levante-dkrz/test.icon-pio.intel-classic @@ -0,0 +1,4 @@ +#!/bin/bash + +echo "WARNING: the current version of CDI-PIO is incompatible with the build system if ICON" >&2 +exit 0 diff --git a/.ci/bb/levante-dkrz/test.icon.gcc b/.ci/bb/levante-dkrz/test.icon.gcc new file mode 100755 index 0000000000000000000000000000000000000000..0b1a23e46f403a41360796d06441f4f7bf5fc581 --- /dev/null +++ b/.ci/bb/levante-dkrz/test.icon.gcc @@ -0,0 +1,80 @@ +#!/bin/bash + +set -eu + +script_dir=$(cd "$(dirname "$0")"; pwd) +top_srcdir=$(cd "${script_dir}/../../.."; pwd) + +. "${script_dir}/utils.sh" +init_gcc1120 + +# The following compiler flags are used by the respective ICON configure +# wrapper. They are not set into stone and can be changed if needed. It is just +# important to keep them the same as in the wrapper. +CFLAGS='-g -gdwarf-4 -march=native -mpc64 -O2' +FCFLAGS='-fmodule-private -fimplicit-none -fmax-identifier-length=63 -Wall -Wcharacter-truncation -Wconversion -Wunderflow -Wunused-parameter -Wno-surprising -fall-intrinsics -g -march=native -mpc64 -fbacktrace -fbounds-check -fstack-protector-all -finit-real=nan -finit-integer=-2147483648 -finit-character=127 -O2 -std=f2008' + +test -f "${top_srcdir}/configure" || "${top_srcdir}/autogen.sh" + +"${top_srcdir}/configure" \ +--disable-cdi-app \ +--disable-maintainer-mode \ +--disable-shared \ +--enable-cf-interface=no \ +--enable-cgribex \ +--enable-grib \ +--enable-iso-c-interface \ +--enable-mpi=no \ +--enable-ppm-dist-array=no \ +--enable-silent-rules=no \ +--enable-static \ +--with-eccodes=yes \ +--with-netcdf \ +--with-on-demand-check-programs \ +--without-example-programs \ +--without-grib_api \ +--without-szlib \ +--without-threads \ +BUILD_CC= \ +BUILD_CFLAGS= \ +BUILD_CXX= \ +BUILD_F77= \ +BUILD_FC= \ +BUILD_FCFLAGS= \ +BUILD_LDFLAGS= \ +BUILD_LIBS= \ +BUILD_MPI_C_LIB= \ +BUILD_MPI_FC_LIB= \ +CC="${MPICC}" \ +CFLAGS="${CFLAGS}" \ +CPPFLAGS="-I${NETCDF_ROOT}/include -I${ECCODES_ROOT}/include" \ +CXX=no \ +F77=no \ +FC="${MPIFC}" \ +FCFLAGS="${FCFLAGS}" \ +LDFLAGS="-L${NETCDF_ROOT}/lib -L${ECCODES_ROOT}/lib64" \ +LIBS='-leccodes -lnetcdf' \ +MPIROOT= \ +MPI_C_INCLUDE= \ +MPI_C_LIB= \ +MPI_FC_LIB= \ +MPI_FC_MOD= \ +MPI_LAUNCH="${MPI_LAUNCH}" \ +PKG_CONFIG= \ +PPM_CORE_C_INCLUDE= \ +PPM_CORE_C_LIB= \ +YAXT_C_INCLUDE= \ +YAXT_C_LIB= \ +YAXT_FC_LIB= \ +YAXT_FC_MOD= \ +ac_cv_func_uuid_create=no \ +ac_cv_lib_uuid_uuid_generate=no \ +acx_cv_have_libnc_dap=no \ +acx_cv_have_nc4hdf5=no \ +acx_cv_have_netcdf2=yes \ +acx_cv_have_netcdf4=yes \ +acx_cv_have_pnetcdf=no + +make -j8 + +make -j8 check diff --git a/.ci/bb/levante-dkrz/utils.sh b/.ci/bb/levante-dkrz/utils.sh new file mode 100644 index 0000000000000000000000000000000000000000..0be138ae34319d65eff6ce3ac47e7566ac4006c3 --- /dev/null +++ b/.ci/bb/levante-dkrz/utils.sh @@ -0,0 +1,182 @@ +# +# Accepts a list of environment modules and loads them witch conflict +# resolution. +# +switch_for_module () +{ + for sfm_module in "$@"; do + 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" + + # 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 +} + +# +# Initializes the environment. +# +init_env () +{ + : +} + +# +# Sets variables for tests with GCC 11.2.0. +# +init_gcc1120 () +{ + init_env + switch_for_module gcc/11.2.0-gcc-11.2.0 openmpi/4.1.2-gcc-11.2.0 + + CC=gcc + CXX=g++ + FC=gfortran + MPICC=mpicc + MPIFC=mpif90 + MPI_LAUNCH="$(which mpirun)" + + ECCODES_ROOT='/sw/spack-levante/eccodes-2.21.0-4ywkk4' + NETCDF_ROOT='/sw/spack-levante/netcdf-c-4.8.1-6qheqr' + PPM_ROOT='/work/mh0287/m300488/libcdi-ci-sw/install/ppm-1.0.8-gcc-11.2.0' + YAXT_ROOT='/work/mh0287/m300488/libcdi-ci-sw/install/yaxt-0.9.3-gcc-11.2.0' + + # Here we fix a never-ending story with Libtool overlinkning, absence of + # '*.la' files when they could help, and '-Wl,--disable/enable-new-dtags': + export LD_LIBRARY_PATH="${ECCODES_ROOT}/lib64:${NETCDF_ROOT}/lib:${LD_LIBRARY_PATH-}" +} + +# +# Sets variables for tests with Intel Classic 2021.5.0. +# +init_intelclassic202150 () +{ + init_env + # Try to make sure that the compiler works with the system gcc: + module unload gcc + # For whatever reason, Intel Classic 2021.5.0 is enabled with + # intel-oneapi-compilers/2022.0.1-gcc-11.2.0: + switch_for_module intel-oneapi-compilers/2022.0.1-gcc-11.2.0 openmpi/4.1.2-intel-2021.5.0 + + AR=xiar + CC=icc + CXX=icpc + FC=ifort + MPICC=mpicc + MPIFC=mpif90 + MPI_LAUNCH="$(which mpirun)" + + ECCODES_ROOT='/sw/spack-levante/eccodes-2.21.0-3ehkbb' + NETCDF_ROOT='/sw/spack-levante/netcdf-c-4.8.1-2k3cmu' + PPM_ROOT='/work/mh0287/m300488/libcdi-ci-sw/install/ppm-1.0.8-intel-classic-2021.5.0' + YAXT_ROOT='/work/mh0287/m300488/libcdi-ci-sw/install/yaxt-0.9.3-intel-classic-2021.5.0' + + # Here we fix a never-ending story with Libtool overlinkning, absence of + # '*.la' files when they could help, and '-Wl,--disable/enable-new-dtags': + export LD_LIBRARY_PATH="${ECCODES_ROOT}/lib64:${NETCDF_ROOT}/lib:${LD_LIBRARY_PATH-}" +} + +# +# Accepts a path to a file containing the testsuite summary (either the +# 'test-suite.log' or the standard output of the 'make check' command) and +# checks whether all tests were run and passed. +# +check_all_tests_passed () +{ + awk '/SKIP: /{ + print "ERROR: the total number of tests is not equal to the number of passed tests"; + exit 1; + }' $1 >&2 +} + +# +# Checks whether the current working directory or any of its subdirectories +# contain a file and fails with an error message if that is the case. +# +check_no_files_in_cwd () +{ + cnfic_files=`find . -type f 2>/dev/null` + if test -n "$cnfic_files"; then + { + echo "ERROR: the current working directory contains undeleted files:" + echo "$cnfic_files" + } >&2 + exit 1 + fi +} diff --git a/.ci/bb/run_all.sh b/.ci/bb/run_all.sh new file mode 100755 index 0000000000000000000000000000000000000000..583e36a23de183b73984ada54a427ebe65dada46 --- /dev/null +++ b/.ci/bb/run_all.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +set -eu +set -o pipefail + +script_dir=$(cd "$(dirname "$0")"; pwd) +top_srcdir=$(cd "${script_dir}/../.."; pwd) + +test_environment='unknown' +case $(uname -s) in + Linux) + node_name=$(uname -n) + case $(host "${node_name}") in + mpipc*.mpimet.mpg.de\ * | \ + breeze*.mpimet.mpg.de\ *) + test_environment='breeze-mpim' ;; + levante*.atos.local\ *) + test_environment='levante-dkrz' ;; + daint*.login.cscs.ch\ *) + test_environment='daint-cscs' ;; + esac +esac + +test "x${test_environment}" != 'xunknown' || { + echo 'ERROR: unknown test environment' >&2 + exit 1 +} + +cd "${top_srcdir}" + +git update-index -q --refresh || { + echo "ERROR: failed to update git index in '${top_srcdir}'" >&2 + exit 1 +} + +git diff-files --quiet || { + echo "ERROR: '${top_srcdir}' has unstaged changes" >&2 + exit 1 +} + +untracked_files=`git ls-files --others` || { + echo "ERROR: failed to get list of untracked files in '${top_srcdir}'" >&2 + exit 1 +} +if test -n "${untracked_files}"; then + { + echo "ERROR: '${top_srcdir}' has untracked files:" >&2 + echo "${untracked_files}" >&2 + } >&2 + exit 1 +fi + +echo "Running tests for '${test_environment}'" + +for script in $(find "${script_dir}/${test_environment}" -type f -name 'test.*' -executable); do + echo "Running '${script}'" + "${script}" + git clean -fdx + git checkout . +done diff --git a/ChangeLog b/ChangeLog index 62c8ef7606d6d72561ca2c2b0fd2a288191b357e..879960a148007daa960ed1a6c0154a2afe5922d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,46 @@ +2022-11-05 Uwe Schulzweida + + * NetCDF output: added compression support for data on GRID_GENERIC + +2022-10-19 Uwe Schulzweida + + * Replaced CDI function vlistDefVarExtra() by cdiDefKeyString() with CDI_KEY_CHUNKS + * Replaced CDI function vlistInqVarExtra() by cdiInqKeyString() with CDI_KEY_CHUNKS + * Replaced CDI function vlistDefVarScalefactor() by cdiDefKeyFloat() with CDI_KEY_SCALEFACTOR + * Replaced CDI function vlistInqVarScalefactor() by cdiDefKeyFloat () with CDI_KEY_SCALEFACTOR + * Replaced CDI function vlistDefVarAddoffset() by cdiDefKeyFloat () with CDI_KEY_ADDOFFSET + * Replaced CDI function vlistInqVarAddoffset() by cdiDefKeyFloat () with CDI_KEY_ADDOFFSET + +2022-10-17 Uwe Schulzweida + + * Added environment variable CDI_SHUFFLE to set shuffle option to NetCDF4 deflation compression + +2022-10-16 Uwe Schulzweida + + * Improved read performance of temporal chunked NetCDF4 data + * Added environment variable CDI_CHUNK_CACHE to set the NetCDF4 chunk cache size + * Added environment variable CDI_CHUNK_CACHE_MAX to set the maximum chunk cache size + +2022-10-14 Uwe Schulzweida + + * NetCDF: reading of lower time bounds is wrong since 2.0.6 (bug fix) + +2022-10-06 Uwe Schulzweida + + * Version 2.1.0 released + +2022-10-05 Uwe Schulzweida + + * Added CDI_PROJ_HEALPIX + +2022-10-04 Uwe Schulzweida + + * cdi_encode_timeval: added support for TUNIT_SECOND + +2022-09-30 Uwe Schulzweida + + * install cmake files in <install>/lib/cmake/cdi + 2022-08-12 Uwe Schulzweida * added CDI_KEY_CHUNKTYPE and CDI_KEY_CHUNKSIZE @@ -56,7 +99,7 @@ 2022-01-28 Uwe Schulzweida - * cdf_read_coordinates: check that bounds have only 2 dimensions [Bug #10575] + * cdf_read_coordinates: check that grid cell bounds have only 2 dimensions [Bug #10575] * gribIterator::gridGenerate: copy CDI_KEY_UUID (bug fix) 2022-01-12 Uwe Schulzweida diff --git a/NEWS b/NEWS index f424f07c0b0a6ac2fbefc2729a5a18a4bbe44f8f..ad1d2d665d26ca50f2a1ffe2c45127fd7a29c5c0 100644 --- a/NEWS +++ b/NEWS @@ -1,16 +1,27 @@ CDI NEWS -------- -Version 2.1.0 (11 October 2021): +Version 2.2.0 (6 October 2023): + + New features: + * Improved read performance of temporal chunked NetCDF4 data + Fixed bugs: + +Version 2.1.0 (6 October 2022): New features: * Added support for NCZarr * Set number of significant bits used for NetCDF 4.9.0 bit-roundung: vlistDefVarNSB()/vlistInqVarNSB() * Added support for milli seconds * Changed DateType back to int + * Made CDI compatible to revision 1.8.3 used in ICON Fixed bugs: + * recalculate optimal chunk_size if gridsize is > chunk_size_lim + * ecCodes encode: fix problem with startStep for step type MIN/MAX + * GRIB read: recalculate start date/time for every record and timestep + * changed chunk_size_lim from 1073741823 to 16777216 * compareXYvals failed for unstructured grids (segmentation fault) [Bug #10632] - * cdf_read_coordinates: check that bounds have only 2 dimensions [Bug #10575] + * cdf_read_coordinates: check that grid cell bounds have only 2 dimensions [Bug #10575] Version 2.0.0 (11 October 2021): diff --git a/app/cdi.c b/app/cdi.c index 19f518a32774371d401d37ede09040eb9baa6b9f..689bba083f0e534ed88a4fb9ceadee76f76a3deb 100644 --- a/app/cdi.c +++ b/app/cdi.c @@ -78,8 +78,8 @@ static int datamode = DP_MODE; static void version(void) { - int filetypes[] = { CDI_FILETYPE_SRV, CDI_FILETYPE_EXT, CDI_FILETYPE_IEG, CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, - CDI_FILETYPE_NC, CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C, CDI_FILETYPE_NC5, CDI_FILETYPE_NCZARR }; + int filetypes[] = { CDI_FILETYPE_SRV, CDI_FILETYPE_EXT, CDI_FILETYPE_IEG, CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, CDI_FILETYPE_NC, + CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C, CDI_FILETYPE_NC5, CDI_FILETYPE_NCZARR }; const char *typenames[] = { "srv", "ext", "ieg", "grb", "grb2", "nc", "nc2", "nc4", "nc4c", "nc5", "nczarr" }; fprintf(stderr, "CDI version 2.1\n"); @@ -497,8 +497,8 @@ printShortinfo(int streamID, int vlistID, int vardis) { const CdiDateTime dt = taxisInqRdatetime(taxisID); - fprintf(stdout, " RefTime = %4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", - dt.date.year, dt.date.month, dt.date.day, dt.time.hour, dt.time.minute, dt.time.second); + fprintf(stdout, " RefTime = %4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", dt.date.year, dt.date.month, dt.date.day, + dt.time.hour, dt.time.minute, dt.time.second); if (dt.time.ms) fprintf(stdout, ".%d", dt.time.ms); const int tunits = taxisInqTunit(taxisID); @@ -560,8 +560,9 @@ setDefaultDataType(char *datatypestr) else { fprintf(stderr, "Unsupported number of bits %d!\n", nbits); - fprintf(stderr, - "Use I8/I16/I32/F32/F64 for nc/nc2/nc4/nc4c/nc5/nczarr; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb/grb2.\n"); + fprintf( + stderr, + "Use I8/I16/I32/F32/F64 for nc/nc2/nc4/nc4c/nc5/nczarr; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb/grb2.\n"); exit(EXIT_FAILURE); } } diff --git a/app/printinfo.c b/app/printinfo.c index 0110224530e94fd3bfd90cc0481d6d87f42efa7d..21f1b26734f0b782de437012aa45f1f273937aa8 100644 --- a/app/printinfo.c +++ b/app/printinfo.c @@ -9,15 +9,14 @@ #include "printinfo.h" - #define DATE_FORMAT "%5.4d-%2.2d-%2.2d" #define TIME_FORMAT "%2.2d:%2.2d:%2.2d" void datetime2str(CdiDateTime dt, char *datetimestr, int maxlen) { - snprintf(datetimestr, maxlen, DATE_FORMAT "T" TIME_FORMAT, - dt.date.year, dt.date.month, dt.date.day, dt.time.hour, dt.time.minute, dt.time.second); + snprintf(datetimestr, maxlen, DATE_FORMAT "T" TIME_FORMAT, dt.date.year, dt.date.month, dt.date.day, dt.time.hour, dt.time.minute, + dt.time.second); } void @@ -44,7 +43,8 @@ time2str(CdiTime time, char *timestr, int maxlen) } if (msDigitsNum) - snprintf(timestr, maxlen, "%2.2d:%2.2d:%0*.*f", time.hour, time.minute, msDigitsNum + 3, msDigitsNum, time.second + time.ms / 1000.0); + snprintf(timestr, maxlen, "%2.2d:%2.2d:%0*.*f", time.hour, time.minute, msDigitsNum + 3, msDigitsNum, + time.second + time.ms / 1000.0); else snprintf(timestr, maxlen, TIME_FORMAT, time.hour, time.minute, time.second); } diff --git a/config/default b/config/default index 9454f5561565851ff53290c96572606dc36f9216..78cba4d32d89e306d3b3a300a331e5b72463cd74 100755 --- a/config/default +++ b/config/default @@ -42,7 +42,7 @@ case "${HOSTNAME}" in CC=icc CFLAGS="-g -D_REENTRANT -Wall -Wwrite-strings -O3 -march=native -fp-model source" ;; bailung*|d133*|d134*) - ${CONFPATH}configure --prefix=$HOME/local \ + ${CONFPATH}configure --prefix=$HOME/local/cdi \ --enable-maintainer-mode \ --enable-iso-c-interface \ --enable-swig \ @@ -69,7 +69,7 @@ case "${HOSTNAME}" in --with-fdb5=$HOME/src/fdb \ --with-eccodes=$HOME/local/eccodes-2.22.0 \ --with-netcdf=$HOME/local/netcdf-c-4.9.0" - PREFIX="--prefix=$HOME/local" + PREFIX="--prefix=$HOME/local/cdi" LD_ADD="-Wl,-rpath,$HOME/local/eccodes-2.22.0/lib -Wl,-rpath,$HOME/src/fdb/lib" if test "$COMP" = clang ; then ${CONFPATH}configure $CONFIG_OPTS $PREFIX $CDILIBS LDFLAGS="$LD_ADD $LDFLAGS" \ diff --git a/configure.ac b/configure.ac index b3469f9e843cd6624fb4bc2627260a6043efa2a7..1b0232e6909f0e8cb0aef163ad88d5fe39fa09af 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ AC_PREREQ([2.69]) LT_PREREQ([2.4.6]) -AC_INIT([cdi],[2.0.7],[https://mpimet.mpg.de/cdi]) +AC_INIT([cdi],[2.1.1],[https://mpimet.mpg.de/cdi]) AC_DEFINE_UNQUOTED(CDI, ["$PACKAGE_VERSION"], [CDI version]) @@ -395,13 +395,13 @@ dnl m4_foreach([build_flag_var],[[BUILD_CFLAGS],[BUILD_FCFLAGS],[BUILD_LDFLAGS],[BUILD_LIBS],[BUILD_MPI_C_LIB],[BUILD_MPI_FC_LIB],[BUILD_C_INCLUDE],[BUILD_FC_INCLUDE]], [AC_ARG_VAR(build_flag_var, [append to ]m4_bpatsubst(build_flag_var, [BUILD_], [])[ during build but not in configure phase])dnl -AC_CONFIG_COMMANDS_PRE(m4_bpatsubst(build_flag_var, [BUILD_], [])[="$]m4_bpatsubst(build_flag_var, [BUILD_], [])[$]{build_flag_var+ $build_flag_var[}"])dnl +AC_CONFIG_COMMANDS_PRE(m4_bpatsubst(build_flag_var, [BUILD_], [])[="$]m4_bpatsubst(build_flag_var, [BUILD_], [])[$]{build_flag_var:+ $build_flag_var[}"])dnl AM_SUBST_NOTMAKE(build_flag_var)])dnl m4_foreach([build_tool_var],[[BUILD_CC],[BUILD_CXX],[BUILD_FC],[BUILD_F77]], [AC_ARG_VAR(build_tool_var, [replace ]m4_bpatsubst(build_tool_var, [BUILD_], [])[ with expansion of $]build_tool_var[ during build but not in configure phase])dnl -AC_CONFIG_COMMANDS_PRE(m4_bpatsubst(build_tool_var, [BUILD_], [])[="$]{build_tool_var-$[]m4_bpatsubst(build_tool_var, [BUILD_], [])}["])dnl +AC_CONFIG_COMMANDS_PRE(m4_bpatsubst(build_tool_var, [BUILD_], [])[="$]{build_tool_var:-$[]m4_bpatsubst(build_tool_var, [BUILD_], [])}["])dnl AM_SUBST_NOTMAKE(build_tool_var)])dnl dnl dnl @@ -440,7 +440,7 @@ AC_CONFIG_FILES([tests/test_cksum_grib \ AC_CONFIG_FILES([Makefile src/Makefile interfaces/Makefile app/Makefile \ tests/Makefile examples/Makefile cdi.settings \ - examples/pio/Makefile src/cmake/libcdi/cdi-config.cmake src/cmake/libcdi/cdi-config-version.cmake \ + examples/pio/Makefile src/cmake/cdi/cdi-config.cmake src/cmake/cdi/cdi-config-version.cmake \ src/pkgconfig/cdi.pc src/pkgconfig/cdipio.pc src/pkgconfig/cdi_f2003.pc]) AC_OUTPUT diff --git a/doc/tex/c_quick_ref.tex b/doc/tex/c_quick_ref.tex index 690c6789232da753f94cc5badca08f42c1a31fa6..daf8205cd8d41bfb2bf87273c7446844b25b6d00 100644 --- a/doc/tex/c_quick_ref.tex +++ b/doc/tex/c_quick_ref.tex @@ -1065,15 +1065,6 @@ Define the data type of a Variable. Set an arbitrary keyword/double value pair for GRIB API. -\section*{\tt \htmlref{vlistDefVarExtra}{vlistDefVarExtra}} - -\begin{verbatim} - void vlistDefVarExtra (int vlistID, int varID, const char *extra); -\end{verbatim} - -Define extra information of a Variable. - - \section*{\tt \htmlref{vlistDefVarIntKey}{vlistDefVarIntKey}} \begin{verbatim} @@ -1210,15 +1201,6 @@ Get the data type of a Variable. raw access to GRIB meta-data. -\section*{\tt \htmlref{vlistInqVarExtra}{vlistInqVarExtra}} - -\begin{verbatim} - void vlistInqVarExtra (int vlistID, int varID, char *extra); -\end{verbatim} - -Get extra information of a Variable. - - \section*{\tt \htmlref{vlistInqVarIntKey}{vlistInqVarIntKey}} \begin{verbatim} diff --git a/doc/tex/cdi_cman.tex b/doc/tex/cdi_cman.tex index 14a8fd4315cd24589615726c818a7232ccfcef3c..a7143c1810b5ad412bc93967ad17f3b1df12a539 100644 --- a/doc/tex/cdi_cman.tex +++ b/doc/tex/cdi_cman.tex @@ -47,6 +47,7 @@ \renewcommand{\headrulewidth}{0pt} } +\usepackage{html} \usepackage{exscale} \usepackage{array,colortbl} % color table @@ -135,7 +136,7 @@ \end{picture} \begin{flushright} -{\large\bfseries Climate Data Interface \\ Version 2.0.0 \\ October 2021} +{\large\bfseries Climate Data Interface \\ Version 2.2.0 \\ October 2023} \end{flushright} \vfill diff --git a/doc/tex/cdi_fman.tex b/doc/tex/cdi_fman.tex index 37a76cb994dac6f486f20cd8230a02b15bb41e52..a656e41b287218e86ebf2566b5b8233d193e6af4 100644 --- a/doc/tex/cdi_fman.tex +++ b/doc/tex/cdi_fman.tex @@ -45,6 +45,7 @@ \renewcommand{\headrulewidth}{0pt} } +\usepackage{html} \usepackage{exscale} \usepackage{array,colortbl} % color table @@ -132,7 +133,7 @@ \end{picture} \begin{flushright} -{\large\bfseries Climate Data Interface \\ Version 2.0.0 \\ October 2021} +{\large\bfseries Climate Data Interface \\ Version 2.2.0 \\ October 2023} \end{flushright} \vfill diff --git a/doc/tex/dataset.tex b/doc/tex/dataset.tex index a0cef17c1fcbbca6801bed77a452ab04f99c3c80..cedca3be9976e2e42a915f2b920ea48fd3da555d 100644 --- a/doc/tex/dataset.tex +++ b/doc/tex/dataset.tex @@ -12,6 +12,7 @@ with one of the following predefined file format types: \item[{\large\texttt{CDI\_FILETYPE\_NC4}}] File type NetCDF-4 (HDF5) \item[{\large\texttt{CDI\_FILETYPE\_NC4C}}] File type NetCDF-4 classic \item[{\large\texttt{CDI\_FILETYPE\_NC5}}] File type NetCDF version 5 (64-bit data) +\item[{\large\texttt{CDI\_FILETYPE\_NCZARR}}] File type NetCDF NCZarr \item[{\large\texttt{CDI\_FILETYPE\_SRV}}] File type SERVICE \item[{\large\texttt{CDI\_FILETYPE\_EXT}}] File type EXTRA \item[{\large\texttt{CDI\_FILETYPE\_IEG}}] File type IEG diff --git a/doc/tex/environment.tex b/doc/tex/environment.tex index ba6b8f0efc496fbf1b5915231c1e28f73560d62a..c086ffc2415d0202abb8ef178e1521cfc813f098 100644 --- a/doc/tex/environment.tex +++ b/doc/tex/environment.tex @@ -11,9 +11,12 @@ The following table describes the environment variables that affect {\CDI}. %\cellcolor{pcolor2} {\bfseries Variable name} & {\bfseries Default} & {\bfseries Description} \\ \hline CDI\_CONVERT\_CUBESPHERE & 1 & Convert cubed-sphere data to unstructured grid. \\ +CDI\_CHUNK\_CACHE & 0 & Set the NetCDF4 chunk cache size. \\ +CDI\_CHUNK\_CACHE\_MAX & 0 & Set maximum chunk cache size. \\ CDI\_GRIB1\_TEMPLATE & None & Path to a GRIB1 template file for GRIB\_API. \\ CDI\_GRIB2\_TEMPLATE & None & Path to a GRIB2 template file for GRIB\_API. \\ CDI\_INVENTORY\_MODE & None & Set to time to skip double variable entries. \\ CDI\_READ\_CELL\_CORNERS & 1 & Read grid cell corners. \\ +CDI\_SHUFFLE & 0 & Set shuffle option to NetCDF4 deflation compression. \\ CDI\_VERSION\_INFO & 1 & Set to 0 to disable NetCDF global attribute CDI. \end{tabular} diff --git a/doc/tex/f_quick_ref.tex b/doc/tex/f_quick_ref.tex index b44741069d603cdec19e356a0db7954428afa7be..e72627a4db4e4b3701c48314b17ad8e3ea86bf09 100644 --- a/doc/tex/f_quick_ref.tex +++ b/doc/tex/f_quick_ref.tex @@ -1077,15 +1077,6 @@ Define the data type of a Variable. Set an arbitrary keyword/double value pair for GRIB API. -\section*{\tt \htmlref{vlistDefVarExtra}{vlistDefVarExtra}} - -\begin{verbatim} - SUBROUTINE vlistDefVarExtra (INTEGER vlistID, INTEGER varID, CHARACTER*(*) extra) -\end{verbatim} - -Define extra information of a Variable. - - \section*{\tt \htmlref{vlistDefVarIntKey}{vlistDefVarIntKey}} \begin{verbatim} @@ -1229,15 +1220,6 @@ Get the data type of a Variable. raw access to GRIB meta-data. -\section*{\tt \htmlref{vlistInqVarExtra}{vlistInqVarExtra}} - -\begin{verbatim} - SUBROUTINE vlistInqVarExtra (INTEGER vlistID, INTEGER varID, CHARACTER*(*) extra) -\end{verbatim} - -Get extra information of a Variable. - - \section*{\tt \htmlref{vlistInqVarIntKey}{vlistInqVarIntKey}} \begin{verbatim} diff --git a/doc/tex/keys.tex b/doc/tex/keys.tex index 6e54ecd26ed14a592eee52e067520ec5d88b8405..cc56e1f0bc9d1c31bf1e70763e391f6d38dae3ee 100644 --- a/doc/tex/keys.tex +++ b/doc/tex/keys.tex @@ -10,10 +10,10 @@ Use the variable ID or one of the following identifiers for the coordinates: \vspace*{3mm} \hspace*{8mm}\begin{minipage}{15cm} -\begin{deflist}{\large\texttt{CDI\_KEY\_GLOBAL \ \ }} -\item[\large\texttt{CDI\_KEY\_XAXIS}] X-axis ID -\item[\large\texttt{CDI\_KEY\_YAXIS}] Y-axis ID -\item[\large\texttt{CDI\_KEY\_GLOBAL}] Global Z-axis +\begin{deflist}{\large\texttt{CDI\_GLOBAL \ \ }} +\item[\large\texttt{CDI\_XAXIS}] X-axis ID +\item[\large\texttt{CDI\_YAXIS}] Y-axis ID +\item[\large\texttt{CDI\_GLOBAL}] Global Z-axis \end{deflist} \end{minipage} \vspace*{4mm} @@ -48,12 +48,22 @@ The following key attributes are available: \item[\large\texttt{CDI\_KEY\_NUMBEROFGRIDINREFERENCE}] GRIB2 numberOfGridInReference \item[\large\texttt{CDI\_KEY\_NUMBEROFVGRIDUSED}] GRIB2 numberOfVGridUsed \item[\large\texttt{CDI\_KEY\_NLEV}] GRIB2 nlev +\item[\large\texttt{CDI\_KEY\_CHUNKTYPE}] ChunkType: CDI\_CHUNK\_AUTO/CDI\_CHUNK\_GRID/CDI\_CHUNK\_LINES +\item[\large\texttt{CDI\_KEY\_CHUNKSIZE}] ChunkSize \end{deflist} \end{minipage} \vspace*{4mm} \textbf{Floating point keys} +\vspace*{3mm} +\hspace*{8mm}\begin{minipage}{15cm} +\begin{deflist}{\large\texttt{CDI\_KEY\_MISSVAL \ \ }} +\item[\large\texttt{CDI\_KEY\_MISSVAL}] Missing value +\end{deflist} +\end{minipage} +\vspace*{4mm} + \textbf{Byte array keys} \vspace*{3mm} diff --git a/examples/pio/Makefile.am b/examples/pio/Makefile.am index 82f232df7a853f2ec7325990e497572ec8c2ae58..e840afb55e1a0c0a20ec1ae8f9dfa28b98d18604 100644 --- a/examples/pio/Makefile.am +++ b/examples/pio/Makefile.am @@ -16,8 +16,8 @@ endif collectData_SOURCES=collectData.c if USE_MPI -LDADD=$(top_builddir)/src/libcdipio.la $(LIBRT) $(MPI_C_LIB) -collectData2003_LDADD=$(top_builddir)/src/libcdipio.la $(LIBRT) $(MPI_FC_LIB) +LDADD=$(top_builddir)/src/libcdipio.la $(top_builddir)/src/libcdi.la $(YAXT_LIBS) $(MPI_C_LIB) +collectData2003_LDADD=$(top_builddir)/src/libcdipio.la $(top_builddir)/src/libcdi.la $(YAXT_LIBS) $(MPI_FC_LIB) else LDADD=$(top_builddir)/src/libcdi.la collectData2003_LDADD=$(top_builddir)/src/libcdi.la diff --git a/interfaces/cdi.cpp b/interfaces/cdi.cpp index 0894b58414cc68f3cd44a39eb805827c26143a5f..fe3d33871c4692bbc37c01ce03502fb16a475a3b 100644 --- a/interfaces/cdi.cpp +++ b/interfaces/cdi.cpp @@ -288,7 +288,7 @@ double * CdiVariable::getValuesAsPointer() { int levelID = 0, tsID = 0; - size_t nmiss; + SizeType nmiss; int nrecs = streamInqTimestep(streamID, tsID); int vdate = taxisInqVdate(taxisID); @@ -303,7 +303,7 @@ double ** CdiVariable::getValuesWithLevelAsPointer(int tsID) { int levelID, nrecs; - size_t nmiss; + SizeType nmiss; double **fieldWithLevel, *field; nrecs = streamInqTimestep(streamID, tsID); diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 index d383ad5c6d6a5061370800bb1dc89b7a334c0638..1598d077ff020f1f0be8388fded01c871c946354 100644 --- a/m4/ax_pthread.m4 +++ b/m4/ax_pthread.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# https://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS @@ -19,10 +19,10 @@ # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, -# but also link it with them as well. e.g. you should link with +# but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # -# If you are only building threads programs, you may wish to use these +# If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" @@ -30,8 +30,8 @@ # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant -# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name -# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with @@ -55,6 +55,7 @@ # # Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu> # Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG> +# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl> # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -67,7 +68,7 @@ # Public License for more details. # # You should have received a copy of the GNU General Public License along -# with this program. If not, see <http://www.gnu.org/licenses/>. +# with this program. If not, see <https://www.gnu.org/licenses/>. # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure @@ -82,35 +83,40 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 21 +#serial 27 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). +# requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) - AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes]) + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) - if test x"$ax_pthread_ok" = xno; then + if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different @@ -118,12 +124,14 @@ fi # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. +# Create a list of thread flags to try. Items with a "," contain both +# C compiler flags (before ",") and linker flags (after ","). Other items +# starting with a "-" are C compiler flags, and remaining items are +# library names, except for "none" which indicates that we try without +# any flags at all, and "pthread-config" which is a program returning +# the flags for the Pth emulation library. -ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: @@ -132,82 +140,163 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# ... -mt is also the pthreads flag for HP/aCC +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) -case ${host_os} in +case $host_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" + ;; +esac + +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +# Note that for GCC and Clang -pthread generally implies -lpthread, +# except when -nostdlib is passed. +# This is problematic using libtool to build C++ shared libraries with pthread: +# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 +# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 +# To solve this, first try -pthread together with -lpthread for GCC + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) + +# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first + +AS_IF([test "x$ax_pthread_clang" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread"]) - ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" ;; - darwin*) - ax_pthread_flags="-pthread $ax_pthread_flags" + aix*) + ax_pthread_check_macro="_THREAD_SAFE" ;; -esac -# Clang doesn't consider unrecognized options an error unless we specify -# -Werror. We throw in some extra Clang-specific options to ensure that -# this doesn't happen for GCC, which also accepts -Werror. + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) -AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags]) -save_CFLAGS="$CFLAGS" -ax_pthread_extra_flags="-Werror" -CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument" -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], - [AC_MSG_RESULT([yes])], - [ax_pthread_extra_flags= - AC_MSG_RESULT([no])]) -CFLAGS="$save_CFLAGS" -if test x"$ax_pthread_ok" = xno; then -for flag in $ax_pthread_flags; do +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do - case $flag in + case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; + *,*) + PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` + PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` + AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) + ;; + -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - PTHREAD_CFLAGS="$flag" + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - if test x"$ax_pthread_config" = xno; then continue; fi + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - PTHREAD_LIBS="-l$flag" + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we @@ -218,8 +307,18 @@ for flag in $ax_pthread_flags; do # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h> - static void routine(void *a) { a = 0; } +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void *some_global = NULL; + static void routine(void *a) + { + /* To avoid any unused-parameter or + unused-but-set-parameter warning. */ + some_global = a; + } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); @@ -227,88 +326,164 @@ for flag in $ax_pthread_flags; do pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) + [ax_pthread_ok=yes], + []) - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" AC_MSG_RESULT([$ax_pthread_ok]) - if test "x$ax_pthread_ok" = xyes; then - break; - fi + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + + + # Various other checks: -if test "x$ax_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_MSG_CHECKING([for joinable pthread attribute]) - attr_name=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>], - [int attr = $attr; return attr /* ; */])], - [attr_name=$attr; break], - []) - done - AC_MSG_RESULT([$attr_name]) - if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then - AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name], - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - fi - - AC_MSG_CHECKING([if more special flags are required for pthreads]) - flag=no - case ${host_os} in - aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; - osf* | hpux*) flag="-D_REENTRANT";; - solaris*) - if test "$GCC" = "yes"; then - flag="-D_REENTRANT" - else - # TODO: What about Clang on Solaris? - flag="-mt -D_REENTRANT" - fi - ;; - esac - AC_MSG_RESULT([$flag]) - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - [ax_cv_PTHREAD_PRIO_INHERIT], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], - [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], + [[int i = PTHREAD_PRIO_INHERIT; + return i;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], - [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant - if test "x$GCC" != xyes; then + if test "x$GCC" != "xyes"; then case $host_os in aix*) AS_CASE(["x/$CC"], - [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], - [#handle absolute path differently from PATH based program lookup - AS_CASE(["x$CC"], - [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) ;; esac fi @@ -321,7 +496,7 @@ AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$ax_pthread_ok" = xyes; then +if test "x$ax_pthread_ok" = "xyes"; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else diff --git a/patch/ltmain.sh.nag_pthread.patch b/patch/ltmain.sh.nag_pthread.patch index 4ec8747158f956419fdc34046049e88782d535be..63b3d3c66dd379150633c99c24e80358171e20f2 100644 --- a/patch/ltmain.sh.nag_pthread.patch +++ b/patch/ltmain.sh.nag_pthread.patch @@ -8,7 +8,7 @@ + # Additionally convert " -pthread" to " -Wl,-pthread" for nagfor + func_cc_basename $CC + case $func_cc_basename_result in -+ nagfor*) tmp_inherited_linker_flags=`$ECHO "$tmp_inherited_linker_flags" | $SED 's/ -pthread/ -Wl,-pthread/g'` ;; ++ nagfor*) tmp_inherited_linker_flags=`$ECHO " $tmp_inherited_linker_flags" | $SED 's/ -pthread/ -Wl,-pthread/g'` ;; + esac + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do diff --git a/src/Makefile.am b/src/Makefile.am index 2cea954ce896dc240fad72049bd1d2d62c9b0d90..77e1c06cbbe4c46157ffebb9d482887d8b935d1a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -259,7 +259,7 @@ libcdipio_la_SOURCES += $(libcdipio_la_HAVE_PARALLEL_NC4_extra_sources) endif endif -libcdipio_la_LIBADD = libcdi.la $(PPM_CORE_LIBS) $(YAXT_LIBS) $(MPI_C_LIB) +libcdipio_la_LIBADD = libcdi.la $(LIBRT) $(PPM_CORE_LIBS) $(YAXT_LIBS) $(MPI_C_LIB) # #cdilib.c: @@ -270,8 +270,8 @@ libcdipio_la_LIBADD = libcdi.la $(PPM_CORE_LIBS) $(YAXT_LIBS) $(MPI_C_LIB) LOCALTARGETS = if ENABLE_CDI_LIB -LOCALTARGETS += cmake/libcdi/cdi-config.cmake -LOCALTARGETS += cmake/libcdi/cdi-config-version.cmake +LOCALTARGETS += cmake/cdi/cdi-config.cmake +LOCALTARGETS += cmake/cdi/cdi-config-version.cmake LOCALTARGETS += pkgconfig/cdi.pc if USE_MPI LOCALTARGETS += pkgconfig/cdipio.pc @@ -295,11 +295,11 @@ mo_cdi.$(FCMODEXT): mo_cdi.lo endif @if test ! -f $@; then rm -f $<; $(MAKE) $<; fi # -cmake/libcdi/cdi-config.cmake: cmake/libcdi/cdi-config.cmake.in ../config.status - (cd .. ; ./config.status src/cmake/libcdi/cdi-config.cmake) +cmake/cdi/cdi-config.cmake: cmake/cdi/cdi-config.cmake.in ../config.status + (cd .. ; ./config.status src/cmake/cdi/cdi-config.cmake) -cmake/libcdi/cdi-config-version.cmake: cmake/libcdi/cdi-config-version.cmake.in ../config.status - (cd .. ; ./config.status src/cmake/libcdi/cdi-config-version.cmake) +cmake/cdi/cdi-config-version.cmake: cmake/cdi/cdi-config-version.cmake.in ../config.status + (cd .. ; ./config.status src/cmake/cdi/cdi-config-version.cmake) pkgconfig/cdi.pc: pkgconfig/cdi.pc.in ../config.status (cd .. ; ./config.status src/pkgconfig/cdi.pc) @@ -326,10 +326,10 @@ endif endif if ENABLE_CDI_LIB -CMAKECONFIG_FILES = cmake/libcdi/cdi-config.cmake -CLEANFILES += cmake/libcdi/cdi-config.cmake -CMAKECONFIG_FILES += cmake/libcdi/cdi-config-version.cmake -CLEANFILES += cmake/libcdi/cdi-config-version.cmake +CMAKECONFIG_FILES = cmake/cdi/cdi-config.cmake +CLEANFILES += cmake/cdi/cdi-config.cmake +CMAKECONFIG_FILES += cmake/cdi/cdi-config-version.cmake +CLEANFILES += cmake/cdi/cdi-config-version.cmake PKGCONFIG_FILES = pkgconfig/cdi.pc CLEANFILES += pkgconfig/cdi.pc if USE_MPI diff --git a/src/calendar.h b/src/calendar.h index dad6978c7ebb10f889ed9b355cf37215e84946ed..cf38f24d7355af213743d526d27ba68960d1f58a 100644 --- a/src/calendar.h +++ b/src/calendar.h @@ -2,7 +2,7 @@ #define CALENDAR_H #include "cdi.h" -#include <stdint.h> // int64_t +#include <stdint.h> // int64_t // clang-format off diff --git a/src/cdf.c b/src/cdf.c index 8b0061cd6c60db4e7c65935fcaccc3b61b311fdc..0c81882bb26958cdad3370c003d6733363e2b32a 100644 --- a/src/cdf.c +++ b/src/cdf.c @@ -42,9 +42,9 @@ hdfLibraryVersion(void) unsigned majnum, minnum, relnum; H5get_libversion(&majnum, &minnum, &relnum); #ifdef HAVE_NC4HDF5_THREADSAFE - sprintf(hdf_libvers, "%u.%u.%u threadsafe", majnum, minnum, relnum); + snprintf(hdf_libvers, sizeof(hdf_libvers), "%u.%u.%u threadsafe", majnum, minnum, relnum); #else - sprintf(hdf_libvers, "%u.%u.%u", majnum, minnum, relnum); + snprintf(hdf_libvers, sizeof(hdf_libvers), "%u.%u.%u", majnum, minnum, relnum); #endif } diff --git a/src/cdf_int.c b/src/cdf_int.c index 80add6a6b157aab7b0840d88b4c450ff5d26a10e..e3485f02438959ed5723b7acf779a6f4e4ae2c8a 100644 --- a/src/cdf_int.c +++ b/src/cdf_int.c @@ -36,7 +36,7 @@ cdf__create(const char *path, int cmode, int *ncidp) size_t initialsz = 0; #if defined(__SX__) || defined(ES) - chunksizehint = 16777216; // 16 MB + chunksizehint = 16777216; // 16 MB #endif if (CDI_Netcdf_Chunksizehint != CDI_UNDEFID) chunksizehint = (size_t) CDI_Netcdf_Chunksizehint; diff --git a/src/cdf_read.c b/src/cdf_read.c index 0e7bcb4de6e9dec21a0b72a97056660b917dd508..e1d53333f18a551b05b6329a46cb7d00dcba9bf8 100644 --- a/src/cdf_read.c +++ b/src/cdf_read.c @@ -93,12 +93,11 @@ cdfDoInputDataTransformationDP(int vlistID, int varID, size_t valueCount, double const int haveMissVal = vlistInqVarMissvalUsed(vlistID, varID); double validRange[2]; if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange))) validRange[0] = DBL_MIN, validRange[1] = DBL_MAX; - const double offset = vlistInqVarAddoffset(vlistID, varID); - const double scaleFactor = vlistInqVarScalefactor(vlistID, varID); + double addoffset = 0.0, scalefactor = 1.0; + const int haveAddoffset = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_ADDOFFSET, &addoffset) == CDI_NOERR); + const int haveScalefactor = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_SCALEFACTOR, &scalefactor) == CDI_NOERR); const bool missValIsNaN = DBL_IS_NAN(missVal); - const int haveOffset = IS_NOT_EQUAL(offset, 0.0); - const int haveScaleFactor = IS_NOT_EQUAL(scaleFactor, 1.0); size_t missValCount = 0; double validMin = validRange[0]; @@ -109,33 +108,33 @@ cdfDoInputDataTransformationDP(int vlistID, int varID, size_t valueCount, double const int haveRangeCheck = (IS_NOT_EQUAL(validMax, DBL_MAX)) | (IS_NOT_EQUAL(validMin, DBL_MIN)); assert(!haveRangeCheck || haveMissVal); - switch (haveMissVal | (haveScaleFactor << 1) | (haveOffset << 2) | (haveRangeCheck << 3)) + switch (haveMissVal | (haveScalefactor << 1) | (haveAddoffset << 2) | (haveRangeCheck << 3)) { - case 15: // haveRangeCheck & haveMissVal & haveScaleFactor & haveOffset + case 15: // haveRangeCheck & haveMissVal & haveScalefactor & haveAddoffset for (size_t i = 0; i < valueCount; ++i) { int outOfRange = (data[i] < validMin || data[i] > validMax); int isMissVal = DBL_IS_EQUAL(data[i], missVal); missValCount += (size_t) (outOfRange | isMissVal); - data[i] = outOfRange ? missVal : isMissVal ? data[i] : data[i] * scaleFactor + offset; + data[i] = outOfRange ? missVal : isMissVal ? data[i] : data[i] * scalefactor + addoffset; } break; - case 13: // haveRangeCheck & haveMissVal & haveOffset + case 13: // haveRangeCheck & haveMissVal & haveAddoffset for (size_t i = 0; i < valueCount; ++i) { int outOfRange = (data[i] < validMin || data[i] > validMax); int isMissVal = DBL_IS_EQUAL(data[i], missVal); missValCount += (size_t) (outOfRange | isMissVal); - data[i] = outOfRange ? missVal : isMissVal ? data[i] : data[i] + offset; + data[i] = outOfRange ? missVal : isMissVal ? data[i] : data[i] + addoffset; } break; - case 11: // haveRangeCheck & haveMissVal & haveScaleFactor + case 11: // haveRangeCheck & haveMissVal & haveScalefactor for (size_t i = 0; i < valueCount; ++i) { int outOfRange = (data[i] < validMin || data[i] > validMax); int isMissVal = DBL_IS_EQUAL(data[i], missVal); missValCount += (size_t) (outOfRange | isMissVal); - data[i] = outOfRange ? missVal : isMissVal ? data[i] : data[i] * scaleFactor; + data[i] = outOfRange ? missVal : isMissVal ? data[i] : data[i] * scalefactor; } break; case 9: // haveRangeCheck & haveMissVal @@ -147,35 +146,35 @@ cdfDoInputDataTransformationDP(int vlistID, int varID, size_t valueCount, double data[i] = outOfRange ? missVal : data[i]; } break; - case 7: // haveMissVal & haveScaleFactor & haveOffset + case 7: // haveMissVal & haveScalefactor & haveAddoffset for (size_t i = 0; i < valueCount; ++i) if (DBL_IS_EQUAL(data[i], missVal)) missValCount++; else - data[i] = data[i] * scaleFactor + offset; + data[i] = data[i] * scalefactor + addoffset; break; - case 6: // haveOffset & haveScaleFactor - for (size_t i = 0; i < valueCount; ++i) data[i] = data[i] * scaleFactor + offset; + case 6: // haveAddoffset & haveScalefactor + for (size_t i = 0; i < valueCount; ++i) data[i] = data[i] * scalefactor + addoffset; break; - case 5: // haveMissVal & haveOffset + case 5: // haveMissVal & haveAddoffset for (size_t i = 0; i < valueCount; ++i) if (DBL_IS_EQUAL(data[i], missVal)) missValCount++; else - data[i] += offset; + data[i] += addoffset; break; - case 4: // haveOffset - for (size_t i = 0; i < valueCount; ++i) data[i] += offset; + case 4: // haveAddoffset + for (size_t i = 0; i < valueCount; ++i) data[i] += addoffset; break; - case 3: // haveMissVal & haveScaleFactor + case 3: // haveMissVal & haveScalefactor for (size_t i = 0; i < valueCount; ++i) if (DBL_IS_EQUAL(data[i], missVal)) missValCount++; else - data[i] *= scaleFactor; + data[i] *= scalefactor; break; - case 2: // haveScaleFactor - for (size_t i = 0; i < valueCount; ++i) data[i] *= scaleFactor; + case 2: // haveScalefactor + for (size_t i = 0; i < valueCount; ++i) data[i] *= scalefactor; break; case 1: // haveMissVal if (missValIsNaN) @@ -199,12 +198,11 @@ cdfDoInputDataTransformationSP(int vlistID, int varID, size_t valueCount, float const int haveMissVal = vlistInqVarMissvalUsed(vlistID, varID); double validRange[2]; if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange))) validRange[0] = DBL_MIN, validRange[1] = DBL_MAX; - const double offset = vlistInqVarAddoffset(vlistID, varID); - const double scaleFactor = vlistInqVarScalefactor(vlistID, varID); + double addoffset = 0.0, scalefactor = 1.0; + const int haveAddoffset = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_ADDOFFSET, &addoffset) == CDI_NOERR); + const int haveScalefactor = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_SCALEFACTOR, &scalefactor) == CDI_NOERR); const bool missValIsNaN = DBL_IS_NAN(missVal); - const int haveOffset = IS_NOT_EQUAL(offset, 0.0); - const int haveScaleFactor = IS_NOT_EQUAL(scaleFactor, 1.0); size_t missValCount = 0; double validMin = validRange[0]; @@ -215,33 +213,33 @@ cdfDoInputDataTransformationSP(int vlistID, int varID, size_t valueCount, float const int haveRangeCheck = (IS_NOT_EQUAL(validMax, DBL_MAX)) | (IS_NOT_EQUAL(validMin, DBL_MIN)); assert(!haveRangeCheck || haveMissVal); - switch (haveMissVal | (haveScaleFactor << 1) | (haveOffset << 2) | (haveRangeCheck << 3)) + switch (haveMissVal | (haveScalefactor << 1) | (haveAddoffset << 2) | (haveRangeCheck << 3)) { - case 15: // haveRangeCheck & haveMissVal & haveScaleFactor & haveOffset + case 15: // haveRangeCheck & haveMissVal & haveScalefactor & haveAddoffset for (size_t i = 0; i < valueCount; ++i) { int outOfRange = (data[i] < validMin || data[i] > validMax); int isMissVal = DBL_IS_EQUAL(data[i], missVal); missValCount += (size_t) (outOfRange | isMissVal); - data[i] = outOfRange ? (float) missVal : isMissVal ? data[i] : (float) (data[i] * scaleFactor + offset); + data[i] = outOfRange ? (float) missVal : isMissVal ? data[i] : (float) (data[i] * scalefactor + addoffset); } break; - case 13: // haveRangeCheck & haveMissVal & haveOffset + case 13: // haveRangeCheck & haveMissVal & haveAddoffset for (size_t i = 0; i < valueCount; ++i) { int outOfRange = (data[i] < validMin || data[i] > validMax); int isMissVal = DBL_IS_EQUAL(data[i], missVal); missValCount += (size_t) (outOfRange | isMissVal); - data[i] = outOfRange ? (float) missVal : isMissVal ? data[i] : (float) (data[i] + offset); + data[i] = outOfRange ? (float) missVal : isMissVal ? data[i] : (float) (data[i] + addoffset); } break; - case 11: // haveRangeCheck & haveMissVal & haveScaleFactor + case 11: // haveRangeCheck & haveMissVal & haveScalefactor for (size_t i = 0; i < valueCount; ++i) { int outOfRange = (data[i] < validMin || data[i] > validMax); int isMissVal = DBL_IS_EQUAL(data[i], missVal); missValCount += (size_t) (outOfRange | isMissVal); - data[i] = outOfRange ? (float) missVal : isMissVal ? data[i] : (float) (data[i] * scaleFactor); + data[i] = outOfRange ? (float) missVal : isMissVal ? data[i] : (float) (data[i] * scalefactor); } break; case 9: // haveRangeCheck & haveMissVal @@ -253,35 +251,35 @@ cdfDoInputDataTransformationSP(int vlistID, int varID, size_t valueCount, float data[i] = outOfRange ? (float) missVal : data[i]; } break; - case 7: // haveMissVal & haveScaleFactor & haveOffset + case 7: // haveMissVal & haveScalefactor & haveAddoffset for (size_t i = 0; i < valueCount; ++i) if (DBL_IS_EQUAL(data[i], missVal)) missValCount++; else - data[i] = (float) (data[i] * scaleFactor + offset); + data[i] = (float) (data[i] * scalefactor + addoffset); break; - case 6: // haveOffset & haveScaleFactor - for (size_t i = 0; i < valueCount; ++i) data[i] = (float) (data[i] * scaleFactor + offset); + case 6: // haveAddoffset & haveScalefactor + for (size_t i = 0; i < valueCount; ++i) data[i] = (float) (data[i] * scalefactor + addoffset); break; - case 5: // haveMissVal & haveOffset + case 5: // haveMissVal & haveAddoffset for (size_t i = 0; i < valueCount; ++i) if (DBL_IS_EQUAL(data[i], missVal)) missValCount++; else - data[i] = (float) (data[i] + offset); + data[i] = (float) (data[i] + addoffset); break; - case 4: // haveOffset - for (size_t i = 0; i < valueCount; ++i) data[i] = (float) (data[i] + offset); + case 4: // haveAddoffset + for (size_t i = 0; i < valueCount; ++i) data[i] = (float) (data[i] + addoffset); break; - case 3: // haveMissVal & haveScaleFactor + case 3: // haveMissVal & haveScalefactor for (size_t i = 0; i < valueCount; ++i) if (DBL_IS_EQUAL(data[i], missVal)) missValCount++; else - data[i] = (float) (data[i] * scaleFactor); + data[i] = (float) (data[i] * scalefactor); break; - case 2: // haveScaleFactor - for (size_t i = 0; i < valueCount; ++i) data[i] = (float) (data[i] * scaleFactor); + case 2: // haveScalefactor + for (size_t i = 0; i < valueCount; ++i) data[i] = (float) (data[i] * scalefactor); break; case 1: // haveMissVal if (missValIsNaN) diff --git a/src/cdf_util.c b/src/cdf_util.c index 14cdf0641bd160de50ddeaee1f57596497d11412..7735fbf1b51614374aedd7a0cdf8a12241747b6e 100644 --- a/src/cdf_util.c +++ b/src/cdf_util.c @@ -30,7 +30,7 @@ strStartsWith(const char *vstr, const char *cstr) } int -get_timeunit(size_t len, const char *ptu) +get_time_units(size_t len, const char *ptu) { int timeunit = -1; @@ -51,7 +51,7 @@ get_timeunit(size_t len, const char *ptu) else if (strStartsWith(ptu, "calendar_month")) timeunit = TUNIT_MONTH; else if (strStartsWith(ptu, "year")) timeunit = TUNIT_YEAR; } - else if (len == 1 && ptu[0] == 's') timeunit = TUNIT_SECOND; + else if (len == 1 && ptu[0] == 's') timeunit = TUNIT_SECOND; // clang-format on return timeunit; @@ -87,17 +87,15 @@ is_timeaxis_units(const char *timeunits) for (size_t i = 0; i < len; i++) ptu[i] = (char) tolower((int) ptu[i]); - int timeunit = get_timeunit(len, ptu); + int timeunit = get_time_units(len, ptu); if (timeunit != -1) { while (!isspace(*ptu) && *ptu != 0) ptu++; if (*ptu) { while (isspace(*ptu)) ptu++; - int timetype = strStartsWith(ptu, "as") ? TAXIS_ABSOLUTE : strStartsWith(ptu, "since") ? TAXIS_RELATIVE : -1; - - status = timetype != -1; + status = (timetype != -1); } } diff --git a/src/cdf_util.h b/src/cdf_util.h index 974e7dd619aac3751dac377ea4fac72c83eb1a49..22f5061a409255bdc6d012f98c34391d2322ca32 100644 --- a/src/cdf_util.h +++ b/src/cdf_util.h @@ -3,7 +3,7 @@ #include <stdbool.h> -int get_timeunit(size_t len, const char *ptu); +int get_time_units(size_t len, const char *ptu); bool is_time_units(const char *timeunits); bool is_timeaxis_units(const char *timeunits); diff --git a/src/cdf_write.c b/src/cdf_write.c index 570fa85d0bdd7984bb7c87271545a2511887fece..da8e0b6624ae8e4e8661ba469e2102d353598706 100644 --- a/src/cdf_write.c +++ b/src/cdf_write.c @@ -14,16 +14,16 @@ #include "vlist_var.h" void -cdfDefVarDeflate(int ncid, int ncvarID, int deflate_level) +cdfDefVarDeflate(int ncid, int ncvarID, int deflateLevel) { #ifdef HAVE_NETCDF4 // Set chunking, shuffle, and deflate. - const int shuffle = 1, deflate = 1; + const int shuffle = (CDI_Shuffle > 0), deflate = 1; - if (deflate_level < 1 || deflate_level > 9) deflate_level = 1; + if (deflateLevel < 1 || deflateLevel > 9) deflateLevel = 1; int status; - if ((status = nc_def_var_deflate(ncid, ncvarID, shuffle, deflate, deflate_level))) + if ((status = nc_def_var_deflate(ncid, ncvarID, shuffle, deflate, deflateLevel))) { Error("nc_def_var_deflate failed; %s", nc_strerror(status)); } @@ -267,7 +267,7 @@ cdfDefineCellMethods(stream_t *streamptr, int cdiID, int varID, int fileID, int { const char *attname = "cell_methods"; char atttxt[CDI_MAX_NAME + 10]; - sprintf(atttxt, "%s: %s", timeVarName, cellMethod); + snprintf(atttxt, sizeof(atttxt), "%s: %s", timeVarName, cellMethod); cdf_put_att_text(fileID, ncvarID, attname, strlen(atttxt), atttxt); } } @@ -287,7 +287,7 @@ cdfDefineAttributes(int cdiID, int varID, int fileID, int ncvarID) { cdiInqAtt(cdiID, varID, iatt, attname, &atttype, &attlen); - //if (attlen == 0) continue; + // if (attlen == 0) continue; if (atttype == CDI_DATATYPE_TXT) { @@ -426,7 +426,8 @@ cdfDefVarCompression(const stream_t *streamptr, int ncvarID, nc_type xtype) { if (streamptr->comptype == CDI_COMPRESS_ZIP) { - if (streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C || streamptr->filetype == CDI_FILETYPE_NCZARR) + if (streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C + || streamptr->filetype == CDI_FILETYPE_NCZARR) { cdfDefVarDeflate(streamptr->fileID, ncvarID, streamptr->complevel); } @@ -442,7 +443,8 @@ cdfDefVarCompression(const stream_t *streamptr, int ncvarID, nc_type xtype) } else if (streamptr->comptype == CDI_COMPRESS_SZIP) { - if (streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C || streamptr->filetype == CDI_FILETYPE_NCZARR) + if (streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C + || streamptr->filetype == CDI_FILETYPE_NCZARR) { cdfDefVarSzip(streamptr->fileID, ncvarID, xtype2ppb(xtype)); } @@ -463,12 +465,11 @@ cdfDefVarPacking(const stream_t *streamptr, int ncvarID, nc_type xtype, int vlis { // if ( xtype == NC_BYTE || xtype == NC_SHORT || xtype == NC_INT ) { - const double addoffset = vlistInqVarAddoffset(vlistID, varID); - const double scalefactor = vlistInqVarScalefactor(vlistID, varID); - const bool laddoffset = IS_NOT_EQUAL(addoffset, 0); - const bool lscalefactor = IS_NOT_EQUAL(scalefactor, 1); + double addoffset = 0.0, scalefactor = 1.0; + const bool haveAddoffset = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_ADDOFFSET, &addoffset) == CDI_NOERR); + const bool haveScalefactor = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_SCALEFACTOR, &scalefactor) == CDI_NOERR); - if (laddoffset || lscalefactor) + if (haveAddoffset || haveScalefactor) { nc_type astype = (xtype == NC_FLOAT) ? NC_FLOAT : NC_DOUBLE; if ((astype == NC_DOUBLE) && IS_EQUAL(addoffset, (double) ((float) addoffset)) @@ -635,7 +636,7 @@ calc_chunksize(size_t chunkSizeLim, size_t size) size_t numChunks = (size / chunkSizeLim) + 1; size_t chunkSize = size / numChunks; - if (chunkSize%pageSize) chunkSize = (chunkSize / pageSize + 1) * pageSize; + if (chunkSize % pageSize) chunkSize = (chunkSize / pageSize + 1) * pageSize; return chunkSize; } @@ -656,7 +657,7 @@ size_t calc_chunksize_x(int chunkType, int chunkSize, size_t xsize, bool yIsUndefined) { if (chunkType == CDI_CHUNK_AUTO && yIsUndefined) - return (chunkSize > 0) ? (size_t)chunkSize : ((xsize <= chunkSizeMax) ? xsize : chunkSizeMax); + return (chunkSize > 0) ? (size_t) chunkSize : ((xsize <= chunkSizeMax) ? xsize : chunkSizeMax); else return calc_chunksize(chunkSizeLim, xsize); } @@ -724,8 +725,8 @@ cdfDefineDimsAndChunks(const stream_t *streamptr, int varID, int xid, int yid, i } if (CDI_Debug) - fprintf(stderr, "useChunks %d chunkType %d chunkSize %d chunks %zu %zu %zu %zu\n", - useChunks, chunkType, chunkSize, chunks[0], chunks[1], chunks[2], chunks[3]); + fprintf(stderr, "useChunks %d chunkType %d chunkSize %d chunks %zu %zu %zu %zu\n", useChunks, chunkType, chunkSize, chunks[0], + chunks[1], chunks[2], chunks[3]); *piax = iax; return ndims; @@ -775,7 +776,7 @@ cdfCheckVarname(int fileID, char name[CDI_MAX_NAME]) { int ncvarID; char varname[CDI_MAX_NAME]; - sprintf(varname, "%s", name); + snprintf(varname, sizeof(varname), "%s", name); char *varname2 = varname + strlen(varname); unsigned iz = 0; @@ -808,9 +809,9 @@ cdfGenVarname(int fileID, char name[CDI_MAX_NAME], int pnum, int pcat, int *pdis if (pnum < 0) pnum = -pnum; if (*pdis == 255) - sprintf(varname, "var%d", code); + snprintf(varname, sizeof(varname), "var%d", code); else - sprintf(varname, "param%d.%d.%d", pnum, pcat, *pdis); + snprintf(varname, sizeof(varname), "param%d.%d.%d", pnum, pcat, *pdis); char *varname2 = varname + strlen(varname); int ncvarID; @@ -861,9 +862,10 @@ cdfDefVar(stream_t *streamptr, int varID) const int zaxisindex = vlistZaxisIndex(vlistID, zaxisID); const int zid = streamptr->zaxisID[zaxisindex]; - int dimorder[3]; // ZYX and ZXY + int dimorder[3]; // ZYX/321 and ZXY/312 vlistInqVarDimorder(vlistID, varID, &dimorder); - const bool useChunks = (dimorder[0] == 3) ? (gridsize >= 32) : false; + const bool useGridsize = (dimorder[0] == 3) || (dimorder[1] == 3 && dimorder[2] == 1 && gridsize == gridInqXsize(gridID)); + const bool useChunks = useGridsize ? (gridsize >= 32) : false; if (((dimorder[0] > 0) + (dimorder[1] > 0) + (dimorder[2] > 0)) < ((xid != CDI_UNDEFID) + (yid != CDI_UNDEFID) + (zid != CDI_UNDEFID))) @@ -911,11 +913,13 @@ cdfDefVar(stream_t *streamptr, int varID) { const int nsb = vlistInqVarNSB(vlistID, varID); if (nsb > 0) nc_def_var_quantize(fileID, ncvarID, NC_QUANTIZE_BITROUND, nsb); - //if (nsb > 0) nc_def_var_quantize(fileID, ncvarID, NC_QUANTIZE_GRANULARBR, nsb); + // if (nsb > 0) nc_def_var_quantize(fileID, ncvarID, NC_QUANTIZE_GRANULARBR, nsb); } #endif - if (useChunks && (streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C || streamptr->filetype == CDI_FILETYPE_NCZARR)) + if (useChunks + && (streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C + || streamptr->filetype == CDI_FILETYPE_NCZARR)) cdf_def_var_chunking(fileID, ncvarID, NC_CHUNKED, chunks); #endif @@ -1028,12 +1032,11 @@ cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarID, int dtype, s /* if ( dtype == CDI_DATATYPE_INT8 || dtype == CDI_DATATYPE_INT16 || dtype == CDI_DATATYPE_INT32 ) */ { const double missval = vlistInqVarMissval(vlistID, varID); - const double addoffset = vlistInqVarAddoffset(vlistID, varID); - const double scalefactor = vlistInqVarScalefactor(vlistID, varID); - const bool laddoffset = IS_NOT_EQUAL(addoffset, 0); - const bool lscalefactor = IS_NOT_EQUAL(scalefactor, 1); + double addoffset = 0.0, scalefactor = 1.0; + const bool haveAddoffset = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_ADDOFFSET, &addoffset) == CDI_NOERR); + const bool haveScalefactor = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_SCALEFACTOR, &scalefactor) == CDI_NOERR); - if (laddoffset || lscalefactor) + if (haveAddoffset || haveScalefactor) { if (memtype == MEMTYPE_FLOAT) { @@ -1048,8 +1051,8 @@ cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarID, int dtype, s double temp = mdata_sp[i]; if (!DBL_IS_EQUAL(temp, missval)) { - if (laddoffset) temp -= addoffset; - if (lscalefactor) temp /= scalefactor; + if (haveAddoffset) temp -= addoffset; + if (haveScalefactor) temp /= scalefactor; mdata_sp[i] = (float) temp; } } @@ -1059,8 +1062,8 @@ cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarID, int dtype, s for (size_t i = 0; i < nvals; ++i) { double temp = mdata_sp[i]; - if (laddoffset) temp -= addoffset; - if (lscalefactor) temp /= scalefactor; + if (haveAddoffset) temp -= addoffset; + if (haveScalefactor) temp /= scalefactor; mdata_sp[i] = (float) temp; } } @@ -1077,8 +1080,8 @@ cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarID, int dtype, s { if (!DBL_IS_EQUAL(mdata_dp[i], missval)) { - if (laddoffset) mdata_dp[i] -= addoffset; - if (lscalefactor) mdata_dp[i] /= scalefactor; + if (haveAddoffset) mdata_dp[i] -= addoffset; + if (haveScalefactor) mdata_dp[i] /= scalefactor; } } } @@ -1086,8 +1089,8 @@ cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarID, int dtype, s { for (size_t i = 0; i < nvals; ++i) { - if (laddoffset) mdata_dp[i] -= addoffset; - if (lscalefactor) mdata_dp[i] /= scalefactor; + if (haveAddoffset) mdata_dp[i] -= addoffset; + if (haveScalefactor) mdata_dp[i] /= scalefactor; } } } diff --git a/src/cdi.h b/src/cdi.h index 1df50877eebd4bbfb3bf7c10fa9c362548d537f5..af02e06465593062fa099b274afc9e865c2bf779 100644 --- a/src/cdi.h +++ b/src/cdi.h @@ -185,6 +185,7 @@ extern "C" { #define CDI_PROJ_LAEA 23 // Lambert Azimuthal Equal Area #define CDI_PROJ_SINU 24 // Sinusoidal #define CDI_PROJ_STERE 25 // Polar stereographic +#define CDI_PROJ_HEALPIX 26 // Healpix // ZAXIS types @@ -672,17 +673,6 @@ void vlistDefVarMissval(int vlistID, int varID, double missval); // vlistInqVarMissval: Get the missing value of a Variable double vlistInqVarMissval(int vlistID, int varID); -// vlistDefVarExtra: Define extra information of a Variable -void vlistDefVarExtra(int vlistID, int varID, const char *extra); - -// vlistInqVarExtra: Get extra information of a Variable -void vlistInqVarExtra(int vlistID, int varID, char *extra); - -void vlistDefVarScalefactor(int vlistID, int varID, double scalefactor); -double vlistInqVarScalefactor(int vlistID, int varID); -void vlistDefVarAddoffset(int vlistID, int varID, double addoffset); -double vlistInqVarAddoffset(int vlistID, int varID); - SizeType vlistInqVarSize(int vlistID, int varID); void vlistDefIndex(int vlistID, int varID, int levID, int index); @@ -830,6 +820,7 @@ SizeType gridInqYCvals(int gridID, char *ycvals[]); #define CDI_KEY_UNITS 945 // Units of the variable #define CDI_KEY_DATATYPE 946 // Data type #define CDI_KEY_REFERENCEURI 947 // Reference URI to grid file +#define CDI_KEY_CHUNKS 948 // Chunks // Integer keys #define CDI_KEY_NUMBEROFGRIDUSED 961 // GRIB2 numberOfGridUsed @@ -841,6 +832,8 @@ SizeType gridInqYCvals(int gridID, char *ycvals[]); // Floating point keys #define CDI_KEY_MISSVAL 701 // Missing value +#define CDI_KEY_ADDOFFSET 702 // Add offset +#define CDI_KEY_SCALEFACTOR 703 // Scale factor // Byte array keys #define CDI_KEY_UUID 960 // UUID for grid/Z-axis reference [size: CDI_UUID_SIZE] diff --git a/src/cdi.inc b/src/cdi.inc index 646cb1bc4343ce2f82b848cc7302d8d1c99e607a..6bcfce6dd1231657076950cbfb1ebc7e84ef6ae6 100644 --- a/src/cdi.inc +++ b/src/cdi.inc @@ -1,10 +1,10 @@ ! This file was automatically generated, don't edit! ! -! Fortran interface for CDI library version 2.0.0 +! Fortran interface for CDI library version 2.1.0 ! ! Author: ! ------- -! Uwe Schulzweida, MPI-MET, Hamburg, August 2022 +! Uwe Schulzweida, MPI-MET, Hamburg, October 2022 ! ! @@ -293,6 +293,8 @@ PARAMETER (CDI_PROJ_SINU = 24) INTEGER CDI_PROJ_STERE PARAMETER (CDI_PROJ_STERE = 25) + INTEGER CDI_PROJ_HEALPIX + PARAMETER (CDI_PROJ_HEALPIX = 26) ! ! ZAXIS types ! @@ -1254,40 +1256,6 @@ ! INTEGER varID) EXTERNAL vlistInqVarMissval -! vlistDefVarExtra -! (INTEGER vlistID, -! INTEGER varID, -! CHARACTER*(*) extra) - EXTERNAL vlistDefVarExtra - -! vlistInqVarExtra -! (INTEGER vlistID, -! INTEGER varID, -! CHARACTER*(*) extra) - EXTERNAL vlistInqVarExtra - -! vlistDefVarScalefactor -! (INTEGER vlistID, -! INTEGER varID, -! DOUBLEPRECISION scalefactor) - EXTERNAL vlistDefVarScalefactor - - DOUBLEPRECISION vlistInqVarScalefactor -! (INTEGER vlistID, -! INTEGER varID) - EXTERNAL vlistInqVarScalefactor - -! vlistDefVarAddoffset -! (INTEGER vlistID, -! INTEGER varID, -! DOUBLEPRECISION addoffset) - EXTERNAL vlistDefVarAddoffset - - DOUBLEPRECISION vlistInqVarAddoffset -! (INTEGER vlistID, -! INTEGER varID) - EXTERNAL vlistInqVarAddoffset - INTEGER vlistInqVarSize ! (INTEGER vlistID, ! INTEGER varID) @@ -1630,6 +1598,8 @@ PARAMETER (CDI_KEY_DATATYPE = 946) INTEGER CDI_KEY_REFERENCEURI PARAMETER (CDI_KEY_REFERENCEURI = 947) + INTEGER CDI_KEY_CHUNKS + PARAMETER (CDI_KEY_CHUNKS = 948) ! ! Integer keys ! @@ -1650,6 +1620,10 @@ ! INTEGER CDI_KEY_MISSVAL PARAMETER (CDI_KEY_MISSVAL = 701) + INTEGER CDI_KEY_ADDOFFSET + PARAMETER (CDI_KEY_ADDOFFSET = 702) + INTEGER CDI_KEY_SCALEFACTOR + PARAMETER (CDI_KEY_SCALEFACTOR = 703) ! ! Byte array keys ! diff --git a/src/cdiFortran.c b/src/cdiFortran.c index 0fef6d6777d51e9f71f771cc996e97224d36d7a1..cac999910f6ce46e5d07018547b9c7a55322cde7 100644 --- a/src/cdiFortran.c +++ b/src/cdiFortran.c @@ -395,12 +395,6 @@ FCALLSCSUB3 (vlistDefVarUnits, VLISTDEFVARUNITS, vlistdefvarunits, INT, INT, STR FCALLSCSUB3 (vlistInqVarUnits, VLISTINQVARUNITS, vlistinqvarunits, INT, INT, PSTRING) FCALLSCSUB3 (vlistDefVarMissval, VLISTDEFVARMISSVAL, vlistdefvarmissval, INT, INT, DOUBLE) FCALLSCFUN2 (DOUBLE, vlistInqVarMissval, VLISTINQVARMISSVAL, vlistinqvarmissval, INT, INT) -FCALLSCSUB3 (vlistDefVarExtra, VLISTDEFVAREXTRA, vlistdefvarextra, INT, INT, STRING) -FCALLSCSUB3 (vlistInqVarExtra, VLISTINQVAREXTRA, vlistinqvarextra, INT, INT, PSTRING) -FCALLSCSUB3 (vlistDefVarScalefactor, VLISTDEFVARSCALEFACTOR, vlistdefvarscalefactor, INT, INT, DOUBLE) -FCALLSCFUN2 (DOUBLE, vlistInqVarScalefactor, VLISTINQVARSCALEFACTOR, vlistinqvarscalefactor, INT, INT) -FCALLSCSUB3 (vlistDefVarAddoffset, VLISTDEFVARADDOFFSET, vlistdefvaraddoffset, INT, INT, DOUBLE) -FCALLSCFUN2 (DOUBLE, vlistInqVarAddoffset, VLISTINQVARADDOFFSET, vlistinqvaraddoffset, INT, INT) static int vlistInqVarSize_fwrap(int vlistID, int varID) { SizeType v; diff --git a/src/cdi_datetime.c b/src/cdi_datetime.c index 6711b1a896e12b04dc4113fc8300a144d6f108f5..187c1a95ec5d29dc2fda47a22e58e4eb589d1c44 100644 --- a/src/cdi_datetime.c +++ b/src/cdi_datetime.c @@ -53,8 +53,8 @@ cdiDate_set(int64_t date) CdiDate cdiDate; cdiDate.year = year; - cdiDate.month = (short)month; - cdiDate.day = (short)day; + cdiDate.month = (short) month; + cdiDate.day = (short) day; return cdiDate; } @@ -66,9 +66,9 @@ cdiTime_set(int time) cdiDecodeTime(time, &hour, &minute, &second); CdiTime cdiTime; - cdiTime.hour = (short)hour; - cdiTime.minute = (short)minute; - cdiTime.second = (short)second; + cdiTime.hour = (short) hour; + cdiTime.minute = (short) minute; + cdiTime.second = (short) second; cdiTime.ms = ms; return cdiTime; diff --git a/src/cdi_int.c b/src/cdi_int.c index 1f98b381449ae52ce2317274c5ea56a6318f07bf..c7623b504aae1cbe59316d5c83933b067f25cc34 100644 --- a/src/cdi_int.c +++ b/src/cdi_int.c @@ -38,7 +38,10 @@ int CDI_Convert_Cubesphere = 1; int CDI_Read_Cell_Corners = 1; int CDI_CMOR_Mode = 0; int CDI_Reduce_Dim = 0; +int CDI_Shuffle = 0; size_t CDI_Netcdf_Hdr_Pad = 0UL; +size_t CDI_Chunk_Cache = 0UL; +size_t CDI_Chunk_Cache_Max = 0UL; bool CDI_Netcdf_Lazy_Grid_Load = false; char *cdiPartabPath = NULL; @@ -77,7 +80,7 @@ int cdiSortParam = 0; int cdiHaveMissval = 0; static long -cdiGetenvInt(const char *envName) +cdi_getenv_int(const char *envName) { long envValue = -1; @@ -328,48 +331,57 @@ cdiInitialize(void) grib_multi_support_off(NULL); #endif - value = cdiGetenvInt("CDI_DEBUG"); + value = cdi_getenv_int("CDI_DEBUG"); if (value >= 0) CDI_Debug = (int) value; - value = cdiGetenvInt("CDI_GRIBAPI_DEBUG"); + value = cdi_getenv_int("CDI_GRIBAPI_DEBUG"); if (value >= 0) CDI_gribapi_debug = (bool) value; - value = cdiGetenvInt("CDI_ECCODES_DEBUG"); + value = cdi_getenv_int("CDI_ECCODES_DEBUG"); if (value >= 0) CDI_gribapi_debug = (bool) value; - value = cdiGetenvInt("CDI_ECCODES_GRIB1"); + value = cdi_getenv_int("CDI_ECCODES_GRIB1"); if (value >= 0) cdiSetEccodesGrib1((bool) value); - value = cdiGetenvInt("CDI_READ_CELL_CORNERS"); + value = cdi_getenv_int("CDI_READ_CELL_CORNERS"); if (value >= 0) CDI_Read_Cell_Corners = (int) value; - value = cdiGetenvInt("CDI_RECOPT"); + value = cdi_getenv_int("CDI_RECOPT"); if (value >= 0) CDI_Recopt = (int) value; - value = cdiGetenvInt("CDI_REGULARGRID"); + value = cdi_getenv_int("CDI_REGULARGRID"); if (value >= 0) cdiDataUnreduced = (int) value; - value = cdiGetenvInt("CDI_SORTNAME"); + value = cdi_getenv_int("CDI_SORTNAME"); if (value >= 0) cdiSortName = (int) value; - value = cdiGetenvInt("CDI_SORTPARAM"); + value = cdi_getenv_int("CDI_SORTPARAM"); if (value >= 0) cdiSortParam = (int) value; - value = cdiGetenvInt("CDI_HAVE_MISSVAL"); + value = cdi_getenv_int("CDI_HAVE_MISSVAL"); if (value >= 0) cdiHaveMissval = (int) value; - value = cdiGetenvInt("CDI_LEVELTYPE"); + value = cdi_getenv_int("CDI_LEVELTYPE"); if (value >= 0) cdiDefaultLeveltype = (int) value; - value = cdiGetenvInt("CDI_NETCDF_HDR_PAD"); + value = cdi_getenv_int("CDI_NETCDF_HDR_PAD"); if (value >= 0) CDI_Netcdf_Hdr_Pad = (size_t) value; + value = cdi_getenv_int("CDI_CHUNK_CACHE"); + if (value >= 0) CDI_Chunk_Cache = (size_t) value; + + value = cdi_getenv_int("CDI_CHUNK_CACHE_MAX"); + if (value >= 0) CDI_Chunk_Cache_Max = (size_t) value; + envstr = getenv("CDI_GRIB1_TEMPLATE"); if (envstr) CDI_GRIB1_Template = envstr; envstr = getenv("CDI_GRIB2_TEMPLATE"); if (envstr) CDI_GRIB2_Template = envstr; + envstr = getenv("CDI_SHUFFLE"); + if (envstr) CDI_Shuffle = atoi(envstr); + envstr = getenv("CDI_MISSVAL"); if (envstr) CDI_Default_Missval = atof(envstr); /* diff --git a/src/cdi_int.h b/src/cdi_int.h index bcd39cd1834ecbc9cda6699b7c7ec6f569f9302a..f1985b8521efc8a3431b1b2d5b16395b33a4b2fe 100644 --- a/src/cdi_int.h +++ b/src/cdi_int.h @@ -162,8 +162,8 @@ typedef struct int gridID; int varID; int levelID; - int prec; // ext, srv - void *objectp; // pointer to ieg, ext, srv or cgribex objects + int prec; // ext, srv + void *objectp; // pointer to ieg, ext, srv or cgribex objects } Record; // data structure specifying tile-related meta-data. structure contains "-1" if this is no tile-variable. @@ -240,7 +240,7 @@ typedef struct sleveltable_t *recordTable; // record IDs for each subtype int ncvarid; int subtypeSize; - bool defmiss; // true: if missval is defined in file + bool defmiss; // true: if missval is defined in file bool isUsed; int gridID; @@ -260,7 +260,7 @@ typedef struct #ifdef HAVE_LIBNETCDF enum cdfIDIdx { - CDF_DIMID_E, // 3rd dimID of cube sphere grid (len=6) + CDF_DIMID_E, // 3rd dimID of cube sphere grid (len=6) CDF_DIMID_X, CDF_DIMID_Y, CDF_DIMID_RP, // reducedPoints @@ -281,23 +281,23 @@ typedef struct typedef struct { int self; - int accesstype; // TYPE_REC or TYPE_VAR + int accesstype; // TYPE_REC or TYPE_VAR int accessmode; int filetype; int byteorder; int fileID; int filemode; - int nrecs; // number of records + int nrecs; // number of records SizeType numvals; char *filename; Record *record; svarinfo_t *vars; - int nvars; // number of variables + int nvars; // number of variables int varsAllocated; - int curTsID; // current timestep ID - int rtsteps; // number of tsteps accessed - long ntsteps; // number of tsteps : only set if all records accessed - int maxSteps; // max. number of timesteps (needed for CDI_FILETYPE_NCZARR) + int curTsID; // current timestep ID + int rtsteps; // number of tsteps accessed + long ntsteps; // number of tsteps : only set if all records accessed + int maxSteps; // max. number of timesteps (needed for CDI_FILETYPE_NCZARR) tsteps_t *tsteps; int tstepsTableSize; int tstepsNextID; @@ -404,7 +404,10 @@ extern int CDI_Convert_Cubesphere; extern int CDI_Read_Cell_Corners; extern int CDI_CMOR_Mode; extern int CDI_Reduce_Dim; +extern int CDI_Shuffle; extern size_t CDI_Netcdf_Hdr_Pad; +extern size_t CDI_Chunk_Cache; +extern size_t CDI_Chunk_Cache_Max; extern bool CDI_Netcdf_Lazy_Grid_Load; extern int STREAM_Debug; diff --git a/src/cdi_key.c b/src/cdi_key.c index c5ce9a0fa7b50526c5a0947aefd36d6870db77df..be1dde0142cc651826a696e313e8a1a8ba1bd44a 100644 --- a/src/cdi_key.c +++ b/src/cdi_key.c @@ -8,10 +8,8 @@ static cdi_keys_t * vlist_get_keysp(vlist_t *vlistptr, int varID) { - if (varID == CDI_GLOBAL) - return &vlistptr->keys; - else if (varID >= 0 && varID < vlistptr->nvars) - return &(vlistptr->vars[varID].keys); + if (varID == CDI_GLOBAL) return &vlistptr->keys; + if (varID >= 0 && varID < vlistptr->nvars) return &(vlistptr->vars[varID].keys); return NULL; } @@ -19,12 +17,9 @@ vlist_get_keysp(vlist_t *vlistptr, int varID) static cdi_keys_t * grid_get_keysp(grid_t *gridptr, int varID) { - if (varID == CDI_GLOBAL) - return &gridptr->keys; - else if (varID == CDI_XAXIS) - return &gridptr->x.keys; - else if (varID == CDI_YAXIS) - return &gridptr->y.keys; + if (varID == CDI_GLOBAL) return &gridptr->keys; + if (varID == CDI_XAXIS) return &gridptr->x.keys; + if (varID == CDI_YAXIS) return &gridptr->y.keys; return NULL; } @@ -32,9 +27,7 @@ grid_get_keysp(grid_t *gridptr, int varID) static cdi_keys_t * zaxis_get_keysp(zaxis_t *zaxisptr, int varID) { - if (varID == CDI_GLOBAL) return &zaxisptr->keys; - - return NULL; + return (varID == CDI_GLOBAL) ? &zaxisptr->keys : NULL; } static cdi_key_t * @@ -48,8 +41,8 @@ new_key(cdi_keys_t *keysp, int key) keysp->nelems++; keyp->key = key; - keyp->length = 0; keyp->type = 0; + keyp->length = 0; keyp->v.s = NULL; return keyp; @@ -90,12 +83,9 @@ find_key_const(const cdi_keys_t *keysp, int key) static cdi_keys_t * cdi_get_keysp(int objID, int varID) { - if (reshGetTxCode(objID) == GRID) - return grid_get_keysp(grid_to_pointer(objID), varID); - else if (reshGetTxCode(objID) == ZAXIS) - return zaxis_get_keysp(zaxis_to_pointer(objID), varID); - else if (reshGetTxCode(objID) == VLIST) - return vlist_get_keysp(vlist_to_pointer(objID), varID); + if (reshGetTxCode(objID) == GRID) return grid_get_keysp(grid_to_pointer(objID), varID); + if (reshGetTxCode(objID) == ZAXIS) return zaxis_get_keysp(zaxis_to_pointer(objID), varID); + if (reshGetTxCode(objID) == VLIST) return vlist_get_keysp(vlist_to_pointer(objID), varID); return NULL; } @@ -107,39 +97,45 @@ cdi_key_compare(cdi_keys_t *keyspa, cdi_keys_t *keyspb, int keynum) cdi_key_t *keypa = keyspa->value + keynum, *keypb = keyspb->value + keynum; if (keypa->key != keypb->key) return 1; - if (keypa->type != keypb->type) return 1; + if (keypa->length != keypb->length) return 1; - if (keypa->type == KEY_BYTES) - { - if (keypa->length != keypb->length) return 1; - return memcmp(keypa->v.s, keypb->v.s, keypa->length); - } - else if (keypa->type == KEY_FLOAT) - { - if (IS_NOT_EQUAL(keypa->v.d, keypb->v.d)) return 1; - } - else if (keypa->type == KEY_INT) - { - if (keypa->v.i != keypb->v.i) return 1; - } + if (keypa->type == KEY_BYTES) return (memcmp(keypa->v.s, keypb->v.s, keypa->length) != 0); + if (keypa->type == KEY_FLOAT) return (IS_NOT_EQUAL(keypa->v.d, keypb->v.d)); + if (keypa->type == KEY_INT) return (keypa->v.i != keypb->v.i); return 0; } +static void +cdi_delete_key(cdi_key_t *keyp) +{ + if (keyp != NULL && keyp->length) // key in use + { + keyp->length = 0; + if (keyp->type == KEY_BYTES) + { + if (keyp->v.s) free(keyp->v.s); + keyp->v.s = NULL; + } + else if (keyp->type == KEY_FLOAT) + { + keyp->v.d = 0.0; + } + else if (keyp->type == KEY_INT) + { + keyp->v.i = 0; + } + } +} + void cdiDeleteVarKeys(cdi_keys_t *keysp) { const int nelems = keysp ? (int) keysp->nelems : 0; for (int keyid = 0; keyid < nelems; keyid++) { - cdi_key_t *keyp = &(keysp->value[keyid]); - if (keyp->length) - { - free(keyp->v.s); - keyp->v.s = NULL; - keyp->length = 0; - } + cdi_delete_key(&(keysp->value[keyid])); } keysp->nelems = 0; @@ -161,17 +157,18 @@ cdiPrintVarKeys(cdi_keys_t *keysp) for (int keyid = 0; keyid < nelems; keyid++) { cdi_key_t *keyp = &(keysp->value[keyid]); + if (keyp->length == 0) continue; if (keyp->type == KEY_BYTES) { - printf("%d key %d length %d value %s\n", keyid + 1, keyp->key, keyp->length, keyp->v.s); + fprintf(stdout, "%d key %d length %d value %s\n", keyid + 1, keyp->key, keyp->length, keyp->v.s); } else if (keyp->type == KEY_FLOAT) { - printf("%d key %d value %g\n", keyid + 1, keyp->key, keyp->v.d); + fprintf(stdout, "%d key %d value %g\n", keyid + 1, keyp->key, keyp->v.d); } else if (keyp->type == KEY_INT) { - printf("%d key %d value %d\n", keyid + 1, keyp->key, keyp->v.i); + fprintf(stdout, "%d key %d value %d\n", keyid + 1, keyp->key, keyp->v.i); } } } @@ -195,10 +192,9 @@ cdiInqKeyLen(int cdiID, int varID, int key, int *length) xassert(keysp != NULL); const cdi_key_t *keyp = find_key_const(keysp, key); - if (keyp != NULL) + if (keyp != NULL && keyp->length > 0) { *length = keyp->length; - if (*length == 0) *length = 1; status = CDI_NOERR; } @@ -208,32 +204,22 @@ cdiInqKeyLen(int cdiID, int varID, int key, int *length) static void cdi_define_key(const cdi_key_t *keyp, cdi_keys_t *keysp) { - if (keyp->type == KEY_INT) - cdiDefVarKeyInt(keysp, keyp->key, keyp->v.i); - else if (keyp->type == KEY_FLOAT) - cdiDefVarKeyFloat(keysp, keyp->key, keyp->v.d); - else if (keyp->type == KEY_BYTES) - cdiDefVarKeyBytes(keysp, keyp->key, keyp->v.s, keyp->length); + // clang-format off + if (keyp->type == KEY_INT) cdiDefVarKeyInt(keysp, keyp->key, keyp->v.i); + else if (keyp->type == KEY_FLOAT) cdiDefVarKeyFloat(keysp, keyp->key, keyp->v.d); + else if (keyp->type == KEY_BYTES) cdiDefVarKeyBytes(keysp, keyp->key, keyp->v.s, keyp->length); + // clang-format on } int cdiDeleteKey(int cdiID, int varID, int key) { - int status = CDI_NOERR; + const int status = CDI_NOERR; cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID); xassert(keysp != NULL); - cdi_key_t *keyp = find_key(keysp, key); - if (keyp != NULL) // key in use - { - if (keyp->length) - { - free(keyp->v.s); - keyp->v.s = NULL; - keyp->length = 0; - } - } + cdi_delete_key(find_key(keysp, key)); return status; } @@ -244,14 +230,14 @@ cdiCopyVarKeys(const cdi_keys_t *keysp1, cdi_keys_t *keysp2) for (size_t keyid = 0; keyid < keysp1->nelems; keyid++) { const cdi_key_t *keyp = &(keysp1->value[keyid]); - cdi_define_key(keyp, keysp2); + if (keyp->length > 0) cdi_define_key(keyp, keysp2); } } int cdiCopyKeys(int cdiID1, int varID1, int cdiID2, int varID2) { - int status = CDI_NOERR; + const int status = CDI_NOERR; cdi_keys_t *keysp1 = cdi_get_keysp(cdiID1, varID1); xassert(keysp1 != NULL); @@ -267,12 +253,12 @@ cdiCopyKeys(int cdiID1, int varID1, int cdiID2, int varID2) int cdiCopyVarKey(const cdi_keys_t *keysp1, int key, cdi_keys_t *keysp2) { - int status = CDI_NOERR; + const int status = CDI_NOERR; const cdi_key_t *keyp = find_key_const(keysp1, key); if (keyp == NULL) return -1; - cdi_define_key(keyp, keysp2); + if (keyp->length > 0) cdi_define_key(keyp, keysp2); return status; } @@ -301,6 +287,7 @@ cdiDefVarKeyInt(cdi_keys_t *keysp, int key, int value) { keyp->type = KEY_INT; keyp->v.i = value; + keyp->length = 1; } } } @@ -327,7 +314,7 @@ The function @func{cdiDefKeyInt} defines an integer value from a key. int cdiDefKeyInt(int cdiID, int varID, int key, int value) { - int status = CDI_NOERR; + const int status = CDI_NOERR; cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID); xassert(keysp != NULL); @@ -367,7 +354,7 @@ cdiInqKeyInt(int cdiID, int varID, int key, int *value) xassert(keysp != NULL); const cdi_key_t *keyp = find_key_const(keysp, key); - if (keyp != NULL) // key in use + if (keyp != NULL && keyp->length == 1) // key in use { if (keyp->type == KEY_INT) { @@ -398,11 +385,9 @@ cdiDefVarKeyFloat(cdi_keys_t *keysp, int key, double value) if (keyp != NULL) { - // if ( keyp->v.i != value ) - { - keyp->type = KEY_INT; - keyp->v.d = value; - } + keyp->type = KEY_FLOAT; + keyp->v.d = value; + keyp->length = 1; } } @@ -428,7 +413,7 @@ The function @func{cdiDefKeyFloat} defines a CDI floating point value from a key int cdiDefKeyFloat(int cdiID, int varID, int key, double value) { - int status = CDI_NOERR; + const int status = CDI_NOERR; cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID); xassert(keysp != NULL); @@ -462,13 +447,13 @@ cdiInqKeyFloat(int cdiID, int varID, int key, double *value) { int status = -1; - // if ( varID != CDI_GLOBAL ) status = cdiInqKeyFloat(cdiID, CDI_GLOBAL, key, value); + // if (varID != CDI_GLOBAL) status = cdiInqKeyFloat(cdiID, CDI_GLOBAL, key, value); const cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID); xassert(keysp != NULL); const cdi_key_t *keyp = find_key_const(keysp, key); - if (keyp != NULL) // key in use + if (keyp != NULL && keyp->length == 1) // key in use { if (keyp->type == KEY_FLOAT) { @@ -490,7 +475,7 @@ cdiDefVarKeyBytes(cdi_keys_t *keysp, int key, const unsigned char *bytes, int le { if (keyp->length != 0 && keyp->length != length) { - free(keyp->v.s); + if (keyp->v.s) free(keyp->v.s); keyp->length = 0; } if (keyp->length == 0) @@ -527,7 +512,7 @@ The function @func{cdiDefKeyBytes} defines a byte array from a key. int cdiDefKeyBytes(int cdiID, int varID, int key, const unsigned char *bytes, int length) { - int status = CDI_NOERR; + const int status = CDI_NOERR; cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID); xassert(keysp != NULL); @@ -543,7 +528,7 @@ cdiInqVarKeyBytes(const cdi_keys_t *keysp, int key, unsigned char *bytes, int *l int status = -1; const cdi_key_t *keyp = find_key_const(keysp, key); - if (keyp != NULL) // key in use + if (keyp != NULL && keyp->length > 0) // key in use { if (keyp->type == KEY_BYTES) { @@ -583,7 +568,7 @@ cdiInqKeyBytes(int cdiID, int varID, int key, unsigned char *bytes, int *length) xassert(bytes != NULL); xassert(length != NULL); - // if ( varID != CDI_GLOBAL ) status = cdiInqKeyBytes(cdiID, CDI_GLOBAL, key, bytes, length); + // if (varID != CDI_GLOBAL) status = cdiInqKeyBytes(cdiID, CDI_GLOBAL, key, bytes, length); const cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID); xassert(keysp != NULL); @@ -629,8 +614,8 @@ cdiDefKeyString(int cdiID, int varID, int key, const char *string) { xassert(string != NULL); - int length = strlen(string) + 1; - int status = cdiDefKeyBytes(cdiID, varID, key, (const unsigned char *) string, length); + const int length = strlen(string) + 1; + const int status = cdiDefKeyBytes(cdiID, varID, key, (const unsigned char *) string, length); return status; } @@ -684,10 +669,10 @@ cdiInqKeyString(int cdiID, int varID, int key, char *string, int *length) if (maxlength > 0) string[0] = '\0'; int status = cdiInqKeyBytes(cdiID, varID, key, (unsigned char *) string, length); - if (status != CDI_NOERR) - *length = 0; - else + if (CDI_NOERR == status) string[maxlength - 1] = '\0'; + else + *length = 0; return status; } diff --git a/src/cmake/libcdi/cdi-config-version.cmake.in b/src/cmake/cdi/cdi-config-version.cmake.in similarity index 100% rename from src/cmake/libcdi/cdi-config-version.cmake.in rename to src/cmake/cdi/cdi-config-version.cmake.in diff --git a/src/cmake/libcdi/cdi-config.cmake.in b/src/cmake/cdi/cdi-config.cmake.in similarity index 100% rename from src/cmake/libcdi/cdi-config.cmake.in rename to src/cmake/cdi/cdi-config.cmake.in diff --git a/src/grb_read.c b/src/grb_read.c index 453474ef089d20e1e447421c0033cba42177ffa5..632abd3df1a25003ea70c2fe862b6e3162c899d3 100644 --- a/src/grb_read.c +++ b/src/grb_read.c @@ -19,8 +19,8 @@ #include "cgribex.h" /* gribZip gribGetZip gribGinfo */ static int -grbDecode(int filetype, int memtype, void *cgribexp, void *gribbuffer, size_t gribsize, void *data, size_t datasize, int unreduced, - size_t *nmiss, double missval) +grb_decode(int filetype, int memtype, void *cgribexp, void *gribbuffer, size_t gribsize, void *data, size_t datasize, int unreduced, + size_t *nmiss, double missval) { int status = 0; @@ -60,7 +60,7 @@ grbDecode(int filetype, int memtype, void *cgribexp, void *gribbuffer, size_t gr // Decompresses the grib data in gribbuffer. static int -grbUnzipRecord(void *gribbuffer, size_t *gribsize) +grib1_unzip_record(void *gribbuffer, size_t *gribsize) { int zip = 0; @@ -72,7 +72,7 @@ grbUnzipRecord(void *gribbuffer, size_t *gribsize) if ((izip = gribGetZip(igribsize, (unsigned char *) gribbuffer, &unzipsize)) > 0) { zip = izip; - if (izip == 128) /* szip */ + if (izip == 128) // szip { if (unzipsize < igribsize) { @@ -80,7 +80,7 @@ grbUnzipRecord(void *gribbuffer, size_t *gribsize) return 0; } - unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */ + unzipsize += 100; // need 0 to 1 bytes for rounding of bds void *buffer = Malloc(igribsize); memcpy(buffer, gribbuffer, igribsize); @@ -115,9 +115,9 @@ static int grb_decode_record(void *untypedArgs) { DecodeArgs *args = (DecodeArgs *) untypedArgs; - *args->outZip = grbUnzipRecord(args->gribbuffer, &args->recsize); - grbDecode(args->filetype, args->memtype, args->cgribexp, args->gribbuffer, args->recsize, args->data, args->gridsize, - args->unreduced, &args->nmiss, args->missval); + *args->outZip = grib1_unzip_record(args->gribbuffer, &args->recsize); + grb_decode(args->filetype, args->memtype, args->cgribexp, args->gribbuffer, args->recsize, args->data, args->gridsize, + args->unreduced, &args->nmiss, args->missval); return 0; } @@ -135,7 +135,7 @@ grb_read_raw_data(stream_t *streamptr, int recID, int memtype, void *gribbuffer, void *cgribexp = (gribbuffer && streamptr->record->objectp) ? streamptr->record->objectp : NULL; if (!gribbuffer) gribbuffer = Malloc(streamptr->record->buffersize); - if (!data) data = Malloc(gridsize * (memtype == MEMTYPE_FLOAT ? sizeof(float) : sizeof(double))); + if (!data) data = Malloc(gridsize * ((memtype == MEMTYPE_FLOAT) ? sizeof(float) : sizeof(double))); if (streamptr->protocol == CDI_PROTOCOL_FDB) { @@ -148,24 +148,17 @@ grb_read_raw_data(stream_t *streamptr, int recID, int memtype, void *gribbuffer, } else { + if (recsize == 0) Error("Internal problem! Recordsize is zero for record %d at timestep %d", recID + 1, tsID + 1); + const int fileID = streamptr->fileID; const off_t recpos = streamptr->tsteps[tsID].records[recID].position; + const off_t currentfilepos = (resetFilePos ? fileGetPos(fileID) : 0); - if (recsize == 0) Error("Internal problem! Recordsize is zero for record %d at timestep %d", recID + 1, tsID + 1); + fileSetPos(fileID, recpos, SEEK_SET); + if (fileRead(fileID, gribbuffer, recsize) != recsize) Error("Failed to read GRIB record!"); - if (resetFilePos) - { - const off_t currentfilepos = fileGetPos(fileID); - fileSetPos(fileID, recpos, SEEK_SET); - if (fileRead(fileID, gribbuffer, recsize) != recsize) Error("Failed to read GRIB record!"); - fileSetPos(fileID, currentfilepos, SEEK_SET); - } - else - { - fileSetPos(fileID, recpos, SEEK_SET); - if (fileRead(fileID, gribbuffer, recsize) != recsize) Error("Failed to read GRIB record!"); - streamptr->numvals += gridsize; - } + if (resetFilePos) fileSetPos(fileID, currentfilepos, SEEK_SET); + if (!resetFilePos) streamptr->numvals += gridsize; } return (DecodeArgs){ @@ -184,6 +177,14 @@ grb_read_raw_data(stream_t *streamptr, int recID, int memtype, void *gribbuffer, }; } +static size_t +grb_read_and_decode_record(stream_t *streamptr, int recID, int memtype, void *data, bool resetFilePos) +{ + DecodeArgs args = grb_read_raw_data(streamptr, recID, memtype, streamptr->record->buffer, data, resetFilePos); + grb_decode_record(&args); + return args.nmiss; +} + typedef struct JobDescriptor { DecodeArgs args; @@ -202,7 +203,7 @@ static void JobDescriptor_finishJob(AsyncManager *jobManager, JobDescriptor *me, void *data, size_t *nmiss) { if (AsyncWorker_wait(jobManager, me->job)) xabort("error executing job in worker thread"); - memcpy(data, me->args.data, me->args.gridsize * (me->args.memtype == MEMTYPE_FLOAT ? sizeof(float) : sizeof(double))); + memcpy(data, me->args.data, me->args.gridsize * ((me->args.memtype == MEMTYPE_FLOAT) ? sizeof(float) : sizeof(double))); *nmiss = me->args.nmiss; Free(me->args.gribbuffer); @@ -228,7 +229,7 @@ grb_read_next_record(stream_t *streamptr, int recID, int memtype, void *data, si if (!jobs) { - jobs = (JobDescriptor *) malloc(workerCount * sizeof *jobs); + jobs = (JobDescriptor *) malloc(workerCount * sizeof(*jobs)); streamptr->jobs = jobs; for (int i = 0; i < workerCount; i++) jobs[i].args.recID = -1; if (AsyncWorker_init(&jobManager, workerCount)) xabort("error while trying to start worker threads"); @@ -271,12 +272,7 @@ grb_read_next_record(stream_t *streamptr, int recID, int memtype, void *data, si } // perform the work synchronously if we didn't start a job for it yet - if (!jobFound) - { - DecodeArgs args = grb_read_raw_data(streamptr, recID, memtype, streamptr->record->buffer, data, resetFilePos); - grb_decode_record(&args); - *nmiss = args.nmiss; - } + if (!jobFound) *nmiss = grb_read_and_decode_record(streamptr, recID, memtype, data, resetFilePos); } void @@ -295,7 +291,7 @@ grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, voi const int isub = subtypeInqActiveIndex(streamptr->vars[varID].subtypeID); const int recID = streamptr->vars[varID].recordTable[isub].recordID[levelID]; - grb_read_next_record(streamptr, recID, memtype, data, nmiss, true); + *nmiss = grb_read_and_decode_record(streamptr, recID, memtype, data, true); } void @@ -318,16 +314,10 @@ grb_read_var(stream_t *streamptr, int varID, int memtype, void *data, size_t *nm for (int levelID = 0; levelID < nlevs; levelID++) { const int recID = streamptr->vars[varID].recordTable[isub].recordID[levelID]; + const size_t offset = levelID * gridsize; + void *datap = (memtype == MEMTYPE_FLOAT) ? (void*)((float *) data + offset) : (void*)((double *) data + offset); - void *datap = NULL; - if (memtype == MEMTYPE_FLOAT) - datap = (float *) data + levelID * gridsize; - else - datap = (double *) data + levelID * gridsize; - - size_t imiss; - grb_read_next_record(streamptr, recID, memtype, datap, &imiss, false); - *nmiss += imiss; + *nmiss += grb_read_and_decode_record(streamptr, recID, memtype, datap, false); } fileSetPos(fileID, currentfilepos, SEEK_SET); diff --git a/src/grb_write.c b/src/grb_write.c index 41f8223321a175e2ec151c59b1bbcbc59de4cbc0..815cc7239a5108894568cb696f605b4a4b5a5b91 100644 --- a/src/grb_write.c +++ b/src/grb_write.c @@ -343,8 +343,8 @@ grbCopyRecord(stream_t *streamptr2, stream_t *streamptr1) const int zaxisType = zaxisInqType(zaxisID); FDB_Keys fdbKeys; - snprintf(fdbKeys.date, sizeof(fdbKeys.date), "%d", (int)cdiDate_get(streamptr1->tsteps[tsID].taxis.vdatetime.date)); - snprintf(fdbKeys.time, sizeof(fdbKeys.time), "%04d", cdiTime_get(streamptr1->tsteps[tsID].taxis.vdatetime.time) / 100); + snprintf(fdbKeys.date, sizeof(fdbKeys.date), "%d", (int) cdiDate_get(streamptr1->tsteps[tsID].taxis.vdatetime.date)); + snprintf(fdbKeys.time, sizeof(fdbKeys.time), "%04d", (short)(cdiTime_get(streamptr1->tsteps[tsID].taxis.vdatetime.time) / 100)); snprintf(fdbKeys.param, sizeof(fdbKeys.param), "%d", get_fdb_param(record->param)); const bool isML = (zaxisType == ZAXIS_HYBRID || zaxisType == ZAXIS_HYBRID_HALF); snprintf(fdbKeys.levtype, sizeof(fdbKeys.levtype), "%s", isML ? "ml" : "sfc"); @@ -378,7 +378,7 @@ grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, co const int zaxisID = vlistInqVarZaxis(vlistID, varID); const int tsteptype = vlistInqVarTsteptype(vlistID, varID); const int tsID = streamptr->curTsID; - const int date = (int)cdiDate_get(streamptr->tsteps[tsID].taxis.vdatetime.date); + const int date = (int) cdiDate_get(streamptr->tsteps[tsID].taxis.vdatetime.date); const int time = cdiTime_get(streamptr->tsteps[tsID].taxis.vdatetime.time); const int numavg = (tsteptype == TSTEP_AVG) ? streamptr->tsteps[tsID].taxis.numavg : 0; int comptype = streamptr->comptype; @@ -424,8 +424,8 @@ grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, co const double level = zaxisInqLevel(zaxisID, levelID); FDB_Keys fdbKeys; - snprintf(fdbKeys.date, sizeof(fdbKeys.date), "%d", (int)cdiDate_get(streamptr->tsteps[tsID].taxis.vdatetime.date)); - snprintf(fdbKeys.time, sizeof(fdbKeys.time), "%04d", cdiTime_get(streamptr->tsteps[tsID].taxis.vdatetime.time) / 100); + snprintf(fdbKeys.date, sizeof(fdbKeys.date), "%d", (int) cdiDate_get(streamptr->tsteps[tsID].taxis.vdatetime.date)); + snprintf(fdbKeys.time, sizeof(fdbKeys.time), "%04d", (short)(cdiTime_get(streamptr->tsteps[tsID].taxis.vdatetime.time) / 100)); snprintf(fdbKeys.param, sizeof(fdbKeys.param), "%d", get_fdb_param(vlistInqVarParam(vlistID, varID))); const bool isML = (zaxisType == ZAXIS_HYBRID || zaxisType == ZAXIS_HYBRID_HALF); snprintf(fdbKeys.levtype, sizeof(fdbKeys.levtype), "%s", isML ? "ml" : "sfc"); diff --git a/src/gribapi.c b/src/gribapi.c index 7336e13d6203e6f578927488028fc2c0a4df5cd4..c063ac5abc545da111cf31147a03259fecb63a30 100644 --- a/src/gribapi.c +++ b/src/gribapi.c @@ -42,7 +42,7 @@ gribapiLibraryVersionString(void) int major_version, minor_version, revision_version; gribapiLibraryVersion(&major_version, &minor_version, &revision_version); - sprintf(gribapi_libvers, "%d.%d.%d", major_version, minor_version, revision_version); + snprintf(gribapi_libvers, sizeof(gribapi_libvers), "%d.%d.%d", major_version, minor_version, revision_version); gribapi_libvers_init = true; } #endif diff --git a/src/gribapi_utilities.c b/src/gribapi_utilities.c index 5d149cbb03aa5580981e96ff2a9d028a8da228d3..c87c92bf384b1c0f60b637a9201c53dc6a54e493 100644 --- a/src/gribapi_utilities.c +++ b/src/gribapi_utilities.c @@ -271,8 +271,9 @@ addToDate(struct tm *me, long long amount, long unit) static char * makeDateString(struct tm *me) { - char *result = (char *) Malloc(4 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 4 + 1); - sprintf(result, "%04d-%02d-%02dT%02d:%02d:%02d.000", me->tm_year + 1900, me->tm_mon + 1, me->tm_mday, me->tm_hour, me->tm_min, + const size_t length = 4 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 4 + 1; + char *result = (char *) Malloc(length); + snprintf(result, length, "%04d-%02d-%02dT%02d:%02d:%02d.000", me->tm_year + 1900, me->tm_mon + 1, me->tm_mday, me->tm_hour, me->tm_min, me->tm_sec); return result; } diff --git a/src/grid.c b/src/grid.c index 77dea09af6afd09f2a3e3beeae6173ca48a11b48..88937b37c480e1321d88e30b6bbdd93ea536be94 100644 --- a/src/grid.c +++ b/src/grid.c @@ -898,6 +898,7 @@ gridInqProjType(int gridID) else if (strIsEqual(gmapname, "lambert_conformal_conic")) projtype = CDI_PROJ_LCC; else if (strIsEqual(gmapname, "sinusoidal")) projtype = CDI_PROJ_SINU; else if (strIsEqual(gmapname, "polar_stereographic")) projtype = CDI_PROJ_STERE; + else if (strIsEqual(gmapname, "healpix")) projtype = CDI_PROJ_HEALPIX; // clang-format on gridptr->projtype = projtype; } @@ -2593,7 +2594,7 @@ gridCompareP(void *gridptr1, void *gridptr2) } static void -gridComplete(grid_t *grid) +grid_complete(grid_t *grid) { const int gridID = grid->self; @@ -2781,7 +2782,7 @@ gridGenerate(const grid_t *grid) gridptr->gme.ni2 = grid->gme.ni2; gridptr->gme.ni3 = grid->gme.ni3; - gridComplete(gridptr); + grid_complete(gridptr); cdiCopyVarKey(&grid->keys, CDI_KEY_UUID, &gridptr->keys); @@ -4613,8 +4614,8 @@ cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode) 1 search in grid table only 2 search in grid table only and don't store the grid in vlist */ - bool gridglobdefined = false; - bool griddefined = false; + bool gridIsDefinedGlobal = false; + bool gridIsDefined = false; int gridID = CDI_UNDEFID; vlist_t *vlistptr = vlist_to_pointer(vlistID); @@ -4627,7 +4628,7 @@ cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode) { if (gridCompare(gridID, grid, false) == false) { - griddefined = true; + gridIsDefined = true; break; } } @@ -4635,28 +4636,28 @@ cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode) Error("Internal problem: undefined gridID in vlist %d, position %u!", vlistID, index); } - if (!griddefined) + if (!gridIsDefined) { struct gridCompareSearchState query; query.queryKey = grid; // = { .queryKey = grid }; - if ((gridglobdefined = (cdiResHFilterApply(&gridOps, gridCompareSearch, &query) == CDI_APPLY_STOP))) + if ((gridIsDefinedGlobal = (cdiResHFilterApply(&gridOps, gridCompareSearch, &query) == CDI_APPLY_STOP))) gridID = query.resIDValue; - if (mode == 1 && gridglobdefined) + if (mode == 1 && gridIsDefinedGlobal) for (int index = 0; index < ngrids; index++) if (vlistptr->gridIDs[index] == gridID) { - gridglobdefined = false; + gridIsDefinedGlobal = false; break; } } - if (!griddefined) + if (!gridIsDefined) { - if (!gridglobdefined) + if (!gridIsDefinedGlobal) { grid->self = gridID = reshPut(grid, &gridOps); - gridComplete(grid); + grid_complete(grid); } if (mode < 2) { @@ -4666,7 +4667,7 @@ cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode) } } - return (struct addIfNewRes){ .Id = gridID, .isNew = (!griddefined && !gridglobdefined) }; + return (struct addIfNewRes){ .Id = gridID, .isNew = (!gridIsDefined && !gridIsDefinedGlobal) }; } const struct gridVirtTable cdiGridVtable = { diff --git a/src/grid.h b/src/grid.h index 6f1e056e3130415912ed1c4b4139ca81ee30cb34..5546947ff26465ef6c4a04fc39183d681d8a644d 100644 --- a/src/grid.h +++ b/src/grid.h @@ -148,8 +148,8 @@ struct addIfNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode); int gridVerifyProjParamsLCC(struct CDI_GridProjParams *gpp); int gridVerifyProjParamsSTERE(struct CDI_GridProjParams *gpp); -bool isGaussianLatitudes(SizeType nlats, const double *latitudes); -void gaussianLatitudes(SizeType nlats, double *latitudes, double *weights); +bool isGaussianLatitudes(size_t nlats, const double *latitudes); +void gaussianLatitudes(size_t nlats, double *latitudes, double *weights); int gridFromMGF(MGF *mgf); diff --git a/src/iterator_grib.c b/src/iterator_grib.c index 40991e7323c7b1d685d15b26bd25c5722f438807..42699dd9710cf7624602c005db508d2920deebe6 100644 --- a/src/iterator_grib.c +++ b/src/iterator_grib.c @@ -339,10 +339,10 @@ static void hexdump(void *data, size_t size) // Read a record into memory and wrap it in a grib_handle. // XXX: I have omitted checking for szip compression as it is done in grbReadVarDP() & friends since that appears to be a -// non-standard extension of the GRIB1 standard: bit 1 in octet 14 of the binary data section which is used to signal szip compressio -// is defined to be reserved in the standard. As such, it seems prudent not to support this and to encourage people with such szip -// compressed files to switch to the GRIB2/JPEG2000 format. However, in the case that this reasoning is wrong, this function is -// probably the place to add the check for zsip compression. +// non-standard extension of the GRIB1 standard: bit 1 in octet 14 of the binary data section which is used to signal szip +// compressio is defined to be reserved in the standard. As such, it seems prudent not to support this and to encourage people with +// such szip compressed files to switch to the GRIB2/JPEG2000 format. However, in the case that this reasoning is wrong, this +// function is probably the place to add the check for zsip compression. static int readMessage(CdiGribIterator *me) { diff --git a/src/julian_date.c b/src/julian_date.c index 23df04a77df843ca8400ce2bad52616b21312c63..0c9fe2643aa13c68105f720d5cfecc4f3e762ea6 100644 --- a/src/julian_date.c +++ b/src/julian_date.c @@ -3,10 +3,10 @@ // convert Julian calendar day into year, months, day static void -decode_julday(int calendar, int64_t julianDay, // Julian day number to convert - int *year, // Gregorian year (out) - int *mon, // Gregorian month (1-12) (out) - int *day) // Gregorian day (1-31) (out) +decode_julday(int calendar, int64_t julianDay, // Julian day number to convert + int *year, // Gregorian year (out) + int *mon, // Gregorian month (1-12) (out) + int *day) // Gregorian day (1-31) (out) { const int64_t a = julianDay; @@ -241,84 +241,86 @@ main(void) // 1 - Check valid range of years { - int nmin = 11000; - int vdate0 = -80001201; - int vtime0 = 120500; + int nmin = 11000; + int vdate0 = -80001201; + int vtime0 = 120500; - printf("start time: %8d %4d\n", vdate0, vtime0); + printf("start time: %8d %4d\n", vdate0, vtime0); - CdiDateTime dt = cdiDateTime_set(vdate0, vtime0); + CdiDateTime dt = cdiDateTime_set(vdate0, vtime0); - for (int i = 0; i < nmin; i++) - { - JulianDate julianDate = julianDate_encode(calendar, dt); + for (int i = 0; i < nmin; i++) + { + JulianDate julianDate = julianDate_encode(calendar, dt); - dt = julianDate_decode(calendar, julianDate); - int vdate = (int)cdiDate_get(dt.date); - int vtime = cdiTime_get(dt.time); + dt = julianDate_decode(calendar, julianDate); + int vdate = (int) cdiDate_get(dt.date); + int vtime = cdiTime_get(dt.time); - if (vdate0 != vdate || vtime0 != vtime) - printf("%4d %8d %4d %8d %4d %9d %g\n", ++j, vdate0, vtime0, vdate, vtime, (int)julianDate.julianDay, julianDate.secondOfDay); + if (vdate0 != vdate || vtime0 != vtime) + printf("%4d %8d %4d %8d %4d %9d %g\n", ++j, vdate0, vtime0, vdate, vtime, (int) julianDate.julianDay, + julianDate.secondOfDay); - dt.date.year++; - julianDate = julianDate_encode(calendar, dt); + dt.date.year++; + julianDate = julianDate_encode(calendar, dt); - dt = julianDate_decode(calendar, julianDate); - vdate0 = (int)cdiDate_get(dt.date); - vtime0 = cdiTime_get(dt.time); - } + dt = julianDate_decode(calendar, julianDate); + vdate0 = (int) cdiDate_get(dt.date); + vtime0 = cdiTime_get(dt.time); + } - printf("stop time: %8d %4d\n", vdate0, vtime0); + printf("stop time: %8d %4d\n", vdate0, vtime0); } // 2 - Check time increment of one minute { - int nmin = 120000; - int ijulinc = 60; - int vdate0 = 20001201; - int vtime0 = 0; - - printf("start time: %8d %4d\n", vdate0, vtime0); - - CdiDateTime dt = cdiDateTime_set(vdate0, vtime0); - JulianDate julianDate = julianDate_encode(calendar, dt); - - for (int i = 0; i < nmin; i++) - { - int year, mon, day, hour, minute, second; - cdiDecodeDate(vdate0, &year, &mon, &day); - cdiDecodeTime(vtime0, &hour, &minute, &second); - - if (++minute >= 60) - { - minute = 0; - if (++hour >= 24) - { - hour = 0; - if (++day >= 32) - { - day = 1; - if (++mon >= 13) - { - mon = 1; - year++; - } - } - } - } - - vdate0 = cdiEncodeDate(year, mon, day); - vtime0 = cdiEncodeTime(hour, minute, second); - - julianDate = julianDate_add_seconds(julianDate, ijulinc); - dt = julianDate_decode(calendar, julianDate); - int vdate = (int)cdiDate_get(dt.date); - int vtime = cdiTime_get(dt.time); - - if (vdate0 != vdate || vtime0 != vtime) - printf("%4d %8d %4d %8d %4d %9d %g\n", ++j, vdate0, vtime0, vdate, vtime, (int)julianDate.julianDay, julianDate.secondOfDay); - } - - printf("stop time: %8d %4d\n", vdate0, vtime0); + int nmin = 120000; + int ijulinc = 60; + int vdate0 = 20001201; + int vtime0 = 0; + + printf("start time: %8d %4d\n", vdate0, vtime0); + + CdiDateTime dt = cdiDateTime_set(vdate0, vtime0); + JulianDate julianDate = julianDate_encode(calendar, dt); + + for (int i = 0; i < nmin; i++) + { + int year, mon, day, hour, minute, second; + cdiDecodeDate(vdate0, &year, &mon, &day); + cdiDecodeTime(vtime0, &hour, &minute, &second); + + if (++minute >= 60) + { + minute = 0; + if (++hour >= 24) + { + hour = 0; + if (++day >= 32) + { + day = 1; + if (++mon >= 13) + { + mon = 1; + year++; + } + } + } + } + + vdate0 = cdiEncodeDate(year, mon, day); + vtime0 = cdiEncodeTime(hour, minute, second); + + julianDate = julianDate_add_seconds(julianDate, ijulinc); + dt = julianDate_decode(calendar, julianDate); + int vdate = (int) cdiDate_get(dt.date); + int vtime = cdiTime_get(dt.time); + + if (vdate0 != vdate || vtime0 != vtime) + printf("%4d %8d %4d %8d %4d %9d %g\n", ++j, vdate0, vtime0, vdate, vtime, (int) julianDate.julianDay, + julianDate.secondOfDay); + } + + printf("stop time: %8d %4d\n", vdate0, vtime0); } return 0; } @@ -343,19 +345,20 @@ main(void) CdiDateTime dt; dt.date = cdiDate_encode(year, month, day); dt.time = cdiTime_encode(hour, minute, second, ms); - printf("%d/%02d/%02d %02d:%02d:%02d.%03d\n", - dt.date.year, dt.date.month, dt.date.day, dt.time.hour, dt.time.minute, dt.time.second, dt.time.ms); + printf("%d/%02d/%02d %02d:%02d:%02d.%03d\n", dt.date.year, dt.date.month, dt.date.day, dt.time.hour, dt.time.minute, + dt.time.second, dt.time.ms); JulianDate julianDate = julianDate_encode(calendar, dt); dt = julianDate_decode(calendar, julianDate); - printf("%d/%02d/%02d %02d:%02d:%02d.%03d %d %g\n", - dt.date.year, dt.date.month, dt.date.day, dt.time.hour, dt.time.minute, dt.time.second, dt.time.ms, (int)julianDate.julianDay, julianDate.secondOfDay); + printf("%d/%02d/%02d %02d:%02d:%02d.%03d %d %g\n", dt.date.year, dt.date.month, dt.date.day, dt.time.hour, dt.time.minute, + dt.time.second, dt.time.ms, (int) julianDate.julianDay, julianDate.secondOfDay); for (int i = 0; i < 420; i++) { dt = julianDate_decode(calendar, julianDate); - printf("%2d %d/%02d/%02d %02d:%02d:%02d.%03d\n", i, dt.date.year, dt.date.month, dt.date.day, dt.time.hour, dt.time.minute, dt.time.second, dt.time.ms); + printf("%2d %d/%02d/%02d %02d:%02d:%02d.%03d\n", i, dt.date.year, dt.date.month, dt.date.day, dt.time.hour, dt.time.minute, + dt.time.second, dt.time.ms); julianDate = julianDate_add_seconds(julianDate, value * factor); } diff --git a/src/make_fint.c b/src/make_fint.c index db4bcca1d3a5d307b83fd8da134e9ad7d15aa3f3..b06e6c74b1c5c393850636cce75ee3c6ee60544e 100644 --- a/src/make_fint.c +++ b/src/make_fint.c @@ -18,7 +18,7 @@ // clang-format off //#include "config.h" -#define VERSION "2.0.0" +#define VERSION "2.1.0" typedef struct { diff --git a/src/mo_cdi.f90 b/src/mo_cdi.f90 index 85f4c88eac1fee2e1efc1ccc173fe5a8d7fc3be9..5886bc7832707166f229fb27f34c11d0f55317c2 100644 --- a/src/mo_cdi.f90 +++ b/src/mo_cdi.f90 @@ -147,6 +147,7 @@ module mo_cdi integer(c_int), public, parameter :: CDI_PROJ_LAEA = 23 integer(c_int), public, parameter :: CDI_PROJ_SINU = 24 integer(c_int), public, parameter :: CDI_PROJ_STERE = 25 + integer(c_int), public, parameter :: CDI_PROJ_HEALPIX = 26 integer(c_int), public, parameter :: ZAXIS_SURFACE = 0 integer(c_int), public, parameter :: ZAXIS_GENERIC = 1 integer(c_int), public, parameter :: ZAXIS_HYBRID = 2 @@ -412,12 +413,6 @@ module mo_cdi public :: vlistInqVarUnits public :: vlistDefVarMissval public :: vlistInqVarMissval - public :: vlistDefVarExtra - public :: vlistInqVarExtra - public :: vlistDefVarScalefactor - public :: vlistInqVarScalefactor - public :: vlistDefVarAddoffset - public :: vlistInqVarAddoffset public :: vlistInqVarSize public :: vlistDefIndex public :: vlistInqIndex @@ -483,6 +478,7 @@ module mo_cdi integer(c_int), public, parameter :: CDI_KEY_UNITS = 945 integer(c_int), public, parameter :: CDI_KEY_DATATYPE = 946 integer(c_int), public, parameter :: CDI_KEY_REFERENCEURI = 947 + integer(c_int), public, parameter :: CDI_KEY_CHUNKS = 948 integer(c_int), public, parameter :: CDI_KEY_NUMBEROFGRIDUSED = 961 integer(c_int), public, parameter :: CDI_KEY_NUMBEROFGRIDINREFERENCE = 962 integer(c_int), public, parameter :: CDI_KEY_NUMBEROFVGRIDUSED = 963 @@ -490,6 +486,8 @@ module mo_cdi integer(c_int), public, parameter :: CDI_KEY_CHUNKTYPE = 965 integer(c_int), public, parameter :: CDI_KEY_CHUNKSIZE = 966 integer(c_int), public, parameter :: CDI_KEY_MISSVAL = 701 + integer(c_int), public, parameter :: CDI_KEY_ADDOFFSET = 702 + integer(c_int), public, parameter :: CDI_KEY_SCALEFACTOR = 703 integer(c_int), public, parameter :: CDI_KEY_UUID = 960 integer(c_int), public, parameter :: CDI_KEY_DIMNAME = 941 integer(c_int), public, parameter :: CDI_KEY_PSNAME = 950 @@ -1624,38 +1622,6 @@ module mo_cdi real(c_double) :: f_result end function vlistInqVarMissval - subroutine vlistDefVarScalefactor(vlistID_dummy, varID_dummy,& - & scalefactor_dummy) bind(c, name = 'vlistDefVarScalefactor') - import c_double, c_int - integer(c_int), value :: vlistID_dummy - integer(c_int), value :: varID_dummy - real(c_double), value :: scalefactor_dummy - end subroutine vlistDefVarScalefactor - - function vlistInqVarScalefactor(vlistID_dummy, varID_dummy) bind(c, name =& - & 'vlistInqVarScalefactor') result(f_result) - import c_double, c_int - integer(c_int), value :: vlistID_dummy - integer(c_int), value :: varID_dummy - real(c_double) :: f_result - end function vlistInqVarScalefactor - - subroutine vlistDefVarAddoffset(vlistID_dummy, varID_dummy,& - & addoffset_dummy) bind(c, name = 'vlistDefVarAddoffset') - import c_double, c_int - integer(c_int), value :: vlistID_dummy - integer(c_int), value :: varID_dummy - real(c_double), value :: addoffset_dummy - end subroutine vlistDefVarAddoffset - - function vlistInqVarAddoffset(vlistID_dummy, varID_dummy) bind(c, name =& - & 'vlistInqVarAddoffset') result(f_result) - import c_double, c_int - integer(c_int), value :: vlistID_dummy - integer(c_int), value :: varID_dummy - real(c_double) :: f_result - end function vlistInqVarAddoffset - function vlistInqVarSize(vlistID_dummy, varID_dummy) bind(c, name =& & 'vlistInqVarSize') result(f_result) import c_int @@ -4437,61 +4403,6 @@ contains end do end subroutine vlistInqVarUnits - subroutine vlistDefVarExtra(vlistID_dummy, varID_dummy, extra_dummy) - integer(c_int), value :: vlistID_dummy - integer(c_int), value :: varID_dummy - character(kind = c_char, len = *), intent(in) :: extra_dummy - character(kind = c_char) :: extra_temp(len(extra_dummy) + 1) - integer :: extra_i - interface - subroutine lib_vlistDefVarExtra(vlistID_dummy, varID_dummy, extra_dummy)& - & bind(c, name = 'vlistDefVarExtra') - import c_char, c_int - integer(c_int), value :: vlistID_dummy - integer(c_int), value :: varID_dummy - character(kind = c_char) :: extra_dummy(*) - end subroutine lib_vlistDefVarExtra - end interface - do extra_i = 1, len(extra_dummy) - extra_temp(extra_i) = extra_dummy(extra_i:extra_i) - end do - extra_temp(len(extra_dummy) + 1) = c_null_char - call lib_vlistDefVarExtra(vlistID_dummy, varID_dummy, extra_temp) - end subroutine vlistDefVarExtra - - subroutine vlistInqVarExtra(vlistID_dummy, varID_dummy, extra_dummy) - integer(c_int), value :: vlistID_dummy - integer(c_int), value :: varID_dummy - character(kind = c_char, len = *), intent(inout) :: extra_dummy - character(kind = c_char) :: extra_temp(len(extra_dummy) + 1) - integer :: extra_i - interface - subroutine lib_vlistInqVarExtra(vlistID_dummy, varID_dummy, extra_dummy)& - & bind(c, name = 'vlistInqVarExtra') - import c_char, c_int - integer(c_int), value :: vlistID_dummy - integer(c_int), value :: varID_dummy - character(kind = c_char) :: extra_dummy(*) - end subroutine lib_vlistInqVarExtra - end interface - extra_temp(len(extra_dummy) + 1) = c_null_char - do extra_i = len(extra_dummy), 1, -1 - if(extra_dummy(extra_i:extra_i) /= ' ') exit - extra_temp(extra_i) = c_null_char - end do - do extra_i = extra_i, 1, -1 - extra_temp(extra_i) = extra_dummy(extra_i:extra_i) - end do - call lib_vlistInqVarExtra(vlistID_dummy, varID_dummy, extra_temp) - do extra_i = 1, len(extra_dummy) - if(extra_temp(extra_i) == c_null_char) exit - extra_dummy(extra_i:extra_i) = extra_temp(extra_i) - end do - do extra_i = extra_i, len(extra_dummy) - extra_dummy(extra_i:extra_i) = ' ' - end do - end subroutine vlistInqVarExtra - subroutine cdiDefAdditionalKey(string_dummy) character(kind = c_char, len = *), intent(in) :: string_dummy character(kind = c_char) :: string_temp(len(string_dummy) + 1) diff --git a/src/namespace.h b/src/namespace.h index bb725507db86fd96cec5edac319e5298426d2999..58397075e380cf3216301cfcbdd6e3d87b1a2420 100644 --- a/src/namespace.h +++ b/src/namespace.h @@ -47,7 +47,7 @@ union namespaceSwitchValue void (*func)(); }; -#define NSSW_FUNC(p) ((union namespaceSwitchValue){ .func = (void (*)()) (p) }) +#define NSSW_FUNC(p) ((union namespaceSwitchValue){ .func = (void (*)())(p) }) #define NSSW_DATA(p) ((union namespaceSwitchValue){ .data = (void *) (p) }) // int namespaceNew(); diff --git a/src/stream_cdf.h b/src/stream_cdf.h index 1575887e82e9d11c05d9605c747b394f314022e3..14520600efb500fe043c198aa3c7e78b6798b737 100644 --- a/src/stream_cdf.h +++ b/src/stream_cdf.h @@ -32,15 +32,15 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype, const int rect[][2], const void *data, size_t nmiss); -void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level); +void cdfDefVarDeflate(int ncid, int ncvarid, int deflateLevel); void cdfDefTime(stream_t *streamptr); void cdf_scale_add(size_t size, double *data, double addoffset, double scalefactor); int cdfDefDatatype(int datatype, stream_t *streamptr); -#define ChunkSizeMax 65536 -#define ChunkSizeLim 16777216 +#define ChunkSizeMax 65536 +#define ChunkSizeLim 16777216 size_t calc_chunksize_x(int chunkType, int chunkSize, size_t xsize, bool yIsUndefined); size_t calc_chunksize_y(int chunkType, size_t gridsize, size_t xsize, size_t ysize); diff --git a/src/stream_cdf_i.c b/src/stream_cdf_i.c index fb076ffc9853b14e630b571aea5385befcb32701..42d7ee81d089394f6da4447b7af487dc31a7cc71 100644 --- a/src/stream_cdf_i.c +++ b/src/stream_cdf_i.c @@ -104,6 +104,11 @@ typedef struct bool chunked; int chunkType; int chunkSize; + size_t chunkCacheSize; + size_t chunkCacheNelems; + float chunkCachePreemption; + size_t gridSize; + size_t numLevels; int natts; int *atts; size_t vctsize; @@ -120,6 +125,7 @@ typedef struct int typeOfEnsembleForecast; int numberOfForecastsInEnsemble; int perturbationNumber; + int unitsLen; char name[CDI_MAX_NAME]; char longname[CDI_MAX_NAME]; char stdname[CDI_MAX_NAME]; @@ -171,46 +177,46 @@ static int scan_time_units(const char *unitstr) { const size_t len = strlen(unitstr); - const int timeunit = get_timeunit(len, unitstr); + const int timeunit = get_time_units(len, unitstr); if (timeunit == -1) Message("Unsupported TIMEUNIT: %s!", unitstr); return timeunit; } static void -setForecastTime(const char *timestr, taxis_t *taxis) +set_forecast_time(const char *timestr, taxis_t *taxis) { const size_t len = strlen(timestr); if (len != 0) { const CdiDateTime datetime = scan_time_string(timestr); - taxis->fdate = (int)cdiDate_get(datetime.date); + taxis->fdate = (int) cdiDate_get(datetime.date); taxis->ftime = cdiTime_get(datetime.time); - } + } else taxis->fdate = taxis->ftime = 0; } static int -setBaseTime(const char *timeunits, taxis_t *taxis) +set_base_time(const char *timeUnitsStr, taxis_t *taxis) { - int taxistype = TAXIS_ABSOLUTE; + int taxisType = TAXIS_ABSOLUTE; - size_t len = strlen(timeunits); - while (isspace(*timeunits) && len) + size_t len = strlen(timeUnitsStr); + while (isspace(*timeUnitsStr) && len) { - timeunits++; + timeUnitsStr++; len--; } - char *tu = (char *) Malloc((len + 1) * sizeof(char)); + char *tu = (char *) malloc((len + 1) * sizeof(char)); - for (size_t i = 0; i < len; i++) tu[i] = (char) tolower((int) timeunits[i]); + for (size_t i = 0; i < len; i++) tu[i] = (char) tolower((int) timeUnitsStr[i]); tu[len] = 0; - int timeunit = get_timeunit(len, tu); - if (timeunit == -1) + int timeUnits = get_time_units(len, tu); + if (timeUnits == -1) { - Message("Unsupported TIMEUNIT: %s!", timeunits); + Message("Unsupported TIMEUNIT: %s!", timeUnitsStr); return 1; } @@ -220,37 +226,37 @@ setBaseTime(const char *timeunits, taxis_t *taxis) { while (isspace(tu[pos])) ++pos; - if (strStartsWith(tu + pos, "since")) taxistype = TAXIS_RELATIVE; + if (strStartsWith(tu + pos, "since")) taxisType = TAXIS_RELATIVE; while (pos < len && !isspace(tu[pos])) ++pos; if (tu[pos]) { while (isspace(tu[pos])) ++pos; - if (taxistype == TAXIS_ABSOLUTE) + if (taxisType == TAXIS_ABSOLUTE) { - if (timeunit == TUNIT_DAY) + if (timeUnits == TUNIT_DAY) { if (!strStartsWith(tu + pos, "%y%m%d.%f")) { Warning("Unsupported format %s for TIMEUNIT day!", tu + pos); - timeunit = -1; + timeUnits = -1; } } - else if (timeunit == TUNIT_MONTH) + else if (timeUnits == TUNIT_MONTH) { if (!strStartsWith(tu + pos, "%y%m.%f")) { Warning("Unsupported format %s for TIMEUNIT month!", tu + pos); - timeunit = -1; + timeUnits = -1; } } - else if (timeunit == TUNIT_YEAR) + else if (timeUnits == TUNIT_YEAR) { if (!strStartsWith(tu + pos, "%y.%f")) { Warning("Unsupported format %s for TIMEUNIT year!", tu + pos); - timeunit = -1; + timeUnits = -1; } } else @@ -258,20 +264,21 @@ setBaseTime(const char *timeunits, taxis_t *taxis) Warning("Unsupported format for time units: %s!", tu); } } - else if (taxistype == TAXIS_RELATIVE) + else if (taxisType == TAXIS_RELATIVE) { taxis->rdatetime = scan_time_string(tu + pos); - if (CDI_Debug) Message("rdate = %d rtime = %d", (int)cdiDate_get(taxis->rdatetime.date), cdiTime_get(taxis->rdatetime.time)); + if (CDI_Debug) + Message("rdate = %d rtime = %d", (int) cdiDate_get(taxis->rdatetime.date), cdiTime_get(taxis->rdatetime.time)); } } } - taxis->type = taxistype; - taxis->unit = timeunit; + taxis->type = taxisType; + taxis->unit = timeUnits; - Free(tu); + free(tu); - if (CDI_Debug) Message("taxistype = %d unit = %d", taxistype, timeunit); + if (CDI_Debug) Message("taxisType = %d timeUnits = %d", taxisType, timeUnits); return 0; } @@ -315,19 +322,19 @@ cdfInqDatatype(stream_t *streamptr, int xtype, bool lunsigned) #endif // clang-format off - if ( xtype == NC_BYTE ) datatype = CDI_DATATYPE_INT8; - else if ( xtype == NC_CHAR ) datatype = CDI_DATATYPE_UINT8; - else if ( xtype == NC_SHORT ) datatype = CDI_DATATYPE_INT16; - else if ( xtype == NC_INT ) datatype = CDI_DATATYPE_INT32; - else if ( xtype == NC_FLOAT ) datatype = CDI_DATATYPE_FLT32; - else if ( xtype == NC_DOUBLE ) datatype = CDI_DATATYPE_FLT64; + if (xtype == NC_BYTE ) datatype = CDI_DATATYPE_INT8; + else if (xtype == NC_CHAR ) datatype = CDI_DATATYPE_UINT8; + else if (xtype == NC_SHORT ) datatype = CDI_DATATYPE_INT16; + else if (xtype == NC_INT ) datatype = CDI_DATATYPE_INT32; + else if (xtype == NC_FLOAT ) datatype = CDI_DATATYPE_FLT32; + else if (xtype == NC_DOUBLE) datatype = CDI_DATATYPE_FLT64; #ifdef HAVE_NETCDF4 - else if ( xtype == NC_UBYTE ) datatype = CDI_DATATYPE_UINT8; - else if ( xtype == NC_LONG ) datatype = CDI_DATATYPE_INT32; - else if ( xtype == NC_USHORT ) datatype = CDI_DATATYPE_UINT16; - else if ( xtype == NC_UINT ) datatype = CDI_DATATYPE_UINT32; - else if ( xtype == NC_INT64 ) datatype = CDI_DATATYPE_FLT64; - else if ( xtype == NC_UINT64 ) datatype = CDI_DATATYPE_FLT64; + else if (xtype == NC_UBYTE ) datatype = CDI_DATATYPE_UINT8; + else if (xtype == NC_LONG ) datatype = CDI_DATATYPE_INT32; + else if (xtype == NC_USHORT) datatype = CDI_DATATYPE_UINT16; + else if (xtype == NC_UINT ) datatype = CDI_DATATYPE_UINT32; + else if (xtype == NC_INT64 ) datatype = CDI_DATATYPE_FLT64; + else if (xtype == NC_UINT64) datatype = CDI_DATATYPE_FLT64; else { if (xtype != streamptr->nc_complex_float_id && xtype != streamptr->nc_complex_double_id) @@ -355,8 +362,8 @@ cdfInqDatatype(stream_t *streamptr, int xtype, bool lunsigned) } } } - if ( xtype == streamptr->nc_complex_float_id ) datatype = CDI_DATATYPE_CPX32; - else if ( xtype == streamptr->nc_complex_double_id ) datatype = CDI_DATATYPE_CPX64; + if (xtype == streamptr->nc_complex_float_id ) datatype = CDI_DATATYPE_CPX32; + else if (xtype == streamptr->nc_complex_double_id) datatype = CDI_DATATYPE_CPX64; } #endif // clang-format on @@ -416,11 +423,12 @@ cdfCheckAttText(int fileID, int ncvarid, const char *attname) nc_type atttype; const int status_nc = nc_inq_atttype(fileID, ncvarid, attname, &atttype); - return (status_nc == NC_NOERR && (atttype == NC_CHAR + return (status_nc == NC_NOERR + && (atttype == NC_CHAR #ifdef HAVE_NETCDF4 - || atttype == NC_STRING + || atttype == NC_STRING #endif - )); + )); } static void @@ -467,18 +475,18 @@ cdfGetAttText(int fileID, int ncvarid, const char *attname, size_t attlen, char void cdf_scale_add(size_t size, double *data, double addoffset, double scalefactor) { - const bool laddoffset = IS_NOT_EQUAL(addoffset, 0); - const bool lscalefactor = IS_NOT_EQUAL(scalefactor, 1); + const bool haveAddoffset = IS_NOT_EQUAL(addoffset, 0.0); + const bool haveScalefactor = IS_NOT_EQUAL(scalefactor, 1.0); - if (laddoffset && lscalefactor) + if (haveAddoffset && haveScalefactor) { for (size_t i = 0; i < size; ++i) data[i] = data[i] * scalefactor + addoffset; } - else if (lscalefactor) + else if (haveScalefactor) { for (size_t i = 0; i < size; ++i) data[i] *= scalefactor; } - else if (laddoffset) + else if (haveAddoffset) { for (size_t i = 0; i < size; ++i) data[i] += addoffset; } @@ -502,7 +510,7 @@ cdfCreateRecords(stream_t *streamptr, int tsID) if (tsID == 0) { - const int nvrecs = nrecs; /* use all records at first timestep */ + const int nvrecs = nrecs; // use all records at first timestep streamptr->nrecs += nrecs; @@ -709,14 +717,19 @@ init_ncvars(int nvars, ncvar_t *ncvars) ncvar->chunked = false; ncvar->chunkType = CDI_UNDEFID; ncvar->chunkSize = CDI_UNDEFID; + ncvar->chunkCacheSize = 0; + ncvar->chunkCacheNelems = 0; + ncvar->chunkCachePreemption = 0.0; + ncvar->gridSize = 0; + ncvar->numLevels = 0; ncvar->natts = 0; ncvar->atts = NULL; ncvar->vctsize = 0; ncvar->vct = NULL; ncvar->missval = 0; ncvar->fillval = 0; - ncvar->addoffset = 0; - ncvar->scalefactor = 1; + ncvar->addoffset = 0.0; + ncvar->scalefactor = 1.0; ncvar->ldeflate = false; ncvar->lszip = false; ncvar->lunsigned = false; @@ -726,6 +739,7 @@ init_ncvars(int nvars, ncvar_t *ncvars) ncvar->typeOfEnsembleForecast = -1; ncvar->numberOfForecastsInEnsemble = -1; ncvar->perturbationNumber = -1; + ncvar->unitsLen = 0; memset(ncvar->name, 0, CDI_MAX_NAME); memset(ncvar->longname, 0, CDI_MAX_NAME); memset(ncvar->stdname, 0, CDI_MAX_NAME); @@ -1092,6 +1106,21 @@ cdf_get_cell_varid(char *attstring, int ncid) return nc_cell_id; } +static void +set_extra_attr(char *buf, int nvdims, const size_t *chunks) +{ + size_t pos = strlen(buf); + static const char prefix[] = "chunks="; + memcpy(buf + pos, prefix, sizeof(prefix)); + pos += sizeof(prefix) - 1; + for (int i = nvdims - 1; i >= 0; --i) + { + pos += (size_t) (sprintf(buf + pos, "%zu%s", chunks[i], i > 0 ? "x" : "")); + } + buf[pos] = ' '; + buf[pos + 1] = 0; +} + static void cdfScanVarAttr(int nvars, ncvar_t *ncvars, int ndims, ncdim_t *ncdims, int timedimid, int modelID, int format) { @@ -1134,8 +1163,8 @@ cdfScanVarAttr(int nvars, ncvar_t *ncvars, int ndims, ncdim_t *ncdims, int timed #ifdef HAVE_NETCDF4 if (format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4) { - int shuffle = 0, deflate = 0, deflate_level = 0; - nc_inq_var_deflate(ncid, ncvarid, &shuffle, &deflate, &deflate_level); + int shuffle = 0, deflate = 0, deflateLevel = 0; + nc_inq_var_deflate(ncid, ncvarid, &shuffle, &deflate, &deflateLevel); if (deflate > 0) ncvar->ldeflate = true; #ifdef HAVE_NC_DEF_VAR_SZIP @@ -1143,43 +1172,36 @@ cdfScanVarAttr(int nvars, ncvar_t *ncvars, int ndims, ncdim_t *ncdims, int timed nc_inq_var_szip(ncid, ncvarid, &options_mask, &pixels_per_block); if (options_mask && pixels_per_block) ncvar->lszip = true; #endif - /* - size_t cache_size, nelems; - float preemption; - nc_get_chunk_cache(&cache_size, &nelems, &preemption); - printf("cache_size %lu nelems %lu preemption %g\n", cache_size, nelems, preemption); - nc_get_var_chunk_cache(ncid, ncvarid, &cache_size, &nelems, &preemption); - printf("varid %d cache_size %lu nelems %lu preemption %g\n", ncvarid, cache_size, nelems, preemption); - */ size_t chunks[nvdims]; - int storage_in; - if (nc_inq_var_chunking(ncid, ncvarid, &storage_in, chunks) == NC_NOERR) + int storageIn; + if (nc_inq_var_chunking(ncid, ncvarid, &storageIn, chunks) == NC_NOERR) { - if (storage_in == NC_CHUNKED) + if (storageIn == NC_CHUNKED) { ncvar->chunked = true; for (int i = 0; i < nvdims; ++i) ncvar->chunks[i] = chunks[i]; if (CDI_Debug) { - fprintf(stderr, "%s: chunking %d %d %d chunks ", name, storage_in, NC_CONTIGUOUS, NC_CHUNKED); + fprintf(stderr, "%s: chunking %d %d %d chunks ", name, storageIn, NC_CONTIGUOUS, NC_CHUNKED); for (int i = 0; i < nvdims; ++i) fprintf(stderr, "%zu ", chunks[i]); fprintf(stderr, "\n"); } - { - char *buf = ncvar->extra; - size_t pos = strlen(buf); - static const char prefix[] = "chunks="; - memcpy(buf + pos, prefix, sizeof(prefix)); - pos += sizeof(prefix) - 1; - for (int i = nvdims - 1; i >= 0; --i) - { - pos += (size_t) (sprintf(buf + pos, "%zu%s", chunks[i], i > 0 ? "x" : "")); - } - buf[pos] = ' '; - buf[pos + 1] = 0; - } + + set_extra_attr(ncvar->extra, nvdims, chunks); } } + + size_t size; + size_t nelems; + float preemption; + if (nc_get_var_chunk_cache(ncid, ncvarid, &size, &nelems, &preemption) == NC_NOERR) + { + ncvar->chunkCacheSize = size; + ncvar->chunkCacheNelems = nelems; + ncvar->chunkCachePreemption = preemption; + if (CDI_Debug) + fprintf(stderr, "%s: chunkCacheSize=%zu nelems=%zu preemption=%g\n", name, size, nelems, preemption); + } } #endif @@ -1233,6 +1255,7 @@ cdfScanVarAttr(int nvars, ncvar_t *ncvars, int ndims, ncdim_t *ncdims, int timed } else if (isText && strIsEqual(attname, "units")) { + ncvar->unitsLen = attstringsize; memcpy(ncvar->units, attstring, attstringsize); } else if (isText && strIsEqual(attname, "calendar")) @@ -1700,7 +1723,6 @@ cdf_set_dimtype(int nvars, ncvar_t *ncvars, ncdim_t *ncdims) int allcdims = lcdim; if (!lxdim && ncvar->xvarid != CDI_UNDEFID && ncvars[ncvar->xvarid].ndims == 0) lxdim = true; - if (!lydim && ncvar->yvarid != CDI_UNDEFID && ncvars[ncvar->yvarid].ndims == 0) lydim = true; if (lxdim && (lydim || ncvar->gridtype == GRID_UNSTRUCTURED)) @@ -2036,7 +2058,9 @@ grid_set_chunktype(grid_t *grid, ncvar_t *ncvar) if (grid->type == GRID_UNSTRUCTURED) { - ncvar->chunkType = ncvar->chunks[ndims - 1] == grid->size ? CDI_CHUNK_GRID : CDI_CHUNK_AUTO; + size_t chunkSize = ncvar->chunks[ndims - 1]; + ncvar->chunkType = (chunkSize == grid->size) ? CDI_CHUNK_GRID : CDI_CHUNK_AUTO; + if (ncvar->chunkType == CDI_CHUNK_AUTO && ncvar->chunks[ndims - 1] > 1) ncvar->chunkSize = chunkSize; } else { @@ -2224,7 +2248,7 @@ cdf_check_gridtype(int *gridtype, bool isLon, bool isLat, size_t xsize, size_t y { if (isLat && (isLon || xsize == 0)) { - double yinc = 0; + double yinc = 0.0; if (isLon && ysize > 1) { yinc = fabs(grid->y.vals[0] - grid->y.vals[1]); @@ -2241,14 +2265,14 @@ cdf_check_gridtype(int *gridtype, bool isLon, bool isLat, size_t xsize, size_t y grid->np = (int) (ysize / 2); } else - *gridtype = GRID_LONLAT; + { + *gridtype = GRID_LONLAT; + } } - else if (isLon && !isLat && ysize == 0) + else { - *gridtype = GRID_LONLAT; + *gridtype = (isLon && !isLat && ysize == 0) ? GRID_LONLAT : GRID_GENERIC; } - else - *gridtype = GRID_GENERIC; } static bool @@ -2580,7 +2604,7 @@ cdf_read_coordinates(stream_t *streamptr, struct cdfLazyGrid *lazyGrid, ncvar_t if (lwarn) Warning("x-bounds doesn't follow the CF-Convention, skipped!"); lwarn = false; } - } + } } } if (yvarid != CDI_UNDEFID && CDI_Read_Cell_Corners) @@ -2622,7 +2646,7 @@ cdf_read_coordinates(stream_t *streamptr, struct cdfLazyGrid *lazyGrid, ncvar_t if (lwarn) Warning("y-bounds doesn't follow the CF-Convention, skipped!"); lwarn = false; } - } + } } } @@ -2861,6 +2885,7 @@ cdf_set_grid_to_similar_vars(ncvar_t *ncvar1, ncvar_t *ncvar2, int gridtype, int ncvar2->gridID = ncvar1->gridID; ncvar2->chunkType = ncvar1->chunkType; ncvar2->chunkSize = ncvar1->chunkSize; + ncvar2->gridSize = ncvar1->gridSize; } } } @@ -2875,17 +2900,17 @@ cdf_define_all_grids(stream_t *streamptr, ncgrid_t *ncgrid, int vlistID, ncdim_t ncvar_t *ncvar = &ncvars[ncvarid]; if (ncvar->varStatus == DataVar && ncvar->gridID == CDI_UNDEFID) { - int ndims = ncvar->ndims; + const int ndims = ncvar->ndims; int *dimtype = ncvar->dimtype; int vdimid = CDI_UNDEFID; struct addIfNewRes projAdded = { .Id = CDI_UNDEFID, .isNew = 0 }, gridAdded = { .Id = CDI_UNDEFID, .isNew = 0 }; int xdimid = CDI_UNDEFID, ydimid = CDI_UNDEFID; - int nydims = cdf_get_xydimid(ndims, ncvar->dimids, dimtype, &xdimid, &ydimid); + const int nydims = cdf_get_xydimid(ndims, ncvar->dimids, dimtype, &xdimid, &ydimid); int xaxisid = (xdimid != CDI_UNDEFID) ? ncdims[xdimid].ncvarid : CDI_UNDEFID; int yaxisid = (ydimid != CDI_UNDEFID) ? ncdims[ydimid].ncvarid : CDI_UNDEFID; - int xvarid = (ncvar->xvarid != CDI_UNDEFID) ? ncvar->xvarid : xaxisid; - int yvarid = (ncvar->yvarid != CDI_UNDEFID) ? ncvar->yvarid : yaxisid; + const int xvarid = (ncvar->xvarid != CDI_UNDEFID) ? ncvar->xvarid : xaxisid; + const int yvarid = (ncvar->yvarid != CDI_UNDEFID) ? ncvar->yvarid : yaxisid; size_t xsize = (xdimid != CDI_UNDEFID) ? ncdims[xdimid].len : 0; size_t ysize = (ydimid != CDI_UNDEFID) ? ncdims[ydimid].len : 0; @@ -2973,6 +2998,7 @@ cdf_define_all_grids(stream_t *streamptr, ncgrid_t *ncgrid, int vlistID, ncdim_t gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 1); ncvar->gridID = gridAdded.Id; + ncvar->gridSize = grid->size; const int gridID = ncvar->gridID; @@ -3196,6 +3222,7 @@ cdf_define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvar return CDI_EDIMSIZE; } + ncvar->numLevels = zsize; ncvar->zaxisID = varDefZaxis(vlistID, zaxisType, (int) zsize, zvar, (const char **) zcvals, zclength, with_bounds, lbounds, ubounds, (int) vctsize, vct, pname, plongname, punits, zdatatype, 1, 0, -1); @@ -3393,10 +3420,60 @@ cdf_define_institut_and_model_id(int vlistID, int varID) if (varTableID != CDI_UNDEFID) vlistDefVarTable(vlistID, varID, varTableID); } +static int +cdf_xtype_to_numbytes(int xtype) +{ + int numBytes = 8; + + // clang-format off + if (xtype == NC_BYTE ) numBytes = 1; + else if (xtype == NC_CHAR ) numBytes = 1; + else if (xtype == NC_SHORT ) numBytes = 2; + else if (xtype == NC_INT ) numBytes = 4; + else if (xtype == NC_FLOAT ) numBytes = 4; +#ifdef HAVE_NETCDF4 + else if (xtype == NC_UBYTE ) numBytes = 1; + else if (xtype == NC_LONG ) numBytes = 4; + else if (xtype == NC_USHORT) numBytes = 2; + else if (xtype == NC_UINT ) numBytes = 4; +#endif + // clang-format on + + return numBytes; +} + +static size_t +calc_chunk_cache_size(int timedimid, ncvar_t *ncvar) +{ + size_t chunkCacheSize = ncvar->gridSize; + + chunkCacheSize *= (ncvar->dimids[0] == timedimid) ? ncvar->chunks[0] : 1; + + int zdimid = CDI_UNDEFID; + for (int i = 0; i < ncvar->ndims; i++) + { + if (ncvar->dimtype[i] == Z_AXIS) zdimid = ncvar->dimids[i]; + } + if (zdimid != CDI_UNDEFID) chunkCacheSize *= ncvar->chunks[zdimid]; + + chunkCacheSize *= cdf_xtype_to_numbytes(ncvar->xtype); + + if (CDI_Chunk_Cache_Max > 0 && chunkCacheSize > CDI_Chunk_Cache_Max) chunkCacheSize = CDI_Chunk_Cache_Max; + + return chunkCacheSize; +} + +static void +cdf_set_var_chunk_cache(ncvar_t *ncvar, int ncvarid, size_t chunckCacheSize) +{ + if (CDI_Debug) Message("%s: chunckCacheSize=%zu", ncvar->name, chunckCacheSize); + nc_set_var_chunk_cache(ncvar->ncid, ncvarid, chunckCacheSize, ncvar->chunkCacheNelems, ncvar->chunkCachePreemption); +} + // define all input data variables static void cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, int nvars, int num_ncvars, ncvar_t *ncvars, - ncdim_t *ncdims) + ncdim_t *ncdims, int timedimid) { int *varids = (int *) Malloc((size_t) nvars * sizeof(int)); int n = 0; @@ -3421,7 +3498,17 @@ cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, i #ifdef HAVE_NETCDF4 if (ncvar->ldeflate) vlistDefVarCompType(vlistID, varID, CDI_COMPRESS_ZIP); if (ncvar->lszip) vlistDefVarCompType(vlistID, varID, CDI_COMPRESS_SZIP); - if (ncvar->chunked && ncvar->chunkType != CDI_UNDEFID) cdiDefKeyInt(vlistID, varID, CDI_KEY_CHUNKTYPE, ncvar->chunkType); + if (ncvar->chunked) + { + if (ncvar->chunkType != CDI_UNDEFID) cdiDefKeyInt(vlistID, varID, CDI_KEY_CHUNKTYPE, ncvar->chunkType); + if (ncvar->chunkSize > 1) cdiDefKeyInt(vlistID, varID, CDI_KEY_CHUNKSIZE, ncvar->chunkSize); + + const size_t varChunkCacheSize = calc_chunk_cache_size(timedimid, ncvar); + if (CDI_Chunk_Cache > 0) + cdf_set_var_chunk_cache(ncvar, ncvarid, CDI_Chunk_Cache); + else if (varChunkCacheSize > ncvar->chunkCacheSize) + cdf_set_var_chunk_cache(ncvar, ncvarid, varChunkCacheSize); + } #endif streamptr->vars[varID1].defmiss = false; @@ -3433,12 +3520,12 @@ cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, i if (ncvar->code != CDI_UNDEFID) vlistDefVarParam(vlistID, varID, cdiEncodeParam(ncvar->code, ncvar->tabnum, 255)); if (ncvar->longname[0]) cdiDefKeyString(vlistID, varID, CDI_KEY_LONGNAME, ncvar->longname); if (ncvar->stdname[0]) cdiDefKeyString(vlistID, varID, CDI_KEY_STDNAME, ncvar->stdname); - if (ncvar->units[0]) cdiDefKeyString(vlistID, varID, CDI_KEY_UNITS, ncvar->units); + if (ncvar->unitsLen > 0) cdiDefKeyString(vlistID, varID, CDI_KEY_UNITS, ncvar->units); if (ncvar->lvalidrange) vlistDefVarValidrange(vlistID, varID, ncvar->validrange); - if (IS_NOT_EQUAL(ncvar->addoffset, 0)) vlistDefVarAddoffset(vlistID, varID, ncvar->addoffset); - if (IS_NOT_EQUAL(ncvar->scalefactor, 1)) vlistDefVarScalefactor(vlistID, varID, ncvar->scalefactor); + if (IS_NOT_EQUAL(ncvar->addoffset, 0.0)) cdiDefKeyFloat(vlistID, varID, CDI_KEY_ADDOFFSET, ncvar->addoffset); + if (IS_NOT_EQUAL(ncvar->scalefactor, 1.0)) cdiDefKeyFloat(vlistID, varID, CDI_KEY_SCALEFACTOR, ncvar->scalefactor); vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(streamptr, ncvar->xtype, ncvar->lunsigned)); @@ -3505,7 +3592,7 @@ cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, i cdiDefKeyInt(vlistID, varID, CDI_KEY_PERTURBATIONNUMBER, ncvar->perturbationNumber); } - if (ncvar->extra[0] != 0) vlistDefVarExtra(vlistID, varID, ncvar->extra); + if (ncvar->extra[0] != 0) cdiDefKeyString(vlistID, varID, CDI_KEY_CHUNKS, ncvar->extra); } for (int varID = 0; varID < nvars; varID++) @@ -3769,7 +3856,7 @@ find_time_vars(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimid, strea if (timedimid == CDI_UNDEFID) { - char timeunits[CDI_MAX_NAME]; + char timeUnitsStr[CDI_MAX_NAME]; for (ncvarid = 0; ncvarid < nvars; ncvarid++) { @@ -3778,10 +3865,10 @@ find_time_vars(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimid, strea { if (ncvar->units[0]) { - strcpy(timeunits, ncvar->units); - strToLower(timeunits); + strcpy(timeUnitsStr, ncvar->units); + strToLower(timeUnitsStr); - if (is_time_units(timeunits)) + if (is_time_units(timeUnitsStr)) { streamptr->basetime.ncvarid = ncvarid; break; @@ -4068,7 +4155,6 @@ cdfVerifyVars(int nvars, ncvar_t *ncvars, ncdim_t *ncdims) int cdfInqContents(stream_t *streamptr) { - int ndims, nvars, ngatts, unlimdimid; bool time_has_units = false; bool time_has_bounds = false; bool time_climatology = false; @@ -4092,6 +4178,7 @@ cdfInqContents(stream_t *streamptr) nc_inq_format(fileID, &format); #endif + int ndims, nvars, ngatts, unlimdimid; cdf_inq(fileID, &ndims, &nvars, &ngatts, &unlimdimid); if (CDI_Debug) Message("root: ndims %d, nvars %d, ngatts %d", ndims, nvars, ngatts); @@ -4353,7 +4440,7 @@ cdfInqContents(stream_t *streamptr) streamptr->ntsteps = (long) ntsteps; // define all data variables - cdf_define_all_vars(streamptr, vlistID, instID, modelID, nvars_data, nvars, ncvars, ncdims); + cdf_define_all_vars(streamptr, vlistID, instID, modelID, nvars_data, nvars, ncvars, ncdims, timedimid); cdiCreateTimesteps(streamptr); @@ -4367,7 +4454,7 @@ cdfInqContents(stream_t *streamptr) { taxis_t *taxis = &streamptr->tsteps[0].taxis; - if (setBaseTime(ncvars[nctimevarid].units, taxis) == 1) + if (set_base_time(ncvars[nctimevarid].units, taxis) == 1) { nctimevarid = CDI_UNDEFID; streamptr->basetime.ncvarid = CDI_UNDEFID; @@ -4384,7 +4471,7 @@ cdfInqContents(stream_t *streamptr) if (timeunit == -1) timeunit = taxis->unit; taxis->fc_unit = timeunit; - setForecastTime(fcreftime, taxis); + set_forecast_time(fcreftime, taxis); } } @@ -4561,21 +4648,14 @@ cdfInqTimestep(stream_t *streamptr, int tsID) const int nctimeboundsid = streamptr->basetime.ncvarboundsid; if (nctimeboundsid != CDI_UNDEFID) { - { - const size_t start[2] = { tsID, 1 }, count[2] = { 0, 1 }; - cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue); - if (timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE) timevalue = 0.0; - - taxis->vdatetime_lb = cdi_decode_timeval(timevalue, taxis); - } + double values[2]; + const size_t start[2] = { tsID, 0 }, count[2] = { 1, 2 }; + cdf_get_vara_double(fileID, nctimeboundsid, start, count, values); + if (values[0] >= NC_FILL_DOUBLE || values[0] < -NC_FILL_DOUBLE) values[0] = 0.0; + if (values[1] >= NC_FILL_DOUBLE || values[1] < -NC_FILL_DOUBLE) values[1] = 0.0; - { - const size_t start[2] = { tsID, 1 }, count[2] = { 1, 1 }; - cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue); - if (timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE) timevalue = 0.0; - - taxis->vdatetime_ub = cdi_decode_timeval(timevalue, taxis); - } + taxis->vdatetime_lb = cdi_decode_timeval(values[0], taxis); + taxis->vdatetime_ub = cdi_decode_timeval(values[1], taxis); } const int leadtimeid = streamptr->basetime.leadtimeid; diff --git a/src/stream_cdf_o.c b/src/stream_cdf_o.c index 0ffe3cad07ff2039df8bdf1034b1a7530f109460..18c7cdb3820d9819d475238171d749aac60ac98c 100644 --- a/src/stream_cdf_o.c +++ b/src/stream_cdf_o.c @@ -62,45 +62,45 @@ cdfDefTimestep(stream_t *streamptr, int tsID) cdfEndDef(streamptr); } - double timevalue = cdi_encode_timeval(taxis->vdatetime, &streamptr->tsteps[0].taxis); - if (CDI_Debug) Message("tsID = %d timevalue = %f", tsID, timevalue); + double timeValue = cdi_encode_timeval(taxis->vdatetime, &streamptr->tsteps[0].taxis); + if (CDI_Debug) Message("tsID = %d timeValue = %f", tsID, timeValue); int ncvarid = streamptr->basetime.ncvarid; size_t index = (size_t) tsID; - cdf_put_var1_double(fileID, ncvarid, &index, &timevalue); + cdf_put_var1_double(fileID, ncvarid, &index, &timeValue); if (taxis->has_bounds) { ncvarid = streamptr->basetime.ncvarboundsid; if (ncvarid == CDI_UNDEFID) Error("Call to taxisWithBounds() missing!"); - timevalue = cdi_encode_timeval(taxis->vdatetime_lb, &streamptr->tsteps[0].taxis); + timeValue = cdi_encode_timeval(taxis->vdatetime_lb, &streamptr->tsteps[0].taxis); size_t start[2] = { tsID, 0 }, count[2] = { 1, 1 }; - cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue); + cdf_put_vara_double(fileID, ncvarid, start, count, &timeValue); - timevalue = cdi_encode_timeval(taxis->vdatetime_ub, &streamptr->tsteps[0].taxis); + timeValue = cdi_encode_timeval(taxis->vdatetime_ub, &streamptr->tsteps[0].taxis); start[0] = (size_t) tsID; count[0] = 1; start[1] = 1; count[1] = 1; - cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue); + cdf_put_vara_double(fileID, ncvarid, start, count, &timeValue); } ncvarid = streamptr->basetime.leadtimeid; if (taxis->type == TAXIS_FORECAST && ncvarid != CDI_UNDEFID) { - timevalue = taxis->fc_period; - cdf_put_var1_double(fileID, ncvarid, &index, &timevalue); + timeValue = taxis->fc_period; + cdf_put_var1_double(fileID, ncvarid, &index, &timeValue); } } static void -cdfDefComplex(stream_t *streamptr, int gridID, int gridindex) +cdfDefComplex(stream_t *streamptr, int gridID, int gridIndex) { int dimID; ncgrid_t *ncgrid = streamptr->ncgrid; - for (int index = 0; index < gridindex; ++index) + for (int index = 0; index < gridIndex; ++index) { if (ncgrid[index].ncIDs[CDF_DIMID_X] != CDI_UNDEFID) { @@ -124,9 +124,10 @@ cdfDefComplex(stream_t *streamptr, int gridID, int gridindex) cdf_enddef(fileID); streamptr->ncmode = 2; } + dimIDEstablished: - ncgrid[gridindex].gridID = gridID; - ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID; + ncgrid[gridIndex].gridID = gridID; + ncgrid[gridIndex].ncIDs[CDF_DIMID_X] = dimID; } struct idSearch @@ -169,14 +170,14 @@ cdfGridInqHalfSize(int gridID) } static void -cdfDefSPorFC(stream_t *streamptr, int gridID, int gridindex, char *restrict axisname, int gridRefType) +cdfDefSPorFC(stream_t *streamptr, int gridID, int gridIndex, char *restrict axisname, int gridRefType) { ncgrid_t *ncgrid = streamptr->ncgrid; const size_t dimlen = gridInqSize(gridID) / 2; struct idSearch search - = cdfSearchIDBySize(0, (size_t) gridindex, ncgrid, CDF_DIMID_Y, gridRefType, (int) dimlen, gridInqType, cdfGridInqHalfSize); + = cdfSearchIDBySize(0, (size_t) gridIndex, ncgrid, CDF_DIMID_Y, gridRefType, (int) dimlen, gridInqType, cdfGridInqHalfSize); int dimID = search.foundID; const int iz = search.numNonMatching; @@ -196,23 +197,23 @@ cdfDefSPorFC(stream_t *streamptr, int gridID, int gridindex, char *restrict axis streamptr->ncmode = 2; } - ncgrid[gridindex].gridID = gridID; - ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = dimID; + ncgrid[gridIndex].gridID = gridID; + ncgrid[gridIndex].ncIDs[CDF_DIMID_Y] = dimID; } static void -cdfDefSP(stream_t *streamptr, int gridID, int gridindex) +cdfDefSP(stream_t *streamptr, int gridID, int gridIndex) { // char longname[] = "Spherical harmonic coefficient"; char axisname[5] = "nspX"; - cdfDefSPorFC(streamptr, gridID, gridindex, axisname, GRID_SPECTRAL); + cdfDefSPorFC(streamptr, gridID, gridIndex, axisname, GRID_SPECTRAL); } static void -cdfDefFC(stream_t *streamptr, int gridID, int gridindex) +cdfDefFC(stream_t *streamptr, int gridID, int gridIndex) { char axisname[5] = "nfcX"; - cdfDefSPorFC(streamptr, gridID, gridindex, axisname, GRID_FOURIER); + cdfDefSPorFC(streamptr, gridID, gridIndex, axisname, GRID_FOURIER); } static const struct cdfDefGridAxisInqs @@ -273,7 +274,7 @@ grid_inq_xtype(int gridID) } static void -cdfDefTrajLatLon(stream_t *streamptr, int gridID, int gridindex, const struct cdfDefGridAxisInqs *inqs) +cdfDefTrajLatLon(stream_t *streamptr, int gridID, int gridIndex, const struct cdfDefGridAxisInqs *inqs) { const nc_type xtype = grid_inq_xtype(gridID); ncgrid_t *ncgrid = streamptr->ncgrid; @@ -281,7 +282,7 @@ cdfDefTrajLatLon(stream_t *streamptr, int gridID, int gridindex, const struct cd const size_t dimlen = inqs->axisSize(gridID); if (dimlen != 1) Error("%c size isn't 1 for %s grid!", inqs->axisSym, gridNamePtr(gridInqType(gridID))); - int ncvarid = ncgrid[gridindex].ncIDs[inqs->dimIdx]; + int ncvarid = ncgrid[gridIndex].ncIDs[inqs->dimIdx]; if (ncvarid == CDI_UNDEFID) { int dimNcID = streamptr->basetime.ncvarid; @@ -298,21 +299,21 @@ cdfDefTrajLatLon(stream_t *streamptr, int gridID, int gridindex, const struct cd streamptr->ncmode = 2; } - ncgrid[gridindex].gridID = gridID; + ncgrid[gridIndex].gridID = gridID; // var ID for trajectory !!! - ncgrid[gridindex].ncIDs[inqs->dimIdx] = ncvarid; + ncgrid[gridIndex].ncIDs[inqs->dimIdx] = ncvarid; } static void -cdfDefTrajLon(stream_t *streamptr, int gridID, int gridindex) +cdfDefTrajLon(stream_t *streamptr, int gridID, int gridIndex) { - cdfDefTrajLatLon(streamptr, gridID, gridindex, &gridInqsX); + cdfDefTrajLatLon(streamptr, gridID, gridIndex, &gridInqsX); } static void -cdfDefTrajLat(stream_t *streamptr, int gridID, int gridindex) +cdfDefTrajLat(stream_t *streamptr, int gridID, int gridIndex) { - cdfDefTrajLatLon(streamptr, gridID, gridindex, &gridInqsY); + cdfDefTrajLatLon(streamptr, gridID, gridIndex, &gridInqsY); } static int @@ -418,7 +419,19 @@ checkZaxisName(char *axisname, int fileID, int vlistID, int zaxisID, int nzaxis) } static void -cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims, bool addVarToGrid, +cdfGridCompress(int fileID, int ncvarid, size_t gridsize, int filetype, int comptype, size_t *chunks) +{ +#ifdef HAVE_NETCDF4 + if (gridsize >= 32 && comptype == CDI_COMPRESS_ZIP && (filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C || filetype == CDI_FILETYPE_NCZARR)) + { + cdf_def_var_chunking(fileID, ncvarid, NC_CHUNKED, chunks); + cdfDefVarDeflate(fileID, ncvarid, 1); + } +#endif +} + +static void +cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridIndex, int ndims, bool addVarToGrid, const struct cdfDefGridAxisInqs *gridAxisInq, int axisKey, char axisLetter, void (*finishCyclicBounds)(double *pbounds, size_t dimlen, const double *pvals)) { @@ -435,7 +448,7 @@ cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims, bool int length = sizeof(dimname); if (ndims && pvals == NULL) cdiInqKeyString(gridID, axisKey, CDI_KEY_DIMNAME, dimname, &length); - for (int index = 0; index < gridindex; ++index) + for (int index = 0; index < gridIndex; ++index) { const int gridID0 = ncgrid[index].gridID; assert(gridID0 != CDI_UNDEFID); @@ -454,7 +467,7 @@ cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims, bool if (IS_EQUAL(inqVal(gridID0, 0), inqVal(gridID, 0)) && IS_EQUAL(inqVal(gridID0, dimlen - 1), inqVal(gridID, dimlen - 1))) { - dimID = ncgrid[index].ncIDs[axisLetter == 'X' ? CDF_DIMID_X : CDF_DIMID_Y]; + dimID = ncgrid[index].ncIDs[(axisLetter == 'X') ? CDF_DIMID_X : CDF_DIMID_Y]; break; } } @@ -489,6 +502,17 @@ cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims, bool { cdf_def_var(fileID, axisname, xtype, ndims, &dimID, &ncvarid); + int chunkSize = 0; + int chunkType = CDI_CHUNK_GRID; + cdiInqKeyInt(gridID, CDI_GLOBAL, CDI_KEY_CHUNKTYPE, &chunkType); + cdiInqKeyInt(gridID, CDI_GLOBAL, CDI_KEY_CHUNKSIZE, &chunkSize); + if (chunkSize > 0) chunkType = CDI_CHUNK_AUTO; + + if (chunkType == CDI_CHUNK_GRID && dimlen > ChunkSizeLim) chunkType = CDI_CHUNK_LINES; + + size_t chunk = calc_chunksize_x(chunkType, chunkSize, dimlen, true); + cdfGridCompress(fileID, ncvarid, dimlen, streamptr->filetype, streamptr->comptype, &chunk); + cdfPutGridStdAtts(fileID, ncvarid, gridID, axisLetter); { char axisStr[2] = { axisLetter, '\0' }; @@ -535,11 +559,11 @@ cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims, bool if (ncbvarid != CDI_UNDEFID) cdf_put_var_double(fileID, ncbvarid, pbounds); if (gen_bounds) Free(pbounds); - if (ndims == 0 || addVarToGrid) ncgrid[gridindex].ncIDs[axisLetter == 'X' ? CDF_VARID_X : CDF_VARID_Y] = ncvarid; + if (ndims == 0 || addVarToGrid) ncgrid[gridIndex].ncIDs[(axisLetter == 'X') ? CDF_VARID_X : CDF_VARID_Y] = ncvarid; } - ncgrid[gridindex].gridID = gridID; - ncgrid[gridindex].ncIDs[axisLetter == 'X' ? CDF_DIMID_X : CDF_DIMID_Y] = dimID; + ncgrid[gridIndex].gridID = gridID; + ncgrid[gridIndex].ncIDs[(axisLetter == 'X') ? CDF_DIMID_X : CDF_DIMID_Y] = dimID; } static void @@ -557,27 +581,15 @@ finishCyclicYBounds(double *pbounds, size_t dimlen, const double *pvals) } static void -cdfDefXaxis(stream_t *streamptr, int gridID, int gridindex, int ndims, bool addVarToGrid) +cdfDefXaxis(stream_t *streamptr, int gridID, int gridIndex, int ndims, bool addVarToGrid) { - cdfDefAxisCommon(streamptr, gridID, gridindex, ndims, addVarToGrid, &gridInqsX, CDI_XAXIS, 'X', finishCyclicXBounds); + cdfDefAxisCommon(streamptr, gridID, gridIndex, ndims, addVarToGrid, &gridInqsX, CDI_XAXIS, 'X', finishCyclicXBounds); } static void -cdfDefYaxis(stream_t *streamptr, int gridID, int gridindex, int ndims, bool addVarToGrid) -{ - cdfDefAxisCommon(streamptr, gridID, gridindex, ndims, addVarToGrid, &gridInqsY, CDI_YAXIS, 'Y', finishCyclicYBounds); -} - -static void -cdfGridCompress(int fileID, int ncvarid, size_t gridsize, int filetype, int comptype, size_t *chunks) +cdfDefYaxis(stream_t *streamptr, int gridID, int gridIndex, int ndims, bool addVarToGrid) { -#ifdef HAVE_NETCDF4 - if (gridsize > 1 && comptype == CDI_COMPRESS_ZIP && (filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C)) - { - cdf_def_var_chunking(fileID, ncvarid, NC_CHUNKED, chunks); - cdfDefVarDeflate(fileID, ncvarid, 1); - } -#endif + cdfDefAxisCommon(streamptr, gridID, gridIndex, ndims, addVarToGrid, &gridInqsY, CDI_YAXIS, 'Y', finishCyclicYBounds); } static void @@ -687,7 +699,7 @@ cdfDefIrregularGridCommon(stream_t *streamptr, int gridID, size_t xsize, size_t dimIDs[0] = ydimID; dimIDs[1] = xdimID; } - else /* ndims == 2 */ + else // ndims == 2 { chunks[0] = calc_chunksize_x(chunkType, chunkSize, xsize, (ydimID == CDI_UNDEFID)); dimIDs[0] = xdimID; @@ -708,7 +720,7 @@ cdfDefIrregularGridCommon(stream_t *streamptr, int gridID, size_t xsize, size_t cdfPutGridStdAtts(fileID, ncxvarid, gridID, 'X'); // attribute for Panoply - if (ndims == 3) cdf_put_att_text(fileID, ncxvarid, "_CoordinateAxisType", 3, "Lon"); + if (!CDI_CMOR_Mode && ndims == 3) cdf_put_att_text(fileID, ncxvarid, "_CoordinateAxisType", 3, "Lon"); if ((xboundsPtr = gridInqXboundsPtr(gridID)) && nvdimID != CDI_UNDEFID) { @@ -735,7 +747,7 @@ cdfDefIrregularGridCommon(stream_t *streamptr, int gridID, size_t xsize, size_t cdfPutGridStdAtts(fileID, ncyvarid, gridID, 'Y'); // attribute for Panoply - if (ndims == 3) cdf_put_att_text(fileID, ncyvarid, "_CoordinateAxisType", 3, "Lat"); + if (!CDI_CMOR_Mode && ndims == 3) cdf_put_att_text(fileID, ncyvarid, "_CoordinateAxisType", 3, "Lat"); if ((yboundsPtr = gridInqYboundsPtr(gridID)) && nvdimID != CDI_UNDEFID) { @@ -779,7 +791,7 @@ cdfDefIrregularGridCommon(stream_t *streamptr, int gridID, size_t xsize, size_t } static void -cdfDefCurvilinear(stream_t *streamptr, int gridID, int gridindex) +cdfDefCurvilinear(stream_t *streamptr, int gridID, int gridIndex) { ncgrid_t *ncgrid = streamptr->ncgrid; @@ -793,7 +805,7 @@ cdfDefCurvilinear(stream_t *streamptr, int gridID, int gridindex) size_t ofs = 0; do { - struct idSearch search = cdfSearchIDBySize(ofs, (size_t) gridindex, ncgrid, CDF_DIMID_X, GRID_CURVILINEAR, (int) dimlen, + struct idSearch search = cdfSearchIDBySize(ofs, (size_t) gridIndex, ncgrid, CDF_DIMID_X, GRID_CURVILINEAR, (int) dimlen, gridInqType, gridInqSize); const size_t index = search.foundIdx; if (index != SIZE_MAX) @@ -811,7 +823,7 @@ cdfDefCurvilinear(stream_t *streamptr, int gridID, int gridindex) break; } ofs = search.foundIdx; - if (ofs < (size_t) gridindex) continue; + if (ofs < (size_t) gridIndex) continue; } } while (false); @@ -827,16 +839,16 @@ cdfDefCurvilinear(stream_t *streamptr, int gridID, int gridindex) ncavarid = createdIDs.ncavarid; } - ncgrid[gridindex].gridID = gridID; - ncgrid[gridindex].ncIDs[CDF_DIMID_X] = xdimID; - ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = ydimID; - ncgrid[gridindex].ncIDs[CDF_VARID_X] = ncxvarid; - ncgrid[gridindex].ncIDs[CDF_VARID_Y] = ncyvarid; - ncgrid[gridindex].ncIDs[CDF_VARID_A] = ncavarid; + ncgrid[gridIndex].gridID = gridID; + ncgrid[gridIndex].ncIDs[CDF_DIMID_X] = xdimID; + ncgrid[gridIndex].ncIDs[CDF_DIMID_Y] = ydimID; + ncgrid[gridIndex].ncIDs[CDF_VARID_X] = ncxvarid; + ncgrid[gridIndex].ncIDs[CDF_VARID_Y] = ncyvarid; + ncgrid[gridIndex].ncIDs[CDF_VARID_A] = ncavarid; } static void -cdfDefUnstructured(stream_t *streamptr, int gridID, int gridindex) +cdfDefUnstructured(stream_t *streamptr, int gridID, int gridIndex) { ncgrid_t *ncgrid = streamptr->ncgrid; @@ -848,7 +860,7 @@ cdfDefUnstructured(stream_t *streamptr, int gridID, int gridindex) size_t ofs = 0; do { - struct idSearch search = cdfSearchIDBySize(ofs, (size_t) gridindex, ncgrid, CDF_DIMID_X, GRID_UNSTRUCTURED, (int) dimlen, + struct idSearch search = cdfSearchIDBySize(ofs, (size_t) gridIndex, ncgrid, CDF_DIMID_X, GRID_UNSTRUCTURED, (int) dimlen, gridInqType, gridInqSize); const size_t index = search.foundIdx; if (index != SIZE_MAX) @@ -866,7 +878,7 @@ cdfDefUnstructured(stream_t *streamptr, int gridID, int gridindex) break; } ofs = search.foundIdx; - if (ofs < (size_t) gridindex) continue; + if (ofs < (size_t) gridIndex) continue; } } while (false); @@ -882,11 +894,11 @@ cdfDefUnstructured(stream_t *streamptr, int gridID, int gridindex) ncavarid = createdIDs.ncavarid; } - ncgrid[gridindex].gridID = gridID; - ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID; - ncgrid[gridindex].ncIDs[CDF_VARID_X] = ncxvarid; - ncgrid[gridindex].ncIDs[CDF_VARID_Y] = ncyvarid; - ncgrid[gridindex].ncIDs[CDF_VARID_A] = ncavarid; + ncgrid[gridIndex].gridID = gridID; + ncgrid[gridIndex].ncIDs[CDF_DIMID_X] = dimID; + ncgrid[gridIndex].ncIDs[CDF_VARID_X] = ncxvarid; + ncgrid[gridIndex].ncIDs[CDF_VARID_Y] = ncyvarid; + ncgrid[gridIndex].ncIDs[CDF_VARID_A] = ncavarid; } struct attTxtTab2 @@ -1224,9 +1236,9 @@ cdf_def_zaxis_hybrid_cf(stream_t *streamptr, int type, int *ncvaridp, int zaxisI size_t len = 0; char txt[CDI_MAX_NAME]; if (p0status == 0) - len = (size_t) (sprintf(txt, "%s%s %s%s", "a: a b: b p0: ", p0name, "ps: ", psname)); + len = (size_t) (snprintf(txt, sizeof(txt), "%s%s %s%s", "a: a b: b p0: ", p0name, "ps: ", psname)); else - len = (size_t) (sprintf(txt, "%s%s", "ap: ap b: b ps: ", psname)); + len = (size_t) (snprintf(txt, sizeof(txt), "%s%s", "ap: ap b: b ps: ", psname)); cdf_put_att_text(fileID, ncvarid, "formula_terms", len, txt); int ncbvarid = CDI_UNDEFID; @@ -1282,9 +1294,9 @@ cdf_def_zaxis_hybrid_cf(stream_t *streamptr, int type, int *ncvaridp, int zaxisI } if (p0status == 0) - len = (size_t) (sprintf(txt, "%s%s %s%s", "a: a_bnds b: b_bnds p0: ", p0name, "ps: ", psname)); + len = (size_t) (snprintf(txt, sizeof(txt), "%s%s %s%s", "a: a_bnds b: b_bnds p0: ", p0name, "ps: ", psname)); else - len = (size_t) (sprintf(txt, "%s%s", "ap: ap_bnds b: b_bnds ps: ", psname)); + len = (size_t) (snprintf(txt, sizeof(txt), "%s%s", "ap: ap_bnds b: b_bnds ps: ", psname)); cdf_put_att_text(fileID, ncbvarid, "formula_terms", len, txt); } } @@ -1621,18 +1633,18 @@ cdf_def_mapping(stream_t *streamptr, int gridID) } static void -cdfDefCharacter(stream_t *streamptr, int gridID, int gridindex, int cdiAxisID, int strlen) +cdfDefCharacter(stream_t *streamptr, int gridID, int gridIndex, int cdiAxisID, int strlen) { - if (streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X] != CDI_UNDEFID) return; + if (streamptr->ncgrid[gridIndex].ncIDs[CDF_DIMID_X] != CDI_UNDEFID) return; const bool isXaxis = (cdiAxisID == CDI_XAXIS); const size_t dimlen = isXaxis ? gridInqXsize(gridID) : gridInqYsize(gridID); ncgrid_t *ncgrid = streamptr->ncgrid; - // Check for all grids up to gridindex whether it already is defined + // Check for all grids up to gridIndex whether it already is defined - for (int index = 0; index < gridindex; index++) + for (int index = 0; index < gridIndex; index++) { const int gridID0 = ncgrid[index].gridID; const int gridtype0 = gridInqType(gridID0); @@ -1702,24 +1714,24 @@ cdfDefCharacter(stream_t *streamptr, int gridID, int gridindex, int cdiAxisID, i status = nc_put_vara_text(fileID, ncaxisid, start, count, cvals[i]); } - ncgrid[gridindex].gridID = gridID; - ncgrid[gridindex].ncIDs[isXaxis ? CDF_DIMID_X : CDF_DIMID_Y] = dimID; - ncgrid[gridindex].ncIDs[isXaxis ? CDF_VARID_X : CDF_VARID_Y] = ncaxisid; + ncgrid[gridIndex].gridID = gridID; + ncgrid[gridIndex].ncIDs[isXaxis ? CDF_DIMID_X : CDF_DIMID_Y] = dimID; + ncgrid[gridIndex].ncIDs[isXaxis ? CDF_VARID_X : CDF_VARID_Y] = ncaxisid; streamptr->ncmode = 2; } static void -cdfDefRgrid(stream_t *streamptr, int gridID, int gridindex) +cdfDefRgrid(stream_t *streamptr, int gridID, int gridIndex) { ncgrid_t *ncgrid = streamptr->ncgrid; - ncgrid[gridindex].gridID = gridID; + ncgrid[gridIndex].gridID = gridID; { const size_t dimlen = gridInqSize(gridID); - struct idSearch search = cdfSearchIDBySize(0, (size_t) gridindex, ncgrid, CDF_DIMID_X, GRID_GAUSSIAN_REDUCED, (int) dimlen, + struct idSearch search = cdfSearchIDBySize(0, (size_t) gridIndex, ncgrid, CDF_DIMID_X, GRID_GAUSSIAN_REDUCED, (int) dimlen, gridInqType, gridInqSize); const int iz = search.numNonMatching; int dimID = search.foundID; @@ -1742,13 +1754,13 @@ cdfDefRgrid(stream_t *streamptr, int gridID, int gridindex) streamptr->ncmode = 2; } - ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID; + ncgrid[gridIndex].ncIDs[CDF_DIMID_X] = dimID; } { const size_t dimlen = gridInqYsize(gridID); - struct idSearch search = cdfSearchIDBySize(0, (size_t) gridindex, ncgrid, CDF_DIMID_RP, GRID_GAUSSIAN_REDUCED, (int) dimlen, + struct idSearch search = cdfSearchIDBySize(0, (size_t) gridIndex, ncgrid, CDF_DIMID_RP, GRID_GAUSSIAN_REDUCED, (int) dimlen, gridInqType, gridInqSize); const int iz = search.numNonMatching; int dimID = search.foundID; @@ -1761,7 +1773,7 @@ cdfDefRgrid(stream_t *streamptr, int gridID, int gridindex) if (iz == 0) axisname[14] = '\0'; else - sprintf(&axisname[5], "%1d", iz + 1); + sprintf(&axisname[14], "%1d", iz + 1); if (streamptr->ncmode == 2) cdf_redef(fileID); @@ -1781,15 +1793,15 @@ cdfDefRgrid(stream_t *streamptr, int gridID, int gridindex) cdf_put_var_int(fileID, ncvarid, reducedPoints); Free(reducedPoints); - ncgrid[gridindex].ncIDs[CDF_VARID_RP] = ncvarid; + ncgrid[gridIndex].ncIDs[CDF_VARID_RP] = ncvarid; } - ncgrid[gridindex].ncIDs[CDF_DIMID_RP] = dimID; + ncgrid[gridIndex].ncIDs[CDF_DIMID_RP] = dimID; } } static void -cdfDefGdim(stream_t *streamptr, int gridID, int gridindex) +cdfDefGdim(stream_t *streamptr, int gridID, int gridIndex) { ncgrid_t *ncgrid = streamptr->ncgrid; int dimID = CDI_UNDEFID; @@ -1799,14 +1811,14 @@ cdfDefGdim(stream_t *streamptr, int gridID, int gridindex) if (gridInqYsize(gridID) == 0) { struct idSearch search - = cdfSearchIDBySize(0, (size_t) gridindex, ncgrid, CDF_DIMID_X, GRID_GENERIC, (int) dimlen, gridInqType, gridInqSize); + = cdfSearchIDBySize(0, (size_t) gridIndex, ncgrid, CDF_DIMID_X, GRID_GENERIC, (int) dimlen, gridInqType, gridInqSize); dimID = search.foundID; } if (gridInqXsize(gridID) == 0) { struct idSearch search - = cdfSearchIDBySize(0, (size_t) gridindex, ncgrid, CDF_DIMID_Y, GRID_GENERIC, (int) dimlen, gridInqType, gridInqSize); + = cdfSearchIDBySize(0, (size_t) gridIndex, ncgrid, CDF_DIMID_Y, GRID_GENERIC, (int) dimlen, gridInqType, gridInqSize); dimID = search.foundID; } @@ -1826,14 +1838,14 @@ cdfDefGdim(stream_t *streamptr, int gridID, int gridindex) streamptr->ncmode = 2; } - ncgrid[gridindex].gridID = gridID; - ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID; + ncgrid[gridIndex].gridID = gridID; + ncgrid[gridIndex].ncIDs[CDF_DIMID_X] = dimID; } static void -cdfDefGrid(stream_t *streamptr, int gridID, int gridindex) +cdfDefGrid(stream_t *streamptr, int gridID, int gridIndex) { - if (streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X] != CDI_UNDEFID) return; + if (streamptr->ncgrid[gridIndex].ncIDs[CDF_DIMID_X] != CDI_UNDEFID) return; const int gridtype = gridInqType(gridID); const size_t size = gridInqSize(gridID); @@ -1842,87 +1854,79 @@ cdfDefGrid(stream_t *streamptr, int gridID, int gridindex) if (CDI_Reduce_Dim && size == 1) // no grid information { - streamptr->ncgrid[gridindex].gridID = gridID; + streamptr->ncgrid[gridIndex].gridID = gridID; return; } - if (gridtype == GRID_GAUSSIAN || gridtype == GRID_LONLAT || gridtype == GRID_PROJECTION || gridtype == GRID_GENERIC) + if (gridtype == GRID_GAUSSIAN || gridtype == GRID_LONLAT || gridtype == GRID_PROJECTION) { - if (gridtype == GRID_GENERIC) - { - if (size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0) - { - // no grid information - streamptr->ncgrid[gridindex].gridID = gridID; - } - else - { - bool lx = false, ly = false; - if (gridInqXsize(gridID) /*&& gridInqXvals(gridID, NULL) */) - { - cdfDefXaxis(streamptr, gridID, gridindex, 1, false); - lx = true; - } + const int ndims = !(gridtype == GRID_LONLAT && size == 1 && !gridInqHasDims(gridID)); + const size_t xsize = gridInqXsize(gridID); + const size_t ysize = gridInqYsize(gridID); - if (gridInqYsize(gridID) /*&& gridInqYvals(gridID, NULL) */) - { - cdfDefYaxis(streamptr, gridID, gridindex, 1, false); - ly = true; - } + if (xsize) cdfDefXaxis(streamptr, gridID, gridIndex, ndims, false); + if (ysize) cdfDefYaxis(streamptr, gridID, gridIndex, ndims, false); + if (ndims == 1 && xsize == 0 && ysize == 0 && gridtype == GRID_PROJECTION) cdfDefGdim(streamptr, gridID, gridIndex); - if (!lx && !ly) cdfDefGdim(streamptr, gridID, gridindex); - } + cdf_def_mapping(streamptr, gridID); + } + else if (gridtype == GRID_GENERIC) + { + if (size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0) + { + // no grid information + streamptr->ncgrid[gridIndex].gridID = gridID; } else { - const int ndims = !(gridtype == GRID_LONLAT && size == 1 && !gridInqHasDims(gridID)); - - if (gridInqXsize(gridID)) cdfDefXaxis(streamptr, gridID, gridindex, ndims, false); - if (gridInqYsize(gridID)) cdfDefYaxis(streamptr, gridID, gridindex, ndims, false); + const size_t xsize = gridInqXsize(gridID); + const size_t ysize = gridInqYsize(gridID); - cdf_def_mapping(streamptr, gridID); + if (xsize) cdfDefXaxis(streamptr, gridID, gridIndex, 1, false); + if (ysize) cdfDefYaxis(streamptr, gridID, gridIndex, 1, false); + if (xsize == 0 && ysize == 0) cdfDefGdim(streamptr, gridID, gridIndex); } } else if (gridtype == GRID_CURVILINEAR) { - cdfDefCurvilinear(streamptr, gridID, gridindex); + cdfDefCurvilinear(streamptr, gridID, gridIndex); } else if (gridtype == GRID_UNSTRUCTURED) { - cdfDefUnstructured(streamptr, gridID, gridindex); + cdfDefUnstructured(streamptr, gridID, gridIndex); } else if (gridtype == GRID_GAUSSIAN_REDUCED) { - cdfDefRgrid(streamptr, gridID, gridindex); - if (gridInqYsize(gridID)) cdfDefYaxis(streamptr, gridID, gridindex, 1, true); + cdfDefRgrid(streamptr, gridID, gridIndex); + if (gridInqYsize(gridID)) cdfDefYaxis(streamptr, gridID, gridIndex, 1, true); } else if (gridtype == GRID_SPECTRAL) { - cdfDefComplex(streamptr, gridID, gridindex); - cdfDefSP(streamptr, gridID, gridindex); + cdfDefComplex(streamptr, gridID, gridIndex); + cdfDefSP(streamptr, gridID, gridIndex); } else if (gridtype == GRID_FOURIER) { - cdfDefComplex(streamptr, gridID, gridindex); - cdfDefFC(streamptr, gridID, gridindex); + cdfDefComplex(streamptr, gridID, gridIndex); + cdfDefFC(streamptr, gridID, gridIndex); } else if (gridtype == GRID_TRAJECTORY) { - cdfDefTrajLon(streamptr, gridID, gridindex); - cdfDefTrajLat(streamptr, gridID, gridindex); + cdfDefTrajLon(streamptr, gridID, gridIndex); + cdfDefTrajLat(streamptr, gridID, gridIndex); } else if (gridtype == GRID_CHARXY) { int strlen = 0; if ((strlen = gridInqXIsc(gridID))) - cdfDefCharacter(streamptr, gridID, gridindex, CDI_XAXIS, strlen); + cdfDefCharacter(streamptr, gridID, gridIndex, CDI_XAXIS, strlen); else if (gridInqXsize(gridID)) - cdfDefXaxis(streamptr, gridID, gridindex, 1, false); + cdfDefXaxis(streamptr, gridID, gridIndex, 1, false); if ((strlen = gridInqYIsc(gridID))) - cdfDefCharacter(streamptr, gridID, gridindex, CDI_YAXIS, strlen); + cdfDefCharacter(streamptr, gridID, gridIndex, CDI_YAXIS, strlen); else if (gridInqYsize(gridID)) - cdfDefYaxis(streamptr, gridID, gridindex, 1, false); + cdfDefYaxis(streamptr, gridID, gridIndex, 1, false); } else { diff --git a/src/stream_cdf_time.c b/src/stream_cdf_time.c index e3c6e6927472f6e93f877d471654583515ca9b8d..c7828d8f70b77d164febbec7bc06e8dc2ff7abdf 100644 --- a/src/stream_cdf_time.c +++ b/src/stream_cdf_time.c @@ -185,8 +185,7 @@ cdfDefTime(stream_t *streamptr) if (taxis->longname && taxis->longname[0]) cdf_put_att_text(fileID, timeVarId, "long_name", strlen(taxis->longname), taxis->longname); - if (taxis->has_bounds) - streamptr->basetime.ncvarboundsid = cdfDefTimeBounds(fileID, timeVarId, timeDimId, taxisName, taxis); + if (taxis->has_bounds) streamptr->basetime.ncvarboundsid = cdfDefTimeBounds(fileID, timeVarId, timeDimId, taxisName, taxis); char unitsStr[CDI_MAX_NAME]; cdfDefTimeUnits(unitsStr, taxis); diff --git a/src/stream_ext.c b/src/stream_ext.c index b3e2c91951fc816867f61c1289f3c534fe4c2d5c..e0b7c26f662e5a656f8e65f51751ba4ad6367079 100644 --- a/src/stream_ext.c +++ b/src/stream_ext.c @@ -606,7 +606,7 @@ extWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis); int header[4]; - header[0] = (int)cdiDate_get(streamptr->tsteps[tsID].taxis.vdatetime.date); + header[0] = (int) cdiDate_get(streamptr->tsteps[tsID].taxis.vdatetime.date); header[1] = pnum; header[2] = (int) lround(zaxisInqLevel(vlistInqVarZaxis(vlistID, varID), levID)); const int gridID = vlistInqVarGrid(vlistID, varID); diff --git a/src/stream_gribapi.c b/src/stream_gribapi.c index d3d6cd1f7e89825ca78e0c8adb3c28c4b5b2b25c..35b71ef61ccaf98ed6d6bff3b682ddb3258e0260 100644 --- a/src/stream_gribapi.c +++ b/src/stream_gribapi.c @@ -190,7 +190,7 @@ gribapiGetValidityDateTime(grib_handle *gh, int *vDate, int *vTime, int *sDate, // significanceOfReferenceTime == 3. I would recommend replacing this condition with `if(!gribapiTimeIsFC())`. { CdiDateTime vDateTime = gribapiGetDataDateTime(gh); - *vDate = (int)cdiDate_get(vDateTime.date); + *vDate = (int) cdiDate_get(vDateTime.date); *vTime = cdiTime_get(vDateTime.time); } else @@ -213,7 +213,7 @@ gribapiGetValidityDateTime(grib_handle *gh, int *vDate, int *vTime, int *sDate, JulianDate julianDate2 = julianDate_add_seconds(julianDate, timeUnitFactor * startStep); CdiDateTime sDateTime = julianDate_decode(CGRIBEX_grib_calendar, julianDate2); sDateTime.time.second = 0; - *sDate = (int)cdiDate_get(sDateTime.date); + *sDate = (int) cdiDate_get(sDateTime.date); *sTime = cdiTime_get(sDateTime.time); } @@ -221,7 +221,7 @@ gribapiGetValidityDateTime(grib_handle *gh, int *vDate, int *vTime, int *sDate, rDateTime = julianDate_decode(CGRIBEX_grib_calendar, julianDate); } - *vDate = (int)cdiDate_get(rDateTime.date); + *vDate = (int) cdiDate_get(rDateTime.date); *vTime = cdiTime_get(rDateTime.time); } } @@ -868,8 +868,8 @@ gribapiVarCompare(compvar2_t compVar, record_t record, int flag) compVar0.scanKeys = record.scanKeys; compVar0.tiles = record.tiles; - //printf("var1: level1=%d level2=%d\n", compVar.level1, compVar.level2); - //printf("var2: level1=%d level2=%d\n", compVar0.level1, compVar0.level2); + // printf("var1: level1=%d level2=%d\n", compVar.level1, compVar.level2); + // printf("var2: level1=%d level2=%d\n", compVar0.level1, compVar0.level2); return memcmp(&compVar0, &compVar, sizeof(compvar2_t)); } @@ -1055,7 +1055,7 @@ fdbScanTimesteps(stream_t *streamptr) taxis->rdatetime = gribapiGetDataDateTime(gh); fcast = gribapiTimeIsFC(gh); if (fcast) taxis->unit = gribapiGetTimeUnits(gh); - taxis->fdate = (int)cdiDate_get(taxis->rdatetime.date); + taxis->fdate = (int) cdiDate_get(taxis->rdatetime.date); taxis->ftime = cdiTime_get(taxis->rdatetime.time); taxis->sdate = sDate; taxis->stime = sTime; @@ -1217,7 +1217,7 @@ gribapiScanTimestep1(stream_t *streamptr) taxis->rdatetime = gribapiGetDataDateTime(gh); fcast = gribapiTimeIsFC(gh); if (fcast) taxis->unit = gribapiGetTimeUnits(gh); - taxis->fdate = (int)cdiDate_get(taxis->rdatetime.date); + taxis->fdate = (int) cdiDate_get(taxis->rdatetime.date); taxis->ftime = cdiTime_get(taxis->rdatetime.time); taxis->sdate = sDate; taxis->stime = sTime; @@ -1374,12 +1374,12 @@ gribapiScanTimestep2(stream_t *streamptr) taxis->type = TAXIS_RELATIVE; taxis->unit = gribapiGetTimeUnits(gh); taxis->rdatetime = gribapiGetDataDateTime(gh); - } + } else { taxis->type = TAXIS_ABSOLUTE; } - taxis->fdate = (int)cdiDate_get(taxis->rdatetime.date); + taxis->fdate = (int) cdiDate_get(taxis->rdatetime.date); taxis->ftime = cdiTime_get(taxis->rdatetime.time); taxis->vdatetime = cdiDateTime_set(vDate, vTime); taxis->sdate = sDate; @@ -1577,7 +1577,7 @@ gribapiScanTimestep(stream_t *streamptr) { taxis->type = TAXIS_ABSOLUTE; } - taxis->fdate = (int)cdiDate_get(taxis->rdatetime.date); + taxis->fdate = (int) cdiDate_get(taxis->rdatetime.date); taxis->ftime = cdiTime_get(taxis->rdatetime.time); taxis->vdatetime = cdiDateTime_set(vDate, vTime); taxis->sdate = sDate; @@ -1960,8 +1960,10 @@ gribapiDefSteptype(int editionNumber, grib_handle *gh, int productDefinitionTemp proDefTempNum = cdiGribAPI_ts_str_map[tsteptype].productionTemplate; } - if (productDefinitionTemplate != -1) proDefTempNum = productDefinitionTemplate; - else if (typeOfGeneratingProcess == 4) proDefTempNum = (proDefTempNum == 8) ? 11 : 1; + if (productDefinitionTemplate != -1) + proDefTempNum = productDefinitionTemplate; + else if (typeOfGeneratingProcess == 4) + proDefTempNum = (proDefTempNum == 8) ? 11 : 1; if (!gcinit) { @@ -1988,9 +1990,9 @@ gribapiDefDateTimeAbs(int editionNumber, grib_handle *gh, int date, int time, in } static int -gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int fdate, int ftime, int vdate, int vtime, int sdate, - int stime, int productDefinitionTemplate, int typeOfGeneratingProcess, int tsteptype, int timeunit, - int calendar, int gcinit) +gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int fdate, int ftime, int vdate, int vtime, int sdate, int stime, + int productDefinitionTemplate, int typeOfGeneratingProcess, int tsteptype, int timeunit, int calendar, + int gcinit) { int status = -1; @@ -2069,8 +2071,8 @@ gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int fdate, int ftime, } static void -gribapiDefTime(int editionNumber, int productDefinitionTemplate, int typeOfGeneratingProcess, grib_handle *gh, int vdate, - int vtime, int tsteptype, int numavg, int taxisID, int gcinit) +gribapiDefTime(int editionNumber, int productDefinitionTemplate, int typeOfGeneratingProcess, grib_handle *gh, int vdate, int vtime, + int tsteptype, int numavg, int taxisID, int gcinit) { UNUSED(numavg); diff --git a/src/stream_gribapi.h b/src/stream_gribapi.h index c1e5554af3167e74e82ecb9802a3001904721e23..cd7f6f71b71820895fd5e2e68852dd41333212c9 100644 --- a/src/stream_gribapi.h +++ b/src/stream_gribapi.h @@ -13,9 +13,9 @@ int gribapiScanTimestep(stream_t *streamptr); int gribapiDecode(void *gribbuffer, size_t gribsize, void *data, size_t datasize, int unreduced, size_t *nmiss, double missval); -size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID, int vdate, int vtime, int tsteptype, - int numavg, size_t datasize, const void *data, size_t nmiss, void **gribbuffer, size_t *gribbuffersize, - int ljpeg, void *gribContainer); +size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID, int vdate, int vtime, int tsteptype, int numavg, + size_t datasize, const void *data, size_t nmiss, void **gribbuffer, size_t *gribbuffersize, int ljpeg, + void *gribContainer); int gribapiGetScanningMode(grib_handle *gh); void gribapiSetScanningMode(grib_handle *gh, int scanningMode); diff --git a/src/stream_record.c b/src/stream_record.c index 8a5808078fa8f8153ec61d50ef10b0271d2cf358..b3029c6b1748450499cff4052b7973a8cede4308 100644 --- a/src/stream_record.c +++ b/src/stream_record.c @@ -183,7 +183,7 @@ streamDefRecord(int streamID, int varID, int levelID) record->levelID = levelID; record->param = param; record->ilevel = ilevel; - record->vdate = (int)cdiDate_get(streamptr->tsteps[tsID].taxis.vdatetime.date); + record->vdate = (int) cdiDate_get(streamptr->tsteps[tsID].taxis.vdatetime.date); record->vtime = cdiTime_get(streamptr->tsteps[tsID].taxis.vdatetime.time); record->gridID = gridID; record->prec = vlistInqVarDatatype(vlistID, varID); diff --git a/src/stream_srv.c b/src/stream_srv.c index a35e9f196bc90efd0543b7b354ed975c51f27cba..b78b96108348ec72261d8a30473fc277acee4585 100644 --- a/src/stream_srv.c +++ b/src/stream_srv.c @@ -617,7 +617,7 @@ srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data int header[8]; header[0] = pnum; header[1] = (int) lround(zaxisInqLevel(vlistInqVarZaxis(vlistID, varID), levID)); - header[2] = (int)cdiDate_get(streamptr->tsteps[tsID].taxis.vdatetime.date); + header[2] = (int) cdiDate_get(streamptr->tsteps[tsID].taxis.vdatetime.date); header[3] = cdiTime_get(streamptr->tsteps[tsID].taxis.vdatetime.time); size_t xsize = gridInqXsize(gridID); diff --git a/src/table.c b/src/table.c index 2178d5722bd2a473a5b97564b8e56c67c352671d..48c4d0310fb10fbcd1d7aea5a949f91fc9b09f71 100644 --- a/src/table.c +++ b/src/table.c @@ -107,7 +107,7 @@ parTableFinalize(void) for (int tableID = 0; tableID < MAX_TABLE; ++tableID) if (parTable[tableID].used) { - int npars = parTable[tableID].npars; + const int npars = parTable[tableID].npars; for (int item = 0; item < npars; ++item) { if (parTable[tableID].pars[item].dupflags & TABLE_DUP_NAME) Free((void *) parTable[tableID].pars[item].name); @@ -161,7 +161,7 @@ decodeForm1(char *pline, char *name, char *longname, char *units) { char *pstart, *pend; - /* FIXME: parse success isn't verified */ + // FIXME: parse success isn't verified /* long level = */ strtol(pline, &pline, 10); while (isspace((int) *pline)) pline++; @@ -178,10 +178,10 @@ decodeForm1(char *pline, char *name, char *longname, char *units) if (pline[0] == 0) return 0; - /* Format 1 : code name add mult longname [units] */ - /* FIXME: successful parse isn't verified */ + // Format 1 : code name add mult longname [units] + // FIXME: successful parse isn't verified /* double add = */ strtod(pline, &pline); - /* FIXME: successful parse isn't verified */ + // FIXME: successful parse isn't verified /* double mult = */ strtod(pline, &pline); while (isspace((int) *pline)) pline++; @@ -276,7 +276,7 @@ decodeForm2(char *pline, char *name, char *longname, char *units) pend--; while (isspace((int) *pend)) pend--; { - size_t len = (size_t) (pend - pline + 1); + const size_t len = (size_t) (pend - pline + 1); if (len > 0) { memcpy(longname, pline, len); @@ -366,7 +366,7 @@ tableRead(const char *tablefile) if (err) continue; - if (name[0] == 0) sprintf(name, "var%d", id); + if (name[0] == 0) snprintf(name, sizeof(name), "var%d", id); tableDefEntry(tableID, id, ltype, name, longname, units); } @@ -396,8 +396,8 @@ tableFromEnv(int modelID, int tablenum) if (tablenum) tablenameLen += (size_t) (sprintf(tablename + tablenameLen, "_%03d", tablenum)); size_t lenp = 0, lenf = tablenameLen; if (tablePath) lenp = strlen(tablePath); - /* if (tablePath) printf("tablePath = %s\n", tablePath); */ - /* if (tablename) printf("tableName = %s\n", tablename); */ + // if (tablePath) printf("tablePath = %s\n", tablePath); + // if (tablename) printf("tableName = %s\n", tablename); char *tablefile = (char *) Malloc(lenp + lenf + 3); if (tablePath) { @@ -407,15 +407,15 @@ tableFromEnv(int modelID, int tablenum) else tablefile[0] = '\0'; strcat(tablefile, tablename); - /* if (tablefile) printf("tableFile = %s\n", tablefile); */ + // if (tablefile) printf("tableFile = %s\n", tablefile); - int tableID = tableRead(tablefile); + const int tableID = tableRead(tablefile); if (tableID != CDI_UNDEFID) { tableDefModelID(tableID, modelID); tableDefNum(tableID, tablenum); } - /* printf("tableID = %d %s\n", tableID, tablefile); */ + // printf("tableID = %d %s\n", tableID, tablefile); Free(tablefile); return tableID; @@ -469,7 +469,7 @@ tableInq(int modelID, int tablenum, const char *tablename) if ((modelName = modelInqNamePtr(modelID))) { strcpy(tablefile, modelName); - size_t len = strlen(tablefile); + const size_t len = strlen(tablefile); for (size_t i = 0; i < len; i++) if (tablefile[i] == '.') tablefile[i] = '\0'; modelID2 = modelInq(-1, 0, tablefile); @@ -502,10 +502,7 @@ tableDef(int modelID, int tablenum, const char *tablename) int tableID = CDI_UNDEFID; if (!ParTableInit) parTableInit(); - /* - if ( ! (modelID == CDI_UNDEFID && tablenum == 0) ) - tableID = tableInq(modelID, tablenum, tablename); - */ + // if (!(modelID == CDI_UNDEFID && tablenum == 0)) tableID = tableInq(modelID, tablenum, tablename); if (tableID == CDI_UNDEFID) { tableID = tableNewEntry(); @@ -575,6 +572,17 @@ tableInqNamePtr(int tableID) return tablename; } +static size_t +max_length(size_t maxlen, const char *cstring) +{ + if (cstring) + { + const size_t len = strlen(cstring); + if (len > maxlen) maxlen = len; + } + return maxlen; +} + void tableWrite(const char *ptfile, int tableID) { @@ -595,31 +603,16 @@ tableWrite(const char *ptfile, int tableID) FILE *ptfp = fopen(ptfile, "w"); - int npars = parTable[tableID].npars; - + const int npars = parTable[tableID].npars; for (int item = 0; item < npars; item++) { - if (parTable[tableID].pars[item].name) - { - size_t lenname = strlen(parTable[tableID].pars[item].name); - if (lenname > maxname) maxname = lenname; - } - - if (parTable[tableID].pars[item].longname) - { - size_t lenlname = strlen(parTable[tableID].pars[item].longname); - if (lenlname > maxlname) maxlname = lenlname; - } - - if (parTable[tableID].pars[item].units) - { - size_t lenunits = strlen(parTable[tableID].pars[item].units); - if (lenunits > maxunits) maxunits = lenunits; - } + maxname = max_length(maxname, parTable[tableID].pars[item].name); + maxlname = max_length(maxlname, parTable[tableID].pars[item].longname); + maxunits = max_length(maxunits, parTable[tableID].pars[item].units); } - int tablenum = tableInqNum(tableID); - int modelID = parTable[tableID].modelID; + const int tablenum = tableInqNum(tableID); + const int modelID = parTable[tableID].modelID; if (modelID != CDI_UNDEFID) { modelnameptr = modelInqNamePtr(modelID); @@ -680,33 +673,18 @@ tableFWriteC(FILE *ptfp, int tableID) partabCheckID(tableID); - int npars = parTable[tableID].npars; - + const int npars = parTable[tableID].npars; for (int item = 0; item < npars; item++) { - if (parTable[tableID].pars[item].name) - { - size_t lenname = strlen(parTable[tableID].pars[item].name); - if (lenname > maxname) maxname = lenname; - } - - if (parTable[tableID].pars[item].longname) - { - size_t lenlname = strlen(parTable[tableID].pars[item].longname); - if (lenlname > maxlname) maxlname = lenlname; - } - - if (parTable[tableID].pars[item].units) - { - size_t lenunits = strlen(parTable[tableID].pars[item].units); - if (lenunits > maxunits) maxunits = lenunits; - } + maxname = max_length(maxname, parTable[tableID].pars[item].name); + maxlname = max_length(maxlname, parTable[tableID].pars[item].longname); + maxunits = max_length(maxunits, parTable[tableID].pars[item].units); } strncpy(tablename, parTable[tableID].name, sizeof(tablename)); tablename[sizeof(tablename) - 1] = '\0'; { - size_t len = strlen(tablename); + const size_t len = strlen(tablename); for (size_t i = 0; i < len; i++) if (tablename[i] == '.') tablename[i] = '_'; } @@ -738,7 +716,7 @@ tableInqEntry(int tableID, int id, int ltype, char *name, char *longname, char * if (tableID != CDI_UNDEFID) { - int npars = parTable[tableID].npars; + const int npars = parTable[tableID].npars; for (int item = 0; item < npars; item++) { if (parTable[tableID].pars[item].id == id @@ -761,7 +739,7 @@ tableInqParCode(int tableID, char *varname, int *code) if (tableID != CDI_UNDEFID && varname != NULL) { - int npars = parTable[tableID].npars; + const int npars = parTable[tableID].npars; for (int item = 0; item < npars; item++) { if (parTable[tableID].pars[item].name && strcmp(parTable[tableID].pars[item].name, varname) == 0) diff --git a/src/taxis.c b/src/taxis.c index 835923438d2b1ed3d56a07a3edf385a031cbde2d..811e48b367a8ab2252bb76c4e653be20f5d3d070 100644 --- a/src/taxis.c +++ b/src/taxis.c @@ -81,7 +81,8 @@ tunitNamePtr(int unitID) { int size = sizeof(Timeunits) / sizeof(*Timeunits); return (unitID > 0 && unitID < size) ? Timeunits[unitID] : Timeunits[0]; -}static void +} +static void taxisDefaultValue(taxis_t *taxisptr) { taxisptr->self = CDI_UNDEFID; @@ -272,7 +273,7 @@ taxisDefVdate(int taxisID, int vdate) { taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps); - if ((int)cdiDate_get(taxisptr->vdatetime.date) != vdate) + if ((int) cdiDate_get(taxisptr->vdatetime.date) != vdate) { taxisptr->vdatetime.date = cdiDate_set(vdate); reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE); @@ -354,7 +355,7 @@ taxisDefRdate(int taxisID, int rdate) { taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps); - if ((int)cdiDate_get(taxisptr->rdatetime.date) != rdate) + if ((int) cdiDate_get(taxisptr->rdatetime.date) != rdate) { taxisptr->rdatetime.date = cdiDate_set(rdate); @@ -591,7 +592,7 @@ taxisCopyTimestep(int taxisID2, int taxisID1) { taxisptr2->vdatetime_lb = taxisptr1->vdatetime_lb; taxisptr2->vdatetime_ub = taxisptr1->vdatetime_ub; - } + } taxisptr2->fdate = taxisptr1->fdate; taxisptr2->ftime = taxisptr1->ftime; @@ -624,7 +625,6 @@ taxisInqRdatetime(int taxisID) return taxisptr->rdatetime; } - /* @Function taxisInqVdate @Title Get the verification date @@ -645,7 +645,7 @@ int taxisInqVdate(int taxisID) { const taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps); - return (int)cdiDate_get(taxisptr->vdatetime.date); + return (int) cdiDate_get(taxisptr->vdatetime.date); } int @@ -659,8 +659,8 @@ void taxisInqVdateBounds(int taxisID, int *vdate_lb, int *vdate_ub) { const taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps); - *vdate_lb = (int)cdiDate_get(taxisptr->vdatetime_lb.date); - *vdate_ub = (int)cdiDate_get(taxisptr->vdatetime_ub.date); + *vdate_lb = (int) cdiDate_get(taxisptr->vdatetime_lb.date); + *vdate_ub = (int) cdiDate_get(taxisptr->vdatetime_ub.date); } void @@ -676,7 +676,8 @@ taxisDefVdateBounds(int taxisID, int vdate_lb, int vdate_ub) { taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps); - if (taxisptr->has_bounds == false || (int)cdiDate_get(taxisptr->vdatetime_lb.date) != vdate_lb || (int)cdiDate_get(taxisptr->vdatetime_ub.date) != vdate_ub) + if (taxisptr->has_bounds == false || (int) cdiDate_get(taxisptr->vdatetime_lb.date) != vdate_lb + || (int) cdiDate_get(taxisptr->vdatetime_ub.date) != vdate_ub) { taxisptr->vdatetime_lb.date = cdiDate_set(vdate_lb); taxisptr->vdatetime_ub.date = cdiDate_set(vdate_ub); @@ -690,7 +691,8 @@ taxisDefVdatetimeBounds(int taxisID, CdiDateTime vdatetime_lb, CdiDateTime vdate { taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps); - if (taxisptr->has_bounds == false || cdiDateTime_isNE(taxisptr->vdatetime_lb, vdatetime_lb) || cdiDateTime_isNE(taxisptr->vdatetime_ub, vdatetime_ub)) + if (taxisptr->has_bounds == false || cdiDateTime_isNE(taxisptr->vdatetime_lb, vdatetime_lb) + || cdiDateTime_isNE(taxisptr->vdatetime_ub, vdatetime_ub)) { taxisptr->vdatetime_lb = vdatetime_lb; taxisptr->vdatetime_ub = vdatetime_ub; @@ -719,7 +721,7 @@ int taxisInqVtime(int taxisID) { const taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps); - //return taxisptr->vtime; + // return taxisptr->vtime; return cdiTime_get(taxisptr->vdatetime.time); } @@ -743,7 +745,8 @@ taxisDefVtimeBounds(int taxisID, int vtime_lb, int vtime_ub) { taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps); - if (taxisptr->has_bounds == false || cdiTime_get(taxisptr->vdatetime_lb.time) != vtime_lb || cdiTime_get(taxisptr->vdatetime_ub.time) != vtime_ub) + if (taxisptr->has_bounds == false || cdiTime_get(taxisptr->vdatetime_lb.time) != vtime_lb + || cdiTime_get(taxisptr->vdatetime_ub.time) != vtime_ub) { taxisptr->vdatetime_lb.time = cdiTime_set(vtime_lb); taxisptr->vdatetime_ub.time = cdiTime_set(vtime_ub); @@ -779,7 +782,7 @@ taxisInqRdate(int taxisID) reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE); } - return (int)cdiDate_get(taxisptr->rdatetime.date); + return (int) cdiDate_get(taxisptr->rdatetime.date); } /* @@ -1008,7 +1011,8 @@ timevalue_decode(int timeunits, double timevalue) /* { double cval = julianDate.julianDay * 86400.0 + julianDate.secondOfDay; - if (cval != timevalue) printf("TUNIT_SECOND error: %g %g %d %d\n", timevalue, cval, julianDate.julianDay, julianDate.secondOfDay); + if (cval != timevalue) printf("TUNIT_SECOND error: %g %g %d %d\n", timevalue, cval, julianDate.julianDay, + julianDate.secondOfDay); } */ } @@ -1025,7 +1029,8 @@ timevalue_decode(int timeunits, double timevalue) /* { double cval = julianDate.julianDay + julianDate.secondOfDay / 86400.0; - if (cval != timevalue) printf("TUNIT_DAY error: %g %g %d %d\n", timevalue, cval, julianDate.julianDay, julianDate.secondOfDay); + if (cval != timevalue) printf("TUNIT_DAY error: %g %g %d %d\n", timevalue, cval, julianDate.julianDay, + julianDate.secondOfDay); } */ } @@ -1354,8 +1359,8 @@ cdiSetForecastPeriod(double timevalue, taxis_t *taxis) const CdiDateTime dt = julianDate_decode(calendar, julianDate_sub(julianDate, julianDate2)); - (*taxis).fdate = (int)cdiDate_get(dt.date); - (*taxis).ftime = (int)cdiTime_get(dt.time); + (*taxis).fdate = (int) cdiDate_get(dt.date); + (*taxis).ftime = (int) cdiTime_get(dt.time); } CdiDateTime @@ -1367,31 +1372,37 @@ cdi_decode_timeval(double timevalue, taxis_t *taxis) double cdi_encode_timeval(CdiDateTime datetime, taxis_t *taxis) { - double timevalue; + double timeValue = 0.0; if (taxis->type == TAXIS_ABSOLUTE) { if (taxis->unit == TUNIT_YEAR) { - timevalue = datetime.date.year; + timeValue = datetime.date.year; } else if (taxis->unit == TUNIT_MONTH) { - int64_t xdate = cdiDate_get(datetime.date); - timevalue = xdate / 100 + copysign((double) (datetime.date.day != 0) * 0.5, (double) xdate); + const int64_t xdate = cdiDate_get(datetime.date); + timeValue = xdate / 100 + copysign((double) (datetime.date.day != 0) * 0.5, (double) xdate); + } + else if (taxis->unit == TUNIT_SECOND) + { + int hour, minute, second, ms; + cdiTime_decode(datetime.time, &hour, &minute, &second, &ms); + timeValue = hour * 3600 + minute * 60 + second; } else { int hour, minute, second, ms; cdiTime_decode(datetime.time, &hour, &minute, &second, &ms); - int64_t xdate = cdiDate_get(datetime.date); - timevalue = copysign(1.0, (double) xdate) * (fabs((double) xdate) + (hour * 3600 + minute * 60 + second) / 86400.0); + const int64_t xdate = cdiDate_get(datetime.date); + timeValue = copysign(1.0, (double) xdate) * (fabs((double) xdate) + (hour * 3600 + minute * 60 + second) / 86400.0); } } else - timevalue = datetime2rtimeval(datetime, taxis); + timeValue = datetime2rtimeval(datetime, taxis); - return timevalue; + return timeValue; } void @@ -1471,12 +1482,10 @@ taxisPrintKernel(taxis_t *taxisptr, FILE *fp) "fc_unit = %d\n" "fc_period = %g\n" "\n", - taxisptr->self, taxisptr->self, (int) taxisptr->used, taxisptr->type, - (int)cdiDate_get(taxisptr->vdatetime.date), cdiTime_get(taxisptr->vdatetime.time), - (int)cdiDate_get(taxisptr->rdatetime.date), cdiTime_get(taxisptr->rdatetime.time), - taxisptr->fdate, taxisptr->ftime, taxisptr->calendar, taxisptr->unit, taxisptr->numavg, - (int) taxisptr->climatology, (int) taxisptr->has_bounds, vdate_lb, vtime_lb, vdate_ub, vtime_ub, - taxisptr->fc_unit, taxisptr->fc_period); + taxisptr->self, taxisptr->self, (int) taxisptr->used, taxisptr->type, (int) cdiDate_get(taxisptr->vdatetime.date), + cdiTime_get(taxisptr->vdatetime.time), (int) cdiDate_get(taxisptr->rdatetime.date), cdiTime_get(taxisptr->rdatetime.time), + taxisptr->fdate, taxisptr->ftime, taxisptr->calendar, taxisptr->unit, taxisptr->numavg, (int) taxisptr->climatology, + (int) taxisptr->has_bounds, vdate_lb, vtime_lb, vdate_ub, vtime_ub, taxisptr->fc_unit, taxisptr->fc_period); } static int @@ -1486,7 +1495,7 @@ taxisCompareP(void *taxisptr1, void *taxisptr2) xassert(t1 && t2); - return !(t1->used == t2->used && t1->type == t2->type && cdiDateTime_isEQ(t1->vdatetime, t2->vdatetime) + return !(t1->used == t2->used && t1->type == t2->type && cdiDateTime_isEQ(t1->vdatetime, t2->vdatetime) && cdiDateTime_isEQ(t1->rdatetime, t2->rdatetime) && t1->fdate == t2->fdate && t1->ftime == t2->ftime && t1->calendar == t2->calendar && t1->unit == t2->unit && t1->fc_unit == t2->fc_unit && t1->numavg == t2->numavg && t1->climatology == t2->climatology && t1->has_bounds == t2->has_bounds @@ -1595,9 +1604,9 @@ taxisPack(void *voidP, void *packBuffer, int packBufferSize, int *packBufferPos, intBuffer[idx++] = taxisP->self; intBuffer[idx++] = taxisP->used; intBuffer[idx++] = taxisP->type; - intBuffer[idx++] = (int)cdiDate_get(taxisP->vdatetime.date); + intBuffer[idx++] = (int) cdiDate_get(taxisP->vdatetime.date); intBuffer[idx++] = cdiTime_get(taxisP->vdatetime.time); - intBuffer[idx++] = (int)cdiDate_get(taxisP->rdatetime.date); + intBuffer[idx++] = (int) cdiDate_get(taxisP->rdatetime.date); intBuffer[idx++] = cdiTime_get(taxisP->rdatetime.time); intBuffer[idx++] = taxisP->fdate; intBuffer[idx++] = taxisP->ftime; @@ -1607,9 +1616,9 @@ taxisPack(void *voidP, void *packBuffer, int packBufferSize, int *packBufferPos, intBuffer[idx++] = taxisP->numavg; intBuffer[idx++] = taxisP->climatology; intBuffer[idx++] = taxisP->has_bounds; - intBuffer[idx++] = (int)cdiDate_get(taxisP->vdatetime_lb.date); + intBuffer[idx++] = (int) cdiDate_get(taxisP->vdatetime_lb.date); intBuffer[idx++] = cdiTime_get(taxisP->vdatetime_lb.time); - intBuffer[idx++] = (int)cdiDate_get(taxisP->vdatetime_ub.date); + intBuffer[idx++] = (int) cdiDate_get(taxisP->vdatetime_ub.date); intBuffer[idx++] = cdiTime_get(taxisP->vdatetime_ub.time); intBuffer[idx++] = taxisP->name ? (int) strlen(taxisP->name) : 0; intBuffer[idx++] = taxisP->longname ? (int) strlen(taxisP->longname) : 0; diff --git a/src/taxis.h b/src/taxis.h index 7089eaac729c4dfe4c1fc8fe01edad13c37272b1..c9f3526bf9f4aa9f96cfc596ae99363be5ba9dec 100644 --- a/src/taxis.h +++ b/src/taxis.h @@ -15,28 +15,27 @@ typedef struct int self; bool used; short has_bounds; - int datatype; // datatype - int type; // time type - int sdate; // start date - int stime; // start time - CdiDateTime vdatetime; // verification date/time - CdiDateTime rdatetime; // reference date/time - int fdate; // forecast reference date - int ftime; // forecast reference time + int datatype; // datatype + int type; // time type + int sdate; // start date + int stime; // start time + CdiDateTime vdatetime; // verification date/time + CdiDateTime rdatetime; // reference date/time + int fdate; // forecast reference date + int ftime; // forecast reference time int calendar; - int unit; // time unit + int unit; // time unit int numavg; bool climatology; - CdiDateTime vdatetime_lb; // lower bounds of verification date/time - CdiDateTime vdatetime_ub; // upper bounds of verification date/time - int fc_unit; // forecast time unit - double fc_period; // forecast time period + CdiDateTime vdatetime_lb; // lower bounds of verification date/time + CdiDateTime vdatetime_ub; // upper bounds of verification date/time + int fc_unit; // forecast time unit + double fc_period; // forecast time period char *name; char *longname; char *units; } taxis_t; - // taxisInqSdate: Get the start date int taxisInqSdate(int taxisID); diff --git a/src/varscan.c b/src/varscan.c index 84c4e0e9de92a4b5d6620399c57a7a3084f230fb..ab32359b8bbaf02f1df596dd262ba06d1e16a8ea 100644 --- a/src/varscan.c +++ b/src/varscan.c @@ -374,8 +374,8 @@ varAddRecord(int recID, int param, int gridID, int zaxistype, int hasBounds, int const VarScanKeys *scanKeys, const var_tile_t *tiles, int *tile_index) { int varID = (CDI_Split_Ltype105 != 1 || zaxistype != ZAXIS_HEIGHT) - ? varGetEntry(param, gridID, zaxistype, ltype1, tsteptype, name, scanKeys, tiles) - : CDI_UNDEFID; + ? varGetEntry(param, gridID, zaxistype, ltype1, tsteptype, name, scanKeys, tiles) + : CDI_UNDEFID; if (varID == CDI_UNDEFID) { @@ -776,8 +776,8 @@ varDefZAxisReference(int nhlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZE]) } bool -zaxis_compare(int zaxisID, int zaxistype, int nlevels, const double *levels, const double *lbounds, - const double *ubounds, const char *longname, const char *units, int ltype1, int ltype2) +zaxis_compare(int zaxisID, int zaxistype, int nlevels, const double *levels, const double *lbounds, const double *ubounds, + const char *longname, const char *units, int ltype1, int ltype2) { bool differ = true; @@ -812,7 +812,7 @@ zaxis_compare(int zaxisID, int zaxistype, int nlevels, const double *levels, con for (int levelID = 0; levelID < nlevels; levelID++) { if (fabs(lbounds[levelID] - bounds[levelID]) > 1.e-9 - || fabs(ubounds[levelID] - bounds[levelID + nlevels]) > 1.e-9) + || fabs(ubounds[levelID] - bounds[levelID + nlevels]) > 1.e-9) { differ = true; break; @@ -863,8 +863,8 @@ varDefZAxisSearch(int id, void *res, void *data) { struct varDefZAxisSearchState *state = (struct varDefZAxisSearchState *) data; (void) res; - if (zaxis_compare(id, state->zaxistype, state->nlevels, state->levels, state->lbounds, state->ubounds, - state->longname, state->units, state->ltype1, state->ltype2) + if (zaxis_compare(id, state->zaxistype, state->nlevels, state->levels, state->lbounds, state->ubounds, state->longname, + state->units, state->ltype1, state->ltype2) == false) { state->resIDValue = id; diff --git a/src/varscan.h b/src/varscan.h index 93561f2511328a0b67aa29dc8dbc03b11cc617c9..e2ff1469b0aaf2df8ccdb9f43678efebbdfcf69e 100644 --- a/src/varscan.h +++ b/src/varscan.h @@ -34,8 +34,8 @@ void varDefOptGribInt(int varID, int tile_index, long lval, const char *keyword) void varDefOptGribDbl(int varID, int tile_index, double dval, const char *keyword); int varOptGribNentries(int varID); -bool zaxis_compare(int zaxisID, int zaxistype, int nlevels, const double *levels, const double *lbounds, - const double *ubounds, const char *longname, const char *units, int ltype1, int ltype2); +bool zaxis_compare(int zaxisID, int zaxistype, int nlevels, const double *levels, const double *lbounds, const double *ubounds, + const char *longname, const char *units, int ltype1, int ltype2); #endif /* diff --git a/src/vlist.c b/src/vlist.c index 18ef76e918c1e3d4802a129424f369914a3ab0a2..68f13bd8b4ed5115b51de096431e53cbbddb1da6 100644 --- a/src/vlist.c +++ b/src/vlist.c @@ -153,7 +153,7 @@ vlist_copy(vlist_t *vlistptr2, vlist_t *vlistptr1) memcpy(vlistptr2, vlistptr1, sizeof(vlist_t)); vlistptr2->internal = vlist2internal; // the question who's responsible to destroy the vlist is tied to its containing memory // region, so we retain this flag - vlistptr2->immutable = 0; // this is a copy, so it's mutable, independent of whether the original is mutable or not + vlistptr2->immutable = 0; // this is a copy, so it's mutable, independent of whether the original is mutable or not vlistptr2->keys.nelems = 0; vlistptr2->atts.nelems = 0; vlistptr2->self = vlistID2; @@ -425,7 +425,8 @@ vgzZAxisSearch(int id, void *res, void *data) { struct vgzSearchState *state = (struct vgzSearchState *) data; (void) res; - if (zaxis_compare(id, state->zaxistype, state->nlevels, state->levels, state->lbounds, state->ubounds, NULL, NULL, 0, -1) == false) + if (zaxis_compare(id, state->zaxistype, state->nlevels, state->levels, state->lbounds, state->ubounds, NULL, NULL, 0, -1) + == false) { state->resIDValue = id; return CDI_APPLY_STOP; diff --git a/src/vlist.h b/src/vlist.h index 109fa1e0e07297d2652ebb62bcc167edffce7f27..c57a2cffb74c581fbf692f065d4008c4dc679fd3 100644 --- a/src/vlist.h +++ b/src/vlist.h @@ -58,14 +58,11 @@ typedef struct int modelID; int tableID; int timave; - int nsb; // Number of significant bits + int nsb; // Number of significant bits int xyz; bool missvalused; // true if missval is defined bool lvalidrange; - char *extra; double missval; - double scalefactor; - double addoffset; double validrange[2]; levinfo_t *levinfo; int comptype; // compression type @@ -88,10 +85,10 @@ typedef struct // set if this vlist has been created by CDI itself, and must not be destroyed by the user, consequently bool internal; int self; - int nvars; // number of variables + int nvars; // number of variables int ngrids; int nzaxis; - int nsubtypes; // no. of variable subtypes (e.g. sets of tiles) + int nsubtypes; // no. of variable subtypes (e.g. sets of tiles) long ntsteps; int taxisID; int tableID; diff --git a/src/vlist_var.c b/src/vlist_var.c index a1797d735342ef7189f8b1f2ea1e02f8561cf743..7a86e99bbfdd27bd3b39dfd7501a5ddd7c3e6c9a 100644 --- a/src/vlist_var.c +++ b/src/vlist_var.c @@ -31,9 +31,6 @@ vlistvarInitEntry(int vlistID, int varID) vlistptr->vars[varID].tableID = CDI_UNDEFID; vlistptr->vars[varID].missvalused = false; vlistptr->vars[varID].missval = CDI_Default_Missval; - vlistptr->vars[varID].addoffset = 0.0; - vlistptr->vars[varID].scalefactor = 1.0; - vlistptr->vars[varID].extra = NULL; vlistptr->vars[varID].levinfo = NULL; vlistptr->vars[varID].comptype = CDI_COMPRESS_NONE; vlistptr->vars[varID].complevel = 1; @@ -133,7 +130,6 @@ vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int timetype, int tileset fprintf(stdout, "CDI info: vlistDefVarTsteptype(vlistID, varID, tsteptype)\n"); fprintf(stdout, "CDI info: with: timetype = TIME_CONSTANT | TIME_VARYING\n"); fprintf(stdout, "CDI info: tsteptype = TSTEP_AVG .... TSTEP_SUM\n"); - } } @@ -442,21 +438,19 @@ void vlistInqVarName(int vlistID, int varID, char *name) { int length = CDI_MAX_NAME; - (void) cdiInqKeyString(vlistID, varID, CDI_KEY_NAME, name, &length); - - if (!name[0]) + if (CDI_NOERR != cdiInqKeyString(vlistID, varID, CDI_KEY_NAME, name, &length)) { vlistCheckVarID(__func__, vlistID, varID); vlist_t *vlistptr = vlist_to_pointer(vlistID); - int param = vlistptr->vars[varID].param; + const int param = vlistptr->vars[varID].param; int pdis, pcat, pnum; cdiDecodeParam(param, &pnum, &pcat, &pdis); if (pdis == 255) { - int code = pnum; - int tableID = vlistptr->vars[varID].tableID; + const int code = pnum; + const int tableID = vlistptr->vars[varID].tableID; tableInqEntry(tableID, code, -1, name, NULL, NULL); if (!name[0]) sprintf(name, "var%d", code); } @@ -497,13 +491,13 @@ vlistCopyVarName(int vlistID, int varID) vlist_t *vlistptr = vlist_to_pointer(vlistID); // Otherwise we check if we should use the table of parameter descriptions. - int param = vlistptr->vars[varID].param; + const int param = vlistptr->vars[varID].param; int discipline, category, number; cdiDecodeParam(param, &number, &category, &discipline); char *result = NULL; if (discipline == 255) { - int tableID = vlistptr->vars[varID].tableID; + const int tableID = vlistptr->vars[varID].tableID; tableInqEntry(tableID, number, -1, name, NULL, NULL); if (name[0]) result = strdup(name); @@ -548,21 +542,19 @@ void vlistInqVarLongname(int vlistID, int varID, char *longname) { int length = CDI_MAX_NAME; - (void) cdiInqKeyString(vlistID, varID, CDI_KEY_LONGNAME, longname, &length); - - if (!longname[0]) + if (CDI_NOERR != cdiInqKeyString(vlistID, varID, CDI_KEY_LONGNAME, longname, &length)) { vlistCheckVarID(__func__, vlistID, varID); vlist_t *vlistptr = vlist_to_pointer(vlistID); - int param = vlistptr->vars[varID].param; + const int param = vlistptr->vars[varID].param; int pdis, pcat, pnum; cdiDecodeParam(param, &pnum, &pcat, &pdis); if (pdis == 255) { - int code = pnum; - int tableID = vlistptr->vars[varID].tableID; + const int code = pnum; + const int tableID = vlistptr->vars[varID].tableID; tableInqEntry(tableID, code, -1, NULL, longname, NULL); } } @@ -650,21 +642,19 @@ void vlistInqVarUnits(int vlistID, int varID, char *units) { int length = CDI_MAX_NAME; - (void) cdiInqKeyString(vlistID, varID, CDI_KEY_UNITS, units, &length); - - if (!units[0]) + if (CDI_NOERR != cdiInqKeyString(vlistID, varID, CDI_KEY_UNITS, units, &length)) { vlistCheckVarID(__func__, vlistID, varID); vlist_t *vlistptr = vlist_to_pointer(vlistID); - int param = vlistptr->vars[varID].param; + const int param = vlistptr->vars[varID].param; int pdis, pcat, pnum; cdiDecodeParam(param, &pnum, &pcat, &pdis); if (pdis == 255) { - int code = pnum; - int tableID = vlistptr->vars[varID].tableID; + const int code = pnum; + const int tableID = vlistptr->vars[varID].tableID; tableInqEntry(tableID, code, -1, NULL, NULL, units); } } @@ -986,74 +976,6 @@ vlistDefVarMissval(int vlistID, int varID, double missval) vlistptr->vars[varID].missvalused = true; } -/* -@Function vlistDefVarExtra -@Title Define extra information of a Variable - -@Prototype void vlistDefVarExtra(int vlistID, int varID, const char *extra) -@Parameter - @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate}. - @Item varID Variable identifier. - @Item extra Extra information. - -@Description -The function @func{vlistDefVarExtra} defines the extra information of a variable. - -@EndFunction -*/ -void -vlistDefVarExtra(int vlistID, int varID, const char *extra) -{ - vlistCheckVarID(__func__, vlistID, varID); - - vlist_t *vlistptr = vlist_to_pointer(vlistID); - - if (extra) - { - if (vlistptr->vars[varID].extra) - { - Free(vlistptr->vars[varID].extra); - vlistptr->vars[varID].extra = NULL; - } - - vlistptr->vars[varID].extra = strdupx(extra); - reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE); - } -} - -/* -@Function vlistInqVarExtra -@Title Get extra information of a Variable - -@Prototype void vlistInqVarExtra(int vlistID, int varID, char *extra) -@Parameter - @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}. - @Item varID Variable identifier. - @Item extra Returned variable extra information. The caller must allocate space for the - returned string. The maximum possible length, in characters, of - the string is given by the predefined constant @func{CDI_MAX_NAME}. - -@Description -The function @func{vlistInqVarExtra} returns the extra information of a variable. - -@Result -@func{vlistInqVarExtra} returns the extra information of the variable to the parameter extra if available, -otherwise the result is an empty string. - -@EndFunction -*/ -void -vlistInqVarExtra(int vlistID, int varID, char *extra) -{ - vlistCheckVarID(__func__, vlistID, varID); - - const vlist_t *vlistptr = vlist_to_pointer(vlistID); - if (vlistptr->vars[varID].extra == NULL) - sprintf(extra, "-"); - else - strcpy(extra, vlistptr->vars[varID].extra); -} - int vlistInqVarValidrange(int vlistID, int varID, double *validrange) { @@ -1083,50 +1005,6 @@ vlistDefVarValidrange(int vlistID, int varID, const double *validrange) reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE); } -double -vlistInqVarScalefactor(int vlistID, int varID) -{ - vlistCheckVarID(__func__, vlistID, varID); - - const vlist_t *vlistptr = vlist_to_pointer(vlistID); - return vlistptr->vars[varID].scalefactor; -} - -double -vlistInqVarAddoffset(int vlistID, int varID) -{ - vlistCheckVarID(__func__, vlistID, varID); - - vlist_t *vlistptr = vlist_to_pointer(vlistID); - return vlistptr->vars[varID].addoffset; -} - -void -vlistDefVarScalefactor(int vlistID, int varID, double scalefactor) -{ - vlistCheckVarID(__func__, vlistID, varID); - - vlist_t *vlistptr = vlist_to_pointer(vlistID); - if (IS_NOT_EQUAL(vlistptr->vars[varID].scalefactor, scalefactor)) - { - vlistptr->vars[varID].scalefactor = scalefactor; - reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE); - } -} - -void -vlistDefVarAddoffset(int vlistID, int varID, double addoffset) -{ - vlistCheckVarID(__func__, vlistID, varID); - - vlist_t *vlistptr = vlist_to_pointer(vlistID); - if (IS_NOT_EQUAL(vlistptr->vars[varID].addoffset, addoffset)) - { - vlistptr->vars[varID].addoffset = addoffset; - reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE); - } -} - void vlistDefVarTimetype(int vlistID, int varID, int timetype) { @@ -1559,10 +1437,10 @@ vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB) #define FCMPFLT(f) (IS_NOT_EQUAL((pva->f), (pvb->f))) #define FCMPSTR(fs) ((pva->fs) != (pvb->fs) && strcmp((pva->fs), (pvb->fs))) #define FCMP2(f) (namespaceResHDecode(pva->f).idx != namespaceResHDecode(pvb->f).idx) - int diff = FCMP(fvarID) | FCMP(mvarID) | FCMP(flag) | FCMP(param) | FCMP(datatype) | FCMP(timetype) | FCMP(tsteptype) - | FCMP(xyz) | FCMP2(gridID) | FCMP2(zaxisID) | FCMP2(instID) | FCMP2(modelID) | FCMP2(tableID) - | FCMP(missvalused) | FCMPFLT(missval) | FCMPFLT(addoffset) | FCMPFLT(scalefactor) | FCMPSTR(extra) | FCMP(comptype) - | FCMP(complevel) | FCMP(lvalidrange) | FCMPFLT(validrange[0]) | FCMPFLT(validrange[1]); + int diff = (int) FCMP(fvarID) | FCMP(mvarID) | FCMP(flag) | FCMP(param) | FCMP(datatype) | FCMP(timetype) | FCMP(tsteptype) + | FCMP(xyz) | FCMP2(gridID) | FCMP2(zaxisID) | FCMP2(instID) | FCMP2(modelID) | FCMP2(tableID) | FCMP(missvalused) + | FCMPFLT(missval) | FCMP(comptype) | FCMP(complevel) + | FCMP(lvalidrange) | FCMPFLT(validrange[0]) | FCMPFLT(validrange[1]); #undef FCMP #undef FCMPFLT #undef FCMPSTR diff --git a/src/vlist_var_pack.c b/src/vlist_var_pack.c index a3e4d550e2799ce5ec59945f1a6e93177b757f7f..31fe22e911f7f19762cc4498cd252d030a8a6f56 100644 --- a/src/vlist_var_pack.c +++ b/src/vlist_var_pack.c @@ -22,13 +22,12 @@ enum VLISTVAR_PACK_INT_IDX_COMPLEVEL, VLISTVAR_PACK_INT_IDX_NLEVS, VLISTVAR_PACK_INT_IDX_IORANK, - VLISTVAR_PACK_INT_IDX_EXTRALEN, vlistvarNint }; enum { - vlistvar_ndbls = 3, + vlistvar_ndbls = 1, }; int @@ -37,11 +36,9 @@ vlistVarGetPackSize(vlist_t *p, int varID, void *context) var_t *var = p->vars + varID; int varsize = serializeGetSize(vlistvarNint, CDI_DATATYPE_INT, context) + serializeGetSize(vlistvar_ndbls, CDI_DATATYPE_FLT64, context); - if (var->extra) varsize += serializeGetSize((int) strlen(var->extra), CDI_DATATYPE_TXT, context); - varsize += serializeGetSize(4 * zaxisInqSize(var->zaxisID), CDI_DATATYPE_INT, context); + varsize += serializeGetSize(4 * zaxisInqSize(var->zaxisID), CDI_DATATYPE_INT, context); varsize += serializeKeysGetPackSize(&var->keys, context); - varsize += cdiAttsGetSize(p, varID, context); return varsize; @@ -52,7 +49,7 @@ vlistVarPack(vlist_t *p, int varID, char *buf, int size, int *position, void *co { double dtempbuf[vlistvar_ndbls]; var_t *var = p->vars + varID; - int tempbuf[vlistvarNint], extralen; + int tempbuf[vlistvarNint]; tempbuf[VLISTVAR_PACK_INT_IDX_FLAG] = var->flag; tempbuf[VLISTVAR_PACK_INT_IDX_GRIDID] = var->gridID; @@ -69,13 +66,9 @@ vlistVarPack(vlist_t *p, int varID, char *buf, int size, int *position, void *co int nlevs = var->levinfo ? zaxisInqSize(var->zaxisID) : 0; tempbuf[VLISTVAR_PACK_INT_IDX_NLEVS] = nlevs; tempbuf[VLISTVAR_PACK_INT_IDX_IORANK] = var->iorank; - tempbuf[VLISTVAR_PACK_INT_IDX_EXTRALEN] = extralen = var->extra ? (int) strlen(var->extra) : 0; dtempbuf[0] = var->missval; - dtempbuf[1] = var->scalefactor; - dtempbuf[2] = var->addoffset; serializePack(tempbuf, vlistvarNint, CDI_DATATYPE_INT, buf, size, position, context); serializePack(dtempbuf, vlistvar_ndbls, CDI_DATATYPE_FLT64, buf, size, position, context); - if (extralen) serializePack(var->extra, extralen, CDI_DATATYPE_TXT, buf, size, position, context); if (nlevs) { int *levbuf = (int *) malloc(nlevs * sizeof(int)); @@ -99,7 +92,6 @@ vlistVarUnpack(int vlistID, char *buf, int size, int *position, int originNamesp { double dtempbuf[vlistvar_ndbls]; int tempbuf[vlistvarNint]; - char *varname = NULL; vlist_t *vlistptr = vlist_to_pointer(vlistID); serializeUnpack(buf, size, position, tempbuf, vlistvarNint, CDI_DATATYPE_INT, context); serializeUnpack(buf, size, position, dtempbuf, vlistvar_ndbls, CDI_DATATYPE_FLT64, context); @@ -111,14 +103,6 @@ vlistVarUnpack(int vlistID, char *buf, int size, int *position, int originNamesp int newvar = vlistDefVar(vlistID, namespaceAdaptKey(tempbuf[VLISTVAR_PACK_INT_IDX_GRIDID], originNamespace), namespaceAdaptKey(tempbuf[VLISTVAR_PACK_INT_IDX_ZAXISID], originNamespace), tempbuf[VLISTVAR_PACK_INT_IDX_TIMETYPE]); - if (tempbuf[VLISTVAR_PACK_INT_IDX_EXTRALEN]) varname = (char *) Malloc((size_t) tempbuf[VLISTVAR_PACK_INT_IDX_EXTRALEN] + 1); - if (tempbuf[VLISTVAR_PACK_INT_IDX_EXTRALEN]) - { - serializeUnpack(buf, size, position, varname, tempbuf[VLISTVAR_PACK_INT_IDX_EXTRALEN], CDI_DATATYPE_TXT, context); - varname[tempbuf[VLISTVAR_PACK_INT_IDX_EXTRALEN]] = '\0'; - vlistDefVarExtra(vlistID, newvar, varname); - } - Free(varname); vlistDefVarDatatype(vlistID, newvar, tempbuf[VLISTVAR_PACK_INT_IDX_DATATYPE]); vlistDefVarInstitut(vlistID, newvar, namespaceAdaptKey(tempbuf[VLISTVAR_PACK_INT_IDX_INSTID], originNamespace)); vlistDefVarModel(vlistID, newvar, namespaceAdaptKey(tempbuf[VLISTVAR_PACK_INT_IDX_MODELID], originNamespace)); @@ -126,8 +110,6 @@ vlistVarUnpack(int vlistID, char *buf, int size, int *position, int originNamesp // FIXME: changing the table might change the param code vlistDefVarParam(vlistID, newvar, tempbuf[VLISTVAR_PACK_INT_IDX_PARAM]); if (tempbuf[VLISTVAR_PACK_INT_IDX_MISSVALUSED]) vlistDefVarMissval(vlistID, newvar, dtempbuf[0]); - vlistDefVarScalefactor(vlistID, newvar, dtempbuf[1]); - vlistDefVarAddoffset(vlistID, newvar, dtempbuf[2]); vlistDefVarCompType(vlistID, newvar, tempbuf[VLISTVAR_PACK_INT_IDX_COMPTYPE]); vlistDefVarCompLevel(vlistID, newvar, tempbuf[VLISTVAR_PACK_INT_IDX_COMPLEVEL]); const int nlevs = tempbuf[VLISTVAR_PACK_INT_IDX_NLEVS]; diff --git a/tests/Makefile.am b/tests/Makefile.am index 6839dda3748b97c125f272fdcdd4d13bd901ebdc..bdcc8138ba45edf110a4e60f62b9e657a7340051 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -47,11 +47,11 @@ test_byteswap_SOURCES = test_byteswap.c # AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS) $(MPI_C_INCLUDE) if USE_MPI -pio_write_LDADD = ../src/libcdipio.la $(LIBRT) $(MPI_C_LIB) -pio_write_deco2d_LDADD = ../src/libcdipio.la $(LIBRT) $(MPI_C_LIB) +pio_write_LDADD = ../src/libcdipio.la ../src/libcdi.la $(PPM_CORE_LIBS) $(YAXT_LIBS) $(MPI_C_LIB) +pio_write_deco2d_LDADD = ../src/libcdipio.la ../src/libcdi.la $(PPM_CORE_LIBS) $(YAXT_LIBS) $(MPI_C_LIB) TESTS += test_resource_copy_mpi_run check_PROGRAMS += test_resource_copy_mpi -test_resource_copy_mpi_LDADD = ../src/libcdipio.la +test_resource_copy_mpi_LDADD = ../src/libcdipio.la ../src/libcdi.la test_resource_copy_mpi_CFLAGS = $(AM_CFLAGS) $(CFLAGS) \ -DMPI_MARSHALLING else