Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ed3c91a
Bug fix and add testing to demonstrate error
dustinswales Jan 28, 2025
d73512a
Expand to test for correct scheme order in caps.
dustinswales Jan 29, 2025
f107e0c
Address reviewer comment
dustinswales Feb 3, 2025
91f4a4f
Merge branch 'develop' of https://github.com/NCAR/ccpp-framework into…
dustinswales Feb 3, 2025
d322103
Merge pull request #629 from dustinswales/bugfix/scheme_ordering_in_caps
dustinswales Feb 3, 2025
aed2471
ccpp_prebuild.py: remove execute function from common.py, clean files…
climbfuji Feb 6, 2025
6c494b2
Capgen in SCM: Multiple instances of local_name in Group Cap (#631)
dustinswales Feb 12, 2025
dcb5ed5
Capgen in SCM: Fix to allow for scheme subcycling. (#633)
dustinswales Feb 25, 2025
7bc4fbb
Constituent index lookup (#622)
gold2718 Mar 3, 2025
052dac2
Add options for pre-registered DDT names (#644)
gold2718 Mar 3, 2025
5575301
Update develop from main 2025/04/16 (#657)
climbfuji Apr 22, 2025
c322375
New implementation of differing module name (#646)
gold2718 Apr 22, 2025
654b3c5
Support equivalent and identical units in capgen and ccpp-prebuild (#…
climbfuji May 1, 2025
7b26420
DEBUG refinements (#652)
dustinswales May 14, 2025
4d4dc78
Detect invalid horizontal dimensions (loop variables) in metadata for…
climbfuji May 22, 2025
eae6c3d
Capgen in SCM: DDT subfields into Group Caps (#640)
dustinswales May 22, 2025
9254784
Remove case sensitivity for variable dimensions (#660)
peverwhee Jun 3, 2025
981eeae
Throw clearer error message when integer dimension indices are presen…
peverwhee Jul 9, 2025
74b2f22
Testing refactor (#612)
mwaxmonsky Jul 14, 2025
9a40b0f
Allow different ordering in Fortran scheme and associated metadata (#…
gold2718 Jul 24, 2025
c8fd894
Merge branch 'develop' of https://github.com/ncar/ccpp-framework into…
climbfuji Jul 24, 2025
07b356d
Make N m-2 equivalent to Pa (#670)
jimmielin Aug 6, 2025
4ae528b
Bug fixes for ccpp_prebuild to work with partially case-insensitive c…
climbfuji Aug 21, 2025
cd2c99b
Merge branch 'develop' of https://github.com/ncar/ccpp-framework into…
climbfuji Aug 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions .github/workflows/capgen_unit_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,38 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: update repos and install dependencies
run: sudo apt-get update && sudo apt-get install -y build-essential ${{matrix.fortran-compiler}} cmake python3 git libxml2-utils
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
libopenmpi-dev \
${{matrix.fortran-compiler}} \
cmake \
python3 \
git \
libxml2-utils
pip install --user pytest

- name: Build the framework
run: |
cmake -S. -B./build -DOPENMP=ON -DCCPP_FRAMEWORK_ENABLE_TESTS=ON
cd build
make

- name: Run unit tests
run: cd test && ./run_fortran_tests.sh
run: |
cd build
ctest --rerun-failed --output-on-failure . --verbose

- name: Run python tests
run: |
BUILD_DIR=./build \
PYTHONPATH=test/:scripts/ \
pytest \
test/capgen_test/capgen_test_reports.py \
test/advection_test/advection_test_reports.py \
test/ddthost_test/ddthost_test_reports.py \
test/var_compatibility_test/var_compatibility_test_reports.py

- name: Run Fortran to metadata test
run: cd test && ./test_fortran_to_metadata.sh
17 changes: 9 additions & 8 deletions .github/workflows/prebuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ jobs:
export PYTHONPATH=$(pwd)/scripts:$(pwd)/scripts/parse_tools
cd test_prebuild
pytest
- name: ccpp-prebuild blocked data tests
run: |
cd test_prebuild/test_blocked_data
python3 ../../scripts/ccpp_prebuild.py --config=ccpp_prebuild_config.py --builddir=build
cd build
cmake ..
make
./test_blocked_data.x
# No longer possible because of https://github.com/NCAR/ccpp-framework/pull/659
#- name: ccpp-prebuild blocked data tests
# run: |
# cd test_prebuild/test_blocked_data
# python3 ../../scripts/ccpp_prebuild.py --config=ccpp_prebuild_config.py --builddir=build
# cd build
# cmake ..
# make
# ./test_blocked_data.x
- name: ccpp-prebuild chunked data tests
run: |
cd test_prebuild/test_chunked_data
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# All compiled Python modules
*.pyc

# CMake build directory
build/
28 changes: 0 additions & 28 deletions .travis.yml

This file was deleted.

107 changes: 89 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,117 @@ project(ccpp_framework
VERSION 5.0.0
LANGUAGES Fortran)

include(cmake/ccpp_capgen.cmake)

#------------------------------------------------------------------------------
# Set package definitions
set(PACKAGE "ccpp-framework")
set(AUTHORS "Dom Heinzeller" "Grant Firl" "Mike Kavulich" "Dustin Swales" "Courtney Peverley")
string(TIMESTAMP YEAR "%Y")

option(OPENMP "Enable OpenMP support for the framework" OFF)
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
option(CCPP_FRAMEWORK_BUILD_DOCUMENTATION
"Create and install the HTML documentation (requires Doxygen)" OFF)
option(CCPP_FRAMEWORK_ENABLE_TESTS "Enable building/running CCPP regression tests" OFF)
option(CCPP_RUN_ADVECTION_TEST "Enable advection regression test" OFF)
option(CCPP_RUN_CAPGEN_TEST "Enable capgen regression test" OFF)
option(CCPP_RUN_DDT_HOST_TEST "Enable ddt host regression test" OFF)
option(CCPP_RUN_VAR_COMPATIBILITY_TEST "Enable variable compatibility regression test" OFF)

message("")
message("OPENMP .............................. ${OPENMP}")
message("BUILD_SHARED_LIBS ................... ${BUILD_SHARED_LIBS}")
message("")
message("CCPP_FRAMEWORK_BUILD_DOCUMENTATION ...${CCPP_FRAMEWORK_BUILD_DOCUMENTATION}")
message("CCPP_FRAMEWORK_ENABLE_TESTS ......... ${CCPP_FRAMEWORK_ENABLE_TESTS}")
message("CCPP_RUN_ADVECTION_TEST ............. ${CCPP_RUN_ADVECTION_TEST}")
message("CCPP_RUN_CAPGEN_TEST ................ ${CCPP_RUN_CAPGEN_TEST}")
message("CCPP_RUN_DDT_HOST_TEST .............. ${CCPP_RUN_DDT_HOST_TEST}")
message("CCPP_RUN_VAR_COMPATIBILITY_TEST ..... ${CCPP_RUN_VAR_COMPATIBILITY_TEST}")
message("")

set(CCPP_VERBOSITY "0" CACHE STRING "Verbosity level of output (default: 0)")

# Warn user on conflicting test options
if(CCPP_RUN_ADVECTION_TEST OR
CCPP_RUN_CAPGEN_TEST OR
CCPP_RUN_DDT_HOST_TEST OR
CCPP_RUN_VAR_COMPATIBILITY_TEST)
set(CCPP_MANUALLY_DECLARED_TEST ON BOOL)
endif()
if(CCPP_MANUALLY_DECLARED_TEST AND CCPP_FRAMEWORK_ENABLE_TESTS)
message(WARNING "Detected a manual test flag and the flag to run all tests. If only expected to run a single test, please unset CCPP_FRAMEWORK_ENABLE_TESTS option.")
endif()
set(CCPP_RUNNING_TESTS CCPP_FRAMEWORK_ENABLE_TESTS OR CCPP_MANUALLY_DECLARED_TEST)

# If running tests, set appropriate flags to help with debugging test issues.
if(CCPP_RUNNING_TESTS)
if(${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU")
ADD_COMPILE_OPTIONS(-fcheck=all)
ADD_COMPILE_OPTIONS(-fbacktrace)
ADD_COMPILE_OPTIONS(-ffpe-trap=zero)
ADD_COMPILE_OPTIONS(-finit-real=nan)
ADD_COMPILE_OPTIONS(-ggdb)
ADD_COMPILE_OPTIONS(-ffree-line-length-none)
ADD_COMPILE_OPTIONS(-cpp)
elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL "Intel")
ADD_COMPILE_OPTIONS(-fpe0)
ADD_COMPILE_OPTIONS(-warn)
ADD_COMPILE_OPTIONS(-traceback)
ADD_COMPILE_OPTIONS(-debug extended)
ADD_COMPILE_OPTIONS(-fpp)
ADD_COMPILE_OPTIONS(-diag-disable=10448)
elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL "IntelLLVM")
ADD_COMPILE_OPTIONS(-fpe0)
ADD_COMPILE_OPTIONS(-warn)
ADD_COMPILE_OPTIONS(-traceback)
ADD_COMPILE_OPTIONS(-debug full)
ADD_COMPILE_OPTIONS(-fpp)
elseif (${CMAKE_Fortran_COMPILER_ID} STREQUAL "NVIDIA" OR ${CMAKE_Fortran_COMPILER_ID} STREQUAL "NVHPC")
ADD_COMPILE_OPTIONS(-Mnoipa)
ADD_COMPILE_OPTIONS(-traceback)
ADD_COMPILE_OPTIONS(-Mfree)
ADD_COMPILE_OPTIONS(-Ktrap=fp)
ADD_COMPILE_OPTIONS(-Mpreprocess)
else()
message (WARNING "This program may not be able to be compiled with compiler :${CMAKE_Fortran_COMPILER_ID}")
endif()
endif()

# Use rpaths on MacOSX
set(CMAKE_MACOSX_RPATH 1)

#------------------------------------------------------------------------------
# Set MPI flags for Fortran with MPI F08 interface
find_package(MPI REQUIRED Fortran)
find_package(MPI COMPONENTS Fortran REQUIRED)
if(NOT MPI_Fortran_HAVE_F08_MODULE)
message(FATAL_ERROR "MPI implementation does not support the Fortran 2008 mpi_f08 interface")
endif()

#------------------------------------------------------------------------------
# Set OpenMP flags for C/C++/Fortran
if (OPENMP)
if(OPENMP)
find_package(OpenMP REQUIRED)
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${OpenMP_Fortran_FLAGS}")
endif (OPENMP)
endif()

#------------------------------------------------------------------------------
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "Coverage")
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
endif()

#------------------------------------------------------------------------------
# Pass debug/release flag to Fortran files for preprocessor
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DDEBUG)
# Add the sub-directories
add_subdirectory(src)

if(CCPP_RUNNING_TESTS)
enable_testing()
add_subdirectory(test)
endif()

#------------------------------------------------------------------------------
# Request a static build
option(BUILD_SHARED_LIBS "Build a static library" OFF)
if (CCPP_FRAMEWORK_BUILD_DOCUMENTATION)
find_package(Doxygen REQUIRED)
add_subdirectory(doc)
endif()

#------------------------------------------------------------------------------
# Add the sub-directories
add_subdirectory(src)
add_subdirectory(doc)
129 changes: 129 additions & 0 deletions cmake/ccpp_capgen.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# CMake wrapper for ccpp_capgen.py
# Currently meant to be a CMake API needed for generating caps for regression tests.
#
# CAPGEN_DEBUG - ON/OFF (Default: OFF) - Enables debug capability through ccpp_capgen.py
# CAPGEN_EXPECT_THROW_ERROR - ON/OFF (Default: OFF) - Scans ccpp_capgen.py log for error string and errors if not found.
# HOST_NAME - String name of host
# OUTPUT_ROOT - String path to put generated caps
# VERBOSITY - Number of --verbose flags to pass to capgen
# HOSTFILES - CMake list of host metadata filenames
# SCHEMEFILES - CMake list of scheme metadata files
# SUITES - CMake list of suite xml files
function(ccpp_capgen)
set(optionalArgs CAPGEN_DEBUG CAPGEN_EXPECT_THROW_ERROR)
set(oneValueArgs HOST_NAME OUTPUT_ROOT VERBOSITY)
set(multi_value_keywords HOSTFILES SCHEMEFILES SUITES)

cmake_parse_arguments(arg "${optionalArgs}" "${oneValueArgs}" "${multi_value_keywords}" ${ARGN})

# Error if script file not found.
set(CCPP_CAPGEN_CMD_LIST "${CMAKE_SOURCE_DIR}/scripts/ccpp_capgen.py")
if(NOT EXISTS ${CCPP_CAPGEN_CMD_LIST})
message(FATAL_ERROR "function(ccpp_capgen): Could not find ccpp_capgen.py. Looked for ${CCPP_CAPGEN_CMD_LIST}.")
endif()

# Interpret parsed arguments
if(DEFINED arg_CAPGEN_DEBUG)
list(APPEND CCPP_CAPGEN_CMD_LIST "--debug")
endif()
if(DEFINED arg_HOSTFILES)
list(JOIN arg_HOSTFILES "," HOSTFILES_SEPARATED)
list(APPEND CCPP_CAPGEN_CMD_LIST "--host-files" "${HOSTFILES_SEPARATED}")
endif()
if(DEFINED arg_SCHEMEFILES)
list(JOIN arg_SCHEMEFILES "," SCHEMEFILES_SEPARATED)
list(APPEND CCPP_CAPGEN_CMD_LIST "--scheme-files" "${SCHEMEFILES_SEPARATED}")
endif()
if(DEFINED arg_SUITES)
list(JOIN arg_SUITES "," SUITES_SEPARATED)
list(APPEND CCPP_CAPGEN_CMD_LIST "--suites" "${SUITES_SEPARATED}")
endif()
if(DEFINED arg_HOST_NAME)
list(APPEND CCPP_CAPGEN_CMD_LIST "--host-name" "${arg_HOST_NAME}")
endif()
if(DEFINED arg_OUTPUT_ROOT)
message(STATUS "Creating output directory: ${arg_OUTPUT_ROOT}")
file(MAKE_DIRECTORY "${arg_OUTPUT_ROOT}")
list(APPEND CCPP_CAPGEN_CMD_LIST "--output-root" "${arg_OUTPUT_ROOT}")
endif()
if(DEFINED arg_VERBOSITY)
string(REPEAT "--verbose" ${arg_VERBOSITY} VERBOSE_PARAMS_SEPERATED)
separate_arguments(VERBOSE_PARAMS UNIX_COMMAND "${VERBOSE_PARAMS_SEPERATED}")
list(APPEND CCPP_CAPGEN_CMD_LIST ${VERBOSE_PARAMS})
endif()

message(STATUS "Running ccpp_capgen.py from ${CMAKE_CURRENT_SOURCE_DIR}")

unset(CAPGEN_OUT) # Unset CAPGEN_OUT to prevent incorrect output on subsequent ccpp_capgen(...) calls.
execute_process(COMMAND ${CCPP_CAPGEN_CMD_LIST}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE CAPGEN_OUT
ERROR_VARIABLE CAPGEN_OUT
RESULT_VARIABLE RES
COMMAND_ECHO STDOUT)

message(STATUS "ccpp-capgen stdout: ${CAPGEN_OUT}")

if(arg_CAPGEN_EXPECT_THROW_ERROR)
# Determine if the process succeeded but had an expected string in the process log.
string(FIND "${CAPGEN_OUT}" "Variables of type ccpp_constituent_properties_t only allowed in register phase" ERROR_INDEX)

if (ERROR_INDEX GREATER -1)
message(STATUS "Capgen build produces expected error message.")
else()
message(FATAL_ERROR "CCPP cap generation did not generate expected error. Expected 'Variables of type constituent_properties_t only allowed in register phase.")
endif()
else()
if(RES EQUAL 0)
message(STATUS "ccpp-capgen completed successfully")
else()
message(FATAL_ERROR "CCPP cap generation FAILED: result = ${RES}")
endif()
endif()
endfunction()

# CMake wrapper for ccpp_datafile.py
# Currently meant to be a CMake API needed for generating caps for regression tests.
#
# DATATABLE - Path to generated datatable.xml file
# REPORT_NAME - String report name to get list of generated files form capgen (typically --ccpp-files)
function(ccpp_datafile)
set(oneValueArgs DATATABLE REPORT_NAME)
cmake_parse_arguments(arg "" "${oneValueArgs}" "" ${ARGN})

set(CCPP_DATAFILE_CMD "${CMAKE_SOURCE_DIR}/scripts/ccpp_datafile.py")

if(NOT EXISTS ${CCPP_DATAFILE_CMD})
message(FATAL_ERROR "function(ccpp_datafile): Could not find ccpp_datafile.py. Looked for ${CCPP_DATAFILE_CMD}.")
endif()

if(NOT DEFINED arg_REPORT_NAME)
message(FATAL_ERROR "function(ccpp_datafile): REPORT_NAME not set. Must specify the report to generate to run cpp_datafile.py")
endif()
list(APPEND CCPP_DATAFILE_CMD "${arg_REPORT_NAME}")

if(NOT DEFINED arg_DATATABLE)
message(FATAL_ERROR "function(ccpp_datafile): DATATABLE not set. A datatable file must be configured to call ccpp_datafile.")
endif()
list(APPEND CCPP_DATAFILE_CMD "${arg_DATATABLE}")

message(STATUS "Running ccpp_datafile from ${CMAKE_CURRENT_SOURCE_DIR}")

unset(CCPP_CAPS) # Unset CCPP_CAPS to prevent incorrect output on subsequent ccpp_datafile(...) calls.
execute_process(COMMAND ${CCPP_DATAFILE_CMD}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE CCPP_CAPS
RESULT_VARIABLE RES
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
COMMAND_ECHO STDOUT)
message(STATUS "CCPP_CAPS = ${CCPP_CAPS}")
if(RES EQUAL 0)
message(STATUS "CCPP cap files retrieved")
else()
message(FATAL_ERROR "CCPP cap file retrieval FAILED: result = ${RES}")
endif()
string(REPLACE "," ";" CCPP_CAPS_LIST ${CCPP_CAPS}) # Convert "," separated list from python back to ";" separated list for CMake.
set(CCPP_CAPS_LIST "${CCPP_CAPS_LIST}" PARENT_SCOPE)
endfunction()

Loading