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

Upgrade pyPDAF to be compatible with PDAF V2.2.1 #4

Merged
merged 6 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
fixes bugs in C interface code; fixes issues with installation; add C…
…Make configurations; uses single precision integer in examples for compatibility with Fortran and Cython declaration.
  • Loading branch information
yumengch committed Jul 19, 2024
commit 4958ec4571908307e09474933e3fe4868dd23141
86 changes: 45 additions & 41 deletions PDAFBuild/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
cmake_minimum_required(VERSION 3.12)
project(PDAF VERSION 2.1.0 LANGUAGES Fortran)
project(PDAF VERSION 2.2.1 LANGUAGES Fortran)

set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/..)
# Set the PDAF library version
set(PDAF_VERSION "2.2.1")

# In windows, MPI.mod must be compiled by ourselves
if(WIN32)
add_library(mpimod STATIC ${MPI_Fortran_MODULE_DIR}/mpi.f90)
set_source_files_properties(${MPI_Fortran_MODULE_DIR}/mpi.f90 PROPERTIES COMPILE_OPTIONS "/Qdiag-disable:10448")
target_include_directories(mpimod PUBLIC ${MPI_Fortran_INCLUDE_PATH})
endif()
set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/..)

set(MOD_PDAF
PDAF_timer.F90
Expand Down Expand Up @@ -74,6 +70,9 @@ set(OBJ_PDAF_GEN
PDAF_reset_forget.F90
PDAF_get_ensstats.F90
PDAF_set_debug_flag.F90
PDAF_analysis_utils.F90
PDAF_reset_dim_p.F90
PDAF_set_offline_mode.F90
)

# Specific PDAF-routines for SEIK
Expand Down Expand Up @@ -238,6 +237,7 @@ set(OBJ_LNETF
PDAF_lnetf_update.F90
PDAF_lnetf_analysis.F90
PDAF_lnetf_smootherT.F90
PDAF_mod_lnetf.F90
PDAF_smoother_lnetf.F90
)

Expand Down Expand Up @@ -291,11 +291,11 @@ set(OBJ_3DVAR_INI
PDAF_3dvar_init.F90
PDAF_3dvar_alloc.F90
PDAF_3dvar_options.F90
PDAF_3dvar_memtime.F90
)

# Specific PDAF-routines for 3DVAR
set(OBJ_3DVAR
PDAF_3dvar_memtime.F90
set(OBJ_3DVAR
PDAF_put_state_3dvar.F90
PDAF_assimilate_3dvar.F90
PDAF_3dvar_update.F90
Expand Down Expand Up @@ -361,6 +361,9 @@ set(OBJ_OPTIM
../external/LBFGS/timer.f
)

set (OBJ_INTERFACE
PDAF_interfaces_module.F90
)
# List all source files
set(SRC_FILES
${MOD_PDAF}
Expand All @@ -379,43 +382,44 @@ set(SRC_FILES
${OBJ_PF}
${OBJ_LKNETF}
${OBJ_OBSGEN}
${OBJ_3DVAR_INI}
${OBJ_3DVAR}
${OBJ_PDAFOMI}
${OBJ_OPTIM}
${OBJ_OPTIM}
${OBJ_INTERFACE}
${OBJ_3DVAR_INI}
)

# Customize compiler flags
if(${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU")
set_source_files_properties (${SRC_FILES} PROPERTIES COMPILE_OPTIONS "-O3;-ffree-line-length-none -fdefault-real-8")
elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL "Cray")
set_source_files_properties (${SRC_FILES} PROPERTIES COMPILE_OPTIONS "-O3;-N;1023")
elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL "Intel")
if(WIN32)
set_source_files_properties (${SRC_FILES} PROPERTIES COMPILE_OPTIONS "/O3;/4R8;/Qdiag-disable:10448")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} /Od")
else()
# set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -r8")
set_source_files_properties (${SRC_FILES} PROPERTIES COMPILE_OPTIONS "-O3;-r8")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS} -mkl")
#KB For newer versions of CMake - this is the way to go
enable_language(C)
set(BLA_VENDOR Intel10_64lp_seq)
#KB https://cmake.org/cmake/help/latest/module/FindBLAS.html
endif()
# check if Config Path is provided
if(NOT Config_PATH)
message(FATAL_ERROR "Config_PATH is not given. Providing a Config_PATH in commandline by specify -DConfig_PATH=PATH_TO_CONFIG_FILE")
endif()

# Define a target for pdaf-var
add_library(pdaf-var STATIC ${SRC_FILES})
# import configuration file
include(${Config_PATH})

if (${PDAF_NAME} STREQUAL "pdaf-var")
set(SRC_FILES ${SRC_FILES} ${OBJ_3DVAR} ${OBJ_OPTIM})
endif()

# Check if the build type is not explicitly set and default to Release
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()

# extra option for specific files
# set_source_files_properties (${SRC_FILES} PROPERTIES COMPILE_OPTIONS "${RELEASE_COMPILE_OPTIONS}")

# Define a target for pdaf library
add_library(${PDAF_NAME} STATIC ${SRC_FILES})

# Set properties for pdaf library
target_include_directories(${PDAF_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(${PDAF_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

# Set properties for pdaf-var
target_include_directories(pdaf-var PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(pdaf-var PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(pdaf-var PUBLIC ${MPI_Fortran_INCLUDE_PATH})
target_include_directories(pdaf-var PUBLIC ${MPI_Fortran_MODULE_DIR})
# Set include directory for MPI
target_include_directories(${PDAF_NAME} PUBLIC ${MPI_Fortran_INCLUDE_PATH})
target_include_directories(${PDAF_NAME} PUBLIC ${MPI_Fortran_MODULE_DIR})

set_target_properties(pdaf-var PROPERTIES
# Move the static library and include files to given directories.
set_target_properties(${PDAF_NAME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../lib
)
set_target_properties(pdaf-var PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../include)
set_target_properties(${PDAF_NAME} PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../include)
40 changes: 40 additions & 0 deletions PDAFBuild/linux_gfortran_openmpi_pypdaf.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Set the PDAF library name, it can be pdaf-var or pdaf-d
set(PDAF_NAME "pdaf-var")

# Set preprocessor and linker for current system
# AR is used to generate static libraries
set(CMAKE_AR "ar" CACHE FILEPATH "Archiver")
# RANKLIB is used to deal with static libraries
set(CMAKE_RANLIB "ranlib" CACHE FILEPATH "Ranlib")
# Here a linker is specified it can be the compiler used
set(CMAKE_LINKER "/home/username/software/spack-0.22.1/opt/spack/linux-ubuntu22.04-skylake/gcc-13.2.0/openmpi-5.0.3-ummuvvrxsncu6txyqbvehgqkpijndmql/bin/mpif90" CACHE FILEPATH "Linker")
# CPP is the C preprocessor
set(CMAKE_CPP "cpp" CACHE FILEPATH "C Preprocessor")

# set compiler executable
set(CMAKE_Fortran_COMPILER "/home/username/software/spack-0.22.1/opt/spack/linux-ubuntu22.04-skylake/gcc-13.2.0/openmpi-5.0.3-ummuvvrxsncu6txyqbvehgqkpijndmql/bin/mpif90")
# Set compiler flags for Release/Production configurations
set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -ffree-line-length-none -fdefault-real-8 -fPIC")
# Set compiler flags for Debug configurations
set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -Wall -Wextra -g -pedantic -fcheck=all -fbacktrace -ffree-line-length-none -fdefault-real-8 -fPIC")

# set MPI library information
set(MPI_Fortran_INCLUDE_PATH
"/home/username/software/spack-0.22.1/opt/spack/linux-ubuntu22.04-skylake/gcc-13.2.0/openmpi-5.0.3-ummuvvrxsncu6txyqbvehgqkpijndmql/include/"
CACHE STRING "path to the include directory of MPI_Fortran")
set(MPI_Fortran_MODULE_DIR
"/home/username/software/spack-0.22.1/opt/spack/linux-ubuntu22.04-skylake/gcc-13.2.0/openmpi-5.0.3-ummuvvrxsncu6txyqbvehgqkpijndmql/lib/"
CACHE STRING "path to the module directory of MPI_Fortran")

# set BLAS information
set(BLAS_NAME "openblas")
set(BLAS_INCLUDE_PATH "/home/username/software/spack-0.22.1/opt/spack/linux-ubuntu22.04-skylake/gcc-13.2.0/openblas-0.3.26-fhoiyp4jbfxtxry3d6skn5he4hqh7ur7/include")
set(BLAS_LIB_PATH "/home/username/software/spack-0.22.1/opt/spack/linux-ubuntu22.04-skylake/gcc-13.2.0/openblas-0.3.26-fhoiyp4jbfxtxry3d6skn5he4hqh7ur7/lib")

# set LAPACK information
set(LAPACK_NAME "scalapack")
set(LAPACK_INCLUDE_PATH "/home/username/software/spack-0.22.1/opt/spack/linux-ubuntu22.04-skylake/gcc-13.2.0/netlib-scalapack-2.2.0-izrouv2qyqsuchli4s3jybeksc6m7zdo/include")
set(LAPACK_LIB_PATH "/home/username/software/spack-0.22.1/opt/spack/linux-ubuntu22.04-skylake/gcc-13.2.0/netlib-scalapack-2.2.0-izrouv2qyqsuchli4s3jybeksc6m7zdo/lib")

# set PDAF information
set(PDAF_INCLUDE_PATH "/home/username/Documents/pyPDAF/PDAF_V2.2.1/include")
4 changes: 2 additions & 2 deletions example/PDAF_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def setEnKFOptions(self, dim_pint:int, dim_preal:int) -> tuple[np.ndarray[int],
dim_preal : int
size of float filter options
"""
filter_param_i:np.ndarray = np.zeros(dim_pint, dtype=int)
filter_param_i:np.ndarray = np.zeros(dim_pint, dtype=np.intc)
filter_param_r:np.ndarray = np.zeros(dim_preal)

filter_param_i[0] = self.sv.dim_state_p
Expand All @@ -151,7 +151,7 @@ def setETKFOptions(self, dim_pint:int, dim_preal:int) -> tuple[np.ndarray[int],
dim_preal : int
size of float filter options
"""
filter_param_i:np.ndarray = np.zeros(dim_pint, dtype=int)
filter_param_i:np.ndarray = np.zeros(dim_pint, dtype=np.intc)
filter_param_r:np.ndarray = np.zeros(dim_preal)

filter_param_i[0] = self.sv.dim_state_p
Expand Down
6 changes: 3 additions & 3 deletions example/obsA.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,15 @@ def init_dim(self, step:int, dim_obs:int) -> int:
ocoord_p = ocoord_p + 1


id_obs_p:np.ndarray = np.zeros((self.nrows, len(obs_p)))
id_obs_p:np.ndarray = np.zeros((self.nrows, len(obs_p)), dtype=np.intc)
if self.nrows == 1:
# The relationship between observation and state vector
# id_obs_p gives the indices of observed field in state vector
# the index starts from 1
# The index is based on the full state vector instead of the index in the local domain
# The following code is used because in our example, observations are masked and
# have the same shape as the model grid
state_vector_index_p:np.ndarray = np.arange(1, self.model.nx_p*self.model.ny_p + 1, dtype=int)
state_vector_index_p:np.ndarray = np.arange(1, self.model.nx_p*self.model.ny_p + 1, dtype=np.intc)
id_obs_p[0] = state_vector_index_p[condition]
else:
# If interpolation is required for a 2D domain
Expand Down Expand Up @@ -252,7 +252,7 @@ def init_dim_obs_l(self, domain_p:int, step:int, dim_obs:int, dim_obs_l:int) ->
coords_l[1] = np.repeat(np.arange(self.model.ny_p), self.model.nx_p)[domain_p - 1]
coords_l = coords_l + 1

return PDAF.omi_init_dim_obs_l(self.i_obs, coords_l,
return PDAF.omi_init_dim_obs_l_iso(self.i_obs, coords_l,
self.local.loc_weight,
self.local.cradius,
self.local.sradius, dim_obs_l)
Expand Down
6 changes: 3 additions & 3 deletions example/obsB.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,15 @@ def init_dim(self, step:int, dim_obs:int) -> int:
ocoord_p = ocoord_p + 1


id_obs_p:np.ndarray = np.zeros((self.nrows, len(obs_p)))
id_obs_p:np.ndarray = np.zeros((self.nrows, len(obs_p)), dtype=np.intc)
if self.nrows == 1:
# The relationship between observation and state vector
# id_obs_p gives the indices of observed field in state vector
# the index starts from 1
# The index is based on the full state vector instead of the index in the local domain
# The following code is used because in our example, observations are masked and
# have the same shape as the model grid
state_vector_index_p:np.ndarray = np.arange(1, self.model.nx_p*self.model.ny_p + 1, dtype=int)
state_vector_index_p:np.ndarray = np.arange(1, self.model.nx_p*self.model.ny_p + 1, dtype=np.intc)
id_obs_p[0] = state_vector_index_p[condition]
else:
# If interpolation is required for a 2D domain
Expand Down Expand Up @@ -251,7 +251,7 @@ def init_dim_obs_l(self, domain_p:int, step:int, dim_obs:int, dim_obs_l:int) ->
coords_l[1] = np.repeat(np.arange(self.model.ny_p), self.model.nx_p)[domain_p - 1]
coords_l = coords_l + 1

return PDAF.omi_init_dim_obs_l(self.i_obs, coords_l,
return PDAF.omi_init_dim_obs_l_iso(self.i_obs, coords_l,
self.local.loc_weight,
self.local.cradius,
self.local.sradius, dim_obs_l)
Expand Down
Loading