Skip to content

Commit

Permalink
Merge branch 'release/0.40.0'
Browse files Browse the repository at this point in the history
* release/0.40.0: (40 commits)
  Update changelog
  Version 0.40.0
  Add hicLaunchHostFunc for async host functions
  Add test for various use cases of StructuredInterpolation2D with limiter
  Implement StructureInterpolation2D for 3-dimensional fields with extra variables)
  Fix application of limiter for StructuredInterpolation2D
  Protect atlas_test_array_view_variant to eckit v 1.27.0
  Move example-fortran inside atlas_HAVE_DOCS (#235)
  Fix possible device-memory leak in WrappedDataStore (fixes #234)
  add device data on FieldSet
  Add test for fieldset device operators
  Add fieldset device operators
  Update fctest_field_gpu to test acc deviceptr
  Update test_field_acc to test acc deviceptr
  Add device_data Fortran access to Field
  Refactored spherical vector interpolation method. (#227)
  Refactored (un)pack_vector_fields. (#226)
  Integrate `pack_vector_fields` into `SphericalVector` Interpolation method. (#224)
  Fixed ordering of fixup_halos and halo_exhange in StructuredColumns.cc (#223)
  Tidied headers and error message. (#231)
  ...
  • Loading branch information
wdeconinck committed Nov 18, 2024
2 parents 59efc06 + d431940 commit 9a1ea76
Show file tree
Hide file tree
Showing 88 changed files with 4,782 additions and 264 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html

## [Unreleased]

## [0.40.0] - 2024-11-18

### Added
- Add MultiField to pack field allocations by @sbrdar in https://github.com/ecmwf/atlas/pull/229
- Add function to create `std::variant` for multiple array views. by @odlomax in https://github.com/ecmwf/atlas/pull/220
- Add Fortran access to device data through Field and FieldSet by @sbrdar in https://github.com/ecmwf/atlas/pull/232
- Add Fortran API for structured stencil computations by @wdeconinck in https://github.com/ecmwf/atlas/pull/228

### Changed
- Support OpenACC with Cray compiler + use OpenACC_Fortran_FLAGS by @wdeconinck in https://github.com/ecmwf/atlas/pull/225
- Refactor `SphericalVector` interpolation method to use `array::ArrayViewVariant`. by @odlomax in https://github.com/ecmwf/atlas/pull/227
- Integrate `pack_vector_fields` into `SphericalVector` Interpolation method. by @odlomax in https://github.com/ecmwf/atlas/pull/224
- Refactor `util::pack_vector_fields` to use `array::ArrayViewVariant` by @odlomax in https://github.com/ecmwf/atlas/pull/226

### Fixed
- Fix application of limiter for StructuredInterpolation2D by @wdeconinck in https://github.com/ecmwf/atlas/pull/236
- Fix use of ATLAS_ENABLE_CUDA ON/OFF
- Bugfix for Qhull by @benjaminmenetrier in https://github.com/ecmwf/atlas/pull/230
- Fixed ordering of `fixup_halos` and `halo_exhange.execute_adjoint` in `StructuredColumns.cc` by @odlomax in https://github.com/ecmwf/atlas/pull/223


## [0.39.0] - 2024-09-18

### Added
Expand Down Expand Up @@ -564,6 +585,7 @@ Fix StructuredInterpolation2D with retry for failed stencils
## 0.13.0 - 2018-02-16

[Unreleased]: https://github.com/ecmwf/atlas/compare/master...develop
[0.40.0]: https://github.com/ecmwf/atlas/compare/0.39.0...0.40.0
[0.39.0]: https://github.com/ecmwf/atlas/compare/0.38.1...0.39.0
[0.38.1]: https://github.com/ecmwf/atlas/compare/0.38.0...0.38.1
[0.38.0]: https://github.com/ecmwf/atlas/compare/0.37.0...0.38.0
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ ecbuild_add_option( FEATURE ECKIT_DEVELOP
DESCRIPTION "Used to enable new features or API depending on eckit develop branch, not yet in a tagged release"
DEFAULT OFF )

if (DEFINED ATLAS_ENABLE_CUDA AND NOT DEFINED HIC_ENABLE_CUDA )
set( HIC_ENABLE_CUDA ${ATLAS_ENABLE_CUDA} )
endif()
if (DEFINED ATLAS_ENABLE_HIP AND NOT DEFINED HIC_ENABLE_HIP )
set( HIC_ENABLE_HIP ${ATLAS_ENABLE_HIP} )
endif()

add_subdirectory( hic )
find_package(hic)

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.39.0
0.40.0
4 changes: 2 additions & 2 deletions cmake/atlas-import.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ if( atlas_HAVE_ECTRANS AND atlas_REQUIRES_PRIVATE_DEPENDENCIES )
endif()
endif()

## CGAL
## Qhull
if( atlas_HAVE_TESSELATION AND atlas_REQUIRES_PRIVATE_DEPENDENCIES )
find_dependency( CGAL HINTS @CGAL_DIR@ )
find_dependency( Qhull HINTS @Qhull_DIR@ )
endif()

## Fortran
Expand Down
43 changes: 15 additions & 28 deletions cmake/features/ACC.cmake
Original file line number Diff line number Diff line change
@@ -1,40 +1,27 @@
### OpenACC

if( atlas_HAVE_ATLAS_FIELD )
if( atlas_HAVE_ATLAS_FIELD AND HAVE_GPU )

set( ATLAS_ACC_CAPABLE FALSE )
if( HAVE_GPU )
if( CMAKE_Fortran_COMPILER_ID MATCHES "PGI|NVHPC" )
set( ATLAS_ACC_CAPABLE TRUE )
else()
find_package(OpenACC COMPONENTS C Fortran)
if(OpenACC_Fortran_FOUND AND OpenACC_C_FOUND)
set( ATLAS_ACC_CAPABLE TRUE )
if( DEFINED ATLAS_ENABLE_ACC )
set( ENABLE_ACC ${ATLAS_ENABLE_ACC} )
endif()
if( ENABLE_ACC )
if( NOT HAVE_FORTRAN )
enable_language(Fortran)
endif()
find_package( OpenACC COMPONENTS Fortran CXX )
endif()
endif()

ecbuild_add_option( FEATURE ACC
DESCRIPTION "OpenACC capable data structures"
CONDITION ATLAS_ACC_CAPABLE )

if( atlas_HAVE_ACC )
if( CMAKE_Fortran_COMPILER_ID MATCHES "PGI|NVHPC" )
#set( ACC_Fortran_FLAGS -acc -ta=tesla,nordc )
set( ACC_Fortran_FLAGS "-acc=gpu;-gpu=gvmode,lineinfo,fastmath,rdc" )
set( ACC_C_FLAGS ${ACC_Fortran_FLAGS} )
find_program( ACC_C_COMPILER NAMES pgcc HINTS ${PGI_DIR} ${NVPHC_DIR} ENV PGI_DIR NVHPC_DIR PATH_SUFFIXES bin )
if( NOT ACC_C_COMPILER )
ecbuild_error( "Could not find OpenACC capable C compiler" )
endif()
else()
set( ACC_Fortran_FLAGS ${OpenACC_Fortran_FLAGS} )
set( ACC_C_FLAGS ${OpenACC_C_FLAGS} )
ecbuild_add_option( FEATURE ACC
DESCRIPTION "OpenACC capable data structures"
CONDITION OpenACC_Fortran_FOUND )
if( HAVE_ACC )
set( ACC_LINK_OPTIONS ${OpenACC_Fortran_FLAGS} )
endif()
endif()

else()

set( HAVE_ACC 0 )
set( atlas_HAVE_ACC 0 )
endif()

endif()
10 changes: 7 additions & 3 deletions cmake/features/ECTRANS.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ if( atlas_HAVE_ATLAS_FUNCTIONSPACE AND (ENABLE_ECTRANS OR NOT DEFINED ENABLE_ECT
if( TARGET transi_dp )
set( transi_FOUND TRUE )
if( NOT TARGET transi )
get_target_property( transi_dp_IMPORTED transi_dp IMPORTED )
if( transi_dp_IMPORTED )
set_target_properties( transi_dp PROPERTIES IMPORTED_GLOBAL TRUE) # required for aliasing imports
if( CMAKE_VERSION VERSION_LESS 3.18 )
# Before CMake 3.18 it is not possible to alias a non-global imported target
# Make the import global. Warning, this may break further find_package
get_target_property( transi_dp_IMPORTED transi_dp IMPORTED )
if( transi_dp_IMPORTED )
set_target_properties( transi_dp PROPERTIES IMPORTED_GLOBAL TRUE)
endif()
endif()
add_library( transi ALIAS transi_dp )
endif()
Expand Down
4 changes: 1 addition & 3 deletions cmake/project_summary.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ endif()
if( atlas_HAVE_ACC )

ecbuild_info( "ACC" )
ecbuild_info( " ACC_C_COMPILER : [${ACC_C_COMPILER}]" )
ecbuild_info( " ACC_C_FLAGS : [${ACC_C_FLAGS}]" )
ecbuild_info( " ACC_Fortran_FLAGS : [${ACC_Fortran_FLAGS}]" )
ecbuild_info( " OpenACC_Fortran_FLAGS : [${OpenACC_Fortran_FLAGS}]" )

endif()

Expand Down
4 changes: 4 additions & 0 deletions doc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

if(atlas_HAVE_DOCS)

if(atlas_HAVE_FORTRAN)
add_subdirectory(example-fortran)
endif()

add_subdirectory(user-guide)

list( APPEND DOC_CODE_TARGETS
Expand Down
10 changes: 10 additions & 0 deletions doc/example-fortran/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# (C) Copyright 2024- 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.

add_subdirectory(structured-grid-stencils)

12 changes: 12 additions & 0 deletions doc/example-fortran/structured-grid-stencils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# (C) Copyright 2024- 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.

ecbuild_add_executable( TARGET example-fortran-structured-grid-stencils
OUTPUT_NAME program NOINSTALL
SOURCES program.F90
LIBS atlas_f )
210 changes: 210 additions & 0 deletions doc/example-fortran/structured-grid-stencils/program.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
! (C) Copyright 2023 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.

! ------------------------------------------------------------------------------------------------
! Example program on how to access and use StructuredColumns functionspace
! Also includes computation of stencils around a given coordinate
! ------------------------------------------------------------------------------------------------

subroutine run

use, intrinsic :: iso_fortran_env, only : real64, real32
use atlas_module, only : &
& atlas_ReducedGaussianGrid ,&
& atlas_functionspace_StructuredColumns ,&
& atlas_Field, &
& ATLAS_KIND_IDX, &
& atlas_StructuredGrid_ComputeNorth ,&
& atlas_StructuredGrid_ComputeWest ,&
& atlas_StructuredGrid_ComputeStencil ,&
& atlas_StructuredGrid_Stencil, &
& atlas_real

use fckit_mpi_module, only : fckit_mpi

! ------------------------------------------------
implicit none

character(len=:), allocatable :: gridname
type(atlas_ReducedGaussianGrid) :: grid
type(atlas_functionspace_StructuredColumns) :: functionspace
real(real64) :: zlon, zlat
integer(ATLAS_KIND_IDX) :: jlon,jlat, jgp
real(real64), pointer :: xy(:,:)
integer :: log_rank

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

log_rank = 1 ! First partition has rank=0 !!!
if (fckit_mpi%size() == 1) then
log_rank = 0
endif

gridname = "O320"

! Create grid and write some properties
!grid = atlas_StructuredGrid(gridname)
grid = atlas_ReducedGaussianGrid([20,24,28,32,36,40,44,48,52,56,60,64,&
64,60,56,52,48,44,40,36,32,28,24,20])

if (fckit_mpi%rank() == log_rank) then
write(0,*) "grid%name() : ", grid%name()
write(0,*) "grid%size() : ", grid%size()
write(0,*) "grid%ny() : ", grid%ny()
write(0,*) "grid%nxmax() : ", grid%nxmax()
endif

! Create functionspace of grid, distributed across MPI tasks with default partitioner, and with halo of 2 wide
! The default partitioner is "equal_regions"
functionspace = atlas_functionspace_StructuredColumns(grid, halo=2)

! Latitude bounds without and with halos of this partition
if (fckit_mpi%rank() == log_rank) then
write(0,*) "functionspace%size_owned() : ", functionspace%size_owned()
write(0,*) "functionspace%size() : ", functionspace%size()
write(0,'(A,I0,A,I0)') " halo points between index ", functionspace%size_owned()+1 , " and " , functionspace%size()
write(0,*) "functionspace%j_begin(), functionspace%j_end() : ", &
& functionspace%j_begin(), functionspace%j_end()
write(0,*) "functionspace%j_begin_halo(), functionspace%j_end_halo() : ", &
& functionspace%j_begin_halo(), functionspace%j_end_halo()
endif

! Longitude bounds without and with halos of this partition for the first latitude
jlat = functionspace%j_begin()
if (fckit_mpi%rank() == log_rank) then
write(0,*) "functionspace%i_begin(jlat), functionspace%i_end(jlat) : ", functionspace%i_begin(jlat), &
& functionspace%i_end(jlat)
write(0,*) "functionspace%i_begin_halo(jlat), functionspace%i_end_halo(jlat) : ", functionspace%i_begin_halo(jlat),&
& functionspace%i_end_halo(jlat)
endif

! Access i,j indices of grid points
block
type(atlas_Field) :: field_index_i, field_index_j
integer(ATLAS_KIND_IDX), pointer :: index_i(:), index_j(:)
field_index_i = functionspace%index_i()
field_index_j = functionspace%index_j()
call field_index_i%data(index_i)
call field_index_j%data(index_j)
if (fckit_mpi%rank() == log_rank) then
write(0,*) "i,j of first partition point :", index_i(1), index_j(1)
endif
call field_index_i%final()
call field_index_j%final()
end block

! Access to xy coordinates
block
type(atlas_Field) :: field_xy
field_xy = functionspace%xy()
call field_xy%data(xy)
call field_xy%final()
end block

! Creating a horizontal field and perform halo exchange
block
type(atlas_Field) :: field
real(real32), pointer :: view(:)
field = functionspace%create_field(name="myfield", kind=atlas_real(real32))
call field%data(view)
if (fckit_mpi%rank() == log_rank) then
write(0,*) "shape( horizontal field )", shape(view)
endif
view(1:functionspace%size_owned()) = 1.
view(functionspace%size_owned()+1:functionspace%size()) = 0
call field%set_dirty() ! This marks that halos are in "dirty" state
call field%halo_exchange() ! Only exchanges halos when halos are marked as "dirty"
if (fckit_mpi%rank() == log_rank) then
write(0,*) "halo exhange success : ", all(view == 1.)
endif
call field%final()
end block

! Creating a horizontal/vertical field
block
type(atlas_Field) :: field
real(real32), pointer :: view(:,:)
field = functionspace%create_field(name="myfield", kind=atlas_real(real32), levels=10)
call field%data(view)
if (fckit_mpi%rank() == log_rank) then
write(0,*) "shape( horizontal/vertical field )", shape(view)
endif
call field%final()
end block

! Set a coordinate somewhere south-east of the first grid point, but still within this partition
jgp = 1
zlon = xy(1,jgp) + 0.1
zlat = xy(2,jgp) - 0.1

! Compute nearest points to the north-west of a coordinate
block
type(atlas_StructuredGrid_ComputeNorth) :: compute_north
type(atlas_StructuredGrid_ComputeWest) :: compute_west
compute_north = atlas_StructuredGrid_ComputeNorth(grid, halo=2)
compute_west = atlas_StructuredGrid_ComputeWest(grid, halo=2)

jlat = compute_north%execute(zlat)
jlon = compute_west%execute(zlon, jlat)
jgp = functionspace%index(jlon,jlat) ! gridpoint index in 1-dimensional array

if (fckit_mpi%rank() == log_rank) then
write(0,'(A,F6.2,A,I0)') "compute_north%execute(y=",zlat,") : ", jlat
write(0,'(A,F6.2,A,I0,A,I0)') "compute_west%execute(x=",zlon,", j=", jlat,") : ", jlon
write(0,'(A,I0,A,F6.2,A,F6.2,A)') "gridpoint north-west: jpg=",jgp," (lon,lat)=(", xy(1,jgp), ",", xy(2,jgp), ")"
endif
call compute_west%final()
call compute_north%final()
end block

! Stencil computer of 4x4 stencil around a coordinate
block
type(atlas_StructuredGrid_ComputeStencil) :: compute_stencil
type(atlas_StructuredGrid_Stencil) :: stencil
call compute_stencil%setup(grid, stencil_width=4)
call compute_stencil%execute(zlon,zlat,stencil)
if (fckit_mpi%rank() == log_rank) then
write(0,'(A,A,dt)') 'stencil:', new_line('a'), stencil
endif
if (fckit_mpi%rank() == log_rank) then
write(0,'(A,A,dt)') 'stencil gridpoints:'
do jlat=1,stencil%width
do jlon=1,stencil%width
write(0,'(I8)',advance='no') functionspace%index(stencil%i(jlon,jlat),stencil%j(jlat))
enddo
write(0,'(A)') ""
enddo

write(0,'(A,A,dt)') 'stencil coordinates:'
do jlat=1,stencil%width
jgp = functionspace%index(stencil%i(1,jlat),stencil%j(jlat))
write(0,'(A, F6.2,A)', advance='no') " lat : ", xy(2,jgp), " --- lon : "
do jlon=1,stencil%width
jgp = functionspace%index(stencil%i(jlon,jlat),stencil%j(jlat))
write(0,'(F8.2)',advance='no') xy(1,jgp)
enddo
write(0,'(A)') ""
enddo

endif
call compute_stencil%final()
end block

call functionspace%final()
call grid%final()
end subroutine

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

program main
use atlas_module, only : atlas_library
implicit none
call atlas_library%initialize()
call run()
call atlas_library%finalize()
end program
Loading

0 comments on commit 9a1ea76

Please sign in to comment.