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

Implement offload instructions via macros #80

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
field_module.F90
*.swp
build
**__pycache__
29 changes: 3 additions & 26 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,8 @@ ecbuild_find_package(OpenMP COMPONENTS Fortran REQUIRED)
## find fypp
field_api_find_fypp()

## find OpenACC
if( ${CMAKE_VERSION} VERSION_LESS "3.25" )
if ( FIELD_API_ENABLE_ACC OR (NOT DEFINED FIELD_API_ENABLE_ACC AND (ENABLE_ACC OR NOT DEFINED ENABLE_ACC)) )
# See https://gitlab.kitware.com/cmake/cmake/-/issues/23691, fixed in CMake 3.25
# (TL;DR: FindOpenACC sets OpenACC_<LANG>_FOUND correctly but does not set
# OpenACC_FOUND unless all three C, CXX, and Fortran have been found - even if
# only one language has been requested via COMPONENTS)
find_package( OpenACC COMPONENTS Fortran )
if( OpenACC_Fortran_FOUND )
set( OpenACC_FOUND ON )
endif()
endif()
endif()
ecbuild_add_option( FEATURE ACC
DEFAULT ON
DESCRIPTION "Support for using GPUs with OpenACC"
REQUIRED_PACKAGES "OpenACC COMPONENTS Fortran"
CONDITION CMAKE_Fortran_COMPILER_ID MATCHES "PGI|NVHPC")
## determine GPU offload model
field_api_get_offload_model()

## set general compiler flags
field_api_compile_options()
Expand All @@ -75,13 +59,6 @@ endif()
## find fiat
field_api_find_fiat_modules()

## check for CUDA
include(CheckLanguage)
check_language(CUDA)
ecbuild_add_option( FEATURE CUDA
DESCRIPTION "CUDA" DEFAULT ON
CONDITION CMAKE_CUDA_COMPILER AND HAVE_ACC )

