Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ccpp_prebuild.py: add support for chunked arrays #519

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
4 changes: 4 additions & 0 deletions scripts/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
CCPP_BLOCK_SIZES = 'ccpp_block_sizes'
CCPP_THREAD_NUMBER = 'ccpp_thread_number'

CCPP_CHUNK_EXTENT = 'ccpp_chunk_extent'
CCPP_HORIZONTAL_LOOP_BEGIN = 'horizontal_loop_begin'
CCPP_HORIZONTAL_LOOP_END = 'horizontal_loop_end'

CCPP_HORIZONTAL_LOOP_EXTENT = 'horizontal_loop_extent'
CCPP_HORIZONTAL_DIMENSION = 'horizontal_dimension'

Expand Down
299 changes: 224 additions & 75 deletions scripts/mkstatic.py

Large diffs are not rendered by default.

16 changes: 10 additions & 6 deletions src/ccpp_types.F90
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ module ccpp_types
integer, parameter :: CCPP_DEFAULT_LOOP_CNT = -999
integer, parameter :: CCPP_DEFAULT_LOOP_MAX = -999

!> @var The default values for block and thread numbers indicating invalid data
integer, parameter :: CCPP_DEFAULT_BLOCK_AND_THREAD_NUMBER = -999
!> @var The default values for block, chunk and thread numbers indicating invalid data
integer, parameter :: CCPP_DEFAULT_BLOCK_NUMBER = -999
integer, parameter :: CCPP_DEFAULT_CHUNK_NUMBER = -999
integer, parameter :: CCPP_DEFAULT_THREAD_NUMBER = -999

!! \section arg_table_ccpp_t
!! \htmlinclude ccpp_t.html
Expand All @@ -56,8 +58,9 @@ module ccpp_types
character(len=512) :: errmsg = ''
integer :: loop_cnt = CCPP_DEFAULT_LOOP_CNT
integer :: loop_max = CCPP_DEFAULT_LOOP_MAX
integer :: blk_no = CCPP_DEFAULT_BLOCK_AND_THREAD_NUMBER
integer :: thrd_no = CCPP_DEFAULT_BLOCK_AND_THREAD_NUMBER
integer :: blk_no = CCPP_DEFAULT_BLOCK_NUMBER
integer :: chunk_no = CCPP_DEFAULT_CHUNK_NUMBER
integer :: thrd_no = CCPP_DEFAULT_THREAD_NUMBER
integer :: ccpp_instance = 1

contains
Expand All @@ -74,8 +77,9 @@ function ccpp_t_initialized(ccpp_d) result(initialized)
class(ccpp_t) :: ccpp_d
logical :: initialized
!
initialized = (ccpp_d%blk_no /= CCPP_DEFAULT_BLOCK_AND_THREAD_NUMBER .and. &
ccpp_d%thrd_no /= CCPP_DEFAULT_BLOCK_AND_THREAD_NUMBER)
initialized = ccpp_d%thrd_no /= CCPP_DEFAULT_THREAD_NUMBER .or. &
ccpp_d%blk_no /= CCPP_DEFAULT_BLOCK_NUMBER .or. &
ccpp_d%chunk_no /= CCPP_DEFAULT_CHUNK_NUMBER
end function ccpp_t_initialized

end module ccpp_types
6 changes: 6 additions & 0 deletions src/ccpp_types.meta
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@
units = index
dimensions = ()
type = integer
[chunk_no]
standard_name = ccpp_chunk_number
long_name = number of chunk for using array chunks in CCPP
units = index
dimensions = ()
type = integer
[thrd_no]
standard_name = ccpp_thread_number
long_name = number of thread for threading in CCPP
Expand Down
90 changes: 90 additions & 0 deletions test_prebuild/test_chunked_data/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#------------------------------------------------------------------------------
cmake_minimum_required(VERSION 3.0)

project(ccpp_chunked_data
VERSION 1.0.0
LANGUAGES Fortran)

#------------------------------------------------------------------------------
# Request a static build
option(BUILD_SHARED_LIBS "Build a shared library" OFF)

