diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index ab759966c93..5744552646c 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -141,6 +141,8 @@ jobs: init_cime fi + # Get cprnc + # git clone https://github.com/ESMCI/cprnc $INSTALL_PATH/CIME/non_py/cprnc source /opt/conda/etc/profile.d/conda.sh conda activate base diff --git a/.gitmodules b/.gitmodules index e69de29bb2d..13f9ecb952f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "CIME/non_py/cprnc"] + path = CIME/non_py/cprnc + url = git@github.com:ESMCI/cprnc diff --git a/CIME/build_scripts/buildlib.cprnc b/CIME/build_scripts/buildlib.cprnc index 5e6708da133..51426de27c6 100755 --- a/CIME/build_scripts/buildlib.cprnc +++ b/CIME/build_scripts/buildlib.cprnc @@ -6,7 +6,7 @@ sys.path.append(os.path.join(_CIMEROOT, "CIME", "Tools")) from standard_script_setup import * from CIME import utils -from CIME.utils import run_bld_cmd_ensure_logging +from CIME.utils import run_bld_cmd_ensure_logging, CIMEError from CIME.case import Case from CIME.build import get_standard_cmake_args @@ -63,10 +63,35 @@ def buildlib(bldroot, installpath, case): ) cmake_args = get_standard_cmake_args(case, "ignore_sharedpath") + os.environ["CIMEROOT"] = cimeroot - cmake_cmd = ". ./.env_mach_specific.sh && NETCDF=$(dirname $(dirname $(which nf-config))) cmake {cmake_args} -DMPILIB=mpi-serial -DDEBUG=FALSE -C Macros.cmake {cimeroot}/CIME/non_py/cprnc -DCMAKE_PREFIX_PATH={dest_path} -DBLDROOT={bldroot}".format( - cimeroot=cimeroot, dest_path=installpath, cmake_args=cmake_args, bldroot=bldroot + + srcroot = case.get_value("SRCROOT") + + cprnc_src_root = None + candidate_paths = ( + os.path.join(cimeroot, "CIME/non_py/cprnc"), + os.path.join(srcroot, "externals/cprnc"), ) + + for candidate in candidate_paths: + if os.path.exists(candidate): + cprnc_src_root = candidate + + break + else: + logger.debug("{!r} is not a valid cprnc source path") + + if cprnc_src_root is None: + raise CIMEError("Could not find a valid cprnc source directory") + + cmake_cmd = ". ./.env_mach_specific.sh && NETCDF=$(dirname $(dirname $(which nf-config))) cmake {cmake_args} -DMPILIB=mpi-serial -DDEBUG=FALSE -C Macros.cmake {cprnc_src_root} -DCMAKE_PREFIX_PATH={dest_path} -DBLDROOT={bldroot}".format( + cprnc_src_root=cprnc_src_root, + dest_path=installpath, + cmake_args=cmake_args, + bldroot=bldroot, + ) + run_bld_cmd_ensure_logging(cmake_cmd, logger, from_dir=bldroot) gmake_cmd = case.get_value("GMAKE") diff --git a/CIME/non_py/cprnc b/CIME/non_py/cprnc new file mode 160000 index 00000000000..d17494561ac --- /dev/null +++ b/CIME/non_py/cprnc @@ -0,0 +1 @@ +Subproject commit d17494561ace91fc86387c83591c0382a2c79566 diff --git a/CIME/non_py/cprnc/CMakeLists.txt b/CIME/non_py/cprnc/CMakeLists.txt deleted file mode 100644 index 3ec73581ae2..00000000000 --- a/CIME/non_py/cprnc/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -# Generate this with: $cimeroot/CIME/scripts/configure --mpilib=mpi-serial --macros-format=CMake -# You'll also need to source the .env_mach_specific.sh file before trying to build cprnc - -include("${BLDROOT}/Macros.cmake") -set(CMAKE_C_COMPILER "${SCC}") -set(CMAKE_Fortran_COMPILER "${SFC}") - -project(CPRNC C Fortran) -enable_language(Fortran) -set(CMAKE_Fortran_FLAGS "${FFLAGS}") - -message("HERE fortran flags are ${CMAKE_Fortran_FLAGS} FFLAGS are ${FFLAGS}") - -cmake_minimum_required(VERSION 2.8) - -# Find netcdf -set(NetCDF_PATH ${NETCDF_PATH}) - -if (EXISTS ${SRC_ROOT}/libraries/parallelio/cmake) - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${SRC_ROOT}/libraries/parallelio/cmake) -else() - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${SRC_ROOT}/externals/scorpio/cmake) -endif() - -find_package (NetCDF COMPONENTS Fortran REQUIRED) - -# generate compare_vars_mod.F90 -add_custom_command( - OUTPUT ${PROJECT_BINARY_DIR}/compare_vars_mod.F90 - COMMAND perl ${PROJECT_SOURCE_DIR}/../externals/genf90/genf90.pl - ${PROJECT_SOURCE_DIR}/compare_vars_mod.F90.in > ${PROJECT_BINARY_DIR}/compare_vars_mod.F90 - DEPENDS ${PROJECT_SOURCE_DIR}/compare_vars_mod.F90.in ${PROJECT_SOURCE_DIR}/../externals/genf90/genf90.pl -) - -# Set up includes -include_directories( - ${NetCDF_Fortran_INCLUDE_DIRS} - ${PROJECT_SOURCE_DIR} - ${PROJECT_BINARY_DIR} -) - -# -# Set up lib dependencies, relying on nf-config if possible or NetCDF_Fortran_LIBRARIES -# as a fallback. We want the executable to find libraries via RPATH so that cprnc is -# less-dependent on the current environment (since cprnc is built with a serial netcdf, -# it's likely that a parallel case will have different netcdf modules loaded when it -# comes time to execute cprnc). -# -execute_process(COMMAND ${NETCDF_PATH}/bin/nf-config --flibs - RESULT_VARIABLE NF_CONFIG_RESULT - OUTPUT_VARIABLE NF_CONFIG_OUTPUT) - -if (NF_CONFIG_RESULT STREQUAL "0") - separate_arguments(NF_LIB_LIST UNIX_COMMAND "${NF_CONFIG_OUTPUT}") -else() - set(NF_LIB_LIST ${NetCDF_Fortran_LIBRARIES}) -endif() - -message("lib list is: ${NF_LIB_LIST}") - -foreach(NF_LIB IN LISTS NF_LIB_LIST) - if (NF_LIB MATCHES "-l") - continue() - elseif (NF_LIB MATCHES "-L/") - string(REGEX REPLACE "^-L" "" NF_LIB_DIR "${NF_LIB}") - list(APPEND NF_LIB_DIRS ${NF_LIB_DIR}) - else() - get_filename_component(NF_LIB_DIR ${NF_LIB} DIRECTORY) - list(APPEND NF_LIB_DIRS ${NF_LIB_DIR}) - endif() -endforeach() - -message("lib dirs are: ${NF_LIB_DIRS}") - -set(CMAKE_BUILD_RPATH ${NF_LIB_DIRS}) - -# Add targets -set (CPRNC_SRCS - ${PROJECT_BINARY_DIR}/compare_vars_mod.F90 - filestruct.F90 - utils.F90 - prec.F90 - cprnc.F90 -) - -add_executable(cprnc ${CPRNC_SRCS}) - -target_link_libraries(cprnc ${NF_LIB_LIST}) diff --git a/CIME/non_py/cprnc/Depends b/CIME/non_py/cprnc/Depends deleted file mode 100644 index 582f9ee1794..00000000000 --- a/CIME/non_py/cprnc/Depends +++ /dev/null @@ -1,6 +0,0 @@ -cprnc.o: cprnc.F90 filestruct.o compare_vars_mod.o utils.o -filestruct.o: filestruct.F90 prec.o -prec.o : prec.F90 -compare_vars_mod.o: compare_vars_mod.F90 prec.o utils.o filestruct.o -compare_vars_mod.F90 : compare_vars_mod.F90.in -utils.o : utils.F90 filestruct.o prec.o diff --git a/CIME/non_py/cprnc/Makefile b/CIME/non_py/cprnc/Makefile deleted file mode 100644 index d751cfca03f..00000000000 --- a/CIME/non_py/cprnc/Makefile +++ /dev/null @@ -1,96 +0,0 @@ -#----------------------------------------------------------------------- -# This Makefile is for building cprnc on AIX, Compaq, Linux (with pgf90, -# lf95, ifort, or gfortran compilers), IRIX or SUN platforms. -# -# These macros can be changed by setting environment variables: -# -# Set the path to netcdf: -# -# gmake NETCDF=pathToNetcdf -# -# This sets LIB_NETCDF=$NETCDF/lib and INC_NETCDF=$NETCDF/include -# -# LIB_NETCDF --- Library directory location of netcdf. -# INC_NETCDF --- Include directory location of netcdf. This directory needs to contain -# the NetCDF .mod files, i.e., netcdf.mod and typesizes.mod. -# -# If the include and library files don't have a common root directory then set them -# independently in the commandline: -# -# gmake LIB_NETCDF=pathToLIBFiles INC_NETCDF=pathToINCFiles -# -# You also can set the environment variables: -# -# USER_FC ------ User defined Fortran compiler (for Linux can be pgf90, lf95, ifort, gfortran) -# EXEDIR ------- Directory to build executable in. (Defaults to .) -# VPATH -------- GNU make path. (Defaults to current directory) -# -#------------------------------------------------------------------------ -include Macros.make -# Set up special characters -null := - -EXENAME = cprnc -RM = rm - -NETCDF_PATH ?= $(NETCDF_FORTRAN_PATH) - -# Default for the netcdf library and include directories -LIB_NETCDF := $(NETCDF_PATH)/lib -INC_NETCDF := $(NETCDF_PATH)/include -LDFLAGS = -L$(LIB_NETCDF) -lnetcdff -Wl,-rpath=$(LIB_NETCDF) - -# Determine platform -UNAMES := $(shell uname -s) -SNAME := $(shell uname -n | cut -c1-2) - -GENF90 = ../externals/genf90/genf90.pl - -FC := $(SFC) -FFLAGS += -I$(INC_NETCDF) -I. -#------------------------------------------------------------------------ -# Default rules and macros -#------------------------------------------------------------------------ - -# If path to source code not given -ifeq ($(VPATH),$(null)) - VPATH:= . -endif - -OBJS := compare_vars_mod.o cprnc.o filestruct.o prec.o utils.o - -# If executable directory not given -ifeq ($(EXEDIR),$(null)) - EXEDIR := . -endif - -.SUFFIXES: -.SUFFIXES: .F90 .f90 .o .in - -.F90.o: - $(FC) -c $(FFLAGS) $< - -.f90.o: - $(FC) -c $(FFLAGS) $< - -$(EXEDIR)/$(EXENAME): $(OBJS) - $(FC) -o $@ $(OBJS) $(LDFLAGS) $(SLIBS) - -compare_vars_mod.F90 : compare_vars_mod.F90.in - perl $(GENF90) $< > $@ - -clean: - $(RM) -f $(OBJS) *.mod $(EXEDIR)/$(EXENAME) - -# remove generated file during clean -realclean: - $(RM) -f $(OBJS) *.mod $(EXEDIR)/$(EXENAME) compare_vars_mod.F90 core - -include $(CURDIR)/Depends - -# 'make check' will run the standard tests but without baseline -# comparisons. For complete testing, you should generally also do -# baseline comparisons. See the notes in test_inputs/README for details. -check: $(EXEDIR)/$(EXENAME) - $(RM) -fr tmpdir - ./run_tests -outdir tmpdir diff --git a/CIME/non_py/cprnc/README b/CIME/non_py/cprnc/README deleted file mode 100644 index 6f70818d511..00000000000 --- a/CIME/non_py/cprnc/README +++ /dev/null @@ -1,191 +0,0 @@ -cprnc README ------------- - -cprnc is a generic tool for analyzing a netcdf file or comparing -two netcdf files. - -If you are trying to debug an installed cprnc tool make sure that you -are looking at the correct one by comparing the path to the one in -your case directory. - - -Quick Start Guide: ------------------- - -On cime supported systems you can generate a cmake Macros file using the following -(assuming you are running the command from the directory CIME/non_py/cprnc): - -export CIMEROOT=../.. - -../../scripts/configure --macros-format=CMake --mpilib=mpi-serial --machine=machinename -MPILIB=mpi-serial source ./.env_mach_specific.sh -# Flags if you are using the intel compiler: -CC=icc FC=ifort cmake -DBLDROOT=. -DCASEROOT=. -DCOMPILER=intel -DMACH=cheyenne -DSRC_ROOT=../../../ . -make - -Finally, put the resulting executable in CCSM_CPRNC as defined in -config_machines.xml. - - - Usage: cprnc [-v] [-d dimname:start[:count]] file1 [file2] - -m: Compare each time sample. Default is false, i.e. match "time" - coordinate values before comparing - -v: Verbose output - -d dimname:start[:count] - Print variable values for the specified dimname index subrange. - - -Users Guide: ------------- - -cprnc is a Fortran-90 application. It relies on netcdf version 3 or -later and uses the f90 netcdf interfaces. It requires a netcdf include -file and a netcdf library. - -cprnc generates an ascii output file via standard out. It initially -summarizes some characteristics of the input file[s]. A compare file is -generally 132 characters wide and an analyze file is less than 80 -characters wide. - -In analyze mode, the output for a field looks like - - ( lon, lat, time, -----) - 259200 ( 587, 134, 1) ( 269, 59, 1) - FX1 96369 8.273160400390625E+02 0.000000000000000E+00 - avg abs field values: 9.052845920820910E+01 - -and a guide to this information is printed at the top of the file - - ( dim1, dim2, dim3, dim4) - ARRSIZ1 ( indx1, indx2, indx3) file 1 - FIELD NVALID MAX MIN - - -The first 10 characters of the field name are identified in the first - dozen columns of the third line. -The first line summarizes the names of the dimensions of the field -The second line summarizes the indices of the maximum and minimum value - of the field for the first three dimensions. If the fourth dimension - exists, it's always assumed to be time. Time is handled separately. -The third line summarizes the number of valid values in the array - and the maximum and minimum value over those valid values. Invalid - values are values that are identified to be "fill" value. -The last line summarizes some overall statistics including the average - absolute value of the valid values of the field. - -In comparison mode, the output (132 chars wide) for a field looks like - - 96369 ( lon, lat, time) - 259200 ( 422, 198, 1) ( 203, 186, 1) ( 47, 169, 1) ( 224, 171, 1) - FIRA 96369 1.466549530029297E+02 -3.922052764892578E+01 1.4E+02 -3.037954139709473E+01 1.0E+00 -3.979958057403564E+00 - 96369 1.321966247558594E+02 -1.603044700622559E+01 1.084177169799805E+02 3.982142448425293E+00 - 259200 ( 156, 31, 1) ( 573, 178, 1) ( - avg abs field values: 6.778244097051392E+01 rms diff: 1.4E+01 avg rel diff(npos): 4.6E-02 - 5.960437961084186E+01 avg decimal digits(ndif): 1.2 worst: 0.0 - -and a guide to this information is printed at the top of the file - - NDIFFS ( dim1, dim2, dim3, dim4, ... ) - ARRSIZ1 ( indx1, indx2, indx3, ... ) file 1 - FIELD NVALID1 MAX1 MIN1 DIFFMAX VALUES RDIFMAX VALUES - NVALID2 MAX2 MIN2 - ARRSIZ2 ( indx1, indx2, indx3, ...) file 2 - -The information content is identical to the information in analyze -mode with the following additions. Two additional lines are added -in the main body. Lines 4 and 5 are identical to line 3 and 2 -respectively but are associated with file 2 instead of file 1. -In addition, the right hand side of lines 2, 3, and 4 contain -information about the maximum difference, the location and values -of the maximum difference, the relative difference and the location -and values of the maximum relative difference. The last two line -summarize some overall statistics including average absolute values -of the field on the two files, rms difference, average relative -difference, average number of digits that match, and the worst -case for the number of digits that match. - -"avg rel diff" gives the average relative difference (sum of relative -differences normalized by the number of indices where both variables -have valid values). The denominator for each relative difference is -the MAX of the two values. - -"avg decimal digits" is determined by: For each diff, determine the -number of digits that match (as -log10(rdiff(i)); add this to a -running sum; then normalize by the number of diffs (ignoring places -where the two variables are the same). For example, if there are 10 -values, 8 of which match, one has a relative difference of 1e-3 and -one has a relative difference of 1e-5, then the avg decimal digits -will be 4. - -"worst decimal digits" is simply log10(1/rdmax), where rdmax is the -max relative difference (in the above example, this would give 3). - -At the end of the output file, a summary is presented that looks like - -SUMMARY of cprnc: - A total number of 119 fields were compared - of which 83 had non-zero differences - and 17 had differences in fill patterns - and 2 had differences in dimension sizes - A total number of 10 fields could not be analyzed - A total number of 0 time-varying fields on file 1 were not found on file 2. - A total number of 0 time-constant fields on file 1 were not found on file 2. - A total number of 0 time-varying fields on file 2 were not found on file 1. - A total number of 0 time-constant fields on file 2 were not found on file 1. - diff_test: the two files seem to be DIFFERENT - - -This summarizes: -- the number of fields that were compared -- the number of fields that differed (not counting fields that differed - only in the fill pattern) -- the number of fields with differences in fill patterns -- the number of fields with differences in dimension sizes -- the number of fields that could not be analyzed -- the number of fields on one file but not the other - - for files with an unlimited (time) dimension, these counts are - broken down into time-varying fields (i.e., fields with an unlimited - dimension) and time-constant fields (i.e., fields without an - unlimited dimension) -- whether the files are IDENTICAL, DIFFERENT, or DIFFER only in their field lists - - Files are considered DIFFERENT if there are differences in the values, fill - patterns or dimension sizes of any variable - - Files are considered to "DIFFER only in their field lists" if matching - variables are all identical, but there are either fields on file1 that are - not on file2, or fields on file2 that are not on file1 - - However, if the only difference in field lists is in the presence - or absence of time-constant fields on a file that has an unlimited - (time) dimension, the files are considered to be IDENTICAL, with - an extra message appended that notes this fact. (While not ideal, - this exception is needed so that exact restart tests pass despite - some time-constant fields being on the output files from one case - but not the other.) - -Developers Guide: ------------------ - -The tool works as follows. - -Fields can be analyzed if they are int, float or double and -have between 0 and n dimensions - -In general, fields that appear on both files are -compared. If they are sizes, no difference -statistics are computed and only a summary of the fields on -the files are presented. If fields only appear -on one file, those fields are analyzed. - -The unlimited dimension is treated uniquely. In general, for files -that have a dimension named "time", the time axes are compared -and matching time values on the two files are compared one -timestep at a time. Time values that don't match are skipped. -To override the matching behaviour, use cprnc -m. In this mode, -timestamps are compared in indexical space. In analyze mode, -the fields are analyzed one timestamp at a time. In general, -if there is a "time" axis, it will be the outer-most loop in -the output analysis. In compare mode, fields with a time axis -and a timestamp that are not common between the two files are -ignored. - -It is also possible to compare files that don't have an unlimited -dimension; in this case, the '-m' flag must be given. diff --git a/CIME/non_py/cprnc/compare_vars_mod.F90.in b/CIME/non_py/cprnc/compare_vars_mod.F90.in deleted file mode 100644 index 5b2e1a1966e..00000000000 --- a/CIME/non_py/cprnc/compare_vars_mod.F90.in +++ /dev/null @@ -1,638 +0,0 @@ -module compare_vars_mod - use filestruct, only : file_t, var_t, is_time_varying, vdimsize, dim_t, verbose - use prec, only : r4, r8, i4 - use netcdf, only : nf90_char, nf90_int, nf90_double, nf90_float, nf90_get_var, nf90_max_dims, & - nf90_inq_varid, nf90_get_att, nf90_noerr - use utils, only : checknf90, get_dim_str, get_dimname_str - implicit none - logical :: ignoretime - - interface compute_var_stats -! TYPE real,double,int - module procedure compute_var_stats_{TYPE} - end interface - - interface get_rdiff_stats - ! TYPE real,double - module procedure get_rdiff_stats_{TYPE} - end interface - -contains - - subroutine compare_vars(n,file, vtotal, ndiffs, nfilldiffs, vsizes_differ, & - vnot_analyzed, vtypes_differ ) - integer, intent(in) :: n ! number of files to analyze (1 or 2) - integer, intent(out) :: vtotal - integer, intent(out) :: ndiffs ! number of fields with differences (not counting fields that differ only in the fill pattern) - integer, intent(out) :: nfilldiffs ! number of fields with differences in fill pattern - integer, intent(out) :: vsizes_differ - integer, intent(out) :: vnot_analyzed - integer, intent(out) :: vtypes_differ - - - type(file_t) :: file(n) - double precision, pointer :: time(:,:) - double precision :: tdiff - ! start by making sure that times match - integer :: ierr, ns1, ns2, vid1 - type(var_t), pointer :: v1 - integer :: i, t, nvars, t1, t2, nt - integer :: vidnsteph - integer, allocatable :: nsteph(:) - character(len=132) :: dimstr - type(dim_t), pointer :: udim - real(r8), parameter :: timeepsilon = 1.e-9 ! time diff less than this considered insignificant - - - vtotal = 0 - vsizes_differ = 0 - vtypes_differ = 0 - vnot_analyzed = 0 - - if(n==2 .and. .not.ignoretime) then - ! NOTE(wjs, 2019-03-21) Most of the cprnc code allows the unlimited dimension to be - ! named anything - not necessarily 'time'. But this block of code assumes that the - ! unlimited dimension is named 'time' in order to find the associated coordinate - ! variable. We should probably generalize this by looking for a variable with the - ! same name as the unlimited dimension. - call checknf90(nf90_inq_varid(file(1)%fh, 'time', vid1), & - err_str='These files don''t have a time dimension, use cprnc with -m') - - ns1 = file(1)%dim(file(1)%unlimdimid)%dimsize - if(n==2) then - ns2 = file(2)%dim(file(2)%unlimdimid)%dimsize - else - ns2=1 - end if - allocate(time(max(ns1,ns2),2)) - - call checknf90(nf90_get_var(file(1)%fh, vid1, time(1:ns1,1))) - if(n==2) then - call checknf90(nf90_get_var(file(2)%fh, file(1)%var(vid1)%matchid, time(1:ns2,2))) - end if - if(verbose) then - print *,'File 1 time: ', time(1:ns1,1) - print *,'File 2 time: ', time(1:ns2,2) - end if - end if - - nvars = size(file(1)%var) - if (file(1)%has_unlimited_dim()) then - udim => file(1)%dim(file(1)%unlimdimid) - else - if (.not. ignoretime) then - write(6,*) 'ERROR: For files without an unlimited dimension,' - write(6,*) 'ignore_time needs to be true (via setting the -m flag to cprnc)' - stop - end if - end if - - ndiffs = 0 - nfilldiffs = 0 - -! First look at variables which do not have unlimdim - do i=1,nvars - v1 => file(1)%var(i) - - if (.not. is_time_varying(v1, file(1)%has_unlimited_dim(), file(1)%unlimdimid)) then - call get_dimname_str(v1%ndims,v1%dimids,file(1)%dim,dimstr) - write(6,140) trim(v1%name),trim(dimstr) - vtotal = vtotal+1 - - call compare_one_var(v1=v1, numcases=n, file=file, varnum=i, & - vsizes_differ=vsizes_differ, & - vnot_analyzed=vnot_analyzed, & - vtypes_differ=vtypes_differ, & - ndiffs=ndiffs, nfilldiffs=nfilldiffs) - - end if - end do - -! Now look at variables that DO have unlimdim - if (file(1)%has_unlimited_dim()) then - - ierr = nf90_inq_varid(file(1)%fh, 'nsteph', vidnsteph) - if(ierr == NF90_NOERR) then - allocate(nsteph(udim%kount)) - call checknf90(nf90_get_var(file(1)%fh, vidnsteph, nsteph)) - end if - - - do t=1,udim%dimsize,udim%kount - t1 = t ! need to find mathing times - assumed for now - t2 = t - if(.not. ignoretime) then - do while(t1<=ns1 .and. t2<= ns2) - tdiff = abs(time(t1,1) - time(t2,2)) - if (tdiff < timeepsilon) exit - if(time(t1,1) < time(t2,2)) then - Write(6,*) 'Skipping a time sample on file 1' - t1=t1+1 - else if(time(t1,1) > time(t2,2)) then - Write(6,*) 'Skipping a time sample on file 2' - t2=t2+1 - end if - end do - if(verbose) print *,__FILE__,__LINE__,tdiff,timeepsilon, t1, t2 - if(tdiff< timeepsilon .and. t1/=t2) then - Write(6,*) 'Found common timesteps:', t1, t2 - else if(tdiff > timeepsilon) then - Write(6,*) 'No matching time found.' - vnot_analyzed = nvars - return - end if - if(verbose) print *,__FILE__,__LINE__,time(t1,1),time(t2,2), t1, t2, time(:,:) - end if - - - if(allocated(nsteph)) then - print *,'NSTEPH: ',nsteph(t) - deallocate(nsteph) - end if - - do i=1,nvars - v1 => file(1)%var(i) - if (is_time_varying(v1, file(1)%has_unlimited_dim(), file(1)%unlimdimid)) then - call get_dimname_str(v1%ndims,v1%dimids,file(1)%dim,dimstr) - vtotal = vtotal+1 - write(6,145) trim(v1%name),trim(dimstr), t1, t2 - - call compare_one_var(v1=v1, numcases=n, file=file, varnum=i, & - vsizes_differ=vsizes_differ, & - vnot_analyzed=vnot_analyzed, & - vtypes_differ=vtypes_differ, & - ndiffs=ndiffs, nfilldiffs=nfilldiffs, & - tindex=(/t1, t2/)) - - end if - end do - end do - end if ! if (file(1)%has_unlimited_dim()) - -140 format(1x,a,3x,a) -145 format(1x,a,3x,a,' t_index = ',2i6) - - end subroutine compare_vars - - - ! Compare a single variable, and update counts - ! For variables with multiple time slices, this just does comparisons for a single time slice - subroutine compare_one_var(v1, numcases, file, varnum, & - vsizes_differ, vnot_analyzed, vtypes_differ, & - ndiffs, nfilldiffs, & - tindex) - type(var_t) , intent(in) :: v1 ! variable info for the variable in file 1 - integer , intent(in) :: numcases - type(file_t), intent(in) :: file(numcases) - integer , intent(in) :: varnum - integer , intent(inout) :: vsizes_differ - integer , intent(inout) :: vnot_analyzed - integer , intent(inout) :: vtypes_differ - integer , intent(inout) :: ndiffs - integer , intent(inout) :: nfilldiffs - integer , intent(in), optional :: tindex(numcases) - - integer :: idiff, ifilldiff, isizes_differ, inot_analyzed, itypes_differ - - ! initialize output arguments of compare_var in case compare_var doesn't get called - idiff = 0 - ifilldiff = 0 - isizes_differ = 0 - itypes_differ = 0 - inot_analyzed = 0 - - select case(v1%xtype) - case(nf90_int) - call compare_var_int(numcases,file,(/varnum,v1%matchid/), & - idiff, ifilldiff, isizes_differ, itypes_differ, & - tindex) - case(nf90_float) - call compare_var_real(numcases,file,(/varnum,v1%matchid/), & - idiff, ifilldiff, isizes_differ, itypes_differ, & - tindex) - case(nf90_double) - call compare_var_double(numcases,file,(/varnum,v1%matchid/), & - idiff, ifilldiff, isizes_differ, itypes_differ, & - tindex) - case(nf90_char) - inot_analyzed = 1 - ! call compare_var_char(file1,file2,i,v1%matchid) - case default - print *,'Type not recognized for variable: ', v1%name - end select - - vsizes_differ = vsizes_differ+isizes_differ - vtypes_differ = vtypes_differ+itypes_differ - vnot_analyzed = vnot_analyzed+inot_analyzed - ndiffs = ndiffs+idiff - nfilldiffs = nfilldiffs + ifilldiff - end subroutine compare_one_var - - - ! TYPE real,int,double - subroutine compare_var_{TYPE}(n,file, vid, idiff, ifilldiff, ifail, itypes, tindex) - use, intrinsic :: ieee_arithmetic, only: ieee_is_nan - integer, intent(in) :: n - type(file_t) :: file(2) - integer, intent(in) :: vid(2) - integer, intent(out) :: idiff ! 1 if diffs in field, 0 otherwise (0 if only diffs are in fill pattern) - integer, intent(out) :: ifilldiff ! 1 if diffs in fill pattern, 0 otherwise - ! (idiff & ifilldiff are both 1 if there are diffs in both the fill pattern and the valid values) - integer, intent(out) :: ifail ! 1 if variable sizes differ, 0 otherwise - integer, intent(out) :: itypes ! 1 if variable types differ, 0 otherwise - integer, optional :: tindex(2) - - integer :: s1, s2, l1(1), i, ierr - - {VTYPE}, pointer :: buf(:,:), vdiff(:) - {VTYPE} :: fv1, fv2 - real(r8) :: rms, min_val(2), max_val(2), avgval(2), m1, rdmax - real(r8) :: rms_normalized ! rms normalized by absolute values - real(r8) :: rms_normalized_denom ! denominator for computing rms_normalized - real(r8) :: rdsum ! sum of relative differences - real(r8) :: rdlogsum ! sum of negative log10 of relative differences - real(r8) :: rdbar ! average of relative differences - real(r8) :: rdlogbar ! rdlogsum normalized by number of non-zero differences - integer :: t(2), n1, n2, min_loc(2), max_loc(2), spacelen - integer :: start(NF90_MAX_DIMS,2), kount(NF90_MAX_DIMS,2), dsizes(NF90_MAX_DIMS,2) - logical, pointer :: mask(:,:) - integer :: diffcnt, rdmaxloc - character(len=80) :: min_str(2), max_str(2), dmax_str, rdmax_str, space - logical :: compare2 - - min_str = '' - max_str = '' - dmax_str = '' - rdmax_str = '' - space = '' - - if(present(tindex)) then - t = tindex - else - t = 1 - end if - - compare2 = (n==2 .and. vid(2)>0) - ifail = 0 - ifilldiff = 0 - idiff = 0 - s1 = vdimsize(file(1)%dim, file(1)%var(vid(1))%dimids) - - if(verbose) print *,__FILE__,__LINE__,s1,file(1)%var(vid(1))%name - - if(compare2) then - s2 = vdimsize(file(2)%dim, file(2)%var(vid(2))%dimids) - - if(s1 /= s2) then - write(6,*) 'WARNING: Variable ',trim(file(1)%var(vid(1))%name),' sizes differ' - write(6,'(a,a32)') ' DIMSIZEDIFF ', file(1)%var(vid(1))%name - ifail = 1 - return - end if - if(file(2)%var(vid(2))%xtype /= file(1)%var(vid(1))%xtype) then - write(6,*) 'WARNING: Variable ',trim(file(1)%var(vid(1))%name),' types differ' - write(6,'(a,a32,2i2)') ' TYPEDIFF ', file(1)%var(vid(1))%name,file(1)%var(vid(1))%xtype,file(2)%var(vid(2))%xtype - itypes = 1 - endif - - end if - n1 = size(file(1)%var(vid(1))%dimids) - - do i=1,n1 - start(i,1) = file(1)%dim(file(1)%var(vid(1))%dimids(i))%start - kount(i,1) = file(1)%dim(file(1)%var(vid(1))%dimids(i))%kount - dsizes(i,1) = file(1)%dim(file(1)%var(vid(1))%dimids(i))%dimsize - if(file(1)%var(vid(1))%dimids(i) == file(1)%unlimdimid) then - start(i,1)=t(1) - dsizes(i,1) = kount(i,1) - end if - end do - - allocate(buf(s1,n)) - - call checknf90(nf90_get_var(file(1)%fh, vid(1), buf(:,1), start(1:n1,1), kount(1:n1,1))) - - - allocate(mask(s1,n)) - ierr = nf90_get_att(file(1)%fh, vid(1), '_FillValue', fv1) - if(ierr == NF90_NOERR) then - mask(:,1) = (buf(:,1)/=fv1) - else - mask(:,1) = .true. - end if - if(n1>0) then - call compute_var_stats(buf(:,1), s2, mask(:,1), min_loc(1), max_loc(1), min_val(1), max_val(1), avgval(1)) - call get_dim_str(n1,translate_loc(n1,min_loc(1),start(1:n1,1),kount(1:n1,1),dsizes(1:n1,1)),min_str(1)) - call get_dim_str(n1,translate_loc(n1,max_loc(1),start(1:n1,1),kount(1:n1,1),dsizes(1:n1,1)),max_str(1)) - end if - space = ' ' - spacelen=1 - if(n1>3) spacelen=(n1-3)*8 ! adjusts the output format - - if(compare2) then - n2 = size(file(2)%var(vid(2))%dimids) - if(n2/=n1) then - print *,'WARNING variable ',trim(file(1)%var(vid(1))%name),& - ' dims differ but total size is the same, will try to compare anyway' - endif - - - do i=1,n2 - start(i,2) = file(2)%dim(file(2)%var(vid(2))%dimids(i))%start - kount(i,2) = file(2)%dim(file(2)%var(vid(2))%dimids(i))%kount - dsizes(i,2) = file(2)%dim(file(2)%var(vid(2))%dimids(i))%dimsize - if(file(2)%var(vid(2))%dimids(i) == file(2)%unlimdimid) then - start(i,2)=t(2) - dsizes(i,2) = kount(i,2) - end if - end do - - call checknf90(nf90_get_var(file(2)%fh, vid(2), buf(:,2), start(1:n2,2), kount(1:n2,2))) - ierr = nf90_get_att(file(2)%fh, vid(2), '_FillValue', fv2) - if(ierr == NF90_NOERR) then - mask(:,2) = (buf(:,2)/=fv2) - else - mask(:,2) = .true. - end if - if(n2>0) then - call compute_var_stats(buf(:,2), s2, mask(:,2), min_loc(2), max_loc(2), min_val(2), max_val(2), avgval(2)) - call get_dim_str(n2,translate_loc(n2,min_loc(2),start(1:n2,2),kount(1:n2,2),dsizes(1:n2,2)),min_str(2)) - call get_dim_str(n2,translate_loc(n2,max_loc(2),start(1:n2,2),kount(1:n2,2),dsizes(1:n2,2)),max_str(2)) - end if - diffcnt=0 - if(any(buf(:,1) /= buf(:,2))) then - allocate(vdiff(s1)) - -! Use the union of mask1 and mask2 - if(any(mask(:,1) .neqv. mask(:,2))) then - write(6,*) 'WARNING: Fill patterns differ between files' - write(6,'(a,a32)') ' FILLDIFF ', file(1)%var(vid(1))%name - ifilldiff = 1 - mask(:,1) = (mask(:,1) .and. mask(:,2)) - end if - - s2 = count(mask(:,1)) - vdiff = abs(buf(:,1)-buf(:,2)) - rms = sqrt(sum(vdiff**2,mask(:,1))/real(s2)) - diffcnt = 0 -#if {ITYPE}==TYPEDOUBLE || {ITYPE}==TYPEREAL - ! Count the NaN values only if they differ between files - do i=1,s1 - if(mask(i,1)) then - if(ieee_is_nan(buf(i,1)) .neqv. ieee_is_nan(buf(i,2))) then - diffcnt = diffcnt + 1 - endif - endif - enddo -#endif - diffcnt = diffcnt + count(vdiff>0 .and. mask(:,1)) - ! Compute normalized rms difference; normalize using the avg abs field - ! values. Note that this differs from the definition of normalized rms - ! difference found in some references (e.g., normalizing by [max - min], which - ! can be sensitive to outliers). - if (n1 > 0 .and. n2 > 0 .and. rms > 0) then - rms_normalized_denom = (avgval(1) + avgval(2)) / 2.0 - if(abs(rms_normalized_denom)>0)then - rms_normalized = rms / rms_normalized_denom - else - rms_normalized = huge(rms) - end if - else - ! don't try to compute rms_normalized in any of the following conditions: - ! n1 = 0 -- then we won't have avgval(1) - ! n2 = 0 -- then we won't have avgval(2) - ! rms = 0 -- then rms_normalized should be 0... but don't try to compute it - ! above in case we have a 0/0 condition - rms_normalized = 0 - end if - - -! diffcnt==0 implies only diffs are in missing values - if(diffcnt>0) then - idiff = 1 - m1 = maxval(vdiff, mask=mask(:,1)) - l1 = maxloc(vdiff, mask=mask(:,1)) - - - if (n1>0) then - call get_dim_str(n1,translate_loc(n1,l1(1),start(1:n1,1),kount(1:n1,1),dsizes(1:n1,1)),dmax_str) - else - dmax_str = ' ' - end if - -#if ({ITYPE} != TYPEINT) - call get_rdiff_stats(s1,buf(:,1),buf(:,2),vdiff,mask(:,1),rdsum, rdlogsum, rdmax, rdmaxloc) - if (n1>0) then - call get_dim_str(n1,translate_loc(n1,rdmaxloc,start(1:n1,1),kount(1:n1,1),dsizes(1:n1,1)),rdmax_str) - else - rdmax_str = ' ' - end if -#endif - - deallocate(vdiff) - - rdbar = rdsum / real(s2) - rdlogbar = rdlogsum / real(diffcnt) - - if(n1==0) then - ! Note that NORMALIZED RMS is NOT computed in this case, so we simply - ! print 0 for that. -#if ({ITYPE} == TYPEINT) - write(6,902) s2, buf(1,1), buf(2,1) - write(6,811) ' RMS ', file(1)%var(vid(1))%name, rms, ' NORMALIZED ', 0 -#else - write(6,803) s2, buf(1,1), buf(2,1) - write(6,812) ' RMS ', file(1)%var(vid(1))%name, rms, ' NORMALIZED ', 0. -#endif - - else - write(6,800) diffcnt, s1, trim(max_str(1)),trim(min_str(1)), trim(dmax_str), trim(rdmax_str) -#if ({ITYPE} == TYPEINT) - ! Note that rdmaxloc is NOT computed in this case, so we print 0 in place - ! of buf(rdmaxloc,1) and buf(rdmaxloc,2) - write(6,903) s2, max_val(1), min_val(1), m1, buf(l1(1),1), rdbar, 0.0, & - count(mask(:,2)), max_val(2), min_val(2), buf(l1(1),2), 0.0 - write(6,810) s1, trim(max_str(2)), trim(min_str(2)) - ! write(6,905) avgval(1), rms, rdbar, avgval(2), rdlogbar, log10(1./rdmax) - write(6,812) ' RMS ', file(1)%var(vid(1))%name, rms, ' NORMALIZED ', rms_normalized -#else - write(6,803) s2, max_val(1), space(1:spacelen),min_val(1), m1, buf(l1(1),1), rdbar, buf(rdmaxloc,1), & - count(mask(:,2)), max_val(2), space(1:spacelen),min_val(2), buf(l1(1),2), buf(rdmaxloc,2) - write(6,810) s1, trim(max_str(2)), trim(min_str(2)) - write(6,805) avgval(1), rms, rdbar, avgval(2), rdlogbar, log10(1./rdmax) - write(6,812) ' RMS ', file(1)%var(vid(1))%name, rms, ' NORMALIZED ', rms_normalized -#endif - endif - endif - end if - if(diffcnt==0) then ! no differences found - if(n1>0) then - write(6,810) s1, trim(max_str(1)),trim(min_str(1)) -#if ({ITYPE} == TYPEINT) - write(6,914) s2, max_val(1), space(1:spacelen),min_val(1), count(mask(:,2)),& - max_val(2),space(1:spacelen),min_val(2) - write(6,810) s1, trim(max_str(2)), trim(min_str(2)) - write(6,815) avgval(1), avgval(2) -#else - write(6,814) s2, max_val(1), space(1:spacelen),min_val(1), count(mask(:,2)),& - max_val(2),space(1:spacelen),min_val(2) - write(6,810) s1, trim(max_str(2)), trim(min_str(2)) - write(6,815) avgval(1), avgval(2) -#endif - endif - end if - else ! Single file analysis output - if(n==2 ) then - write(6,*) 'Variable on file1: ',trim(file(1)%var(vid(1))%name),' not found on file2' - end if - - write(6,810 ) s1, trim(max_str(1)),trim(min_str(1)) - write(6, 825) s2, max_val(1),min_val(1) - write(6, 826) avgval(1) - end if - - deallocate(buf, mask) -800 format(3x,i8,1x,i8,2x,a,1x,a,1x,a,1x,a) -803 format(12x, i8,1x,1pe23.15,a,e23.15,e8.1, e23.15,e8.1,e23.15,/, & - 12x, i8,1x, e23.15,a,e23.15,8x, e23.15,8x, e23.15) - - -805 format(10x,'avg abs field values: ',1pe23.15,4x,'rms diff:',e8.1, & - 3x,'avg rel diff(npos): ',e8.1,/, & - 10x,' ', e23.15,24x, & - 'avg decimal digits(ndif): ',0p,f4.1,' worst: ',f4.1) - -810 format(12x,i8,2x,a,1x,a) - -! RMS for int -811 format(a,a32,1pe11.4,11x,a,i12,/) - -! RMS for real -812 format(a,a32,1pe11.4,11x,a,1pe11.4,/) - -814 format(12x, i8,1x,e23.15,a,e23.15,/, & - 12x, i8,1x,e23.15,a,e23.15) -815 format(10x,'avg abs field values: ',1pe23.15,/, & - 10x,' ', e23.15) -825 format(12x,i8,1x,1p2e23.15) -826 format(12x,'avg abs field values: ',1pe23.15,/) -902 format(12x, i8,1x,i8,a,i8) - -903 format(12x, i8,3e23.15,i8,2e23.15/, & - 12x, i8,2e23.15,23x,i8,23x,e23.15) - - -905 format(10x,'avg abs field values: ',i8,4x,'rms diff:',i8, & - 3x,'avg rel diff(npos): ',i8,/, & - 10x,' ', i8,24x, & - 'avg decimal digits(ndif): ',i8,' worst: ',i8) -914 format(12x, i8,1x,1pe23.15,a,1pe23.15,/, & - 12x, i8,1x,1pe23.15,a,1pe23.15) -915 format(10x,'avg abs field values: ',i8,/, & - 10x,' ', i8) - - end subroutine compare_var_{TYPE} - - ! TYPE real,double - subroutine get_rdiff_stats_{TYPE} (s1, v1, v2, vdiff, mask, rdsum, rdlogsum, rdmax, loc) - integer, intent(in) :: s1 - {VTYPE}, intent(in) :: v1(:), v2(:), vdiff(:) - logical, intent(in) :: mask(:) - real(r8), intent(out) :: rdsum, rdlogsum, rdmax - integer, intent(out) :: loc - real(r8) :: denom, rdiff(s1) - - integer :: i, iloc(1) - - rdiff=0 - rdsum=0 - rdlogsum=0 - do i=1,s1 - if(vdiff(i)>0) then - denom = max(abs(v1(i)), abs(v2(i))) - rdiff(i) = vdiff(i)/denom - rdsum = rdsum+rdiff(i) - rdlogsum = rdlogsum - log10(rdiff(i)) - end if - end do - rdmax = maxval(rdiff) - iloc = maxloc(rdiff) - - loc = iloc(1) - - end subroutine get_rdiff_stats_{TYPE} - - ! TYPE real,int,double - subroutine compute_var_stats_{TYPE} (buf, nvalid, mask, min_loc, max_loc, min_val, max_val, avgval) - {VTYPE}, intent(in) :: buf(:) - logical, intent(in) :: mask(:) - integer, intent(out) :: nvalid, min_loc, max_loc - real(r8), intent(out) :: min_val, max_val, avgval - - integer :: loc(2) - - nvalid = count(mask) - if(nvalid>0) then - loc(1:1) = maxloc(buf, mask=mask) - loc(2:2) = minloc(buf, mask=mask) - max_loc = loc(1) - min_loc = loc(2) - max_val = maxval(buf, mask=mask) - min_val = minval(buf, mask=mask) - avgval = sum(abs(buf),mask=mask)/real(nvalid) - else - max_loc=0 - min_loc=0 - max_val=0 - min_val=0 - avgval=0 - end if - - - - end subroutine compute_var_stats_{TYPE} - - - - - - function translate_loc(ndims, loc, start, kount, dsize) - integer, intent(in) :: ndims, loc, start(:), kount(:), dsize(:) - integer :: translate_loc(ndims) - - integer :: i, tloc, tprod - - tprod = product(kount) - if(loc>tprod) then - write(6,*) 'ERROR in translate_loc: location ',loc,' exceeds array size',tprod - stop - end if - if(ndims<1) then - stop '0D array in translate_loc' - endif - translate_loc = 1 - if(ndims==1) then - translate_loc = loc - else if(loc<=dsize(1)) then - translate_loc(1) = loc - else - tloc = loc - - if(verbose) print *,__LINE__,loc,ndims,dsize(1:ndims) - do i=ndims,1,-1 - tprod = tprod/dsize(i) - if(tloc>=tprod) then - translate_loc(i) = tloc/tprod + start(i) - tloc = tloc - (tloc/tprod)*tprod - end if - end do - translate_loc(1) = translate_loc(1)-1 - - if(verbose) print *,__LINE__,translate_loc(1:ndims) - end if - - end function translate_loc - - - -end module compare_vars_mod diff --git a/CIME/non_py/cprnc/cprnc.F90 b/CIME/non_py/cprnc/cprnc.F90 deleted file mode 100644 index 735b02c6f7d..00000000000 --- a/CIME/non_py/cprnc/cprnc.F90 +++ /dev/null @@ -1,310 +0,0 @@ -program piocprnc - use netcdf - use filestruct - use compare_vars_mod -#ifdef NAGFOR - use f90_unix -#endif - implicit none - - integer :: nargs, n - character(len=1024) :: arg = '' ! cmd-line argument - character(len=1024) :: fname(2) = ' ' ! input filenames - integer :: nchars - integer :: numcases=1 - integer :: ierr -! integer, external :: iargc - type(file_t) :: file(2) - type(dim_t) :: dimoptions(12) - integer :: dimoptioncnt - integer :: nvars, ndiffs, nfilldiffs - - ! The following variables count the number of fields found on one file but not the - ! other, only considering (a) fields with an unlimited (time) dimension, and (b) fields - ! without an unlimited (time) dimension on a file that doesn't have an unlimited - ! dimension. - integer :: num_not_found_on_file1, num_not_found_on_file2 - - ! The following variables count the number of fields found on one file but not the - ! other, only considering fields without an unlimited (time) dimension on a file that - ! has an unlimited dimension. - integer :: num_not_found_on_file1_timeconst, num_not_found_on_file2_timeconst - - integer :: num_sizes_differ - integer :: num_types_differ - integer :: num_not_analyzed -! -! Parse arg list -! - - - nargs = command_argument_count () - dimoptioncnt=0 - ignoretime=.false. - n = 1 - do while (n <= nargs) - arg = ' ' - call getarg (n, arg) - n = n + 1 - select case (arg) - case ('-v') - verbose = .true. - case ('-d') - call getarg(n, arg) - n=n+1 - dimoptioncnt=dimoptioncnt+1 - call parsearg(arg, dimoptions(dimoptioncnt)%name, dimoptions(dimoptioncnt)%start, dimoptions(dimoptioncnt)%kount) - - case ('-m') - ignoretime=.true. - case default - if (fname(1) == ' ') then - fname(1) = arg(1:len_trim(arg)) - nchars = len_trim (fname(1)) - write (6,*) 'file 1=',fname(1)(1:nchars) - else if (fname(2)==' ') then - fname(2) = arg(1:len_trim(arg)) - nchars = len_trim (fname(2)) - write (6,*) 'file 2=',fname(2)(1:nchars) - numcases = 2 - else - call usage_exit (' ') - end if - end select - end do -! -! Must have at least 1 file input -! - if (fname(1) == ' ') then - call usage_exit ('You must enter at least 1 input file') - end if - -! -! Read the files and initialize file_t -! - do n=1, numcases - ierr = nf90_open(fname(n),NF90_NOWRITE, file(n)%fh) - if(ierr /= NF90_NOERR) then - stop 'Failed to open file ' - endif - if(dimoptioncnt>0) then - call init_file_struct( file(n), dimoptions(1:dimoptioncnt) ) - else - call init_file_struct( file(n)) - end if - end do - - if(numcases==2) then - call compare_metadata(file(1), file(2)) - - call compare_dimensions( file(1)%dim, file(2)%dim) - - num_not_found_on_file1 = 0 - num_not_found_on_file2 = 0 - num_not_found_on_file1_timeconst = 0 - num_not_found_on_file2_timeconst = 0 - call match_vars( file(1), file(2), & - num_not_found_on_file1 = num_not_found_on_file1, & - num_not_found_on_file2 = num_not_found_on_file2, & - num_not_found_on_file1_timeconst = num_not_found_on_file1_timeconst, & - num_not_found_on_file2_timeconst = num_not_found_on_file2_timeconst) - end if - call compare_vars(numcases, file, nvars, ndiffs, nfilldiffs, & - num_sizes_differ, num_not_analyzed, num_types_differ) - - -! -! Summarize results -! - write(6,806) - write(6,*) ' ' - write(6,700) 'SUMMARY of cprnc:' - if(numcases==1) then - write(6,700) ' A total number of ',nvars,' fields in file 1 were analyzed (non-compare mode)' - write(6,700) ' A total number of ',num_not_analyzed, & - ' fields in file 1 could not be analyzed' - else - write(6,700) ' A total number of ',nvars,' fields were compared' - write(6,700) ' of which ',ndiffs,' had non-zero differences' - write(6,700) ' and ',nfilldiffs,' had differences in fill patterns' - write(6,700) ' and ',num_sizes_differ,' had different dimension sizes' - write(6,700) ' and ',num_types_differ,' had different data types' - write(6,700) ' A total number of ',num_sizes_differ + num_not_analyzed, & - ' fields could not be analyzed' - - call print_fields_not_found( & - filenum = 1, & - file_has_unlimited_dim = file(1)%has_unlimited_dim(), & - num_not_found = num_not_found_on_file2, & - num_not_found_timeconst = num_not_found_on_file2_timeconst) - - call print_fields_not_found( & - filenum = 2, & - file_has_unlimited_dim = file(2)%has_unlimited_dim(), & - num_not_found = num_not_found_on_file1, & - num_not_found_timeconst = num_not_found_on_file1_timeconst) - - if (nvars == 0 .or. ndiffs > 0 .or. nfilldiffs > 0 .or. & - num_sizes_differ > 0 .or. num_not_analyzed >= nvars .or. & - num_types_differ > 0) then - write(6,700) ' diff_test: the two files seem to be DIFFERENT ' - else if (num_not_found_on_file1 > 0 .or. num_not_found_on_file2 > 0) then - ! Note that we deliberately allow num_not_found_on_file1_timeconst or - ! num_not_found_on_file2_timeconst to be > 0: those do NOT result in a - ! "DIFFER" result. - ! - ! Ideally, we'd count those fields here, too. Doing so would catch more - ! differences and would simplify the cprnc code. But this sometimes leads to - ! problems when comparing restart vs. baseline files - ! (https://github.com/ESMCI/cime/issues/3007). We could add a flag that you - ! specify to not count these fields, but there are backwards compatibility - ! issues with doing so. Eventually it could be good to count these absent - ! fields as a DIFFER result by default, adding a flag that you can specify to - ! not count them, then have cime specify this flag when doing the in-test - ! comparison (so absent time-constant fields would result in a DIFFER result - ! for cime's baseline comparisons and for interactive use of cprnc). - write(6,'(a)') ' diff_test: the two files DIFFER only in their field lists' - else - write(6,700) ' diff_test: the two files seem to be IDENTICAL ' - if (num_not_found_on_file1_timeconst > 0 .or. & - num_not_found_on_file2_timeconst > 0) then - write(6,'(a)') ' (But note that there were differences in field lists just for time-constant fields.)' - end if - end if - end if - write(6,*) ' ' -700 format(a,i6,a) -806 format(132('*')) - - - - contains - subroutine usage_exit (arg) - implicit none - - character(len=*), intent(in) :: arg - - if (arg /= ' ') write (6,*) arg - write(6,*)'Usage: cprnc [-m] [-v] [-d dimname:start[:count]] file1 [file2]' - write(6,*)'-v: Verbose output' - write(6,*)'-m: Ignore time variable and just match contents (default is to match the values in variable time.)' - write(6,*)'-d dimname:start[:count]: Print variable values for the specified dimension index start and count. If not present,' - write(6,*)' count will default to 1. If count is < 0 then count will be set to dimsize-start' - write(6,*)' ' - - stop 999 - end subroutine usage_exit - - - subroutine parsearg (arg, dimname, v1, v2) - !------------------------------------------------------------------------------------------- - ! Purpose: Parse cmd line args about printing. - ! - ! Method: Input is expected in the form: dimname:number1[:number2] where dimname is expected to - ! be the name of a dimension in the input file(s), number1 is the starting position in that - ! dimension to be evaluated and number2 is the number of values to read in the dimension - ! if number2 is missing all remaining values are read. - ! - !------------------------------------------------------------------------------------------- - implicit none - - character(len=*), intent(in) :: arg ! cmd line arg expected of the form 'num1:num2' or 'num1' - - character(len=*), intent(out) :: dimname - integer, intent(out) :: v1 ! e.g. num1 from above example - integer, intent(out) :: v2 ! e.g. num2 from above example - - integer :: i, j ! indices through arg - integer :: ierr ! io error status - - ! - ! First get a dimension name - ! - dimname = ' ' - i = scan(arg,':') - dimname(1:i-1)=arg(1:i-1) - i=i+1 - - ! - ! now try to get an integer number for everything up to ":" - ! - j=i - do while (j < len(arg) .and. arg(j:j) >= '0' .and. arg(j:j) <= '9' .and. arg(j:j) /= ':') - j = j + 1 - end do - read (arg(i:j-1), '(i5)') v1 - ! - ! Next, if ":" comes after the number, look for the next number - ! - i=j - - if (arg(i:i) == ':') then - j = i + 1 - do while (j < len(arg) .and. scan(arg(j:j),"-0123456789")>0) - j = j + 1 - end do - read (arg(i+1:j-1), '(i5)', iostat=ierr) v2 - ! - ! On unexpected input set v2 = -1, e.g. "-d lon:2:blah" will mean get all lons > 1 - ! - if (ierr /= 0) then - v2 = -1 - end if - else - ! - ! ":" not present. Interpret for example '-d lon:2' to mean '-d lon:2:1' - ! - v2 = 1 - end if - if(verbose) print *,__FILE__,__LINE__,trim(dimname),v1,v2 - return - end subroutine parsearg - - subroutine print_fields_not_found(filenum, file_has_unlimited_dim, & - num_not_found, num_not_found_timeconst) - ! Prints information about the number of fields in filenum not found on the other file - - integer, intent(in) :: filenum ! file number for which we're printing this information - logical, intent(in) :: file_has_unlimited_dim ! whether this file has an unlimited dimension - - ! Number of fields in filenum but not on the other file, only considering (a) fields - ! with an unlimited (time) dimension, and (b) fields without an unlimited (time) - ! dimension on a file that doesn't have an unlimited dimension - integer, intent(in) :: num_not_found - - ! Number of fields in filenum but not on the other file, only considering fields - ! without an unlimited (time) dimension on a file that has an unlimited dimension - integer, intent(in) :: num_not_found_timeconst - - integer :: other_filenum - - if (filenum == 1) then - other_filenum = 2 - else if (filenum == 2) then - other_filenum = 1 - else - stop 'Unexpected value for filenum' - end if - - if (file_has_unlimited_dim) then - write(6,'(a,i6,a,i1,a,i1,a)') & - ' A total number of ', num_not_found, & - ' time-varying fields on file ', filenum, & - ' were not found on file ', other_filenum, '.' - write(6,'(a,i6,a,i1,a,i1,a)') & - ' A total number of ', num_not_found_timeconst, & - ' time-constant fields on file ', filenum, & - ' were not found on file ', other_filenum, '.' - else - write(6,'(a,i6,a,i1,a,i1,a)') & - ' A total number of ', num_not_found, & - ' fields on file ', filenum, & - ' were not found on file ', other_filenum, '.' - if (num_not_found_timeconst > 0) then - stop 'Programming error: file has no unlimited dimension, but num_not_found_timeconst > 0' - end if - end if - - end subroutine print_fields_not_found - - end program piocprnc diff --git a/CIME/non_py/cprnc/filestruct.F90 b/CIME/non_py/cprnc/filestruct.F90 deleted file mode 100644 index 814e7faed5e..00000000000 --- a/CIME/non_py/cprnc/filestruct.F90 +++ /dev/null @@ -1,548 +0,0 @@ -module filestruct - use netcdf - implicit none - type dim_t - integer :: dimsize - integer :: start, kount ! used for user requested dimension subsetting - character(len=nf90_MAX_NAME) ::name = '' - end type dim_t - - type var_t - integer :: matchid - integer :: ndims - integer :: natts - integer, pointer :: dimids(:) - integer :: xtype - character(len=nf90_MAX_NAME) ::name = '' - end type var_t - - type file_t - integer :: fh - integer :: natts - type(dim_t), pointer :: dim(:) - type(var_t), pointer :: var(:) - integer :: unlimdimid - contains - procedure :: has_unlimited_dim ! logical function; returns true if this file has an unlimited dimension - end type file_t - - logical :: verbose - -contains - logical function has_unlimited_dim(file) - ! Returns true if this file has an unlimited dimension - class(file_t), intent(in) :: file - - if (file%unlimdimid == -1) then - has_unlimited_dim = .false. - else - has_unlimited_dim = .true. - end if - end function has_unlimited_dim - - subroutine init_file_struct( file, dimoptions ) - - type(file_t) :: file - type(dim_t), optional :: dimoptions(:) - integer :: ndims, nvars - integer :: dimids(NF90_MAX_DIMS) - integer :: i, ierr, docnt, n1, n2 - integer :: j, start, kount - character(len=NF90_MAX_NAME) :: name, dname - ierr= nf90_inquire(file%fh, ndims, nvars, file%natts, file%unlimdimid) - - allocate(file%dim(ndims)) - allocate(file%var(nvars)) - - - do i=1,ndims - ierr = nf90_inquire_dimension(file%fh, i, file%dim(i)%name, file%dim(i)%dimsize) - file%dim(i)%start=1 - if(i==file%unlimdimid) then - file%dim(i)%kount=1 - else - file%dim(i)%kount=file%dim(i)%dimsize - end if - end do - - if(present(dimoptions)) then - docnt = size(dimoptions) - do j=1,docnt - start = dimoptions(j)%start - kount = dimoptions(j)%kount - name = dimoptions(j)%name - n1 = len_trim(name) - do i=1,ndims - dname = file%dim(i)%name - n2 = len_trim(dname) - if(name(1:n1).eq.dname(1:n2) ) then - - - if((start > 0) .and. (start < file%dim(i)%dimsize)) then - file%dim(i)%start = start - else - write(6,*) 'Command line start value for dim ',name(1:n1),& - ' out of bounds, expected 1-',file%dim(i)%dimsize,' got: ',start - stop - end if - if(kount > 0 .and. start+kount <= file%dim(i)%dimsize) then - file%dim(i)%kount = kount - else if(kount == -1) then - file%dim(i)%kount = file%dim(i)%dimsize-file%dim(i)%start+1 - else - write(6,*) 'Command line count value for dim ',name(1:n1),& - ' out of bounds, expected 1-',file%dim(i)%dimsize-file%dim(i)%start+1,' got: ',kount - stop - - endif - write(6,*) 'Setting dimension bounds for dim ',name(1:n1),file%dim(i)%start,file%dim(i)%kount - - exit - end if - end do - end do - end if - - do i=1,nvars - file%var(i)%matchid=-1 - ierr = nf90_inquire_variable(file%fh, i, file%var(i)%name, file%var(i)%xtype, file%var(i)%ndims, dimids, & - file%var(i)%natts) - allocate(file%var(i)%dimids(file%var(i)%ndims)) - file%var(i)%dimids = dimids(1:file%var(i)%ndims) - end do - - - end subroutine init_file_struct - - - subroutine compare_metadata(file1, file2, vid) - type(file_t) :: file1, file2 - integer, optional, intent(in) :: vid - - integer :: id1, id2, natts1, natts2 - - integer :: i, ierr - character(len=NF90_MAX_NAME) :: attname - integer :: atttype, attlen - - real, pointer :: attreal1(:), attreal2(:) - double precision, pointer :: attdouble1(:),attdouble2(:) - integer, pointer :: attint1(:),attint2(:) - integer, parameter :: maxstrlen=32767 - character(len=maxstrlen) :: attchar1, attchar2 - logical :: found - - - if(present(vid)) then - id1 = vid - id2 = file1%var(id1)%matchid - ierr = nf90_inquire_variable(file1%fh, id1, nAtts=natts1) - ierr = nf90_inquire_variable(file2%fh, id2, nAtts=natts2) - else - id1 = NF90_GLOBAL - id2 = NF90_GLOBAL - natts1 = file1%natts - natts2 = file2%natts - end if - - do i=1,natts1 - found = .true. - attname = '' - ierr = nf90_inq_attname(file1%fh, id1, i, attname) - ierr = nf90_inquire_attribute(file1%fh, id1, trim(attname), atttype, attlen) - - select case(atttype) - case(nf90_char) - if (attlen > maxstrlen) then - stop 'maximum string length exceeded' - endif - attchar1=' ' - attchar2=' ' - - ierr = nf90_get_att(file1%fh,id1, trim(attname), attchar1) - ierr = nf90_get_att(file2%fh,id2, trim(attname), attchar2) - if(ierr==NF90_NOERR) then - if(trim(attname).ne.'case' .and. attchar1(1:attlen) .ne. attchar2(1:attlen)) then - print *, 'Attribute ',trim(attname),' from file1: ',attchar1(1:attlen),& - ' does not match that found on file2: ',attchar2(1:attlen) - end if - else - print *, 'Attribute ',trim(attname),' from file1: ',attchar1(1:attlen),& - ' not found on file2' - end if - if(id1==NF90_GLOBAL .and. trim(attname) .eq. 'case') then - print *, 'CASE 1 : ',trim(attchar1) - print *, 'CASE 2 : ',trim(attchar2) - endif - if(id1==NF90_GLOBAL .and. trim(attname) .eq. 'title') then - print *, 'TITLE 1 : ',trim(attchar1) - print *, 'TITLE 2 : ',trim(attchar2) - end if - case(nf90_int) - allocate(attint1(attlen),attint2(attlen)) - ierr = nf90_get_att(file1%fh,id1, trim(attname), attint1) - ierr = nf90_get_att(file2%fh,id2, trim(attname), attint2) - - if(ierr==NF90_NOERR) then - if(any(attint1 /= attint2)) then - print *, 'Attribute ',trim(attname),' from file1: ',attint1,' does not match that found on file2 ',attint2 - end if - else - print *, 'Attribute ',trim(attname),' from file1: ',attint1,' not found on file2' - end if - deallocate(attint1, attint2) - - - case(nf90_float) - allocate(attreal1(attlen),attreal2(attlen)) - ierr = nf90_get_att(file1%fh,id1, trim(attname), attreal1) - ierr = nf90_get_att(file2%fh,id2, trim(attname), attreal2) - if(ierr==NF90_NOERR) then - if(any(attreal1 /= attreal2)) then - print *, 'Attribute ',trim(attname),' from file1: ',attreal1,' does not match that found on file2 ',attreal2 - end if - else - print *, 'Attribute ',trim(attname),' from file1: ',attreal1,' not found on file2' - end if - deallocate(attreal1, attreal2) - case(nf90_double) - allocate(attdouble1(attlen), attdouble2(attlen)) - ierr = nf90_get_att(file1%fh,id1, trim(attname), attdouble1) - ierr = nf90_get_att(file2%fh,id2, trim(attname), attdouble2) - if(ierr==NF90_NOERR) then - if(any(attdouble1 /= attdouble2)) then - print *, 'Attribute ',trim(attname),' from file1: ',attdouble1,' does not match that found on file2 ',attdouble2 - end if - else - print *, 'Attribute ',trim(attname),' from file1: ',attdouble1,' not found on file2' - end if - deallocate(attdouble1, attdouble2) - case default - print *,' Did not recognize attribute with id: ',i,' type: ',atttype, ' name: ',trim(attname), ' len: ',attlen - end select - end do - - end subroutine compare_metadata - - - - - - - - - subroutine compare_dimensions( dimfile1, dimfile2) - type(dim_t), intent(in) :: dimfile1(:), dimfile2(:) - - integer :: ds1, ds2 - integer :: i, j - logical,pointer :: found(:,:) - - ds1 = size(dimfile1) - ds2 = size(dimfile2) - - allocate(found(2,max(ds1,ds2))) - - found = .false. - do i=1,ds1 - do j=1,ds2 - if(dimfile1(i)%name .eq. dimfile2(j)%name) then - if(dimfile1(i)%dimsize == dimfile2(j)%dimsize) then - print *, 'Dimension ',trim(dimfile1(i)%name), ' matches' - else - print *, 'Dimension ',trim(dimfile1(i)%name), ' differs ', dimfile1(i)%dimsize, ' /= ',dimfile2(j)%dimsize - end if - found(1,i) = .true. - found(2,j) = .true. - end if - end do - end do - do i=1,ds1 - if(.not. found(1,i)) then - print *, 'Could not find match for file 1 dimension ',trim(dimfile1(i)%name) - end if - end do - do i=1,ds2 - if(.not. found(2,i)) then - print *, 'Could not find match for file 2 dimension ',trim(dimfile2(i)%name) - end if - end do - deallocate(found) - end subroutine compare_dimensions - - - subroutine match_vars( file1, file2, & - num_not_found_on_file1, num_not_found_on_file2, & - num_not_found_on_file1_timeconst, num_not_found_on_file2_timeconst) - type(file_t), intent(inout) :: file1, file2 - - ! Accumulates count of variables on file2 not found on file1; this only considers (a) - ! fields with an unlimited (time) dimension, and (b) fields without an unlimited - ! (time) dimension on a file that doesn't have an unlimited dimension. - integer, intent(inout) :: num_not_found_on_file1 - - ! Accumulates count of variables on file1 not found on file2; this only considers (a) - ! fields with an unlimited (time) dimension, and (b) fields without an unlimited - ! (time) dimension on a file that doesn't have an unlimited dimension. - integer, intent(inout) :: num_not_found_on_file2 - - ! Accumulates count of variables on file2 not found on file1; this only considers - ! fields without an unlimited (time) dimension on a file that has an unlimited - ! dimension. - integer, intent(inout) :: num_not_found_on_file1_timeconst - - ! Accumulates count of variables on file1 not found on file2; this only considers - ! fields without an unlimited (time) dimension on a file that has an unlimited - ! dimension. - integer, intent(inout) :: num_not_found_on_file2_timeconst - - type(var_t), pointer :: varfile1(:),varfile2(:) - - integer :: vs1, vs2, i, j - - - - varfile1 => file1%var - varfile2 => file2%var - - vs1 = size(varfile1) - vs2 = size(varfile2) - - do i=1,vs1 - do j=1,vs2 - if(varfile1(i)%name .eq. varfile2(j)%name) then - varfile1(i)%matchid=j - varfile2(j)%matchid=i - end if - end do - end do - do i=1,vs1 - if(varfile1(i)%matchid<0) then - print *, 'Could not find match for file1 variable ',trim(varfile1(i)%name), ' in file2' - if (file1%has_unlimited_dim() .and. & - .not. is_time_varying(varfile1(i), file1%has_unlimited_dim(), file1%unlimdimid)) then - num_not_found_on_file2_timeconst = num_not_found_on_file2_timeconst + 1 - else - num_not_found_on_file2 = num_not_found_on_file2 + 1 - end if - end if - end do - do i=1,vs2 - if(varfile2(i)%matchid<0) then - print *, 'Could not find match for file2 variable ',trim(varfile2(i)%name), ' in file1' - if (file2%has_unlimited_dim() .and. & - .not. is_time_varying(varfile2(i), file2%has_unlimited_dim(), file2%unlimdimid)) then - num_not_found_on_file1_timeconst = num_not_found_on_file1_timeconst + 1 - else - num_not_found_on_file1 = num_not_found_on_file1 + 1 - end if - end if - end do - end subroutine match_vars - - - function is_time_varying(var, file_has_unlimited_dim, unlimdimid) - type(var_t), intent(in) :: var ! variable of interest - logical , intent(in) :: file_has_unlimited_dim ! true if the file has an unlimited dimension - integer , intent(in) :: unlimdimid ! the file's unlimited dim id (if it has one) - - logical :: is_time_varying ! true if the given variable is time-varying - - if (file_has_unlimited_dim) then - is_time_varying = any(var%dimids == unlimdimid) - else - is_time_varying = .false. - end if - end function is_time_varying - - - function vdimsize(dims, dimids) - type(dim_t), intent(in) :: dims(:) - integer, intent(in) :: dimids(:) - - integer :: vdimsize - integer :: i - - vdimsize=1 - do i=1,size(dimids) - if(verbose) print *,__FILE__,__LINE__,i,dimids(i),size(dims),size(dimids) - vdimsize = vdimsize*dims(dimids(i))%kount - end do - - end function vdimsize - - - - - - subroutine compare_var_int(f1, f2, i1, i2, t) - type(file_t) :: f1,f2 - integer, intent(in) :: i1, i2 - integer, optional :: t - - - integer :: s1, s2, m1, m2, l1(1), l2(1), i, ierr - integer, pointer :: v1(:), v2(:), vdiff(:) - integer :: t1, n1 - integer :: start(NF90_MAX_DIMS), count(NF90_MAX_DIMS) - - if(present(t)) then - t1 = t - else - t1 = 1 - end if - - s1 = vdimsize(f1%dim, f1%var(i1)%dimids) - s2 = vdimsize(f2%dim, f2%var(i2)%dimids) - - if(s1 /= s2) then - print *, 'Variable ',f1%var(i)%name,' sizes differ' - end if - - n1 = size(f1%var(i1)%dimids) - start = 1 - do i=1,n1 - count(i) = f1%dim(f1%var(i1)%dimids(i))%dimsize - if(f1%var(i1)%dimids(i) == f1%unlimdimid) then - count(i)=1 - start(i)=t1 - end if - end do - - allocate(v1(s1), v2(s2)) - - ierr = nf90_get_var(f1%fh, i1, v1, start(1:n1), count(1:n1)) - ierr = nf90_get_var(f2%fh, i2, v2, start(1:n1), count(1:n1)) - - if(any(v1 /= v2)) then - allocate(vdiff(s1)) - vdiff = abs(v1-v2) - m1 = maxval(vdiff) - m2 = minval(vdiff) - l1 = maxloc(vdiff) - l2 = minloc(vdiff) - - print *,__FILE__,__LINE__,m1,m2,l1,l2 - deallocate(vdiff) - end if - - deallocate(v1,v2) - end subroutine compare_var_int - - subroutine compare_var_float(f1, f2, i1, i2, t) - type(file_t) :: f1,f2 - integer, intent(in) :: i1, i2 - integer, optional :: t - - - integer :: s1, s2, m1, m2, l1(1), l2(1), i, ierr - real, pointer :: v1(:), v2(:), vdiff(:) - integer :: t1, n1 - integer :: start(NF90_MAX_DIMS), count(NF90_MAX_DIMS) - - if(present(t)) then - t1 = t - else - t1 = 1 - end if - - s1 = vdimsize(f1%dim, f1%var(i1)%dimids) - s2 = vdimsize(f2%dim, f2%var(i2)%dimids) - - if(s1 /= s2) then - print *, 'Variable ',f1%var(i)%name,' sizes differ' - end if - - n1 = size(f1%var(i1)%dimids) - start = 1 - do i=1,n1 - count(i) = f1%dim(f1%var(i1)%dimids(i))%dimsize - if(f1%var(i1)%dimids(i) == f1%unlimdimid) then - count(i)=1 - start(i)=t1 - end if - end do - - allocate(v1(s1), v2(s2)) - - ierr = nf90_get_var(f1%fh, i1, v1, start(1:n1), count(1:n1)) - ierr = nf90_get_var(f2%fh, i2, v2, start(1:n1), count(1:n1)) - - if(any(v1 /= v2)) then - allocate(vdiff(s1)) - vdiff = abs(v1-v2) - m1 = maxval(vdiff) - m2 = minval(vdiff) - l1 = maxloc(vdiff) - l2 = minloc(vdiff) - - print *,__FILE__,__LINE__,m1,m2,l1,l2 - deallocate(vdiff) - end if - - deallocate(v1,v2) - end subroutine compare_var_float - - subroutine compare_var_double(f1, f2, i1, i2, t) - type(file_t) :: f1,f2 - integer, intent(in) :: i1, i2 - integer, optional :: t - - - integer :: s1, s2, m1, m2, l1(1), l2(1), i, ierr - double precision, pointer :: v1(:), v2(:), vdiff(:) - integer :: t1, n1 - integer :: start(NF90_MAX_DIMS), count(NF90_MAX_DIMS) - - if(present(t)) then - t1 = t - else - t1 = 1 - end if - - s1 = vdimsize(f1%dim, f1%var(i1)%dimids) - s2 = vdimsize(f2%dim, f2%var(i2)%dimids) - - if(s1 /= s2) then - print *, 'Variable ',f1%var(i)%name,' sizes differ' - end if - - n1 = size(f1%var(i1)%dimids) - start = 1 - do i=1,n1 - count(i) = f1%dim(f1%var(i1)%dimids(i))%dimsize - if(f1%var(i1)%dimids(i) == f1%unlimdimid) then - count(i)=1 - start(i)=t1 - end if - end do - - allocate(v1(s1), v2(s2)) - - ierr = nf90_get_var(f1%fh, i1, v1, start(1:n1), count(1:n1)) - ierr = nf90_get_var(f2%fh, i2, v2, start(1:n1), count(1:n1)) - - if(any(v1 /= v2)) then - allocate(vdiff(s1)) - vdiff = abs(v1-v2) - m1 = maxval(vdiff) - m2 = minval(vdiff) - l1 = maxloc(vdiff) - l2 = minloc(vdiff) - - print *,__FILE__,__LINE__,m1,m2,l1,l2 - deallocate(vdiff) - end if - - deallocate(v1,v2) - end subroutine compare_var_double - - - - - - - - - -end module filestruct diff --git a/CIME/non_py/cprnc/prec.F90 b/CIME/non_py/cprnc/prec.F90 deleted file mode 100644 index abbaba26ea7..00000000000 --- a/CIME/non_py/cprnc/prec.F90 +++ /dev/null @@ -1,8 +0,0 @@ -module prec -! -! Constants for setting precision -! - integer, parameter :: r4 = selected_real_kind (6) - integer, parameter :: r8 = selected_real_kind (12) - integer, parameter :: i4 = selected_int_kind (6) -end module prec diff --git a/CIME/non_py/cprnc/run_tests b/CIME/non_py/cprnc/run_tests deleted file mode 100755 index 98d1a22f3bd..00000000000 --- a/CIME/non_py/cprnc/run_tests +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env perl -# -# Run all cprnc tests -# See usage message for details -# -# Bill Sacks -# 5-28-13 - -use strict; -use Getopt::Long; - -#---------------------------------------------------------------------- -# Define parameters -#---------------------------------------------------------------------- - -# Hash giving info about each test. Key is the test file; value is a -# hash reference containing at least the associated control file (key: -# control), and possibly extra arguments to cprnc (key: extra_args) -my %tests = ('copy.nc' => {control => 'control.nc'}, - 'extra_variables.nc' => {control => 'control.nc'}, - 'diffs_in_vals.nc' => {control => 'control.nc'}, - 'diffs_in_vals_and_extra_and_missing.nc' => {control => 'control.nc'}, - 'diffs_in_fill.nc' => {control => 'control.nc'}, - 'diffs_in_vals_and_diffs_in_fill.nc' => {control => 'control.nc'}, - 'diffs_in_vals_and_fill.nc' => {control => 'control.nc'}, - 'lon_differs.nc' => {control => 'control.nc'}, - 'missing_variables.nc' => {control => 'control.nc'}, - 'vals_differ_by_1.1.nc' => {control => 'control.nc'}, - 'vals_differ_by_1.1_somewhere.nc' => {control => 'control.nc'}, - 'vals_differ_by_varying_amounts.nc' => {control => 'control.nc'}, - 'vals_differ_by_varying_amounts2.nc' => {control => 'control.nc'}, - - 'int_missing.nc' => {control => 'control_int.nc'}, - - 'multipleTimes_someTimeless_diffs_in_vals_and_fill.nc' => {control => 'control_multipleTimes_someTimeless.nc'}, - 'multipleTimes_someTimeless_extra_and_missing.nc' => {control => 'control_multipleTimes_someTimeless.nc'}, - - 'noTime_diffs_in_vals_and_fill.nc' => {control => 'control_noTime.nc', - extra_args => '-m'}, - 'noTime_extra_and_missing.nc' => {control => 'control_noTime.nc', - extra_args => '-m'}, - - 'diffs_0d.nc' => {control => 'control_0d.nc', - extra_args => '-m'}, - - 'cpl.hi.subset.test.nc' => {control => 'cpl.hi.subset.control.nc'}, - 'clm2.h0.subset.test.nc' => {control => 'clm2.h0.subset.control.nc'}, - 'clm2.h1.subset.test.nc' => {control => 'clm2.h1.subset.control.nc'}, - - 'diffs_in_attribute.nc' => {control => 'control_attributes.nc'}, - - 'copy_char.nc' => {control => 'control_char.nc', - extra_args => '-m'}, - - 'diffs_in_nans.nc' => {control => 'control_floatDoubleNan.nc'}, - ); - -#---------------------------------------------------------------------- -# Get arguments and check them -#---------------------------------------------------------------------- - -my %opts; -GetOptions( - "outdir=s" => \$opts{'outdir'}, - "h|help" => \$opts{'help'}, -) or usage(); - -usage() if $opts{'help'}; - -if (@ARGV) { - print "ERROR: unrecognized arguments: @ARGV\n"; - usage(); -} - -if (!$opts{'outdir'}) { - print "ERROR: -outdir must be provided\n"; - usage(); -} - - -#---------------------------------------------------------------------- -# Main script -#---------------------------------------------------------------------- - -mkdir $opts{'outdir'} or die "ERROR creating directory $opts{'outdir'}; -note that this directory should NOT exist before running this script\n"; - -my $num_tests = keys %tests; -print "Running $num_tests tests...\n"; - -foreach my $test (keys %tests) { - print "$test\n"; - my $test_file = $test; - my $control_file = $tests{$test}{'control'}; - my $outfile = "$opts{'outdir'}/${test}.out"; - - my $extra_args = $tests{$test}{'extra_args'}; - - open (my $file, ">", "$outfile") or die "ERROR opening $outfile"; - print $file `./cprnc $extra_args test_inputs/$control_file test_inputs/$test_file`; - close $file; -} - -#---------------------------------------------------------------------- -# Subroutines -#---------------------------------------------------------------------- - -sub usage { - die < [OPTIONS] - - Run all cprnc tests, putting output in directory given by . - should NOT exist before running this script. - - -OPTIONS - -help [or -h] Display this help - -EOF -} diff --git a/CIME/non_py/cprnc/summarize_cprnc_diffs b/CIME/non_py/cprnc/summarize_cprnc_diffs deleted file mode 100755 index 84933192cc6..00000000000 --- a/CIME/non_py/cprnc/summarize_cprnc_diffs +++ /dev/null @@ -1,573 +0,0 @@ -#!/usr/bin/env perl -# -# Summarize cprnc output from all tests in a CESM test suite. -# See usage message for details. -# -# Bill Sacks -# 4-10-13 - -use strict; -use Getopt::Long; -use File::Basename; -use List::Util qw(max sum); - -#---------------------------------------------------------------------- -# Get arguments and check them -#---------------------------------------------------------------------- - -my %opts; -# set defaults -$opts{'output_suffix'} = ''; -# set up options -GetOptions( - "basedir=s" => \$opts{'basedir'}, - "testid=s" => \$opts{'testid'}, - "output_suffix=s" => \$opts{'output_suffix'}, - "narrow" => \$opts{'narrow'}, - "h|help" => \$opts{'help'}, -) or usage(); - -usage() if $opts{'help'}; - -if (@ARGV) { - print "ERROR: unrecognized arguments: @ARGV\n"; - usage(); -} - -if (!$opts{'basedir'}) { - print "ERROR: -basedir must be provided\n"; - usage(); -} -if (!$opts{'testid'}) { - print "ERROR: -testid must be provided\n"; - usage(); -} - -#---------------------------------------------------------------------- -# Main script -#---------------------------------------------------------------------- - -# Create hash containing summary of cprnc differences. This is a reference to a hash, with: -# Keys: "Directory Filename Variable" -# Values: Reference to a hash containing: -# Dir => directory (gives test name) -# Filename => cprnc filename -# Variable => variable -# RMS => rms value [may or may not be present] -# RMS_NORM => normalized rms value [may or may not be present] -# FILLDIFF => ' ' [may or may not be present] -# DIMSIZEDIFF => ' ' [may or may not be present] -my ($summary_hash) = - process_cprnc_output($opts{'basedir'}, $opts{'testid'}, $opts{'output_suffix'}); - -my $outbase="cprnc.summary.$opts{'testid'}"; -if ($opts{'output_suffix'}) { - $outbase = "$outbase.$opts{'output_suffix'}"; -} - -# set widths of output strings -my $widths_hash; -if ($opts{'narrow'}) { - $widths_hash = { Dir => 40, Filename => 40, Variable => 40 }; -} -else { - $widths_hash = max_widths($summary_hash); -} - - -print_results_by_test("${outbase}.by_test", $summary_hash, $widths_hash); -print_results_by_varname("${outbase}.by_varname", $summary_hash, $widths_hash); -print_results_by_rms("${outbase}.by_rms", $summary_hash, $widths_hash); - - - -#---------------------------------------------------------------------- -# Subroutines -#---------------------------------------------------------------------- - -sub usage { - die < -testid [OPTIONS] - - is the base directory in which test directories can be found - - is the testid of the tests to summarize - (can contain shell wildcards) - - This script can be used to post-process and summarize baseline comparison - output from one or more CESM test suites. - - The script finds all directories in basedir whose name ends with the given - testid; these are the test directories of interest. It then examines the - 'run' subdirectory of each test directory of interest, looking for files of - the form *.nc.cprnc.out. Or, if the -output_suffix argument is given, then - it looks for files of the form *.nc.cprnc.out.SUFFIX. (With this naming - convention [i.e., looking for files of the form *.nc.cprnc.out], note that - it only looks at output for baseline comparisons - NOT output from the test - itself, such as cprnc output files from the exact restart test.) (Actually, - we also allow for files of the form *.nc_[0-9][0-9][0-9][0-9].cprnc.out, - such as *.nc_0001.cprnc.out and *.nc_0002.cprnc.out, to pick up - multi-instance files.) - - Summaries of cprnc differences (RMS and normalized RMS differences, FILLDIFFs and DIMSIZEDIFFs) - are placed in three output files beginning with the name 'cprnc.summary', in - the current directory. These files contain the same information, but one is - sorted by test name, one is sorted by variable name, and is one sorted from - largest to smallest normalized RMS differences. - - -OPTIONS - -output_suffix If provided, look for files of the form *.nc.cprnc.out.SUFFIX - rather than just *.nc.cprnc.out - - -narrow Use generally-narrower output field widths to aid readability, - at the expense of truncated strings - - -help [or -h] Display this help - -EOF -} - - -# process_cprnc_output -# Read through all cprnc files, and build hashes of instances of RMS, normalized RMS, FILLDIFF and DIMSIZEDIFF -# Inputs: -# - basedir -# - testid -# - output_suffix -# Output: hash reference -# Dies with an error if no cprnc output files are found -sub process_cprnc_output { - my ($basedir, $testid, $output_suffix) = @_; - - my %diffs; - my $num_files = 0; - - my @test_dirs = glob "${basedir}/*${testid}"; - - foreach my $test_dir (@test_dirs) { - my $test_dir_base = basename($test_dir); - - my @cprnc_files; - if ($output_suffix) { - @cprnc_files = glob "${test_dir}/run/*.nc.cprnc.out.${output_suffix} ${test_dir}/run/*.nc_[0-9][0-9][0-9][0-9].cprnc.out.${output_suffix}"; - } - else { - @cprnc_files = glob "${test_dir}/run/*.nc.cprnc.out ${test_dir}/run/*.nc_[0-9][0-9][0-9][0-9].cprnc.out"; - } - - foreach my $cprnc_file (@cprnc_files) { - my $cprnc_file_base = basename($cprnc_file); - $num_files++; - - open IN, "<", $cprnc_file or die "ERROR opening ${cprnc_file}"; - - while (my $line = ) { - chomp $line; - - process_line($line, $test_dir_base, $cprnc_file_base, \%diffs); - } # while - - close IN; - } # foreach cprnc_file - - } # foreach test_dir - - if ($num_files == 0) { - die "ERROR: no cprnc.out files found\n"; - } - - return \%diffs; -} - - -# process_line: Process one line from one file -# Inputs: -# - line -# - test_dir -# - cprnc_file -# - diffs hash reference (MODIFIED) -sub process_line { - my ($line, $test_dir, $cprnc_file, $diffs) = @_; - - my $diff_type; - my $varname; - my $rms; - my $ignore; - my $rms_normalized; - - if ($line =~ /^ *RMS /) { - ($diff_type, $varname, $rms, $ignore, $rms_normalized) = split " ", $line; - } elsif ($line =~ /^ *FILLDIFF /) { - ($diff_type, $varname) = split " ", $line; - $rms = ""; - $rms_normalized = ""; - } elsif ($line =~ /^ *DIMSIZEDIFF /) { - ($diff_type, $varname) = split " ", $line; - $rms = ""; - $rms_normalized = ""; - } else { - $diff_type = ""; - } - - if ($diff_type eq 'RMS' || $diff_type eq 'FILLDIFF' || $diff_type eq 'DIMSIZEDIFF') { - # We have found a cprnc difference - - my $key = "$test_dir $cprnc_file $varname"; - - # For RMS errors, keep the highest error found - if ($diff_type eq "RMS") { - if (exists $diffs->{$key} && exists $diffs->{$key}{'RMS_NORM'}) { - if ($diffs->{$key}{'RMS_NORM'} > $rms_normalized) { - warn "WARNING: Ignoring lower RMS value: $key : $rms_normalized < $diffs->{$key}{'RMS_NORM'}\n"; - return; - } - else { - warn "WARNING: Replacing RMS with higher value: $key : $rms_normalized > $diffs->{$key}{'RMS_NORM'}\n"; - } - } - } - - # If the diffs hash doesn't already contain information about this - # directory/filename/variable combo, then we need to create a hash - # reference with the appropriate basic metadata. - if (!exists $diffs->{$key}) { - $diffs->{$key} = { - Dir => $test_dir, - Filename => $cprnc_file, - Variable => $varname, - }; - } - - # Whether or not the hash already contained the given key, we need to add - # the value of interest -- either the RMS and normalized RMS errors, or - # the fact that there is a FILLDIFF or DIMSIZEDIFF. - if ($diff_type eq "RMS") { - $diffs->{$key}{'RMS'} = $rms; - $diffs->{$key}{'RMS_NORM'} = $rms_normalized; - } else { - # No meaningful value here - just record the fact that we saw a - # FILLDIFF or DIMSIZEDIFF - $diffs->{$key}{$diff_type} = ""; - } - } elsif ($diff_type ne '') { - die "Unexpected diff_type: $diff_type"; - } -} - - -# max_widths -# Inputs: -# - summary_hash (hash reference) -# Output: reference to a hash containing the maximum width of each of -# the following in the summary hash: -# - Dir -# - Filename -# - Variable -sub max_widths { - my $summary_hash = shift; - - my %maxes; - - foreach my $var ('Dir','Filename','Variable') { - $maxes{$var} = max (map { length($summary_hash->{$_}{$var}) } keys %$summary_hash); - } - - return \%maxes; -} - - -# print_results_by_test: Print sorted hash entries to a file, sorted by test name -# Inputs: -# - outfile: name of output file -# - summary_hash: hash reference containing results to print -# - widths: hash reference giving widths of output strings -sub print_results_by_test { - my ($outfile, $summary_hash, $widths) = @_; - - open OUT, ">", "$outfile" or die "ERROR opening $outfile"; - - my @sorted_keys = sort{ $summary_hash->{$a}{'Dir'} cmp $summary_hash->{$b}{'Dir'} - or $summary_hash->{$a}{'Filename'} cmp $summary_hash->{$b}{'Filename'} - or $summary_hash->{$a}{'Variable'} cmp $summary_hash->{$b}{'Variable'} } - keys %$summary_hash; - - my $last_dir; - my $last_filename; - - my $separator_width = sum(values %$widths) + 57; - - for my $key (@sorted_keys) { - - # Print a separator line between different files - if ($summary_hash->{$key}{'Dir'} ne $last_dir || - $summary_hash->{$key}{'Filename'} ne $last_filename) { - if ($last_dir && $last_filename) { - print OUT "=" x $separator_width . "\n"; - } - $last_dir = $summary_hash->{$key}{'Dir'}; - $last_filename = $summary_hash->{$key}{'Filename'}; - } - - my $line = format_line($summary_hash->{$key}, $widths); - - print OUT "$line\n"; - } - - close OUT; -} - - -# print_results_by_varname: Print sorted hash entries to a file, sorted by variable name -# Inputs: -# - outfile: name of output file -# - summary_hash: hash reference containing results to print -# - widths: hash reference giving widths of output strings -sub print_results_by_varname { - my ($outfile, $summary_hash, $widths) = @_; - - open OUT, ">", "$outfile" or die "ERROR opening $outfile"; - - my @sorted_keys = sort{ $summary_hash->{$a}{'Variable'} cmp $summary_hash->{$b}{'Variable'} - or $summary_hash->{$a}{'Dir'} cmp $summary_hash->{$b}{'Dir'} - or $summary_hash->{$a}{'Filename'} cmp $summary_hash->{$b}{'Filename'} } - keys %$summary_hash; - - my $last_variable; - - my $separator_width = sum(values %$widths) + 57; - - for my $key (@sorted_keys) { - - # Print a separator line between different variables - if ($summary_hash->{$key}{'Variable'} ne $last_variable) { - if ($last_variable) { - print OUT "=" x $separator_width . "\n"; - } - $last_variable = $summary_hash->{$key}{'Variable'}; - } - - my $line = format_line($summary_hash->{$key}, $widths); - - print OUT "$line\n"; - } - - close OUT; -} - - - -# print_results_by_rms: Print sorted hash entries to a file, sorted by RMS_NORM -# Inputs: -# - outfile: name of output file -# - summary_hash: hash reference containing results to print -# - widths: hash reference giving widths of output strings -sub print_results_by_rms { - my ($outfile, $summary_hash, $widths) = @_; - - open OUT, ">", "$outfile" or die "ERROR opening $outfile"; - - my @sorted_keys = sort {$summary_hash->{$b}{'RMS_NORM'} <=> $summary_hash->{$a}{'RMS_NORM'} - or $summary_hash->{$a}{'Dir'} cmp $summary_hash->{$b}{'Dir'} - or $summary_hash->{$a}{'Filename'} cmp $summary_hash->{$b}{'Filename'} - or $summary_hash->{$a}{'Variable'} cmp $summary_hash->{$b}{'Variable'} } - keys %$summary_hash; - - for my $key (@sorted_keys) { - my $line = format_line($summary_hash->{$key}, $widths); - - print OUT "$line\n"; - } - - close OUT; -} - - -# Inputs: -# - reference to a hash containing: -# - Dir -# - Filename -# - Variable -# - RMS (optional) -# - RMS_NORM (optional) -# - FILLDIFF (optional) -# - DIMSIZEDIFF (optional) -# - widths: hash reference giving widths of output strings -# Return a formatted line for printing -sub format_line { - my ($hash_ref, $widths) = @_; - - my $dir = $hash_ref->{'Dir'}; - my $filename = $hash_ref->{'Filename'}; - my $variable = $hash_ref->{'Variable'}; - my $rms = ""; - my $rms_normalized = ""; - my $filldiff = ""; - my $dimsizediff = ""; - if (exists $hash_ref->{'RMS'}) { - $rms = sprintf(" : RMS %-16g", $hash_ref->{'RMS'}); - } - if (exists $hash_ref->{'RMS_NORM'}) { - $rms_normalized = sprintf(" : RMS_NORM %-16g", $hash_ref->{'RMS_NORM'}); - } - if (exists $hash_ref->{'FILLDIFF'}) { - $filldiff = " : FILLDIFF"; - } - if (exists $hash_ref->{'DIMSIZEDIFF'}) { - $dimsizediff = " : DIMSIZEDIFF"; - } - - # for width=40, the format string will contain '%-40.40s' - my $format = '%-' . $widths->{'Dir'} . '.' . $widths->{'Dir'} . 's : ' . - '%-' . $widths->{'Filename'} . '.' . $widths->{'Filename'} . 's : ' . - '%-' . $widths->{'Variable'} . '.' . $widths->{'Variable'} . 's' . - '%s%s%s%s'; - - sprintf($format, $dir, $filename, $variable, $filldiff, $dimsizediff, $rms, $rms_normalized); -} - -#======================================================================= -# Notes about testing: unit tests -#======================================================================= - -#----------------------------------------------------------------------- -# Testing process_line -#----------------------------------------------------------------------- - -# use Data::Dumper; - -# my %diffs; - -# # shouldn't do anything -# process_line("hello", "test_dir1", "file_a", \%diffs); - -# # test basic filldiff -# process_line("FILLDIFF var1", "test_dir1", "file_b", \%diffs); - -# # add an RMS to existing filldiff -# process_line("RMS var1 4200 NORMALIZED 42", "test_dir1", "file_b", \%diffs); - -# # test basic rms error -# process_line("RMS var17 0.314 NORMALIZED 3.14", "test_dir1", "file_b", \%diffs); - -# # add a filldiff to existing rms error -# process_line("FILLDIFF var17", "test_dir1", "file_b", \%diffs); - -# # add a filldiff without RMS -# process_line("FILLDIFF var42", "test_dir2", "file_c", \%diffs); - -# # add a dimsizediff -# process_line("DIMSIZEDIFF var43", "test_dir2", "file_c", \%diffs); - -# # add an RMS error without filldiff -# process_line("RMS var100 99 NORMALIZED 100", "test_dir2", "file_d", \%diffs); - -# # test a warning: should issue a warning and replace the above setting -# process_line("RMS var100 9 NORMALIZED 200", "test_dir2", "file_d", \%diffs); - -# # test a warning: should issue a warning but NOT replace the above setting -# # (normalized RMS is smaller even though standard RMS is bigger: the normalized -# # one should be considered in deciding whether to replace the previous setting) -# process_line("RMS var100 999 NORMALIZED 50", "test_dir2", "file_d", \%diffs); - -# print Dumper(\%diffs); - - -# THE ABOVE SHOULD PRINT SOMETHING LIKE THIS (though the output from Dumper will -# likely appear in a different order): - -# WARNING: Replacing RMS with higher value: test_dir2 file_d var100 : 200 > 100 -# WARNING: Ignoring lower RMS value: test_dir2 file_d var100 : 50 < 200 -# $VAR1 = { -# 'test_dir1 file_b var17' => { -# 'RMS' => '0.314', -# 'Variable' => 'var17', -# 'Filename' => 'file_b', -# 'FILLDIFF' => '', -# 'Dir' => 'test_dir1', -# 'RMS_NORM' => '3.14' -# }, -# 'test_dir2 file_d var100' => { -# 'Dir' => 'test_dir2', -# 'RMS_NORM' => 200, -# 'Filename' => 'file_d', -# 'Variable' => 'var100', -# 'RMS' => '9' -# }, -# 'test_dir1 file_b var1' => { -# 'Filename' => 'file_b', -# 'RMS_NORM' => '42', -# 'FILLDIFF' => '', -# 'Dir' => 'test_dir1', -# 'RMS' => '4200', -# 'Variable' => 'var1' -# }, -# 'test_dir2 file_c var43' => { -# 'Variable' => 'var43', -# 'DIMSIZEDIFF' => '', -# 'Dir' => 'test_dir2', -# 'Filename' => 'file_c' -# }, -# 'test_dir2 file_c var42' => { -# 'Filename' => 'file_c', -# 'Dir' => 'test_dir2', -# 'FILLDIFF' => '', -# 'Variable' => 'var42' -# } -# }; - - -#----------------------------------------------------------------------- -# Testing the print routines -#----------------------------------------------------------------------- - -# Add the following to the above test code: - -# my $widths_hash = { Dir => 40, Filename => 40, Variable => 40 }; -# print_results_by_test("testout.by_test", \%diffs, $widths_hash); -# print_results_by_rms("testout.by_rms", \%diffs, $widths_hash); - -# This should give: - -# $ cat testout.by_rms -# test_dir2 : file_d : var100 : RMS 9 : RMS_NORM 200 -# test_dir1 : file_b : var1 : FILLDIFF : RMS 4200 : RMS_NORM 42 -# test_dir1 : file_b : var17 : FILLDIFF : RMS 0.314 : RMS_NORM 3.14 -# test_dir2 : file_c : var42 : FILLDIFF -# test_dir2 : file_c : var43 : DIMSIZEDIFF -# $ cat testout.by_test -# test_dir1 : file_b : var1 : FILLDIFF : RMS 4200 : RMS_NORM 42 -# test_dir1 : file_b : var17 : FILLDIFF : RMS 0.314 : RMS_NORM 3.14 -# ================================================================================================================================================================================= -# test_dir2 : file_c : var42 : FILLDIFF -# test_dir2 : file_c : var43 : DIMSIZEDIFF -# ================================================================================================================================================================================= -# test_dir2 : file_d : var100 : RMS 9 : RMS_NORM 200 - - - -#======================================================================= -# Notes about testing: integration tests -#======================================================================= - -# Test the following - -# Note: can do these tests by running the cprnc tests and organizing -# outputs into particular directories. -# -# For each of these tests, sort the different output files and compare -# the sorted files to make sure the same info is in all output files; -# then look at one of the output files. -# -# - no RMS or FILLDIFFs at all (testid that just contains output from -# comparing control & copy) -# -# - some RMS and some FILLDIFFs, split across 2 directories, each with -# 2 cprnc files (this can be done by comparing the control file with -# diffs_in_fill.nc, diffs_in_vals.nc, diffs_in_vals_and_diffs_in_fill.nc -# and diffs_in_vals_and_fill.nc) -# -# - multiple RMS errors to test RMS sorting, split across 2 directories -# (this can be done by comparing the control file with four of the -# vals_differ_by_* files) diff --git a/CIME/non_py/cprnc/test_inputs/README b/CIME/non_py/cprnc/test_inputs/README deleted file mode 100644 index f1bdfbd94e6..00000000000 --- a/CIME/non_py/cprnc/test_inputs/README +++ /dev/null @@ -1,188 +0,0 @@ -This directory contains simple test inputs to test cprnc. - -All comparisons can be run by running the run_tests script in the -parent directory. Suggestion: run this once from the baseline -directory, then once from the new directory; compare against baselines -by doing a directory diff of the two directories, or with, e.g.: - - baseline_out=/PATH/TO/BASELINE/OUTPUT - new_out=/PATH/TO/NEW/OUTPUT - for fl in $baseline_out/*; do echo $fl; diff -a $fl $new_out/`basename $fl`; done > diff_report - -The files here are: - ---- FILES COMPARED AGAINST control.nc --- - -- copy.nc: copy of control file (i.e., no diffs) - -- diffs_in_vals.nc: one variable has differences in values - -- diffs_in_vals_and_extra_and_missing.nc: one variable has differences in - values; also, one variable is missing and there is an extra variable. Purpose - of this test is to make sure that this case is reported as a DIFFERENCE rather - than just a warning due to the missing fields. - -- diffs_in_fill.nc: one variable has differences in fill pattern - -- diffs_in_vals_and_diffs_in_fill.nc: one variable has differences in - values, another has differences in fill pattern - -- diffs_in_vals_and_fill.nc: a single variable has differences in both - values and fill pattern - -- extra_variables.nc: has two extra variables beyond those in control.nc - -- lon_differs.nc: number of longitude points differs - -- missing_variables.nc: missing two variables that are present in control.nc - -- vals_differ_by_1.1.nc: testvar has values equal to 1.1 times those - in the control file. This is useful for testing the relative - difference calculation. - - True values are the following (note that relative difference is - defined using a denominator of max(v1,v2)): - - - RMS diff: 0.6204837 (printed as 6.2e-1) - - avg rel diff: 0.0909091 (printed as 9.1e-2) - - avg decimal digits: 1.041393 (printed as 1.0) - - worst decimal digits: 1.041393 (printed as 1.0) - -- vals_differ_by_1.1_somewhere.nc: similar to vals_differ_by_1.1.nc, - but now only a single value differs by a factor of 1.1 - - True values are the following (note that relative difference is - defined using a denominator of max(v1,v2)): - - - RMS diff: 0.3162278 (printed as 3.2e-1) - - avg rel diff: 0.009090909 (printed as 9.1e-3) - - avg decimal digits: 1.041393 (printed as 1.0) [note that the - average here ignores the indices with no difference] - - worst decimal digits: 1.041393 (printed as 1.0) - -- vals_differ_by_varying_amounts.nc: testvar has values equal to 1, - 1.01, 1.02, ..., 1.09 times those in the control file. This is - useful for testing the relative difference calculation using more - complex differences. - - True values are the following (note that relative difference is - defined using a denominator of max(v1,v2)): - - - RMS diff: 0.4434862 (printed as 4.4e-1) - - avg rel diff: 0.04233828 (printed as 4.2e-2) - - avg decimal digits: 1.403306 (printed as 1.4) [note that the - average here normalizes by 9 rather than 10, since the first index - has a relative difference of 0] - - worst decimal digits: 1.083184 (printed as 1.1) - -- vals_differ_by_varying_amounts2.nc: First 8 values of testvar are - identical to control; 9th is control * (1-1e-3), 10th is control * - (1-1e-5). This is the same as the example given in ../README. - - True values are the following: - - - RMS diff: 0.002846226 (printed as 2.8e-3) - - avg rel diff: 0.000101 (printed as 1.0e-4) - - avg decimal digits: 4.0 - - worst decimal digits: 3.0 - ---- FILES COMPARED AGAINST control_int.nc --- - -Note: This file is the same as control.nc, but stores the main variables -as integers rather than reals. - -- int_missing.nc: A variable is missing. The point of this test is to - cover code that resulted in https://github.com/ESMCI/cime/issues/3661. - ---- FILES COMPARED AGAINST control_multipleTimes_someTimeless.nc --- - -Note: This file has some variables with a time dimension, some -without. The time dimension has multiple times, in order to make sure -that the variables with vs. without the time dimension really are -treated differently. Also, a variable without time appears first, in -order to make sure that cprnc doesn't rely on there being a variable -with time first. - -- multipleTimes_someTimeless_diffs_in_vals_and_fill.nc: one variable - with a time dimension has differences in both values and fill - pattern (in time 2); and one variable without a time dimension has - differences in both values and fill pattern. The differences are the - same for both variables (e.g., RMS errors should be the same for - both). - -- multipleTimes_someTimeless_extra_and_missing.nc: two timeless - variables are missing and there is one extra timeless - variable. Purpose of this test is to make sure that the results are - reported as IDENTICAL when the only diffs in field lists are variables - without an unlimited dimension (in a file that has an unlimited - dimension). - ---- FILES COMPARED AGAINST control_noTime.nc --- - -Note: This file has no time (unlimited) dimension. - -- noTime_diffs_in_vals_and_fill.nc: a single variable has differences - in both values and fill pattern - -- noTime_extra_and_missing.nc: two variables are missing and there is - one extra variable. Purpose of this test is to make sure that even - missing fields without an unlimited dimension trigger a DIFFER result - if the file doesn't have an unlimited dimension to begin with. - ---- FILES COMPARED AGAINST control_0d.nc --- - -Note: This file has two 0-d variables - -- diffs_0d.nc: diffs in both 0-d variables (int & real) - - ---- FILES COMPARED AGAINST cpl.hi.subset.control.nc --- - -Note: This file is a subset of a standard cpl hist file (as of May, 2013). - -- cpl.hi.subset.test.nc: some variables are the same, some differ - - ---- FILES COMPARED AGAINST clm2.h0.subset.control.nc --- - -Note: This file is a subset of a standard clm hist file (as of May, 2013). - -- clm2.h0.subset.test.nc: some variables are the same, some differ - - ---- FILES COMPARED AGAINST clm2.h1.subset.control.nc --- - -Note: This file is a subset of a standard clm 1-d hist file -(dov2xy=false) (as of May, 2013). Note that it also includes two -times. - -- clm2.h1.subset.test.nc: some variables are the same, some - differ. Note that this includes identical & different integer - variables, identical & different real-valued variables, and - variables with different spatial dimensions (e.g., landunit, pft, - and lat x lon). - ---- FILES COMPARED AGAINST control_attributes.nc --- - -Note: This file is like control.nc, but contains some global attributes - -- diffs_in_attribute.nc: one global attribute is the same, one differs; in - addition, one global attribute is missing, and there is a new one on this file - that is not present on the control.nc file - ---- FILES COMPARED AGAINST control_char.nc --- - -Note: This file just has a character variable, in order to test what is output -for character variables (which cannot be analyzed). - -- copy_char.nc: identical to control_char.nc - ---- FILES COMPARED AGAINST control_floatDoubleNan.nc --- - -Note: This file has a float variable, a double variable, and a double -variable with a NaN value. Its initial purpose is for testing -comparisons involving NaNs. - -- diffs_in_nans.nc: a float and double variable each have a NaN where - the control file does not, and another double variable has a NaN - only where the control file also has a NaN diff --git a/CIME/non_py/cprnc/test_inputs/clm2.h0.subset.control.nc b/CIME/non_py/cprnc/test_inputs/clm2.h0.subset.control.nc deleted file mode 100644 index 1ffd6474f60..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/clm2.h0.subset.control.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/clm2.h0.subset.test.nc b/CIME/non_py/cprnc/test_inputs/clm2.h0.subset.test.nc deleted file mode 100644 index 41a08ce7bf7..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/clm2.h0.subset.test.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/clm2.h1.subset.control.nc b/CIME/non_py/cprnc/test_inputs/clm2.h1.subset.control.nc deleted file mode 100644 index 2d96f1fdc74..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/clm2.h1.subset.control.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/clm2.h1.subset.test.nc b/CIME/non_py/cprnc/test_inputs/clm2.h1.subset.test.nc deleted file mode 100644 index db606c4b135..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/clm2.h1.subset.test.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/control.nc b/CIME/non_py/cprnc/test_inputs/control.nc deleted file mode 100644 index d9c0ce6a5c4..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/control.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/control_0d.nc b/CIME/non_py/cprnc/test_inputs/control_0d.nc deleted file mode 100644 index d48586f2282..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/control_0d.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/control_attributes.nc b/CIME/non_py/cprnc/test_inputs/control_attributes.nc deleted file mode 100644 index a26bc946415..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/control_attributes.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/control_char.nc b/CIME/non_py/cprnc/test_inputs/control_char.nc deleted file mode 100644 index 7b4567908ea..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/control_char.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/control_floatDoubleNan.nc b/CIME/non_py/cprnc/test_inputs/control_floatDoubleNan.nc deleted file mode 100644 index 1e99d3281e6..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/control_floatDoubleNan.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/control_int.nc b/CIME/non_py/cprnc/test_inputs/control_int.nc deleted file mode 100644 index 13913cf90e3..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/control_int.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/control_multipleTimes_someTimeless.nc b/CIME/non_py/cprnc/test_inputs/control_multipleTimes_someTimeless.nc deleted file mode 100644 index 9ebf4579c92..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/control_multipleTimes_someTimeless.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/control_noTime.nc b/CIME/non_py/cprnc/test_inputs/control_noTime.nc deleted file mode 100644 index 92be43053d0..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/control_noTime.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/copy.nc b/CIME/non_py/cprnc/test_inputs/copy.nc deleted file mode 100644 index d9c0ce6a5c4..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/copy.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/copy_char.nc b/CIME/non_py/cprnc/test_inputs/copy_char.nc deleted file mode 100644 index 7b4567908ea..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/copy_char.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/cpl.hi.subset.control.nc b/CIME/non_py/cprnc/test_inputs/cpl.hi.subset.control.nc deleted file mode 100644 index c83d8cc499d..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/cpl.hi.subset.control.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/cpl.hi.subset.test.nc b/CIME/non_py/cprnc/test_inputs/cpl.hi.subset.test.nc deleted file mode 100644 index 3fdd331ba42..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/cpl.hi.subset.test.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/diffs_0d.nc b/CIME/non_py/cprnc/test_inputs/diffs_0d.nc deleted file mode 100644 index db275131129..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/diffs_0d.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/diffs_in_attribute.nc b/CIME/non_py/cprnc/test_inputs/diffs_in_attribute.nc deleted file mode 100644 index b81f05122af..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/diffs_in_attribute.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/diffs_in_fill.nc b/CIME/non_py/cprnc/test_inputs/diffs_in_fill.nc deleted file mode 100644 index 07b62e33948..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/diffs_in_fill.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/diffs_in_nans.nc b/CIME/non_py/cprnc/test_inputs/diffs_in_nans.nc deleted file mode 100644 index 732bf56896f..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/diffs_in_nans.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/diffs_in_vals.nc b/CIME/non_py/cprnc/test_inputs/diffs_in_vals.nc deleted file mode 100644 index 16411c4881a..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/diffs_in_vals.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/diffs_in_vals_and_diffs_in_fill.nc b/CIME/non_py/cprnc/test_inputs/diffs_in_vals_and_diffs_in_fill.nc deleted file mode 100644 index 9b7adc86763..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/diffs_in_vals_and_diffs_in_fill.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/diffs_in_vals_and_extra_and_missing.nc b/CIME/non_py/cprnc/test_inputs/diffs_in_vals_and_extra_and_missing.nc deleted file mode 100644 index e29e072a24c..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/diffs_in_vals_and_extra_and_missing.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/diffs_in_vals_and_fill.nc b/CIME/non_py/cprnc/test_inputs/diffs_in_vals_and_fill.nc deleted file mode 100644 index 6db4782e6ae..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/diffs_in_vals_and_fill.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/extra_variables.nc b/CIME/non_py/cprnc/test_inputs/extra_variables.nc deleted file mode 100644 index 2d33ab90796..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/extra_variables.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/int_missing.nc b/CIME/non_py/cprnc/test_inputs/int_missing.nc deleted file mode 100644 index 139b358d57f..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/int_missing.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/lon_differs.nc b/CIME/non_py/cprnc/test_inputs/lon_differs.nc deleted file mode 100644 index bb429246912..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/lon_differs.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/missing_variables.nc b/CIME/non_py/cprnc/test_inputs/missing_variables.nc deleted file mode 100644 index 71d9ae2d082..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/missing_variables.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/multipleTimes_someTimeless_diffs_in_vals_and_fill.nc b/CIME/non_py/cprnc/test_inputs/multipleTimes_someTimeless_diffs_in_vals_and_fill.nc deleted file mode 100644 index 7edf3a495d3..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/multipleTimes_someTimeless_diffs_in_vals_and_fill.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/multipleTimes_someTimeless_extra_and_missing.nc b/CIME/non_py/cprnc/test_inputs/multipleTimes_someTimeless_extra_and_missing.nc deleted file mode 100644 index d2718a86de5..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/multipleTimes_someTimeless_extra_and_missing.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/noTime_diffs_in_vals_and_fill.nc b/CIME/non_py/cprnc/test_inputs/noTime_diffs_in_vals_and_fill.nc deleted file mode 100644 index c3006345ed7..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/noTime_diffs_in_vals_and_fill.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/noTime_extra_and_missing.nc b/CIME/non_py/cprnc/test_inputs/noTime_extra_and_missing.nc deleted file mode 100644 index c6c2d790900..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/noTime_extra_and_missing.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/vals_differ_by_1.1.nc b/CIME/non_py/cprnc/test_inputs/vals_differ_by_1.1.nc deleted file mode 100644 index ddc52582461..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/vals_differ_by_1.1.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/vals_differ_by_1.1_somewhere.nc b/CIME/non_py/cprnc/test_inputs/vals_differ_by_1.1_somewhere.nc deleted file mode 100644 index 703507681b5..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/vals_differ_by_1.1_somewhere.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/vals_differ_by_varying_amounts.nc b/CIME/non_py/cprnc/test_inputs/vals_differ_by_varying_amounts.nc deleted file mode 100644 index f42d2952af2..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/vals_differ_by_varying_amounts.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/test_inputs/vals_differ_by_varying_amounts2.nc b/CIME/non_py/cprnc/test_inputs/vals_differ_by_varying_amounts2.nc deleted file mode 100644 index 4167b2d121b..00000000000 Binary files a/CIME/non_py/cprnc/test_inputs/vals_differ_by_varying_amounts2.nc and /dev/null differ diff --git a/CIME/non_py/cprnc/utils.F90 b/CIME/non_py/cprnc/utils.F90 deleted file mode 100644 index 9bf0d5d82fc..00000000000 --- a/CIME/non_py/cprnc/utils.F90 +++ /dev/null @@ -1,85 +0,0 @@ -module utils - use filestruct, only : dim_t -contains - -subroutine get_dimname_str(ndims,dimids,dims,dimname_str) - integer, intent(in) :: ndims - integer, intent(in) :: dimids(:) - type(dim_t) :: dims(:) - character(len=*),intent(out) :: dimname_str - - integer :: dlen - integer :: j - - dimname_str = ' ' - - if(ndims>0) then - dimname_str(1:1) = '(' - dlen=2 - - do j=1,ndims - dimname_str(dlen:) = trim(dims(dimids(j))%name)//',' - dlen=dlen+ len_trim(dims(dimids(j))%name) + 1 - end do - dimname_str(dlen-1:dlen-1) = ')' - end if - - -end subroutine get_dimname_str - -subroutine get_dim_str(ndims,loc,dim_str) - integer, intent(in) :: ndims - integer, intent(in) :: loc(:) - character(len=*),intent(out) :: dim_str - - integer :: dlen - integer :: j - - dim_str = ' ' - - if(ndims>0) then - dim_str(1:1) = '(' - dlen=2 - - do j=1,ndims - write(dim_str(dlen:),'(i6,a)') loc(j),',' - - dlen=len_trim(dim_str)+1 - end do - dim_str(dlen-1:dlen-1) = ')' - end if - - -end subroutine get_dim_str - - - -subroutine checknf90(ierr,returnflag,err_str) - use netcdf, only : nf90_noerr, nf90_strerror - integer, intent(in) :: ierr - logical, optional, intent(in) :: returnflag - character(len=*), optional, intent(in) :: err_str - - if(ierr/=NF90_NOERR) then - print *, trim(nf90_strerror(ierr)) - if(present(err_str)) then - print *, trim(err_str) - end if - if(present(returnflag)) then - if(returnflag) return - end if -#ifdef AIX - call xl__trbk() -#endif - stop - - end if - - - -end subroutine checknf90 - - - - -end module utils diff --git a/Externals_cime.cfg b/Externals_cime.cfg new file mode 100644 index 00000000000..04d7306e241 --- /dev/null +++ b/Externals_cime.cfg @@ -0,0 +1,7 @@ +[CIME/non_py/cprnc] +protocol = git +from_submodule=True +required = True + +[externals_description] +schema_version = 1.0.0 diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index c89d6a9d375..e57ed141718 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -1,6 +1,9 @@ #!/bin/bash -set -x +if [[ -n "${DEBUG}" ]] +then + set -x +fi readonly INIT=${INIT:-"true"} readonly UPDATE_CIME=${UPDATE_CIME:-"false"} @@ -24,6 +27,8 @@ function clone_repo() { extras="${extras} --depth 1" fi + echo "Cloning branch ${branch} of ${repo} into ${path} using ${flags}" + git clone -b "${branch}" ${extras} "${repo}" "${path}" || true } @@ -38,11 +43,15 @@ function fixup_mct { # TODO make PR to fix if [[ ! -e "${mct_path}/mct/Makefile.bak" ]] then + echo "Fixing AR variable in ${mct_path}/mct/Makefile" + sed -i".bak" "s/\$(AR)/\$(AR) \$(ARFLAGS)/g" "${mct_path}/mct/Makefile" fi if [[ ! -e "${mct_path}/mpeu/Makefile.bak" ]] then + echo "Fixing AR variable in ${mct_path}/mpeu/Makefile" + sed -i".bak" "s/\$(AR)/\$(AR) \$(ARFLAGS)/g" "${mct_path}/mpeu/Makefile" fi } @@ -77,6 +86,8 @@ function update_cime() { # Creates an environment with E3SM source. ####################################### function init_e3sm() { + echo "Setting up E3SM" + export CIME_MODEL="e3sm" local extras="" @@ -91,6 +102,8 @@ function init_e3sm() { if [[ ! -e "${PWD}/.gitmodules.bak" ]] then + echo "Convering git@github.com to https://github.com urls in ${PWD}/.gitmodules" + sed -i".bak" "s/git@github.com:/https:\/\/github.com\//g" "${PWD}/.gitmodules" fi @@ -99,6 +112,8 @@ function init_e3sm() { extras=" --depth 1" fi + echo "Initializing submodules in ${PWD}" + git submodule update --init ${extras} fi @@ -108,15 +123,30 @@ function init_e3sm() { mkdir -p /storage/inputdata + echo "Copying cached inputdata from /cache to /storage/inputdata" + rsync -vr /cache/ /storage/inputdata/ cd "${install_path}/cime" + + if [[ ! -e "${PWD}/.gitmodules.bak" ]] + then + echo "Convering git@github.com to https://github.com urls in ${PWD}/.gitmodules" + + sed -i".bak" "s/git@github.com:/https:\/\/github.com\//g" "${PWD}/.gitmodules" + fi + + echo "Initializing submodules in ${PWD}" + + git submodule update --init ${extras} } ####################################### # Creates an environment with CESM source. ####################################### function init_cesm() { + echo "Setting up CESM" + export CIME_MODEL="cesm" local install_path="${INSTALL_PATH:-/src/CESM}" @@ -128,6 +158,8 @@ function init_cesm() { cd "${install_path}" + echo "Checking out externals" + "${install_path}/manage_externals/checkout_externals" fixup_mct "${install_path}/libraries/mct" @@ -135,6 +167,18 @@ function init_cesm() { update_cime "${install_path}/cime/" cd "${install_path}/cime" + + # Need to run manage_externals again incase branch changes externals instructions + # "${install_path}/manage_externals/checkout_externals -e cime/Externals_cime.cfg" + + if [[ ! -e "${PWD}/.gitmodules.bak" ]] + then + echo "Convering git@github.com to https://github.com urls in ${PWD}/.gitmodules" + + sed -i".bak" "s/git@github.com:/https:\/\/github.com\//g" "${PWD}/.gitmodules" + fi + + git submodule update --init } ####################################### @@ -142,6 +186,8 @@ function init_cesm() { # Similar to old github actions environment. ####################################### function init_cime() { + echo "Settig up CIME" + export CIME_MODEL="cesm" export ESMFMKFILE="/opt/conda/lib/esmf.mk" @@ -164,6 +210,18 @@ function init_cime() { update_cime "${install_path}" cd "${install_path}" + + # Need to run manage_externals again incase branch changes externals instructions + # "${install_path}/manage_externals/checkout_externals -e cime/Externals_cime.cfg" + + if [[ ! -e "${PWD}/.gitmodules.bak" ]] + then + echo "Convering git@github.com to https://github.com urls in ${PWD}/.gitmodules" + + sed -i".bak" "s/git@github.com:/https:\/\/github.com\//g" "${PWD}/.gitmodules" + fi + + git submodule update --init } if [[ ! -e "${HOME}/.cime" ]] diff --git a/tools/mapping/gen_domain_files/src/Makefile b/tools/mapping/gen_domain_files/src/Makefile index 5a12b7daec5..a6fa89bf9bc 100644 --- a/tools/mapping/gen_domain_files/src/Makefile +++ b/tools/mapping/gen_domain_files/src/Makefile @@ -122,7 +122,7 @@ OBJS := gen_domain.o # Append user defined compiler and load flags to Makefile defaults CFLAGS += $(USER_CFLAGS) -I$(INC_NETCDF) -FFLAGS += $(USER_FFLAGS) -I$(MOD_NETCDF) -I$(INC_NETCDF) +FFLAGS += $(USER_FFLAGS) -I$(MOD_NETCDF) -I$(INC_NETCDF) $(CMAKE_Fortran_FLAGS) LDFLAGS += $(USER_LDFLAGS) # Set user specified linker diff --git a/tools/mapping/gen_domain_files/test_gen_domain.sh b/tools/mapping/gen_domain_files/test_gen_domain.sh index b80d482ce13..06e995a8c62 100755 --- a/tools/mapping/gen_domain_files/test_gen_domain.sh +++ b/tools/mapping/gen_domain_files/test_gen_domain.sh @@ -81,12 +81,11 @@ fi # Build the cprnc executable (for comparison of netcdf files) echo "" >> ${test_log} echo "Building cprnc in ${PWD}/builds ..." >> ${test_log} -cp ${cime_root}/CIME/non_py/cprnc/*.F90 . -cp ${cime_root}/CIME/non_py/cprnc/Makefile . -cp ${cime_root}/CIME/non_py/cprnc/Depends . -cp ${cime_root}/CIME/non_py/cprnc/*.in . -(. .env_mach_specific.sh && make GENF90=${cime_root}/CIME/non_py/externals/genf90/genf90.pl) >> ${test_log} 2>&1 -if [ ! -f cprnc ]; then +mkdir ${PWD}/builds/cprnc +cd ${PWD}/builds/cprnc +cmake -DCMAKE_INSTALL_PREFIX=${PWD} ${cime_root}/CIME/non_py/cprnc +make install +if [ ! -f bin/cprnc ]; then echo "ERROR building cprnc" >&2 echo "cat ${test_log} for more info" >&2 exit 1 @@ -104,33 +103,33 @@ for baseline in ${ocn_baseline} ${lnd_baseline}; do # and adding in datestring for current day and .nc file extension. testfile=`basename ${baseline} | rev | cut -d. -f3- | rev`.${datestring}.nc if [ ! -f ${testfile} ]; then - echo "ERROR: ${testfile} not generated" >&2 - echo "cat ${test_log} for more info" >&2 - exit 1 + echo "ERROR: ${testfile} not generated" >&2 + echo "cat ${test_log} for more info" >&2 + exit 1 fi # Compare against baseline and print report from cprnc comparison echo "Comparing $testfile against ${baseline}..." - (. builds/.env_mach_specific.sh && ./builds/cprnc -m ${testfile} ${baseline}) >> ${test_log} 2>&1 + (. builds/.env_mach_specific.sh && ./builds/bin/cprnc -m ${testfile} ${baseline}) >> ${test_log} 2>&1 # Check results last=`tail -n3 ${test_log}` if [[ ${last} =~ "STOP" ]]; then - echo ${last} >&2 - echo "Error running cprnc" >&2 - echo "cat ${test_log} for more info" >&2 - exit 1 + echo ${last} >&2 + echo "Error running cprnc" >&2 + echo "cat ${test_log} for more info" >&2 + exit 1 fi if [[ ${last} =~ "DIFFERENT" ]]; then - echo ${last} >&2 - echo ${baseline} DIFFERENT FROM ${testfile} >&2 - echo "cat ${test_log} for more info" >&2 - exit 1 + echo ${last} >&2 + echo ${baseline} DIFFERENT FROM ${testfile} >&2 + echo "cat ${test_log} for more info" >&2 + exit 1 fi if ! [[ ${last} =~ "IDENTICAL" ]]; then - echo ${last} >&2 - echo "undetermined output from cprnc" >&2 - echo "cat ${test_log} for more info" >&2 - exit 1 + echo ${last} >&2 + echo "undetermined output from cprnc" >&2 + echo "cat ${test_log} for more info" >&2 + exit 1 fi done