diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5bc32697..c36066aa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -121,6 +121,13 @@ jobs: label: PRIF-0.6 FFLAGS: -DFORCE_PRIF_0_6 container: phhargrove/llvm-flang:21.1.0-latest + - os: ubuntu-24.04 + compiler: flang + version: 21 + network: smp + label: PRIF-0.7 + FFLAGS: -DFORCE_PRIF_0_7 + container: phhargrove/llvm-flang:21.1.0-latest # --- udp coverage for selected configs --- - os: macos-15 diff --git a/docs/implementation-status.md b/docs/implementation-status.md index 777d234a..b694ffb7 100644 --- a/docs/implementation-status.md +++ b/docs/implementation-status.md @@ -63,10 +63,10 @@ selected constant values from `ISO_FORTRAN_ENV` of the hosting compiler. | Procedure | Status | Notes | |-----------|--------|-------| -| `prif_allocate_coarray` | **YES** | includes ucobound relaxation expected in PRIF 0.8 | +| `prif_allocate_coarray` | **YES** | includes ucobound relaxation and `final_func` argument rename expected in PRIF 0.8 | | `prif_allocate` | **YES** | | -| `prif_deallocate_coarray` | **YES** | `final_func` support requires flang 20+ | -| `prif_deallocate_coarrays` | **YES** | `final_func` support requires flang 20+ | +| `prif_deallocate_coarray` | **YES** | | +| `prif_deallocate_coarrays` | **YES** | | | `prif_deallocate` | **YES** | | | `prif_alias_create` | **YES** | includes ucobound relaxation expected in PRIF 0.8 | | `prif_alias_destroy` | **YES** | | diff --git a/example/support-test/out_of_memory.F90 b/example/support-test/out_of_memory.F90 index ef213bd9..3a726ff7 100644 --- a/example/support-test/out_of_memory.F90 +++ b/example/support-test/out_of_memory.F90 @@ -1,5 +1,7 @@ program out_of_memory - use iso_c_binding, only: c_bool, c_size_t, c_ptr, c_null_funptr, c_int64_t +# include "../../test/test-uses-alloc.F90" + use unit_test_parameters_m, only: null_final_proc + use iso_c_binding, only: c_bool, c_size_t, c_ptr, c_int64_t use prif implicit none @@ -37,7 +39,7 @@ program out_of_memory ucobounds(1) = num_imgs call prif_allocate_coarray( & - lcobounds, ucobounds, size_in_bytes, c_null_funptr, & + lcobounds, ucobounds, size_in_bytes, null_final_proc, & coarray_handle, allocated_memory) end block else diff --git a/include/language-support.F90 b/include/language-support.F90 index 2ec2dcf9..da546b82 100644 --- a/include/language-support.F90 +++ b/include/language-support.F90 @@ -29,20 +29,6 @@ #endif #endif -#ifndef HAVE_FINAL_FUNC_SUPPORT -# if defined(__GFORTRAN__) && HAVE_GCC_VERSION < 160000 - ! gfortran 14-15 defect prevents declaration of the coarray_cleanup interface: - ! https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113338 - ! reportedly fixed in gfortran 16 -# define HAVE_FINAL_FUNC_SUPPORT 0 -# elif defined(__flang__) && __flang_major__ < 20 - ! also missing in flang before 20 -# define HAVE_FINAL_FUNC_SUPPORT 0 -# else -# define HAVE_FINAL_FUNC_SUPPORT 1 -# endif -#endif - #ifndef NEED_C_FUNLOC_WORKAROUND # if __GFORTRAN__ && HAVE_GCC_VERSION <= 150200 ! Gfortran 13..15.2 bug workaround, believed to be fixed in 15.3 and 16.x: diff --git a/include/version.h b/include/version.h index 3e1cc9b3..d090a8c7 100644 --- a/include/version.h +++ b/include/version.h @@ -30,7 +30,7 @@ #elif FORCE_PRIF_0_8 # define CAF_PRIF_VERSION_MINOR 8 #else -# define CAF_PRIF_VERSION_MINOR 7 +# define CAF_PRIF_VERSION_MINOR 8 #endif #define CAF_PRIF_VERSION (100 * CAF_PRIF_VERSION_MAJOR + CAF_PRIF_VERSION_MINOR) diff --git a/src/caffeine/alias_s.F90 b/src/caffeine/alias_s.F90 index 4e6f2a8c..065dafc2 100644 --- a/src/caffeine/alias_s.F90 +++ b/src/caffeine/alias_s.F90 @@ -13,11 +13,14 @@ module procedure prif_alias_create integer(c_int) :: corank + type(prif_coarray_descriptor), pointer :: cdp + type(prif_coarray_descriptor), pointer :: alias_cdp ! validate inputs call_assert(coarray_handle_check(source_handle)) corank = size(alias_lcobounds) call_assert(corank > 0) + call_assert(corank <= 15) if (size(alias_ucobounds) == corank) then call_assert(all(alias_lcobounds <= alias_ucobounds)) call_assert(product(alias_ucobounds - alias_lcobounds + 1) >= current_team%info%num_images) @@ -26,50 +29,50 @@ call_assert(all(alias_lcobounds(1:corank-1) <= alias_ucobounds)) end if - - allocate(alias_handle%info) + cdp => handle_to_cdp(source_handle) ! start with a copy of the source descriptor - alias_handle%info = source_handle%info + allocate(alias_cdp, source=cdp) # if CAF_PRIF_VERSION >= 6 - alias_handle%info%coarray_data = & - as_c_ptr(as_int(alias_handle%info%coarray_data) + data_pointer_offset) + alias_cdp%coarray_data = & + as_c_ptr(as_int(alias_cdp%coarray_data) + data_pointer_offset) # endif ! apply provided cobounds - alias_handle%info%corank = corank - alias_handle%info%lcobounds(1:corank) = alias_lcobounds - alias_handle%info%ucobounds(1:corank-1) = alias_ucobounds(1:corank-1) + alias_cdp%corank = corank + alias_cdp%lcobounds(1:corank) = alias_lcobounds + alias_cdp%ucobounds(1:corank-1) = alias_ucobounds(1:corank-1) call compute_coshape_epp(alias_lcobounds, alias_ucobounds, & - alias_handle%info%coshape_epp(1:corank)) + alias_cdp%coshape_epp(1:corank)) # if ASSERTIONS ! The following entries are dead, but initialize them to help detect defects - alias_handle%info%lcobounds(corank+1:15) = huge(0_c_int64_t) - alias_handle%info%ucobounds(corank:14) = -huge(0_c_int64_t) - alias_handle%info%coshape_epp(corank+1:15) = 0 + alias_cdp%lcobounds(corank+1:15) = huge(0_c_int64_t) + alias_cdp%ucobounds(corank:14) = -huge(0_c_int64_t) + alias_cdp%coshape_epp(corank+1:15) = 0 # endif ! reset some fields that are unused in aliases - alias_handle%info%reserved = c_null_ptr - alias_handle%info%previous_handle = c_null_ptr - alias_handle%info%next_handle = c_null_ptr - alias_handle%info%final_func = c_null_funptr + alias_cdp%reserved = c_null_ptr + alias_cdp%previous_handle = c_null_ptr + alias_cdp%next_handle = c_null_ptr + alias_cdp%final_proc = c_null_funptr + alias_handle = cdp_to_handle(alias_cdp) call_assert(coarray_handle_check(alias_handle)) end procedure module procedure prif_alias_destroy - type(prif_coarray_descriptor), pointer :: info + type(prif_coarray_descriptor), pointer :: cdp call_assert(coarray_handle_check(alias_handle)) - info => alias_handle%info - call_assert(.not. c_associated(info%reserved)) - call_assert(.not. c_associated(info%previous_handle)) - call_assert(.not. c_associated(info%next_handle)) - call_assert(.not. c_associated(info%final_func)) + cdp => handle_to_cdp(alias_handle) + call_assert(.not. c_associated(cdp%reserved)) + call_assert(.not. c_associated(cdp%previous_handle)) + call_assert(.not. c_associated(cdp%next_handle)) + call_assert(.not. c_associated(cdp%final_proc)) - deallocate(info) + deallocate(cdp) end procedure end submodule alias_s diff --git a/src/caffeine/allocation_s.F90 b/src/caffeine/allocation_s.F90 index 859e0373..b0158aae 100644 --- a/src/caffeine/allocation_s.F90 +++ b/src/caffeine/allocation_s.F90 @@ -12,22 +12,42 @@ contains - module procedure prif_allocate_coarray + module subroutine prif_allocate_coarray(lcobounds, ucobounds, size_in_bytes, & +# if CAF_PRIF_VERSION >= 8 + final_proc, & +# else + final_func, & +# endif + coarray_handle, allocated_memory, stat, errmsg, errmsg_alloc) + implicit none + ! redundant redeclaration of arguments here is a GCC 13..15 bug workaround: + integer(c_int64_t), dimension(:), intent(in) :: lcobounds, ucobounds + integer(c_size_t), intent(in) :: size_in_bytes +# if CAF_PRIF_VERSION >= 8 + procedure(prif_coarray_cleanup_interface), pointer, intent(in) :: final_proc +# else + type(c_funptr), intent(in) :: final_func +# endif + type(prif_coarray_handle), intent(out) :: coarray_handle + type(c_ptr), intent(out) :: allocated_memory + integer(c_int), intent(out), optional :: stat + character(len=*), intent(inout), optional :: errmsg + character(len=:), intent(inout), allocatable, optional :: errmsg_alloc + ! TODO: determining the size of the handle and where the coarray begins ! becomes a bit more complicated if we don't allocate space for ! 15 cobounds integer :: me type(c_ptr) :: whole_block integer(c_ptrdiff_t) :: block_offset - integer(c_size_t) :: descriptor_size, total_size integer(c_int) :: corank - type(prif_coarray_descriptor) :: unused - type(prif_coarray_descriptor), pointer :: unused2(:) + type(prif_coarray_descriptor), pointer :: cdp call_assert(team_check(current_team)) corank = size(lcobounds) call_assert(corank > 0) + call_assert(corank <= 15) if (size(ucobounds) == corank) then call_assert(all(lcobounds <= ucobounds)) call_assert(product(ucobounds - lcobounds + 1) >= current_team%info%num_images) @@ -44,14 +64,17 @@ end if end if if (me == 1) then - descriptor_size = c_sizeof(unused) - total_size = descriptor_size + size_in_bytes + block + type(prif_coarray_descriptor) :: unused + integer(c_size_t) :: total_size + total_size = c_sizeof(unused) + size_in_bytes whole_block = caf_allocate(current_team%info%heap_mspace, total_size) if (.not. c_associated(whole_block)) then block_offset = -1 ! out of memory else block_offset = as_int(whole_block) - current_team%info%heap_start end if + end block else block_offset = 0 end if @@ -69,36 +92,47 @@ end if if (me /= 1) whole_block = as_c_ptr(current_team%info%heap_start + block_offset) - call c_f_pointer(whole_block, coarray_handle%info) - call c_f_pointer(whole_block, unused2, [2]) - - coarray_handle%info%coarray_data = c_loc(unused2(2)) - coarray_handle%info%corank = corank - coarray_handle%info%coarray_size = size_in_bytes - coarray_handle%info%final_func = final_func - coarray_handle%info%lcobounds(1:corank) = lcobounds - coarray_handle%info%ucobounds(1:corank-1) = ucobounds(1:corank-1) - call compute_coshape_epp(lcobounds, ucobounds, coarray_handle%info%coshape_epp(1:corank)) + coarray_handle%info = whole_block ! descriptor comes first in memory + cdp => handle_to_cdp(coarray_handle) + block + type(prif_coarray_descriptor), pointer :: unused2(:) + call c_f_pointer(whole_block, unused2, [2]) + cdp%coarray_data = c_loc(unused2(2)) ! element data comes after descriptor + end block + cdp%corank = corank + cdp%coarray_size = size_in_bytes +# if CAF_PRIF_VERSION >= 8 + if (associated(final_proc)) then + cdp%final_proc = CAF_C_FUNLOC_PROCPTR(final_proc) + else + cdp%final_proc = c_null_funptr + end if +# else + cdp%final_proc = final_func +# endif + cdp%lcobounds(1:corank) = lcobounds + cdp%ucobounds(1:corank-1) = ucobounds(1:corank-1) + call compute_coshape_epp(lcobounds, ucobounds, cdp%coshape_epp(1:corank)) # if ASSERTIONS ! The following entries are dead, but initialize them to help detect defects - coarray_handle%info%lcobounds(corank+1:15) = huge(0_c_int64_t) - coarray_handle%info%ucobounds(corank:14) = -huge(0_c_int64_t) - coarray_handle%info%coshape_epp(corank+1:15) = 0 + cdp%lcobounds(corank+1:15) = huge(0_c_int64_t) + cdp%ucobounds(corank:14) = -huge(0_c_int64_t) + cdp%coshape_epp(corank+1:15) = 0 # endif - coarray_handle%info%previous_handle = c_null_ptr - coarray_handle%info%next_handle = c_null_ptr + cdp%previous_handle = c_null_ptr + cdp%next_handle = c_null_ptr call add_to_team_list(coarray_handle) - coarray_handle%info%reserved = c_null_ptr - coarray_handle%info%p_context_data = c_loc(coarray_handle%info%reserved) + cdp%reserved = c_null_ptr ! reserved holds the value of the context data + cdp%p_context_data = c_loc(cdp%reserved) - allocated_memory = coarray_handle%info%coarray_data + allocated_memory = cdp%coarray_data if (caf_have_child_teams()) then call caf_establish_child_heap end if call_assert(coarray_handle_check(coarray_handle)) call_assert(team_check(current_team)) - end procedure + end subroutine module procedure prif_allocate type(c_ptr) :: mem @@ -156,24 +190,27 @@ function pad(str) result(s) #endif integer :: i, num_handles type(prif_coarray_handle), target :: coarray_handle -# if HAVE_FINAL_FUNC_SUPPORT - abstract interface + type(prif_coarray_descriptor), pointer :: cdp +# if CAF_PRIF_VERSION >= 8 + procedure(prif_coarray_cleanup_interface), pointer :: coarray_cleanup +# else + abstract interface subroutine coarray_cleanup_i(handle, stat, errmsg) bind(C) - import c_int, prif_coarray_handle + import c_char, c_int, prif_coarray_handle implicit none - type(prif_coarray_handle), pointer, intent(in) :: handle + type(prif_coarray_handle), value, intent(in) :: handle integer(c_int), intent(out) :: stat - character(len=:), intent(out), allocatable :: errmsg + character(kind=c_char,len=:), intent(out), allocatable :: errmsg end subroutine - end interface - procedure(coarray_cleanup_i), pointer :: coarray_cleanup - integer(c_int) :: local_stat - character(len=:), allocatable :: local_errmsg -#endif + end interface + procedure(coarray_cleanup_i), pointer :: coarray_cleanup + integer(c_int) :: local_stat + character(len=:), allocatable :: local_errmsg +# endif call prif_sync_all ! Need to ensure we don't deallocate anything till everyone gets here num_handles = size(coarray_handles) - if (.not. all([(associated(coarray_handles(i)%info), i = 1, num_handles)])) then + if (.not. all([(c_associated(coarray_handles(i)%info), i = 1, num_handles)])) then call report_error(CAF_STAT_INVALID_ARGUMENT, "Attempted to deallocate unallocated coarray", & stat, errmsg, errmsg_alloc) return @@ -181,12 +218,15 @@ subroutine coarray_cleanup_i(handle, stat, errmsg) bind(C) call_assert(all(coarray_handle_check(coarray_handles))) call_assert(team_check(current_team)) - ! invoke finalizers from coarray_handles(:)%info%final_func + ! invoke finalizers from coarray_handles(:)%final_proc do i = 1, num_handles coarray_handle = coarray_handles(i) ! Add target attribute - if (c_associated(coarray_handle%info%final_func)) then -# if HAVE_FINAL_FUNC_SUPPORT - call c_f_procpointer(coarray_handle%info%final_func, coarray_cleanup) + cdp => handle_to_cdp(coarray_handle) + if (c_associated(cdp%final_proc)) then + call c_f_procpointer(cdp%final_proc, coarray_cleanup) +# if CAF_PRIF_VERSION >= 8 + call coarray_cleanup(coarray_handle) +# else call coarray_cleanup(coarray_handle, local_stat, local_errmsg) call prif_co_max(local_stat) ! Need to be sure it didn't fail on any images if (local_stat /= 0) then @@ -197,8 +237,6 @@ subroutine coarray_cleanup_i(handle, stat, errmsg) bind(C) stat, errmsg, errmsg_alloc) return ! NOTE: We no longer have guarantees that coarrays are in consistent state end if -# else - ! TODO: issue a warning that we are ignoring the final_func? # endif end if end do @@ -206,7 +244,7 @@ subroutine coarray_cleanup_i(handle, stat, errmsg) bind(C) do i = 1, num_handles call remove_from_team_list(coarray_handles(i)) if (current_team%info%this_image == 1) & - call caf_deallocate(current_team%info%heap_mspace, c_loc(coarray_handles(i)%info)) + call caf_deallocate(current_team%info%heap_mspace, coarray_handles(i)%info) end do if (present(stat)) stat = 0 if (caf_have_child_teams()) then @@ -226,38 +264,43 @@ subroutine coarray_cleanup_i(handle, stat, errmsg) bind(C) subroutine add_to_team_list(coarray_handle) type(prif_coarray_handle), intent(in) :: coarray_handle + type(prif_coarray_descriptor), pointer :: cdp - call_assert(.not.c_associated(coarray_handle%info%previous_handle)) - call_assert(.not.c_associated(coarray_handle%info%next_handle)) + cdp => handle_to_cdp(coarray_handle) + + call_assert(.not.c_associated(cdp%previous_handle)) + call_assert(.not.c_associated(cdp%next_handle)) if (associated(current_team%info%coarrays)) then - current_team%info%coarrays%previous_handle = c_loc(coarray_handle%info) - coarray_handle%info%next_handle = c_loc(current_team%info%coarrays) + current_team%info%coarrays%previous_handle = coarray_handle%info + cdp%next_handle = c_loc(current_team%info%coarrays) end if - current_team%info%coarrays => coarray_handle%info + current_team%info%coarrays => cdp end subroutine subroutine remove_from_team_list(coarray_handle) type(prif_coarray_handle), intent(in) :: coarray_handle - type(prif_coarray_descriptor), pointer :: tmp_data + type(prif_coarray_descriptor), pointer :: nbr_cdp, cdp - if ( .not.c_associated(coarray_handle%info%previous_handle) & - .and. .not.c_associated(coarray_handle%info%next_handle)) then - call_assert(associated(current_team%info%coarrays, coarray_handle%info)) - nullify(current_team%info%coarrays) - return - end if - if (c_associated(coarray_handle%info%previous_handle)) then - call c_f_pointer(coarray_handle%info%previous_handle, tmp_data) - tmp_data%next_handle = coarray_handle%info%next_handle - else - call_assert(associated(current_team%info%coarrays, coarray_handle%info)) - call c_f_pointer(coarray_handle%info%next_handle, current_team%info%coarrays) + call_assert(associated(current_team%info%coarrays)) + cdp => handle_to_cdp(coarray_handle) + + if (c_associated(cdp%previous_handle)) then ! have a predecessor + call c_f_pointer(cdp%previous_handle, nbr_cdp) + nbr_cdp%next_handle = cdp%next_handle + else ! head of list + call_assert(associated(current_team%info%coarrays, cdp)) + if (c_associated(cdp%next_handle)) then ! have a successor + call c_f_pointer(cdp%next_handle, current_team%info%coarrays) + else ! sole element + nullify(current_team%info%coarrays) + return + end if end if - if (c_associated(coarray_handle%info%next_handle)) then - call c_f_pointer(coarray_handle%info%next_handle, tmp_data) - tmp_data%previous_handle = coarray_handle%info%previous_handle + if (c_associated(cdp%next_handle)) then ! have a successor + call c_f_pointer(cdp%next_handle, nbr_cdp) + nbr_cdp%previous_handle = cdp%previous_handle end if end subroutine diff --git a/src/caffeine/caffeine.c b/src/caffeine/caffeine.c index a3968a1b..df7ea6a4 100644 --- a/src/caffeine/caffeine.c +++ b/src/caffeine/caffeine.c @@ -34,7 +34,6 @@ static gex_TM_t myworldteam; static mspace* non_symmetric_heap; static gasnett_mutex_t non_symmetric_heap_lock = GASNETT_MUTEX_INITIALIZER; -typedef void(*final_func_ptr)(void*, size_t) ; typedef uint8_t byte; static void event_init(void); diff --git a/src/caffeine/coarray_queries_s.F90 b/src/caffeine/coarray_queries_s.F90 index b58de71c..baec58ed 100644 --- a/src/caffeine/coarray_queries_s.F90 +++ b/src/caffeine/coarray_queries_s.F90 @@ -11,37 +11,46 @@ contains module procedure prif_lcobound_with_dim + type(prif_coarray_descriptor), pointer :: cdp + call_assert(coarray_handle_check(coarray_handle)) - call_assert(dim >= 1 .and. dim <= coarray_handle%info%corank) + cdp => handle_to_cdp(coarray_handle) + call_assert(dim >= 1 .and. dim <= cdp%corank) - lcobound = coarray_handle%info%lcobounds(dim) + lcobound = cdp%lcobounds(dim) end procedure module procedure prif_lcobound_no_dim + type(prif_coarray_descriptor), pointer :: cdp + call_assert(coarray_handle_check(coarray_handle)) - call_assert(size(lcobounds) == coarray_handle%info%corank) + cdp => handle_to_cdp(coarray_handle) + call_assert(size(lcobounds) == cdp%corank) - lcobounds = coarray_handle%info%lcobounds(1:coarray_handle%info%corank) + lcobounds = cdp%lcobounds(1:size(lcobounds)) end procedure module procedure prif_ucobound_with_dim + type(prif_coarray_descriptor), pointer :: cdp + call_assert(coarray_handle_check(coarray_handle)) call_assert(team_check(current_team)) - associate (info => coarray_handle%info, corank => coarray_handle%info%corank) + cdp => handle_to_cdp(coarray_handle) + associate (corank => cdp%corank) call_assert(dim >= 1 .and. dim <= corank) if (corank == 1) then ! common-case optimization - ucobound = info%lcobounds(1) + current_team%info%num_images - 1 + ucobound = cdp%lcobounds(1) + current_team%info%num_images - 1 elseif (dim < corank) then - ucobound = info%ucobounds(dim) + ucobound = cdp%ucobounds(dim) else ! compute trailing ucobound, based on current team size call_assert(dim == corank) - associate (epp => info%coshape_epp(corank), num_imgs => current_team%info%num_images) + associate (epp => cdp%coshape_epp(corank), num_imgs => current_team%info%num_images) if (epp >= num_imgs) then ! optimization to skip a divide - ucobound = info%lcobounds(corank) + ucobound = cdp%lcobounds(corank) else - ucobound = info%lcobounds(corank) + (num_imgs + epp - 1) / epp - 1 + ucobound = cdp%lcobounds(corank) + (num_imgs + epp - 1) / epp - 1 end if end associate end if @@ -49,34 +58,40 @@ end procedure module procedure prif_ucobound_no_dim + type(prif_coarray_descriptor), pointer :: cdp + call_assert(coarray_handle_check(coarray_handle)) - call_assert(size(ucobounds) == coarray_handle%info%corank) - associate (corank => coarray_handle%info%corank) - ucobounds(1:corank-1) = coarray_handle%info%ucobounds(1:corank-1) + cdp => handle_to_cdp(coarray_handle) + associate (corank => size(ucobounds)) + call_assert(corank == cdp%corank) + ucobounds(1:corank-1) = cdp%ucobounds(1:corank-1) call prif_ucobound_with_dim(coarray_handle, corank, ucobounds(corank)) end associate end procedure module procedure prif_coshape + type(prif_coarray_descriptor), pointer :: cdp + integer :: corank + call_assert(coarray_handle_check(coarray_handle)) - call_assert(size(sizes) == coarray_handle%info%corank) call_assert(team_check(current_team)) - associate(info => coarray_handle%info, corank => coarray_handle%info%corank) - if (corank == 1) then ! common-case optimization - sizes(1) = current_team%info%num_images - else - sizes(1:corank-1) = info%ucobounds(1:corank-1) - info%lcobounds(1:corank-1) + 1 - associate (epp => info%coshape_epp(corank), num_imgs => current_team%info%num_images) - if (epp >= num_imgs) then ! optimization to skip a divide - sizes(corank) = 1 - else - sizes(corank) = (num_imgs + epp - 1) / epp - end if - end associate - end if - end associate + cdp => handle_to_cdp(coarray_handle) + corank = size(sizes) + call_assert(corank == cdp%corank) + if (corank == 1) then ! common-case optimization + sizes(1) = current_team%info%num_images + else + sizes(1:corank-1) = cdp%ucobounds(1:corank-1) - cdp%lcobounds(1:corank-1) + 1 + associate (epp => cdp%coshape_epp(corank), num_imgs => current_team%info%num_images) + if (epp >= num_imgs) then ! optimization to skip a divide + sizes(corank) = 1 + else + sizes(corank) = (num_imgs + epp - 1) / epp + end if + end associate + end if end procedure subroutine image_index_helper(coarray_handle, sub, team, image_index) @@ -86,26 +101,29 @@ subroutine image_index_helper(coarray_handle, sub, team, image_index) type(prif_team_type), intent(in) :: team integer(c_int), intent(out) :: image_index + type(prif_coarray_descriptor), pointer :: cdp integer :: dim call_assert(coarray_handle_check(coarray_handle)) call_assert(team_check(team)) - associate (info => coarray_handle%info, corank => coarray_handle%info%corank) - call_assert(size(sub) == corank) - if (sub(1) .lt. info%lcobounds(1) .or. & - (corank > 1 .and. sub(1) .gt. info%ucobounds(1))) then + cdp => handle_to_cdp(coarray_handle) + + associate (corank => size(sub)) + call_assert(corank == cdp%corank) + if (sub(1) .lt. cdp%lcobounds(1) .or. & + (corank > 1 .and. sub(1) .gt. cdp%ucobounds(1))) then image_index = 0 return end if - image_index = 1 + INT(sub(1) - info%lcobounds(1), c_int) + image_index = 1 + INT(sub(1) - cdp%lcobounds(1), c_int) do dim = 2, size(sub) - if (sub(dim) .lt. info%lcobounds(dim) .or. & - (dim < corank .and. sub(dim) .gt. info%ucobounds(dim))) then + if (sub(dim) .lt. cdp%lcobounds(dim) .or. & + (dim < corank .and. sub(dim) .gt. cdp%ucobounds(dim))) then image_index = 0 return end if - image_index = image_index + INT(sub(dim) - info%lcobounds(dim), c_int) * info%coshape_epp(dim) + image_index = image_index + INT(sub(dim) - cdp%lcobounds(dim), c_int) * cdp%coshape_epp(dim) end do end associate @@ -142,19 +160,21 @@ subroutine initial_index_helper(coarray_handle, sub, team, initial_team_index) type(prif_team_type), intent(in) :: team integer(c_int), intent(out) :: initial_team_index + type(prif_coarray_descriptor), pointer :: cdp integer :: dim integer(c_int) :: image_index call_assert(team_check(team)) call_assert(coarray_handle_check(coarray_handle)) - associate (info => coarray_handle%info, corank => coarray_handle%info%corank) - call_assert(size(sub) == corank) - call_assert(sub(1) .ge. info%lcobounds(1) .and. (corank == 1 .or. sub(1) .le. info%ucobounds(1))) - image_index = 1 + INT(sub(1) - info%lcobounds(1), c_int) + cdp => handle_to_cdp(coarray_handle) + associate (corank => size(sub)) + call_assert(corank == cdp%corank) + call_assert(sub(1) .ge. cdp%lcobounds(1) .and. (corank == 1 .or. sub(1) .le. cdp%ucobounds(1))) + image_index = 1 + INT(sub(1) - cdp%lcobounds(1), c_int) do dim = 2, size(sub) - call_assert(sub(dim) .ge. info%lcobounds(dim) .and. (dim == corank .or. sub(dim) .le. info%ucobounds(dim))) - image_index = image_index + INT(sub(dim) - info%lcobounds(dim), c_int) * info%coshape_epp(dim) + call_assert(sub(dim) .ge. cdp%lcobounds(dim) .and. (dim == corank .or. sub(dim) .le. cdp%ucobounds(dim))) + image_index = image_index + INT(sub(dim) - cdp%lcobounds(dim), c_int) * cdp%coshape_epp(dim) end do end associate @@ -190,31 +210,43 @@ subroutine initial_index_helper(coarray_handle, sub, team, initial_team_index) !--------------------------------------------------------------------- module procedure prif_local_data_pointer + type(prif_coarray_descriptor), pointer :: cdp + call_assert(coarray_handle_check(coarray_handle)) + cdp => handle_to_cdp(coarray_handle) - local_data = coarray_handle%info%coarray_data + local_data = cdp%coarray_data end procedure module procedure prif_set_context_data type(c_ptr), pointer :: array_context_data + type(prif_coarray_descriptor), pointer :: cdp + call_assert(coarray_handle_check(coarray_handle)) + cdp => handle_to_cdp(coarray_handle) - call c_f_pointer(coarray_handle%info%p_context_data, array_context_data) + call c_f_pointer(cdp%p_context_data, array_context_data) array_context_data = context_data end procedure module procedure prif_get_context_data type(c_ptr), pointer :: array_context_data + type(prif_coarray_descriptor), pointer :: cdp + call_assert(coarray_handle_check(coarray_handle)) + cdp => handle_to_cdp(coarray_handle) - call c_f_pointer(coarray_handle%info%p_context_data, array_context_data) + call c_f_pointer(cdp%p_context_data, array_context_data) context_data = array_context_data end procedure module procedure prif_size_bytes + type(prif_coarray_descriptor), pointer :: cdp + call_assert(coarray_handle_check(coarray_handle)) + cdp => handle_to_cdp(coarray_handle) - data_size = coarray_handle%info%coarray_size + data_size = cdp%coarray_size end procedure end submodule coarray_queries_s diff --git a/src/caffeine/image_queries_s.F90 b/src/caffeine/image_queries_s.F90 index de63b832..fd293ed7 100644 --- a/src/caffeine/image_queries_s.F90 +++ b/src/caffeine/image_queries_s.F90 @@ -42,11 +42,12 @@ end procedure module procedure prif_this_image_with_coarray + type(prif_coarray_descriptor), pointer :: cdp integer(c_int) :: offset, doff, dsz integer :: dim call_assert(coarray_handle_check(coarray_handle)) - call_assert(size(cosubscripts) == coarray_handle%info%corank) + cdp => handle_to_cdp(coarray_handle) if (present(team)) then call_assert(team_check(team)) @@ -56,16 +57,16 @@ offset = current_team%info%this_image - 1 endif - associate (info => coarray_handle%info) - call_assert(size(cosubscripts) == info%corank) - do dim = 1, info%corank-1 - dsz = INT(info%ucobounds(dim) - info%lcobounds(dim) + 1, c_int) + associate (corank => size(cosubscripts)) + call_assert(corank == cdp%corank) + do dim = 1, corank-1 + dsz = INT(cdp%ucobounds(dim) - cdp%lcobounds(dim) + 1, c_int) doff = mod(offset, dsz) - cosubscripts(dim) = doff + info%lcobounds(dim) - call_assert(cosubscripts(dim) <= info%ucobounds(dim)) + cosubscripts(dim) = doff + cdp%lcobounds(dim) + call_assert(cosubscripts(dim) <= cdp%ucobounds(dim)) offset = offset / dsz end do - cosubscripts(info%corank) = offset + info%lcobounds(info%corank) + cosubscripts(corank) = offset + cdp%lcobounds(corank) end associate # if ASSERTIONS @@ -83,12 +84,15 @@ end procedure module procedure prif_this_image_with_dim + type(prif_coarray_descriptor), pointer :: cdp + call_assert(coarray_handle_check(coarray_handle)) + cdp => handle_to_cdp(coarray_handle) block - integer(c_int64_t) :: cosubscripts(coarray_handle%info%corank) + integer(c_int64_t) :: cosubscripts(cdp%corank) - call_assert(dim >= 1 .and. dim <= coarray_handle%info%corank) + call_assert(dim >= 1 .and. dim <= cdp%corank) call prif_this_image_with_coarray(coarray_handle, team, cosubscripts) diff --git a/src/caffeine/prif_private_s.F90 b/src/caffeine/prif_private_s.F90 index dd8fc4d7..4c8c8b44 100644 --- a/src/caffeine/prif_private_s.F90 +++ b/src/caffeine/prif_private_s.F90 @@ -442,14 +442,31 @@ pure function as_c_ptr(i) as_c_ptr = transfer(i, as_c_ptr) end function + ! cdp = "coarray descriptor pointer" + function handle_to_cdp(coarray_handle) result(cdp) + type(prif_coarray_handle), intent(in) :: coarray_handle + type(prif_coarray_descriptor), pointer :: cdp + call_assert(c_associated(coarray_handle%info)) + call c_f_pointer(coarray_handle%info, cdp) + end function + + pure function cdp_to_handle(cdp) result(coarray_handle) + type(prif_coarray_descriptor), pointer, intent(in) :: cdp + type(prif_coarray_handle) :: coarray_handle + call_assert(associated(cdp)) + coarray_handle%info = c_loc(cdp) + end function + subroutine base_pointer(coarray_handle, image_num, ptr) type(prif_coarray_handle), intent(in) :: coarray_handle integer(c_int), intent(in) :: image_num integer(c_intptr_t), intent(out) :: ptr + type(prif_coarray_descriptor), pointer :: cdp call_assert(coarray_handle_check(coarray_handle)) call_assert_describe(image_num > 0 .and. image_num <= initial_team%num_images, "base_pointer: image_num not within valid range") - ptr = caf_convert_base_addr(coarray_handle%info%coarray_data, image_num) + cdp => handle_to_cdp(coarray_handle) + ptr = caf_convert_base_addr(cdp%coarray_data, image_num) end subroutine subroutine unimplemented(proc_name) @@ -519,17 +536,19 @@ elemental impure function coarray_handle_check(coarray_handle) result(result_) type(prif_coarray_handle), intent(in) :: coarray_handle logical :: result_ integer(c_int) :: i, epp(15) + type(prif_coarray_descriptor), pointer :: cdp - call assert_always(associated(coarray_handle%info), "unassociated info pointer in prif_coarray_handle") - associate(info => coarray_handle%info, corank => coarray_handle%info%corank) + call assert_always(c_associated(coarray_handle%info), "unassociated info pointer in prif_coarray_handle") + cdp => handle_to_cdp(coarray_handle) + associate(corank => cdp%corank) call assert_always(corank >= 1, "invalid corank in prif_coarray_handle") - call assert_always(corank <= size(info%lcobounds), "invalid corank in prif_coarray_handle") - call assert_always(all([(info%lcobounds(i) <= info%ucobounds(i), i = 1, corank-1)]), & + call assert_always(corank <= size(cdp%lcobounds), "invalid corank in prif_coarray_handle") + call assert_always(all([(cdp%lcobounds(i) <= cdp%ucobounds(i), i = 1, corank-1)]), & "invalid cobounds in prif_coarray_handle") - call assert_always(info%coarray_size > 0, "invalid data size in prif_coarray_handle") - call assert_always(c_associated(info%coarray_data), "invalid data pointer in prif_coarray_handle") - call compute_coshape_epp(info%lcobounds(1:corank),info%ucobounds(1:corank-1),epp(1:corank)) - call assert_always(all(info%coshape_epp(1:corank) == epp(1:corank)), & + call assert_always(cdp%coarray_size > 0, "invalid data size in prif_coarray_handle") + call assert_always(c_associated(cdp%coarray_data), "invalid data pointer in prif_coarray_handle") + call compute_coshape_epp(cdp%lcobounds(1:corank),cdp%ucobounds(1:corank-1),epp(1:corank)) + call assert_always(all(cdp%coshape_epp(1:corank) == epp(1:corank)), & "invalid coshape_epp in prif_coarray_handle") end associate diff --git a/src/caffeine/sync_stmt_s.F90 b/src/caffeine/sync_stmt_s.F90 index 7724bfbb..5070c039 100644 --- a/src/caffeine/sync_stmt_s.F90 +++ b/src/caffeine/sync_stmt_s.F90 @@ -1,6 +1,7 @@ ! Copyright (c), The Regents of the University of California ! Terms of use are as specified in LICENSE.txt +#include "version.h" #include "assert_macros.h" submodule(prif:prif_private_s) sync_stmt_s @@ -39,16 +40,21 @@ ! ALLOCATE( si_evt(NUM_IMAGES()) ) type(prif_event_type) :: dummy_event type(c_ptr) :: allocated_memory +# if CAF_PRIF_VERSION >= 8 + procedure(prif_coarray_cleanup_interface), pointer :: null_final_proc + null_final_proc => NULL() +# else + type(c_funptr), parameter :: null_final_proc = c_null_funptr +# endif associate(num_imgs => initial_team%num_images) sizeof_event = int(storage_size(dummy_event)/8, c_size_t) call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [int(num_imgs,c_int64_t)], & - size_in_bytes = sizeof_event * num_imgs, & - final_func = c_null_funptr, & + [1_c_int64_t], [int(num_imgs,c_int64_t)], & + sizeof_event * num_imgs, & + null_final_proc, & coarray_handle = si_coarray_handle, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, si_evt, [num_imgs]) diff --git a/src/caffeine/teams_s.F90 b/src/caffeine/teams_s.F90 index 4e16f171..407937bd 100644 --- a/src/caffeine/teams_s.F90 +++ b/src/caffeine/teams_s.F90 @@ -37,7 +37,7 @@ module procedure prif_end_team type(prif_coarray_handle), allocatable :: teams_coarrays(:) integer :: num_coarrays_in_team, i - type(prif_coarray_descriptor), pointer :: tmp_data + type(prif_coarray_descriptor), pointer :: cdp call_assert(team_check(current_team)) call_assert_describe(associated(current_team%info%parent_team), "Invalid END TEAM from the initial team.") @@ -46,18 +46,23 @@ ! Currently we work to batch together all the deallocations into a single call ! to prif_deallocate_coarray(), in the hope it can amortize some costs num_coarrays_in_team = 0 - tmp_data => current_team%info%coarrays - do while (associated(tmp_data)) + cdp => current_team%info%coarrays + do while (associated(cdp)) num_coarrays_in_team = num_coarrays_in_team + 1 - call c_f_pointer(tmp_data%next_handle, tmp_data) + if (c_associated(cdp%next_handle)) then + call c_f_pointer(cdp%next_handle, cdp) + else + exit + end if end do if (num_coarrays_in_team > 0) then allocate(teams_coarrays(num_coarrays_in_team)) - tmp_data => current_team%info%coarrays - do i = 1, num_coarrays_in_team - teams_coarrays(i)%info => tmp_data - call c_f_pointer(tmp_data%next_handle, tmp_data) + cdp => current_team%info%coarrays + do i = 1, num_coarrays_in_team-1 + teams_coarrays(i)%info = c_loc(cdp) + call c_f_pointer(cdp%next_handle, cdp) end do + teams_coarrays(num_coarrays_in_team)%info = c_loc(cdp) #if CAF_PRIF_VERSION <= 6 call prif_deallocate_coarray & #else diff --git a/src/caffeine/unit_test_parameters_m.F90 b/src/caffeine/unit_test_parameters_m.F90 index 8a391857..76d12f0c 100644 --- a/src/caffeine/unit_test_parameters_m.F90 +++ b/src/caffeine/unit_test_parameters_m.F90 @@ -1,8 +1,14 @@ ! Copyright (c), The Regents of the University ! Terms of use are as specified in LICENSE.txt + +#include "version.h" + module unit_test_parameters_m - use iso_c_binding, only: c_int + use iso_c_binding, only: c_int, c_funptr, c_null_funptr use prif, only: prif_sync_all, prif_this_image_no_coarray +#if CAF_PRIF_VERSION >= 8 + use prif, only: prif_coarray_cleanup_interface +#endif !! Define values and utilities for consistent use throughout the test suite implicit none @@ -14,8 +20,22 @@ module unit_test_parameters_m character(len=:), allocatable :: subjob_prefix character(len=:), allocatable :: fpm_driver +#if CAF_PRIF_VERSION >= 8 + procedure(prif_coarray_cleanup_interface), pointer :: null_final_proc => NULL() +#else + type(c_funptr) :: null_final_proc = c_null_funptr +#endif + contains +#if CAF_PRIF_VERSION >= 8 + function final_proc_usher(fp) result(res) + procedure(prif_coarray_cleanup_interface) :: fp + procedure(prif_coarray_cleanup_interface), pointer :: res + res => fp + end function +#endif + ! Retrieve an environment parameter or its default value subroutine getenv_withdefault(key, default, result) use iso_fortran_env, only: error_unit diff --git a/src/prif.F90 b/src/prif.F90 index 4fa08065..068c4907 100644 --- a/src/prif.F90 +++ b/src/prif.F90 @@ -32,6 +32,9 @@ module prif public :: prif_register_stop_callback, prif_stop_callback_interface public :: prif_stop, prif_error_stop, prif_fail_image public :: prif_allocate_coarray, prif_allocate, prif_deallocate +#if CAF_PRIF_VERSION >= 8 + public :: prif_coarray_cleanup_interface +#endif #if CAF_PRIF_VERSION <= 6 public :: prif_deallocate_coarray #else @@ -145,9 +148,9 @@ module prif integer(PRIF_ATOMIC_INT_KIND) :: counter = 0 end type - type, public :: prif_coarray_handle + type, public, bind(C) :: prif_coarray_handle private - type(prif_coarray_descriptor), pointer :: info + type(c_ptr) :: info end type type, public :: prif_team_type @@ -172,6 +175,14 @@ subroutine prif_operation_wrapper_interface(arg1, arg2_and_out, count, cdata) bi integer(c_size_t), intent(in), value :: count type(c_ptr), intent(in), value :: cdata end subroutine + +# if CAF_PRIF_VERSION >= 8 + subroutine prif_coarray_cleanup_interface(handle) bind(C) + import :: prif_coarray_handle + implicit none + type(prif_coarray_handle), value, intent(in) :: handle + end subroutine +# endif end interface interface @@ -205,12 +216,21 @@ module subroutine prif_fail_image() end subroutine module subroutine prif_allocate_coarray( & - lcobounds, ucobounds, size_in_bytes, final_func, coarray_handle, & - allocated_memory, stat, errmsg, errmsg_alloc) + lcobounds, ucobounds, size_in_bytes, & +# if CAF_PRIF_VERSION >= 8 + final_proc, & +# else + final_func, & +# endif + coarray_handle, allocated_memory, stat, errmsg, errmsg_alloc) implicit none integer(c_int64_t), dimension(:), intent(in) :: lcobounds, ucobounds integer(c_size_t), intent(in) :: size_in_bytes +# if CAF_PRIF_VERSION >= 8 + procedure(prif_coarray_cleanup_interface), pointer, intent(in) :: final_proc +# else type(c_funptr), intent(in) :: final_func +# endif type(prif_coarray_handle), intent(out) :: coarray_handle type(c_ptr), intent(out) :: allocated_memory integer(c_int), intent(out), optional :: stat @@ -663,26 +683,26 @@ module impure elemental subroutine prif_image_status(image, team, image_status) integer(c_int), intent(out) :: image_status end subroutine - module subroutine prif_local_data_pointer(coarray_handle, local_data) - type(prif_coarray_handle), intent(in) :: coarray_handle + module subroutine prif_local_data_pointer(coarray_handle, local_data) bind(C) + type(prif_coarray_handle), value, intent(in) :: coarray_handle type(c_ptr), intent(out) :: local_data end subroutine - module subroutine prif_set_context_data(coarray_handle, context_data) + module subroutine prif_set_context_data(coarray_handle, context_data) bind(C) implicit none - type(prif_coarray_handle), intent(in) :: coarray_handle - type(c_ptr), intent(in) :: context_data + type(prif_coarray_handle), value, intent(in) :: coarray_handle + type(c_ptr), value, intent(in) :: context_data end subroutine - module subroutine prif_get_context_data(coarray_handle, context_data) + module subroutine prif_get_context_data(coarray_handle, context_data) bind(C) implicit none - type(prif_coarray_handle), intent(in) :: coarray_handle + type(prif_coarray_handle), value, intent(in) :: coarray_handle type(c_ptr), intent(out) :: context_data end subroutine - module subroutine prif_size_bytes(coarray_handle, data_size) + module subroutine prif_size_bytes(coarray_handle, data_size) bind(C) implicit none - type(prif_coarray_handle), intent(in) :: coarray_handle + type(prif_coarray_handle), value, intent(in) :: coarray_handle integer(c_size_t), intent(out) :: data_size end subroutine @@ -1191,7 +1211,7 @@ module subroutine prif_atomic_ref_logical_indirect(image_num, atom_remote_ptr, v type(c_ptr) :: coarray_data integer(c_int) :: corank integer(c_size_t) :: coarray_size - type(c_funptr) :: final_func + type(c_funptr) :: final_proc type(c_ptr) :: previous_handle = c_null_ptr, next_handle = c_null_ptr integer(c_int64_t) :: lcobounds(15), ucobounds(14) integer(c_int) :: coshape_epp(15) diff --git a/test/prif_allocate_test.F90 b/test/prif_allocate_test.F90 index 64432850..d39f0a55 100644 --- a/test/prif_allocate_test.F90 +++ b/test/prif_allocate_test.F90 @@ -1,9 +1,9 @@ #include "test-utils.F90" #include "version.h" -#include "language-support.F90" module prif_allocate_test_m # include "test-uses-alloc.F90" + use iso_c_binding, only: c_char use prif, only : & prif_num_images, prif_size_bytes, & prif_set_context_data, prif_get_context_data, prif_local_data_pointer, & @@ -23,15 +23,24 @@ module prif_allocate_test_m procedure, nopass, non_overridable :: results end type -#if HAVE_FINAL_FUNC_SUPPORT ! Global state used to coordinate with finalizers - integer :: ff_count + integer(kind=c_int), bind(c), target :: ff_count type(prif_coarray_handle) :: ff_handle type(test_diagnosis_t) :: ff_diag +#if CAF_PRIF_VERSION < 8 logical :: ff_force_fail = .false. character(len=*), parameter :: ff_err = "test error message" #endif +#if CAF_PRIF_VERSION >= 8 + interface + subroutine coarray_cleanup_simple_c(handle) bind(C) + import c_int, c_char, prif_coarray_handle + type(prif_coarray_handle), value, intent(in) :: handle + end subroutine + end interface +#endif + contains pure function subject() @@ -51,9 +60,7 @@ function results() result(test_results) ,test_description_t("allocating, using and deallocating memory non-symmetrically", & usher(check_allocate_non_symmetric)) & ,test_description_t("allocating and deallocating coarrays with finalizers" & -# if HAVE_FINAL_FUNC_SUPPORT - , usher(check_final_func) & -# endif + , usher(check_final_proc) & ) & ,test_description_t("reporting out-of-memory errors", & usher(check_allocation_oom)) & @@ -80,7 +87,7 @@ function check_allocate_integer_scalar_coarray_with_corank1() result(diag) data_size = storage_size(dummy_element)/8 call prif_allocate_coarray( & - [integer(c_int64_t) :: 1], [integer(c_int64_t) :: ], data_size, c_null_funptr, & + [integer(c_int64_t) :: 1], [integer(c_int64_t) :: ], data_size, null_final_proc, & coarray_handle, allocated_memory) call c_f_pointer(allocated_memory, local_slice) @@ -108,21 +115,18 @@ function check_allocate_integer_scalar_coarray_with_corank1() result(diag) end function -#if HAVE_FINAL_FUNC_SUPPORT - function check_final_func() result(retdiag) + function check_final_proc() result(retdiag) type(test_diagnosis_t) retdiag ! this function shares several global vars with finalizers, see ff_* above ! globalize diag for ALSO: # define diag ff_diag - integer :: num_imgs, me, dummy_element + integer :: num_imgs, me + integer(c_int) :: dummy_element type(c_ptr) :: allocated_memory - integer, pointer :: local_slice - integer(c_size_t) :: data_size, query_size - integer(c_int) :: stat - character(len=len(ff_err)) :: errmsg - character(len=:), allocatable :: errmsg_alloc + integer(c_size_t) :: data_size + integer(c_int), pointer :: local_slice diag = .true. @@ -130,22 +134,47 @@ function check_final_func() result(retdiag) call prif_this_image_no_coarray(this_image=me) data_size = storage_size(dummy_element)/8 - ! simple final_func case + ! simple final_proc case ff_count = 0 call prif_allocate_coarray( & [integer(c_int64_t) :: 1], [integer(c_int64_t) :: ], & - data_size, c_funloc(coarray_cleanup_simple), & + data_size, final_proc(coarray_cleanup_simple), & ff_handle, allocated_memory) ALSO(ff_count .equalsExpected. 0) call prif_deallocate_coarray(ff_handle) ALSO(ff_count .equalsExpected. 1) + +# if CAF_PRIF_VERSION >= 8 + ! final_proc written in C + call prif_allocate_coarray( & + [integer(c_int64_t) :: 1], [integer(c_int64_t) :: ], & + data_size, final_proc(coarray_cleanup_simple_c), & + ff_handle, allocated_memory) + ALSO(ff_count .equalsExpected. 1) + + ! set-up some values to be checked from C + call c_f_pointer(allocated_memory, local_slice) + ALSO(associated(local_slice)) + local_slice = 42 + ALSO(local_slice .equalsExpected. 42) + call prif_set_context_data(ff_handle, c_loc(ff_count)) + + call prif_deallocate_coarray(ff_handle) + ALSO(ff_count .equalsExpected. 3) + +# else + block + integer(c_int) :: stat + character(len=len(ff_err)) :: errmsg + character(len=:), allocatable :: errmsg_alloc + ! CAF_PRIF_VERSION < 8 ! final_func that errors on first three deallocations ff_count = 0 call prif_allocate_coarray( & [integer(c_int64_t) :: 1], [integer(c_int64_t) :: ], & - data_size, c_funloc(coarray_cleanup_first_error), & + data_size, final_proc(coarray_cleanup_first_error), & ff_handle, allocated_memory) ALSO(ff_count .equalsExpected. 0) @@ -174,27 +203,36 @@ function check_final_func() result(retdiag) ALSO(ff_count .equalsExpected. 4) ALSO(stat .equalsExpected. 0) ALSO(.not. allocated(errmsg_alloc)) - + end block +# endif retdiag = diag end function +#if CAF_PRIF_VERSION < 8 subroutine coarray_cleanup_simple(handle , stat, errmsg) bind(C) - type(prif_coarray_handle), pointer , intent(in) :: handle + type(prif_coarray_handle), value, intent(in) :: handle integer(c_int), intent(out) :: stat - character(len=:), intent(out), allocatable :: errmsg + character(kind=c_char,len=:), intent(out), allocatable :: errmsg +#else + subroutine coarray_cleanup_simple(handle) bind(C) + type(prif_coarray_handle), value, intent(in) :: handle +#endif - ALSO(assert_aliased(handle, ff_handle, 0)) + ALSO(assert_aliased(handle, ff_handle)) ff_count = ff_count + 1 +# if CAF_PRIF_VERSION < 8 stat = 0 +# endif end subroutine +#if CAF_PRIF_VERSION < 8 subroutine coarray_cleanup_first_error(handle , stat, errmsg) bind(C) - type(prif_coarray_handle), pointer , intent(in) :: handle + type(prif_coarray_handle), value, intent(in) :: handle integer(c_int), intent(out) :: stat - character(len=:), intent(out), allocatable :: errmsg + character(kind=c_char,len=:), intent(out), allocatable :: errmsg - ALSO(assert_aliased(handle, ff_handle, 0)) + ALSO(assert_aliased(handle, ff_handle)) ff_count = ff_count + 1 errmsg = ff_err @@ -204,8 +242,8 @@ subroutine coarray_cleanup_first_error(handle , stat, errmsg) bind(C) stat = 0 end if end subroutine -# undef diag #endif +# undef diag function check_allocate_non_symmetric() result(diag) type(test_diagnosis_t) diag @@ -301,7 +339,7 @@ function check_allocate_integer_array_coarray_with_corank2() result(diag) data_size = 10*storage_size(dummy_element)/8 call prif_allocate_coarray( & - [integer(c_int64_t) :: 1,1], [integer(c_int64_t) :: 4], data_size, c_null_funptr, & + [integer(c_int64_t) :: 1,1], [integer(c_int64_t) :: 4], data_size, null_final_proc, & coarray_handle, allocated_memory) call prif_size_bytes(coarray_handle, data_size=query_size) @@ -394,7 +432,7 @@ function check_allocation_oom() result(diag) deallocate(errmsg) call prif_allocate_coarray( & - [integer(c_int64_t) :: 1], [integer(c_int64_t) :: ], size_in_bytes, c_null_funptr, & + [integer(c_int64_t) :: 1], [integer(c_int64_t) :: ], size_in_bytes, null_final_proc, & coarray_handle, allocated_memory, stat, errmsg_alloc=errmsg) ALSO(stat .equalsExpected. PRIF_STAT_OUT_OF_MEMORY) ALSO(allocated(errmsg)) diff --git a/test/prif_atomic_test.F90 b/test/prif_atomic_test.F90 index a4aa0284..20669088 100644 --- a/test/prif_atomic_test.F90 +++ b/test/prif_atomic_test.F90 @@ -91,20 +91,18 @@ function check_atomic_uncontended() result(diag) ! integer(PRIF_ATOMIC_INT_KIND) :: atomic_int[*] call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = sizeof_atomic_int, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + sizeof_atomic_int, & + null_final_proc, & coarray_handle = coarray_handle_int, & allocated_memory = c_ptr_int) base_addr_int = transfer(c_ptr_int, base_addr_int) ! logical(PRIF_ATOMIC_LOGICAL_KIND) :: atomic_logical[*] call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = sizeof_atomic_logical, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + sizeof_atomic_logical, & + null_final_proc, & coarray_handle = coarray_handle_logical, & allocated_memory = c_ptr_logical) base_addr_logical = transfer(c_ptr_logical, base_addr_logical) diff --git a/test/prif_coarray_inquiry_test.F90 b/test/prif_coarray_inquiry_test.F90 index 99661ca0..faa3de58 100644 --- a/test/prif_coarray_inquiry_test.F90 +++ b/test/prif_coarray_inquiry_test.F90 @@ -60,7 +60,7 @@ function check_prif_local_data_pointer() result(diag) [integer(c_int64_t):: 1], & [integer(c_int64_t)::], & int(storage_size(dummy_element)/8, c_size_t), & - c_null_funptr, & + null_final_proc, & coarray_handle, & allocation_ptr) call prif_local_data_pointer(coarray_handle, local_ptr) @@ -100,10 +100,10 @@ impure elemental function check_cobound(corank, omit_trailing) result(diag) if (omit_trailing) then leading_ucobounds = ucobounds(1:corank-1) - call prif_allocate_coarray( lcobounds, leading_ucobounds, data_size, c_null_funptr, & + call prif_allocate_coarray( lcobounds, leading_ucobounds, data_size, null_final_proc, & coarray_handle, allocated_memory) else - call prif_allocate_coarray( lcobounds, ucobounds, data_size, c_null_funptr, & + call prif_allocate_coarray( lcobounds, ucobounds, data_size, null_final_proc, & coarray_handle, allocated_memory) end if diff --git a/test/prif_event_test.F90 b/test/prif_event_test.F90 index b6237af5..3c760c35 100644 --- a/test/prif_event_test.F90 +++ b/test/prif_event_test.F90 @@ -76,10 +76,9 @@ function check_event_serial() result(diag) ! type(event_type) :: evt[*] call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = sizeof_event, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + sizeof_event, & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_event) @@ -166,10 +165,9 @@ function check_event_parallel() result(diag) ! type(event_type) :: evt[*] call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = sizeof_event, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + sizeof_event, & + null_final_proc, & coarray_handle = coarray_handle_evt, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_evt) @@ -177,10 +175,9 @@ function check_event_parallel() result(diag) ! integer :: ctr(num_images())[*] call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = num_imgs * sizeof_int, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + num_imgs * sizeof_int, & + null_final_proc, & coarray_handle = coarray_handle_ctr, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_ctr, [num_imgs]) @@ -263,10 +260,9 @@ function check_notify() result(diag) ! type(notify_type) :: evt[*] call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = sizeof_notify, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + sizeof_notify, & + null_final_proc, & coarray_handle = coarray_handle_evt, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_evt) @@ -274,10 +270,9 @@ function check_notify() result(diag) ! integer :: ctr(num_images())[*] call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = num_imgs * sizeof_int, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + num_imgs * sizeof_int, & + null_final_proc, & coarray_handle = coarray_handle_ctr, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_ctr, [num_imgs]) diff --git a/test/prif_image_index_test.F90 b/test/prif_image_index_test.F90 index 587089bc..8c236ce0 100644 --- a/test/prif_image_index_test.F90 +++ b/test/prif_image_index_test.F90 @@ -100,10 +100,9 @@ function check_simple_case() result(diag) diag = .true. call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = 1_c_size_t, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + 1_c_size_t, & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call prif_image_index(coarray_handle, [1_c_int64_t], image_index=answer) @@ -127,10 +126,9 @@ function check_lower_bounds() result(diag) diag = .true. call prif_allocate_coarray( & - lcobounds = [2_c_int64_t, 3_c_int64_t], & - ucobounds = [3_c_int64_t], & - size_in_bytes = 1_c_size_t, & - final_func = c_null_funptr, & + [2_c_int64_t, 3_c_int64_t], [3_c_int64_t], & + 1_c_size_t, & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call prif_image_index(coarray_handle, [2_c_int64_t, 3_c_int64_t], image_index=answer) @@ -154,10 +152,9 @@ function check_invalid_subscripts() result(diag) diag = .true. call prif_allocate_coarray( & - lcobounds = [-2_c_int64_t, 2_c_int64_t], & - ucobounds = [2_c_int64_t], & - size_in_bytes = 1_c_size_t, & - final_func = c_null_funptr, & + [-2_c_int64_t, 2_c_int64_t], [2_c_int64_t], & + 1_c_size_t, & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call prif_image_index(coarray_handle, [-1_c_int64_t, 1_c_int64_t], image_index=answer) @@ -180,10 +177,9 @@ function check_complicated_2d() result(diag) call prif_num_images(num_images=ni) call prif_allocate_coarray( & - lcobounds = [1_c_int64_t, 2_c_int64_t], & - ucobounds = [2_c_int64_t], & - size_in_bytes = 1_c_size_t, & - final_func = c_null_funptr, & + [1_c_int64_t, 2_c_int64_t], [2_c_int64_t], & + 1_c_size_t, & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call prif_image_index(coarray_handle, [1_c_int64_t, 3_c_int64_t], image_index=answer) @@ -214,10 +210,9 @@ function check_complicated_3d() result(diag) call prif_num_images_with_team(team=initial_team, num_images=ni) call prif_allocate_coarray( & - lcobounds = [1_c_int64_t, 0_c_int64_t, 0_c_int64_t], & - ucobounds = [2_c_int64_t, 1_c_int64_t], & - size_in_bytes = 1_c_size_t, & - final_func = c_null_funptr, & + [1_c_int64_t, 0_c_int64_t, 0_c_int64_t], [2_c_int64_t, 1_c_int64_t], & + 1_c_size_t, & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call prif_image_index_with_team(coarray_handle, & @@ -254,10 +249,9 @@ function check_complicated_2d_team() result(diag) call prif_this_image_no_coarray(this_image=me) call prif_allocate_coarray( & - lcobounds = [0_c_int64_t, 2_c_int64_t], & - ucobounds = [1_c_int64_t], & - size_in_bytes = 1_c_size_t, & - final_func = c_null_funptr, & + [0_c_int64_t, 2_c_int64_t], [1_c_int64_t], & + 1_c_size_t, & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) diff --git a/test/prif_rma_test.F90 b/test/prif_rma_test.F90 index 567b532c..f7f84c46 100644 --- a/test/prif_rma_test.F90 +++ b/test/prif_rma_test.F90 @@ -51,8 +51,8 @@ function check_put() result(diag) call prif_allocate_coarray( & [integer(c_int64_t) :: 1], [integer(c_int64_t)::], & - size_in_bytes = int(storage_size(dummy_element)/8, c_size_t), & - final_func = c_null_funptr, & + int(storage_size(dummy_element)/8, c_size_t), & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_slice) @@ -96,8 +96,8 @@ function check_put_indirect() result(diag) call prif_allocate_coarray( & [integer(c_int64_t) :: 1], [integer(c_int64_t)::], & - size_in_bytes = int(storage_size(dummy_element)/8, c_size_t), & - final_func = c_null_funptr, & + int(storage_size(dummy_element)/8, c_size_t), & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_slice) @@ -143,8 +143,8 @@ function check_get() result(diag) call prif_allocate_coarray( & [integer(c_int64_t) :: 1], [integer(c_int64_t)::], & - size_in_bytes = int(storage_size(dummy_element)/8, c_size_t), & - final_func = c_null_funptr, & + int(storage_size(dummy_element)/8, c_size_t), & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_slice) @@ -186,8 +186,8 @@ function check_get_indirect() result(diag) call prif_allocate_coarray( & [integer(c_int64_t) :: 1], [integer(c_int64_t)::], & - size_in_bytes = int(storage_size(dummy_element)/8, c_size_t), & - final_func = c_null_funptr, & + int(storage_size(dummy_element)/8, c_size_t), & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_slice) diff --git a/test/prif_strided_test.F90 b/test/prif_strided_test.F90 index 0cd9a6e4..d4e6b670 100644 --- a/test/prif_strided_test.F90 +++ b/test/prif_strided_test.F90 @@ -59,8 +59,8 @@ function check_put() result(diag) call prif_allocate_coarray( & [integer(c_int64_t) :: 1], [integer(c_int64_t)::], & - size_in_bytes = sizeof_int*product(shape(mydata)), & - final_func = c_null_funptr, & + sizeof_int*product(shape(mydata)), & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_slice, shape(mydata)) @@ -118,8 +118,8 @@ function check_put_indirect() result(diag) call prif_allocate_coarray( & [integer(c_int64_t) :: 1], [integer(c_int64_t)::], & - size_in_bytes = int(storage_size(dummy_element)/8, c_size_t), & - final_func = c_null_funptr, & + int(storage_size(dummy_element)/8, c_size_t), & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_slice) @@ -182,8 +182,8 @@ function check_get() result(diag) call prif_allocate_coarray( & [integer(c_int64_t) :: 1], [integer(c_int64_t)::], & - size_in_bytes = sizeof_int*product(shape(mydata)), & - final_func = c_null_funptr, & + sizeof_int*product(shape(mydata)), & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_slice, shape(mydata)) @@ -239,8 +239,8 @@ function check_get_indirect() result(diag) call prif_allocate_coarray( & [integer(c_int64_t) :: 1], [integer(c_int64_t)::], & - size_in_bytes = int(storage_size(dummy_element)/8, c_size_t), & - final_func = c_null_funptr, & + int(storage_size(dummy_element)/8, c_size_t), & + null_final_proc, & coarray_handle = coarray_handle, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_slice) diff --git a/test/prif_support_test.c b/test/prif_support_test.c new file mode 100644 index 00000000..90f60897 --- /dev/null +++ b/test/prif_support_test.c @@ -0,0 +1,42 @@ +#include +#include "ISO_Fortran_binding.h" +#include + +extern int ff_count; + +struct coarray_handle { + void *info; +}; + +extern void coarray_cleanup_simple(struct coarray_handle handle); +extern void prif_get_context_data(struct coarray_handle handle, void **context_data); +extern void prif_set_context_data(struct coarray_handle handle, void *context_data); +extern void prif_local_data_pointer(struct coarray_handle handle, void **local_data); +extern void prif_size_bytes(struct coarray_handle handle, size_t *data_size); + +extern void coarray_cleanup_simple_c(struct coarray_handle handle) { +#if VERBOSE + printf("Hello from coarray_cleanup_simple_c in C! ff_count=%i\n", ff_count); fflush(0); +#endif + + ff_count++; + + size_t sz = 0; + prif_size_bytes(handle, &sz); + assert(sz == sizeof(int)); + + void *data = 0; + prif_local_data_pointer(handle, &data); + assert(data); + assert(*(int*)data == 42); + + void *p = 0; + prif_get_context_data(handle, &p); + assert(p == &ff_count); + prif_set_context_data(handle, &p); + prif_get_context_data(handle, &p); + assert(p == &p); + + // dispatch back to the test cleanup function written in Fortran: + coarray_cleanup_simple(handle); +} diff --git a/test/prif_teams_test.F90 b/test/prif_teams_test.F90 index 95dd3e29..9f608dce 100644 --- a/test/prif_teams_test.F90 +++ b/test/prif_teams_test.F90 @@ -1,8 +1,9 @@ #include "test-utils.F90" -#include "language-support.F90" +#include "version.h" module prif_teams_test_m # include "test-uses-alloc.F90" + use iso_c_binding, only: c_char use prif use julienne_m, only: test_description_t, test_diagnosis_t, test_result_t, test_t, string_t, usher & ,operator(.also.), operator(.isAtLeast.), operator(.isAtMost.), operator(.equalsExpected.), operator(//) @@ -96,10 +97,9 @@ function check_teams() result(diag) element_size = int(storage_size(dummy_element)/8, c_size_t) call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = element_size, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + element_size, & + null_final_proc, & coarray_handle = initial_coarray, & allocated_memory = allocated_memory) n = 0 ! clear outputs @@ -179,19 +179,13 @@ function check_teams() result(diag) ALSO(cleanup_count .equalsExpected. 0) do i = 1, num_coarrays call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = element_size, & -#if HAVE_FINAL_FUNC_SUPPORT - final_func = c_funloc(coarray_cleanup), & -# define CHECK_COUNT(n) ALSO(cleanup_count .equalsExpected. n) -#else - final_func = c_null_funptr, & -# define CHECK_COUNT(n) -#endif + [1_c_int64_t], [integer(c_int64_t)::], & + element_size, & + final_proc(coarray_cleanup), & coarray_handle = coarrays(i), & allocated_memory = allocated_memory) end do +# define CHECK_COUNT(n) ALSO(cleanup_count .equalsExpected. n) CHECK_COUNT(0) call prif_deallocate_coarrays(coarrays(4:4)) call prif_deallocate_coarrays(coarrays(2:2)) @@ -246,14 +240,21 @@ function check_teams() result(diag) end function -#if HAVE_FINAL_FUNC_SUPPORT +# if CAF_PRIF_VERSION < 8 subroutine coarray_cleanup(handle, stat, errmsg) bind(C) - type(prif_coarray_handle), pointer, intent(in) :: handle + type(prif_coarray_handle), value, intent(in) :: handle integer(c_int), intent(out) :: stat - character(len=:), intent(out), allocatable :: errmsg + character(kind=c_char, len=:), intent(out), allocatable :: errmsg cleanup_count = cleanup_count + 1 stat = 0 end subroutine -#endif +# else + subroutine coarray_cleanup(handle) bind(C) + type(prif_coarray_handle), value, intent(in) :: handle + + cleanup_count = cleanup_count + 1 + end subroutine +# endif + end module prif_teams_test_m diff --git a/test/prif_threaded_test.F90 b/test/prif_threaded_test.F90 index bec7b1c6..c788daba 100644 --- a/test/prif_threaded_test.F90 +++ b/test/prif_threaded_test.F90 @@ -126,10 +126,9 @@ function check_notify() result(diag) ! type(notify_type) :: evt[*] call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = sizeof_notify, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + sizeof_notify, & + null_final_proc, & coarray_handle = coarray_handle_evt, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_evt) @@ -137,10 +136,9 @@ function check_notify() result(diag) ! integer :: ctr[*] call prif_allocate_coarray( & - lcobounds = [1_c_int64_t], & - ucobounds = [integer(c_int64_t)::], & - size_in_bytes = sizeof_int, & - final_func = c_null_funptr, & + [1_c_int64_t], [integer(c_int64_t)::], & + sizeof_int, & + null_final_proc, & coarray_handle = coarray_handle_ctr, & allocated_memory = allocated_memory) call c_f_pointer(allocated_memory, local_ctr) diff --git a/test/prif_types_test.F90 b/test/prif_types_test.F90 index 3e563e4d..7e8dc5d5 100644 --- a/test/prif_types_test.F90 +++ b/test/prif_types_test.F90 @@ -2,7 +2,8 @@ module prif_types_test_m use iso_fortran_env, only: int8 - use prif, only: prif_team_type, prif_event_type, prif_notify_type, prif_lock_type, prif_critical_type + use iso_c_binding, only: c_ptr + use prif, only: prif_team_type, prif_event_type, prif_notify_type, prif_lock_type, prif_critical_type, prif_coarray_handle use julienne_m, only: test_description_t, test_diagnosis_t, test_result_t, test_t, string_t, usher & ,operator(.all.), operator(.also.), operator(.equalsExpected.), operator(.greaterThan.), operator(.isAtMost.), operator(//) @@ -28,6 +29,11 @@ module prif_types_test_m type(dummy_t), pointer :: info => null() end type + type :: cptr_wrapper_t + private + type(c_ptr) :: info + end type + contains pure function subject() character(len=:), allocatable :: subject @@ -44,6 +50,7 @@ function results() result(test_results) , test_description_t("having a compliant prif_lock_type representation", usher(check_lock_type)) & , test_description_t("having a compliant prif_notify_type representation", usher(check_notify_type)) & , test_description_t("having a compliant prif_critical_type representation", usher(check_critical_type)) & + , test_description_t("having a compliant prif_coarray_handle representation", usher(check_coarray_handle)) & ])) end function @@ -140,4 +147,15 @@ function check_critical_type() result(diag) ALSO2(.all.(int(bytes) .equalsExpected. 0), "default initialization to zero") end function + function check_coarray_handle() result(diag) + type(test_diagnosis_t) :: diag + type(prif_coarray_handle) :: handle + type(cptr_wrapper_t) :: cptr_wrap + + diag = .true. + + ! size check + ALSO(storage_size(handle) .equalsExpected. storage_size(cptr_wrap)) + end function + end module prif_types_test_m diff --git a/test/test-uses-alloc.F90 b/test/test-uses-alloc.F90 index 6ac3b42e..a971cecf 100644 --- a/test/test-uses-alloc.F90 +++ b/test/test-uses-alloc.F90 @@ -6,6 +6,7 @@ #define CAF_INCLUDED_TEST_USES_ALLOC #include "version.h" +#include "language-support.F90" use prif, only : & prif_allocate_coarray, & @@ -24,6 +25,19 @@ # define prif_deallocate_coarrays(arr) prif_deallocate_coarray_(arr) # define prif_deallocate_coarray3(h,a2,a3) prif_deallocate_coarray_([h],a2,a3) # define prif_deallocate_coarrays3(arr,a2,a3) prif_deallocate_coarray_(arr,a2,a3) +#endif + + ! final func support + use unit_test_parameters_m, only: null_final_proc +#if !defined(CAF_PRIF_VERSION) || CAF_PRIF_VERSION >= 8 + use unit_test_parameters_m, only: final_proc_usher +# if HAVE_PROCEDURE_ACTUAL_FOR_POINTER_DUMMY +# define final_proc(proc) proc +# else +# define final_proc(proc) final_proc_usher(proc) +# endif +#else +# define final_proc(proc) c_funloc(proc) #endif use iso_c_binding, only: &