#------------------------------------------------------------------------------
# Set the sources: physics type definitions
set(TYPEDEFS $ENV{CCPP_TYPEDEFS})
if(TYPEDEFS)
message(STATUS "Got CCPP TYPEDEFS from environment variable: ${TYPEDEFS}")
else(TYPEDEFS)
include(${CMAKE_CURRENT_BINARY_DIR}/CCPP_TYPEDEFS.cmake)
message(STATUS "Got CCPP TYPEDEFS from cmakefile include file: ${TYPEDEFS}")
endif(TYPEDEFS)

# Generate list of Fortran modules from the CCPP type
# definitions that need need to be installed
foreach(typedef_module ${TYPEDEFS})
list(APPEND MODULES_F90 ${CMAKE_CURRENT_BINARY_DIR}/${typedef_module})
endforeach()

#------------------------------------------------------------------------------
# Set the sources: physics schemes
set(SCHEMES $ENV{CCPP_SCHEMES})
if(SCHEMES)
message(STATUS "Got CCPP SCHEMES from environment variable: ${SCHEMES}")
else(SCHEMES)
include(${CMAKE_CURRENT_BINARY_DIR}/CCPP_SCHEMES.cmake)
message(STATUS "Got CCPP SCHEMES from cmakefile include file: ${SCHEMES}")
endif(SCHEMES)

# Set the sources: physics scheme caps
set(CAPS $ENV{CCPP_CAPS})
if(CAPS)
message(STATUS "Got CCPP CAPS from environment variable: ${CAPS}")
else(CAPS)
include(${CMAKE_CURRENT_BINARY_DIR}/CCPP_CAPS.cmake)
message(STATUS "Got CCPP CAPS from cmakefile include file: ${CAPS}")
endif(CAPS)

# Set the sources: physics scheme caps
set(API $ENV{CCPP_API})
if(API)
message(STATUS "Got CCPP API from environment variable: ${API}")
else(API)
include(${CMAKE_CURRENT_BINARY_DIR}/CCPP_API.cmake)
message(STATUS "Got CCPP API from cmakefile include file: ${API}")
endif(API)

set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -O0 -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans -ffpe-trap=invalid,zero,overflow -fbounds-check -ggdb -fbacktrace -ffree-line-length-none")

#------------------------------------------------------------------------------
add_library(ccpp_chunked_data STATIC ${SCHEMES} ${CAPS} ${API})
# Generate list of Fortran modules from defined sources
foreach(source_f90 ${CAPS} ${API})
get_filename_component(tmp_source_f90 ${source_f90} NAME)
string(REGEX REPLACE ".F90" ".mod" tmp_module_f90 ${tmp_source_f90})
string(TOLOWER ${tmp_module_f90} module_f90)
list(APPEND MODULES_F90 ${CMAKE_CURRENT_BINARY_DIR}/${module_f90})
endforeach()

set_target_properties(ccpp_chunked_data PROPERTIES VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR})

add_executable(test_chunked_data.x main.F90)
add_dependencies(test_chunked_data.x ccpp_chunked_data)
target_link_libraries(test_chunked_data.x ccpp_chunked_data)
set_target_properties(test_chunked_data.x PROPERTIES LINKER_LANGUAGE Fortran)

# Define where to install the library
install(TARGETS ccpp_chunked_data
EXPORT ccpp_chunked_data-targets
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION lib
)
# Export our configuration
install(EXPORT ccpp_chunked_data-targets
FILE ccpp_chunked_data-config.cmake
DESTINATION lib/cmake
)
# Define where to install the C headers and Fortran modules
#install(FILES ${HEADERS_C} DESTINATION include)
install(FILES ${MODULES_F90} DESTINATION include)
13 changes: 13 additions & 0 deletions test_prebuild/test_chunked_data/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# How to build the chunked data test

1. Set compiler environment as appropriate for your system
2. Run the following commands:
```
cd test_prebuild/test_chunked_data/
rm -fr build
mkdir build
../../scripts/ccpp_prebuild.py --config=ccpp_prebuild_config.py --builddir=build
cd build
cmake .. 2>&1 | tee log.cmake
make 2>&1 | tee log.make
```
81 changes: 81 additions & 0 deletions test_prebuild/test_chunked_data/ccpp_prebuild_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env python

# CCPP prebuild config for GFDL Finite-Volume Cubed-Sphere Model (FV3)

