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

Add etrans #203

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
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 CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ ecbuild_add_option( FEATURE GPU_STATIC
DEFAULT ${GPU_STATIC_DEFAULT}
DESCRIPTION "Compile GPU library as static library")

ecbuild_add_option( FEATURE ETRANS
DEFAULT ON
samhatfield marked this conversation as resolved.
Show resolved Hide resolved
DESCRIPTION "Include Limited-Area-Model Transforms" )

ectrans_find_lapack()

ecbuild_add_option( FEATURE TESTS
Expand Down
3 changes: 3 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ add_subdirectory( programs )
if( HAVE_TRANSI )
add_subdirectory(transi)
endif()
if( HAVE_ETRANS )
add_subdirectory(etrans)
endif()
154 changes: 154 additions & 0 deletions src/etrans/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@


# (C) Copyright 2020- ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.

function(generate_file)
set (options)
set (oneValueArgs INPUT OUTPUT BACKEND)
set (multiValueArgs)
cmake_parse_arguments(_PAR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

set(output ${_PAR_OUTPUT})
set(input ${_PAR_INPUT})
set(backend ${_PAR_BACKEND})
set(sed_rules ${PROJECT_SOURCE_DIR}/src/etrans/sedrenames.txt)

set( JPRB_dp JPRD )
set( jprb_dp jprd )
set( JPRB_sp JPRM )
set( jprb_sp jprm )
set( JPRB_gpu_dp JPRD )
set( jprb_gpu_dp jprd )
set( JPRB_gpu_sp JPRM )
set( jprb_gpu_sp jprm )

add_custom_command(
OUTPUT ${output}
COMMAND cat ${sed_rules} |
sed -e "s/VARIANTDESIGNATOR/${backend}/g" |
sed -e "s/TYPEDESIGNATOR_UPPER/${JPRB_${backend}}/g" |
sed -e "s/TYPEDESIGNATOR_LOWER/${jprb_${backend}}/g" |
sed -rf - ${input} > ${output}
DEPENDS ${input} ${sed_rules}
COMMENT "Generating ${output}"
VERBATIM
)
endfunction(generate_file)


function(generate_backend_includes)
set (options)
set (oneValueArgs BACKEND TARGET DESTINATION INCLUDE_DIRECTORY)
set (multiValueArgs)
cmake_parse_arguments(_PAR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

set(destination ${_PAR_DESTINATION} )
set(backend ${_PAR_BACKEND})

file(MAKE_DIRECTORY ${destination})
file(MAKE_DIRECTORY ${destination}/etrans_${backend})

ecbuild_list_add_pattern( LIST absolute_files GLOB etrans/*.h SOURCE_DIR ${_PAR_INCLUDE_DIRECTORY} QUIET )
set( files )
foreach(file_i ${absolute_files})
file(RELATIVE_PATH file_i ${_PAR_INCLUDE_DIRECTORY} ${file_i})
list(APPEND files ${file_i})
endforeach()
set( outfiles )
foreach(file_i ${files})
get_filename_component(outfile_name ${file_i} NAME)
get_filename_component(outfile_name_we ${file_i} NAME_WE)
get_filename_component(outfile_ext ${file_i} EXT)
get_filename_component(outfile_dir ${file_i} DIRECTORY)
if (${file_i} IN_LIST ectrans_common_includes)
configure_file(${_PAR_INCLUDE_DIRECTORY}/${file_i} ${destination}/${outfile_name})
else()
set(outfile "${destination}/${outfile_name_we}_${backend}${outfile_ext}")
ecbuild_debug("Generate ${outfile}")
generate_file(BACKEND ${backend} INPUT ${_PAR_INCLUDE_DIRECTORY}/${file_i} OUTPUT ${outfile})
list(APPEND outfiles ${outfile})
string(TOUPPER ${outfile_name_we} OUTFILE_NAME_WE )
ecbuild_debug("Generate ${destination}/trans_${backend}/${outfile_name}")
file(WRITE ${destination}/trans_${backend}/${outfile_name} "! Automatically generated interface header for backward compatibility of generic symbols !\n")
file(APPEND ${destination}/trans_${backend}/${outfile_name} "#if defined(${outfile_name_we})\n")
file(APPEND ${destination}/trans_${backend}/${outfile_name} "#undef ${outfile_name_we}\n")
file(APPEND ${destination}/trans_${backend}/${outfile_name} "#endif\n")
file(APPEND ${destination}/trans_${backend}/${outfile_name} "#if defined(${OUTFILE_NAME_WE})\n")
file(APPEND ${destination}/trans_${backend}/${outfile_name} "#undef ${OUTFILE_NAME_WE}\n")
file(APPEND ${destination}/trans_${backend}/${outfile_name} "#endif\n")
file(APPEND ${destination}/trans_${backend}/${outfile_name} "#include \"${outfile_name_we}_${backend}${outfile_ext}\"\n")
file(APPEND ${destination}/trans_${backend}/${outfile_name} "#define ${outfile_name_we} ${OUTFILE_NAME_WE}_${backend}\n")
file(APPEND ${destination}/trans_${backend}/${outfile_name} "#define ${OUTFILE_NAME_WE} ${OUTFILE_NAME_WE}_${backend}\n")
endif()
endforeach(file_i)

add_custom_target(${_PAR_TARGET}_generate DEPENDS ${outfiles})
ecbuild_add_library(TARGET ${_PAR_TARGET} TYPE INTERFACE)
add_dependencies(${_PAR_TARGET} ${_PAR_TARGET}_generate)
target_include_directories(${_PAR_TARGET} INTERFACE $<BUILD_INTERFACE:${destination}>)
endfunction(generate_backend_includes)





# TODO: move precision-independent files to common
#add_subdirectory( common )

if( HAVE_CPU)
add_subdirectory( cpu )
endif()

# placeholder
#if( HAVE_GPU )
# add_subdirectory( gpu )
#endif()


if (FALSE)
# original cmake file for etrans; keeping it for reference, but should be cleaned later
message(FATAL_ERROR "Hold it right there!")

# build list of sources to add to trans library
# (using CMAKE_CURRENT_SOURCE_DIR is necessary because sources are in a different directory than the target library (trans_${prec})
ecbuild_list_add_pattern( LIST etrans_src
GLOB
${CMAKE_CURRENT_SOURCE_DIR}/biper/internal/*
${CMAKE_CURRENT_SOURCE_DIR}/biper/external/*
${CMAKE_CURRENT_SOURCE_DIR}/etrans/internal/*
${CMAKE_CURRENT_SOURCE_DIR}/etrans/external/*
QUIET
)

# dummies to be able to loop over precisions
set( HAVE_dp ${HAVE_DOUBLE_PRECISION} )
set( HAVE_sp ${HAVE_SINGLE_PRECISION} )

# loop over precisions
foreach( prec sp dp )
if( HAVE_${prec} )
# add sources
target_sources(trans_${prec} PRIVATE ${etrans_src})
# add include directories
target_include_directories(trans_${prec}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/biper/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/etrans/include>
)
endif()
endforeach()

# install headers
file( GLOB etrans_interface biper/include/* etrans/include/*)
install(
FILES ${etrans_interface}
DESTINATION include/ectrans
)

endif()
99 changes: 99 additions & 0 deletions src/etrans/cpu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# (C) Copyright 2020- ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.

## Apply workarounds for some known compilers
## see trans/ for example

function(generate_backend_sources)
set (options)
set (oneValueArgs BACKEND DESTINATION OUTPUT)
set (multiValueArgs)

cmake_parse_arguments(_PAR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
set(backend ${_PAR_BACKEND})
set(destination ${_PAR_DESTINATION})
file(MAKE_DIRECTORY ${destination}/biper/internal)
file(MAKE_DIRECTORY ${destination}/biper/external)
file(MAKE_DIRECTORY ${destination}/internal)
file(MAKE_DIRECTORY ${destination}/external)

ecbuild_list_add_pattern( LIST files
GLOB
internal/*.F90
external/*.F90
biper/internal/*.F90
biper/external/*.F90
QUIET
)

set(outfiles)
foreach(file_i ${files})
get_filename_component(outfile_name ${file_i} NAME)
get_filename_component(outfile_name_we ${file_i} NAME_WE)
get_filename_component(outfile_ext ${file_i} EXT)
get_filename_component(outfile_dir ${file_i} DIRECTORY)
set(outfile "${destination}/${file_i}")
ecbuild_debug("Generate ${outfile}")
generate_file(BACKEND ${backend} INPUT ${CMAKE_CURRENT_SOURCE_DIR}/${file_i} OUTPUT ${outfile})
list(APPEND outfiles ${outfile})
endforeach(file_i)
set(${_PAR_OUTPUT} ${outfiles} PARENT_SCOPE)
endfunction(generate_backend_sources)

set( BUILD_INTERFACE_INCLUDE_DIR ${CMAKE_BINARY_DIR}/include/ectrans )

foreach( prec dp sp )
if( HAVE_${prec} )

generate_backend_includes(BACKEND ${prec} TARGET ectrans_etrans_${prec}_includes DESTINATION ${BUILD_INTERFACE_INCLUDE_DIR} INCLUDE_DIRECTORY ${PROJECT_SOURCE_DIR}/src/etrans/include )
generate_backend_sources( BACKEND ${prec} OUTPUT ectrans_etrans_${prec}_src DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/generated/ectrans_etrans_${prec})
ecbuild_add_library(
TARGET ectrans_etrans_${prec}
LINKER_LANGUAGE Fortran
SOURCES ${ectrans_etrans_${prec}_src}
PUBLIC_INCLUDES $<INSTALL_INTERFACE:include/ectrans>
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${BUILD_INTERFACE_INCLUDE_DIR}>
PUBLIC_LIBS fiat ectrans_common ectrans_${prec}_includes ectrans_${prec} ectrans_etrans_${prec}_includes
)

ectrans_target_fortran_module_directory(
TARGET ectrans_etrans_${prec}
MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/module/ectrans
INSTALL_DIRECTORY module/ectrans
)

set( FFTW_LINK PRIVATE )
if( LAPACK_LIBRARIES MATCHES "mkl" AND NOT FFTW_LIBRARIES MATCHES "mkl" )
ecbuild_warn( "Danger: Both MKL and FFTW are linked in trans_${prec}. "
"No guarantees on link order can be made for the final executable.")
set( FFTW_LINK PUBLIC ) # Attempt anyway to give FFTW precedence
endif()
ecbuild_debug("target_link_libraries( trans_${prec} ${FFTW_LINK} ${FFTW_LIBRARIES} )")
target_link_libraries( ectrans_etrans_${prec} ${FFTW_LINK} ${FFTW_LIBRARIES} )
target_include_directories( ectrans_etrans_${prec} PRIVATE ${FFTW_INCLUDE_DIRS} )
target_compile_definitions( ectrans_etrans_${prec} PRIVATE WITH_FFTW )
# daand: lam transforms don't need lapack
#ecbuild_debug("target_link_libraries( ectrans_etrans_${prec} PRIVATE ${LAPACK_LIBRARIES} )")
#target_link_libraries( ectrans_${prec} PRIVATE ${LAPACK_LIBRARIES} )

if( HAVE_OMP )
ecbuild_debug("target_link_libraries( ectrans_${prec} PRIVATE OpenMP::OpenMP_Fortran )")
target_link_libraries( ectrans_${prec} PRIVATE OpenMP::OpenMP_Fortran )
endif()

# This interface library is for backward compatibility, and provides the older includes
ecbuild_add_library( TARGET etrans_${prec} TYPE INTERFACE )
target_include_directories( etrans_${prec} INTERFACE $<BUILD_INTERFACE:${BUILD_INTERFACE_INCLUDE_DIR}/etrans_${prec}> )
target_include_directories( etrans_${prec} INTERFACE $<INSTALL_INTERFACE:include/ectrans/etrans_${prec}> )
target_link_libraries( trans_${prec} INTERFACE fiat ectrans_${prec} ectrans_etrans_${prec} parkind_${prec})
endif()
endforeach()

## Install trans interface
install( DIRECTORY ${BUILD_INTERFACE_INCLUDE_DIR}/ DESTINATION include/ectrans )
112 changes: 112 additions & 0 deletions src/etrans/cpu/biper/external/etibihie.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
! (C) Copyright 2001- ECMWF.
! (C) Copyright 2001- Meteo-France.
!
! This software is licensed under the terms of the Apache Licence Version 2.0
! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
! In applying this licence, ECMWF does not waive the privileges and immunities
! granted to it by virtue of its status as an intergovernmental organisation
! nor does it submit to any jurisdiction.
!


SUBROUTINE ETIBIHIE(KDLON,KDGL,KNUBI,KDLUX,KDGUX,&
& KSTART,KDLSM,PGPBI,LDBIX,LDBIY,KDADD)

!**** tool ETIBIHIE : Doubly-periodicisation : isotropic spline
! ------------- method.

! purpose :
! --------
! KNUBI horizontal fields which are known on C U I,
! are extended over E, in order to obtain doubly-periodic
! fields.
! IF LDBIX is equal .TRUE. , then the fields are periodicise
! in the x ( or longitude ) direction. If it is not the case,
! KDLUX must be equal to KDLON.
! IF LDBIY is equal .TRUE. , then the fields are periodicise
! in the y ( or latitude ) direction. If it is not the case,
! KDGUX must be equal to KDGL.

!* *CALL* *ETIBIHIE*(...)

! externals :
! ----------
! ESPLIN spline extension
! ESMOOTH smoothing across to get isotropy.

! explicit arguments :
! ------------------
! KDLON : upper bound for the x (or longitude) dimension
! of the gridpoint array on C U I U E
! KDGL : upper bound for the y (or latitude) dimension
! of the gridpoint array on C U I U E
! KNUBI : number of horizontal fields to doubly-periodicise.
! KDLUX : upper bound for the x (or longitude) dimension
! of C U I.
! KDGUX : upper bound for the y (or latitude) dimension
! of C U I.
! KSTART : first dimension in x direction of g-p array
! KDLSM : second dimension in x direction of g-p array
! PGPBI : gridpoint array on C U I U E.
! LDBIX : logical to periodicize or not
! in the x ( or longitude ) direction.
! LDBIY : logical to periodicize or not
! in the y ( or latitude ) direction.
! KDADD : 1 to test biperiodiz.

! references :
! ----------

! author :
! ------
! V. Ducrocq

! modification :
! ------------
! A. Stanesic 28/03/2008: KDADD - test of externalized biper.
! -------------------------------------------------------------------------

USE PARKIND1 ,ONLY : JPIM ,JPRB
USE YOMHOOK ,ONLY : LHOOK, DR_HOOK, JPHOOK

USE ESPLINE_MOD
USE ESMOOTHE_MOD

! -------------------------------------------------------------------------

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN) :: KNUBI
INTEGER(KIND=JPIM),INTENT(IN) :: KSTART
INTEGER(KIND=JPIM),INTENT(IN) :: KDLSM
INTEGER(KIND=JPIM),INTENT(IN) :: KDLON
INTEGER(KIND=JPIM),INTENT(IN) :: KDGL
INTEGER(KIND=JPIM),INTENT(IN) :: KDLUX
INTEGER(KIND=JPIM),INTENT(IN) :: KDGUX
INTEGER(KIND=JPIM),INTENT(IN) :: KDADD
REAL(KIND=JPRB),INTENT(INOUT) :: PGPBI(KSTART:KDLSM+KDADD,KNUBI,1:KDGL+KDADD)
LOGICAL,INTENT(IN) :: LDBIX
LOGICAL,INTENT(IN) :: LDBIY

! -------------------------------------------------------------------------

REAL(KIND=JPRB) :: ZALFA
REAL(KIND=JPHOOK) :: ZHOOK_HANDLE

! -------------------------------------------------------------------------
IF (LHOOK) CALL DR_HOOK('ETIBIHIE',0,ZHOOK_HANDLE)
! -------------------------------------------------------------------------

!* 1. DOUBLY-PERIODICISE :
! ------------------

ZALFA = 0.0_JPRB

CALL ESPLINE(1,KDLON,1,KDGL,KDLUX,KDGUX,KSTART,&
& KDLSM+KDADD,1,KDGL+KDADD,KNUBI,PGPBI,ZALFA,LDBIX,LDBIY,KDADD)
CALL ESMOOTHE(1,KDLON,1,KDGL,KDLUX,KDGUX,KSTART,&
& KDLSM+KDADD,1,KDGL+KDADD,KNUBI,PGPBI,LDBIX,LDBIY)

! -------------------------------------------------------------------------
IF (LHOOK) CALL DR_HOOK('ETIBIHIE',1,ZHOOK_HANDLE)
END SUBROUTINE ETIBIHIE
Loading
Loading