## buddy allocator option
ecbuild_add_option( FEATURE BUDDY_MALLOC
DESCRIPTION "Use buddy allocator for shadow host allocation"
Expand All @@ -100,7 +77,7 @@ if(HAVE_BUDDY_MALLOC)
list( APPEND fypp_defines "-DUSE_BUDDY_MALLOC")
endif()
if(HAVE_CUDA)
list( APPEND fypp_defines "-DCUDA")
list( APPEND fypp_defines "-DWITH_HIC")
endif()
if(fiat_FOUND)
list( APPEND fypp_defines "-DWITH_FIAT")
Expand Down
1 change: 1 addition & 0 deletions cmake/field_api_add_object_library.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ macro(field_api_add_object_library)
${_PAR_DEFINITIONS}
$<$<NOT:${fiat_FOUND}>:${FIELD_API_DEFINITIONS}>
$<${fiat_FOUND}:WITH_FIAT>
${FIELD_API_OFFLOAD_DEFINITIONS}
PRIVATE_LIBS
${_PAR_LIBRARIES}
$<${HAVE_ACC}:OpenACC::OpenACC_Fortran>
Expand Down
4 changes: 3 additions & 1 deletion cmake/field_api_expand_fypp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ macro( field_api_expand_fypp )
foreach (SRC ${_PAR_INPUT_SRCS} )

add_custom_command (OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${SRC}.F90
COMMAND ${FYPP} -m os ${fypp_defines} -M ${_PAR_PYTHON_MODULE_DIR} -m fieldType ${_PAR_SOURCE_DIR}/${SRC}.fypp > ${CMAKE_CURRENT_BINARY_DIR}/${SRC}.F90
COMMAND ${FYPP} -m os ${fypp_defines} -M ${_PAR_PYTHON_MODULE_DIR} -m fieldType
-DOFFLOAD_MODEL="${FIELD_API_OFFLOAD_MODEL}" -M ${_PAR_PYTHON_MODULE_DIR} -m offload_macros
${_PAR_SOURCE_DIR}/${SRC}.fypp > ${CMAKE_CURRENT_BINARY_DIR}/${SRC}.F90
DEPENDS ${_PAR_SOURCE_DIR}/${SRC}.fypp
VERBATIM)

Expand Down
2 changes: 2 additions & 0 deletions cmake/field_api_expand_fypp_ranksuff.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ macro( field_api_expand_fypp_ranksuff )

add_custom_command (OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/field_${RANK}${suff}${FUNC}_module.F90
COMMAND ${FYPP} -DRANK=${RANK} -DSUFF='${SUFF}' ${fypp_defines} -m os -M ${_PAR_PYTHON_MODULE_DIR} -m fieldType
-DOFFLOAD_MODEL="${FIELD_API_OFFLOAD_MODEL}" -M ${_PAR_PYTHON_MODULE_DIR} -m offload_macros
${_PAR_SOURCE_DIR}/field_RANKSUFF${FUNC}_module.fypp > ${CMAKE_CURRENT_BINARY_DIR}/field_${RANK}${suff}${FUNC}_module.F90
DEPENDS ${_PAR_SOURCE_DIR}/field_RANKSUFF${FUNC}_module.fypp
VERBATIM)
Expand All @@ -62,6 +63,7 @@ macro( field_api_expand_fypp_ranksuff )

add_custom_command (OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/field_${RANK}${suff}${FUNC}_module.F90
COMMAND ${FYPP} -DRANK=${RANK} -DSUFF='${SUFF}' ${fypp_defines} -m os -M ${_PAR_PYTHON_MODULE_DIR} -m fieldType
-DOFFLOAD_MODEL="${FIELD_API_OFFLOAD_MODEL}" -M ${_PAR_PYTHON_MODULE_DIR} -m offload_macros
${_PAR_SOURCE_DIR}/field_RANKSUFF${FUNC}_module.fypp > ${CMAKE_CURRENT_BINARY_DIR}/field_${RANK}${suff}${FUNC}_module.F90
DEPENDS ${_PAR_SOURCE_DIR}/field_RANKSUFF${FUNC}_module.fypp
VERBATIM)
Expand Down
19 changes: 9 additions & 10 deletions cmake/field_api_find_fypp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,15 @@ macro( field_api_find_fypp )

if( fckit_FOUND AND fckit_HAVE_FCKIT_VENV )
set( FYPP ${FCKIT_VENV_EXE} -m fypp )
elseif( fckit_FOUND )
# This is only needed for building in environments with python3 older than 3.8
list( APPEND _fckit_fypp_path "${FYPP}" )
list( LENGTH _fckit_fypp_path _list_length )
MATH( EXPR _last_entry "${_list_length} - 1" )
list( GET _fckit_fypp_path ${_last_entry} FYPP )
elseif( FYPP MATCHES FYPP-NOTFOUND )
include(cmake/field_api_fetchcontent_fypp.cmake)
set(FYPP ${fypp_SOURCE_DIR}/bin/fypp)
ecbuild_info("fypp downloaded to: ${FYPP}")
elseif( FYPP MATCHES FYPP-NOTFOUND OR (fckit_FOUND AND (NOT fckit_HAVE_FCKIT_VENV OR NOT DEFINED fckit_HAVE_FCKIT_VENV)) )
# Discover only system install Python 3
set( Python3_FIND_VIRTUALENV STANDARD )
find_package( Python3 COMPONENTS Interpreter )

execute_process( COMMAND ${Python3_EXECUTABLE} -m ensurepip --upgrade OUTPUT_QUIET )
execute_process( COMMAND ${Python3_EXECUTABLE} -m pip --disable-pip-version-check install fypp OUTPUT_QUIET )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small comment from something we've hit very recently: Bare-metal Python installations may come without any pip or only ancient versions available. But they are guaranteed to have a bootstrap mechanism for it that ensures that you have at least a pip version equivalent to the ensurepip version packaged with the installation. For this, add the following:

Suggested change
execute_process( COMMAND ${Python3_EXECUTABLE} -m pip --disable-pip-version-check install fypp OUTPUT_QUIET )
execute_process( COMMAND ${Python3_EXECUTABLE} -m ensurepip --upgrade OUTPUT_QUIET )
execute_process( COMMAND ${Python3_EXECUTABLE} -m pip --disable-pip-version-check install fypp OUTPUT_QUIET )

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even know we could have pip-less python, thanks!

ecbuild_info("field_api installed fypp as a pip package")
set( FYPP ${Python3_EXECUTABLE} -m fypp )
endif()

endmacro()
62 changes: 62 additions & 0 deletions cmake/field_api_get_offload_model.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# (C) Copyright 2022- ECMWF.
# (C) Copyright 2022- 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.

##############################################################################
#.rst:
#
# field_api_get_offload_model
# ===========================
#
# Determine the GPU offload model to be used. ::
#
# field_api_get_offload_model()
#
##############################################################################

macro( field_api_get_offload_model )

## find OpenACC
if( ${CMAKE_VERSION} VERSION_LESS "3.25" )
if ( FIELD_API_ENABLE_ACC OR (NOT DEFINED FIELD_API_ENABLE_ACC AND (ENABLE_ACC OR NOT DEFINED ENABLE_ACC)) )
# See https://gitlab.kitware.com/cmake/cmake/-/issues/23691, fixed in CMake 3.25
# (TL;DR: FindOpenACC sets OpenACC_<LANG>_FOUND correctly but does not set
# OpenACC_FOUND unless all three C, CXX, and Fortran have been found - even if
# only one language has been requested via COMPONENTS)
find_package( OpenACC COMPONENTS Fortran )
if( OpenACC_Fortran_FOUND )
set( OpenACC_FOUND ON )
endif()
endif()
endif()
ecbuild_add_option( FEATURE ACC
DEFAULT ON
DESCRIPTION "Support for using GPUs with OpenACC"
REQUIRED_PACKAGES "OpenACC COMPONENTS Fortran"
CONDITION CMAKE_Fortran_COMPILER_ID MATCHES "PGI|NVHPC")

## check for CUDA
include(CheckLanguage)
check_language(CUDA)
ecbuild_add_option( FEATURE CUDA
DESCRIPTION "CUDA" DEFAULT ON
CONDITION CMAKE_CUDA_COMPILER AND HAVE_ACC )

set(FIELD_API_OFFLOAD_MODEL "HostOnly")
if( HAVE_CUDA )
set(FIELD_API_OFFLOAD_MODEL "NVHPCOpenACCCUDA")
elseif( HAVE_ACC )
set(FIELD_API_OFFLOAD_MODEL "NVHPCOpenACC")
endif()

unset(FIELD_API_OFFLOAD_DEFINITIONS)
if( HAVE_ACC )
list(APPEND FIELD_API_OFFLOAD_DEFINITIONS WITH_GPU_OFFLOAD)
endif()

endmacro()
1 change: 1 addition & 0 deletions cmake/field_api_macros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ include( field_api_expand_fypp )
include( field_api_expand_fypp_ranksuff )
include( field_api_add_object_library )
include( field_api_target_add_module_dirs )
include( field_api_get_offload_model )
11 changes: 11 additions & 0 deletions python_utils/offload_backends/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# (C) Copyright 2022- ECMWF.
# (C) Copyright 2022- 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.

from offload_backends.nvhpc import *
from offload_backends.host_only import *
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.

# Download fypp preprocessor if not found.

include(FetchContent)
__all__ = ['HostOnly']

FetchContent_Declare(
fypp
GIT_REPOSITORY https://github.com/aradi/fypp
GIT_TAG 3.1
)
class HostOnly():
"""
A dummy class only to be used if GPU offload is disabled.
"""

FetchContent_MakeAvailable(fypp)
pragma = ''
11 changes: 11 additions & 0 deletions python_utils/offload_backends/nvhpc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# (C) Copyright 2022- ECMWF.
# (C) Copyright 2022- 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.

from offload_backends.nvhpc.openacc import *
from offload_backends.nvhpc.openacc_cuda import *
Loading
Loading