###############################################################################
# Definitions #
###############################################################################

HOST_MODEL_IDENTIFIER = "FV3"

# Add all files with metadata tables on the host model side and in CCPP,
# relative to basedir = top-level directory of host model. This includes
# kind and type definitions used in CCPP physics. Also add any internal
# dependencies of these files to the list.
VARIABLE_DEFINITION_FILES = [
# actual variable definition files
'../../src/ccpp_types.F90',
'data.F90',
]

TYPEDEFS_NEW_METADATA = {
'ccpp_types' : {
'ccpp_t' : 'cdata',
'ccpp_types' : '',
},
'data' : {
'chunked_data_type' : 'chunked_data_instance',
'data' : '',
},
}

# Add all physics scheme files relative to basedir
SCHEME_FILES = [
'chunked_data_scheme.F90',
]

# Default build dir, relative to current working directory,
# if not specified as command-line argument
DEFAULT_BUILD_DIR = 'build'

# Auto-generated makefile/cmakefile snippets that contain all type definitions
TYPEDEFS_MAKEFILE = '{build_dir}/CCPP_TYPEDEFS.mk'
TYPEDEFS_CMAKEFILE = '{build_dir}/CCPP_TYPEDEFS.cmake'
TYPEDEFS_SOURCEFILE = '{build_dir}/CCPP_TYPEDEFS.sh'

# Auto-generated makefile/cmakefile snippets that contain all schemes
SCHEMES_MAKEFILE = '{build_dir}/CCPP_SCHEMES.mk'
SCHEMES_CMAKEFILE = '{build_dir}/CCPP_SCHEMES.cmake'
SCHEMES_SOURCEFILE = '{build_dir}/CCPP_SCHEMES.sh'

# Auto-generated makefile/cmakefile snippets that contain all caps
CAPS_MAKEFILE = '{build_dir}/CCPP_CAPS.mk'
CAPS_CMAKEFILE = '{build_dir}/CCPP_CAPS.cmake'
CAPS_SOURCEFILE = '{build_dir}/CCPP_CAPS.sh'

# Directory where to put all auto-generated physics caps
CAPS_DIR = '{build_dir}'

# Directory where the suite definition files are stored
SUITES_DIR = '.'

# Optional arguments - only required for schemes that use
# optional arguments. ccpp_prebuild.py will throw an exception
# if it encounters a scheme subroutine with optional arguments
# if no entry is made here. Possible values are: 'all', 'none',
# or a list of standard_names: [ 'var1', 'var3' ].
OPTIONAL_ARGUMENTS = {}

# Directory where to write static API to
STATIC_API_DIR = '{build_dir}'
STATIC_API_CMAKEFILE = '{build_dir}/CCPP_API.cmake'
STATIC_API_SOURCEFILE = '{build_dir}/CCPP_API.sh'

# Directory for writing HTML pages generated from metadata files
METADATA_HTML_OUTPUT_DIR = '{build_dir}'

# HTML document containing the model-defined CCPP variables
HTML_VARTABLE_FILE = '{build_dir}/CCPP_VARIABLES_CHUNKED_DATA.html'

# LaTeX document containing the provided vs requested CCPP variables
LATEX_VARTABLE_FILE = '{build_dir}/CCPP_VARIABLES_CHUNKED_DATA.tex'
118 changes: 118 additions & 0 deletions test_prebuild/test_chunked_data/chunked_data_scheme.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
!>\file chunked_data_scheme.F90
!! This file contains a chunked_data_scheme CCPP scheme that does nothing
!! except requesting the minimum, mandatory variables.

module chunked_data_scheme

use, intrinsic :: iso_fortran_env, only: error_unit
implicit none

private
public :: chunked_data_scheme_init, &
chunked_data_scheme_timestep_init, &
chunked_data_scheme_run, &
chunked_data_scheme_timestep_finalize, &
chunked_data_scheme_finalize

! This is for unit testing only
integer, parameter, dimension(4) :: data_array_sizes = (/6,6,6,3/)

contains

!! \section arg_table_chunked_data_scheme_init Argument Table
!! \htmlinclude chunked_data_scheme_init.html
!!
subroutine chunked_data_scheme_init(data_array, errmsg, errflg)
character(len=*), intent(out) :: errmsg
integer, intent(out) :: errflg
integer, intent(in) :: data_array(:)
! Initialize CCPP error handling variables
errmsg = ''
errflg = 0
! Check size of data array
write(error_unit,'(a,i3)') 'In chunked_data_scheme_init: checking size of data array to be', sum(data_array_sizes)
if (size(data_array)/=sum(data_array_sizes)) then
write(errmsg,'(2(a,i3))') "Error, expected size(data_array)==", sum(data_array_sizes), "but got ", size(data_array)
errflg = 1
return
end if
end subroutine chunked_data_scheme_init

!! \section arg_table_chunked_data_scheme_timestep_init Argument Table
!! \htmlinclude chunked_data_scheme_timestep_init.html
!!
subroutine chunked_data_scheme_timestep_init(data_array, errmsg, errflg)
character(len=*), intent(out) :: errmsg
integer, intent(out) :: errflg
integer, intent(in) :: data_array(:)
! Initialize CCPP error handling variables
errmsg = ''
errflg = 0
! Check size of data array
write(error_unit,'(a,i3)') 'In chunked_data_scheme_timestep_init: checking size of data array to be', sum(data_array_sizes)
if (size(data_array)/=sum(data_array_sizes)) then
write(errmsg,'(2(a,i3))') "Error, expected size(data_array)==", sum(data_array_sizes), " but got ", size(data_array)
errflg = 1
return
end if
end subroutine chunked_data_scheme_timestep_init

!! \section arg_table_chunked_data_scheme_run Argument Table
!! \htmlinclude chunked_data_scheme_run.html
!!
subroutine chunked_data_scheme_run(nchunk, data_array, errmsg, errflg)
character(len=*), intent(out) :: errmsg
integer, intent(out) :: errflg
integer, intent(in) :: nchunk
integer, intent(in) :: data_array(:)
! Initialize CCPP error handling variables
errmsg = ''
errflg = 0
! Check size of data array
write(error_unit,'(2(a,i3))') 'In chunked_data_scheme_run: checking size of data array for chunk', nchunk, ' to be', data_array_sizes(nchunk)
if (size(data_array)/=data_array_sizes(nchunk)) then
write(errmsg,'(a,i4)') "Error in chunked_data_scheme_run, expected size(data_array)==6, got ", size(data_array)
errflg = 1
return
end if
end subroutine chunked_data_scheme_run

!! \section arg_table_chunked_data_scheme_timestep_finalize Argument Table
!! \htmlinclude chunked_data_scheme_timestep_finalize.html
!!
subroutine chunked_data_scheme_timestep_finalize(data_array, errmsg, errflg)
character(len=*), intent(out) :: errmsg
integer, intent(out) :: errflg
integer, intent(in) :: data_array(:)
! Initialize CCPP error handling variables
errmsg = ''
errflg = 0
! Check size of data array
write(error_unit,'(a,i3)') 'In chunked_data_scheme_timestep_finalize: checking size of data array to be', sum(data_array_sizes)
if (size(data_array)/=sum(data_array_sizes)) then
write(errmsg,'(2(a,i3))') "Error, expected size(data_array)==", sum(data_array_sizes), "but got ", size(data_array)
errflg = 1
return
end if
end subroutine chunked_data_scheme_timestep_finalize

!! \section arg_table_chunked_data_scheme_finalize Argument Table
!! \htmlinclude chunked_data_scheme_finalize.html
!!
subroutine chunked_data_scheme_finalize(data_array, errmsg, errflg)
character(len=*), intent(out) :: errmsg
integer, intent(out) :: errflg
integer, intent(in) :: data_array(:)
! Initialize CCPP error handling variables
errmsg = ''
errflg = 0
! Check size of data array
write(error_unit,'(a,i3)') 'In chunked_data_scheme_finalize: checking size of data array to be', sum(data_array_sizes)
if (size(data_array)/=sum(data_array_sizes)) then
write(errmsg,'(2(a,i3))') "Error, expected size(data_array)==", sum(data_array_sizes), "but got ", size(data_array)
errflg = 1
return
end if
end subroutine chunked_data_scheme_finalize

end module chunked_data_scheme
Loading