Skip to content

Commit d37315a

Browse files
committed
Renames routine to match MPI call
*lock_all() is different to *lock(), so changed name and added to comments. Also fix use statement, which was using mpi_win_unlock() instead of mpi_win_unlock_all()
1 parent 78dd4ee commit d37315a

File tree

3 files changed

+86
-31
lines changed

3 files changed

+86
-31
lines changed

CHANGELOG.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ Change Log
44

55
Notable project changes in various releases.
66

7+
Unreleased
8+
==========
9+
10+
Fixed
11+
-----
12+
13+
For windows, lock and unlock renamed to lock_all() and unlock_all() to
14+
match the MPI calls they are actually using.
15+
716

817
1.5
918
===

lib/mpifx_win.fpp

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
module mpifx_win_module
77
use mpi_f08, only : MPI_ADDRESS_KIND, mpi_barrier, mpi_comm, MPI_INFO_NULL, MPI_MODE_NOCHECK,&
88
& mpi_win, mpi_win_allocate_shared, mpi_win_fence, mpi_win_free, mpi_win_lock_all,&
9-
& mpi_win_shared_query, mpi_win_sync, mpi_win_unlock
10-
use mpifx_helper_module, only : handle_errorflag, sp, dp
9+
& mpi_win_shared_query, mpi_win_sync, mpi_win_unlock_all
10+
use mpifx_helper_module, only : dp, getoptarg, handle_errorflag, sp
1111
use mpifx_comm_module, only : mpifx_comm
1212
use mpifx_constants_module, only : MPIFX_SIZE_T
1313
use iso_c_binding, only : c_ptr, c_f_pointer
@@ -24,19 +24,26 @@ module mpifx_win_module
2424
type(mpi_comm) :: comm !< MPI communicator handle.
2525
contains
2626

27-
#:for TYPE in WIN_DATA_TYPES
28-
#:for _, ADDRESS_SUFFIX in ADDRESS_KINDS_SUFFIXES
29-
#:set SUFFIX = TYPE_ABBREVS[TYPE] + '_' + ADDRESS_SUFFIX
30-
procedure, private :: mpifx_win_allocate_shared_${SUFFIX}$
31-
generic :: allocate_shared => mpifx_win_allocate_shared_${SUFFIX}$
32-
#:endfor
27+
#:for TYPE in WIN_DATA_TYPES
28+
#:for _, ADDRESS_SUFFIX in ADDRESS_KINDS_SUFFIXES
29+
#:set SUFFIX = TYPE_ABBREVS[TYPE] + '_' + ADDRESS_SUFFIX
30+
procedure, private :: mpifx_win_allocate_shared_${SUFFIX}$
31+
generic :: allocate_shared => mpifx_win_allocate_shared_${SUFFIX}$
3332
#:endfor
33+
#:endfor
3434

3535
!> Locks a shared memory segment for remote access.
36-
procedure :: lock => mpifx_win_lock
37-
38-
!> Unlocks a shared memory segment.
39-
procedure :: unlock => mpifx_win_unlock
36+
!!
37+
!! Notes based on the MPI3.1 documentation: Start RMA access epoch for all processes in win,
38+
!! (lock of type MPI_LOCK_SHARED). During the epoch, any window member processses calling
39+
!! lock_all can access the window memory on all processes (using RMA ops). Routine is not
40+
!! collective — All is a from being a lock on all members of the win group.
41+
!! Accesses protected by a shared lock are not concurrent in the window.
42+
procedure :: lock_all => mpifx_win_lock_all
43+
44+
!> Unlocks a shared memory window.
45+
!! Ends the RMA access epoch at all processes with access to the window.
46+
procedure :: unlock_all => mpifx_win_unlock_all
4047

4148
!> Synchronizes shared memory across MPI ranks after remote access.
4249
procedure :: sync => mpifx_win_sync
@@ -112,21 +119,32 @@ contains
112119

113120
!> Locks a shared memory segment for remote access. Starts a remote access epoch.
114121
!!
115-
!! \param self Handle of the shared memory window.
116-
!! \param error Optional error code on return.
122+
!! \param self Handle of the shared memory window.
123+
!! \param checkLock Optional check if other locks are also applied to the window.
124+
!! \param error Optional error code on return.
117125
!!
118126
!! \see MPI documentation (\c MPI_WIN_LOCK_ALL)
119127
!!
120-
subroutine mpifx_win_lock(self, error)
128+
subroutine mpifx_win_lock_all(self, checkLock, error)
121129
class(mpifx_win), intent(inout) :: self
130+
logical, intent(in), optional :: checkLock
122131
integer, intent(out), optional :: error
123132

124133
integer :: error0
134+
! May be MPI implementation dependent, but if true no other process holds (or attempts to
135+
! acquire) a conflicting lock, while the caller(s) holds the window lock:
136+
logical :: assert
125137

126-
call mpi_win_lock_all(MPI_MODE_NOCHECK, self%win, error0)
127-
call handle_errorflag(error0, "MPI_WIN_LOCK_ALL in mpifx_win_lock", error)
138+
call getoptarg(.false., assert, checkLock)
139+
140+
if (assert) then
141+
call mpi_win_lock_all(0, self%win, error0)
142+
else
143+
call mpi_win_lock_all(MPI_MODE_NOCHECK, self%win, error0)
144+
end if
145+
call handle_errorflag(error0, "MPI_WIN_LOCK_ALL in mpifx_win_lock_all", error)
128146

129-
end subroutine mpifx_win_lock
147+
end subroutine mpifx_win_lock_all
130148

131149

132150
!> Unlocks a shared memory segment. Finishes a remote access epoch.
@@ -136,16 +154,16 @@ contains
136154
!!
137155
!! \see MPI documentation (\c MPI_WIN_UNLOCK_ALL)
138156
!!
139-
subroutine mpifx_win_unlock(self, error)
157+
subroutine mpifx_win_unlock_all(self, error)
140158
class(mpifx_win), intent(inout) :: self
141159
integer, intent(out), optional :: error
142160

143161
integer :: error0
144162

145163
call mpi_win_unlock_all(self%win, error0)
146-
call handle_errorflag(error0, "MPI_WIN_UNLOCK_ALL in mpifx_win_unlock", error)
164+
call handle_errorflag(error0, "MPI_WIN_UNLOCK_ALL in mpifx_win_unlock_all", error)
147165

148-
end subroutine mpifx_win_unlock
166+
end subroutine mpifx_win_unlock_all
149167

150168

151169
!> Synchronizes shared memory across MPI ranks after remote access.

test/test_win_shared_mem.f90

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,27 @@ program test_win_shared_mem
22
use libmpifx_module
33
implicit none
44

5+
! global communicator and within each shared memory node
56
type(mpifx_comm) :: globalcomm, nodecomm
7+
! RMA window, in this case shared memory
68
type(mpifx_win) :: win
7-
integer, parameter :: sample_value = 42, size_rank_0 = 7, size_rank_other = 4
9+
! Value to store for testing
10+
integer, parameter :: sample_value = 42
11+
! Specific local sub-region sizes for one of the tests, either on the leader or followers in a
12+
! node
13+
integer, parameter :: size_rank_0 = 7, size_rank_other = 4
14+
! Global and local sizes of array in window
815
integer(MPIFX_SIZE_T) :: global_length, local_length
16+
917
integer :: global_length_int32, local_length_int32
1018
integer :: rank, ii
19+
! Pointer to whole array in window and the local part
1120
integer, pointer :: global_pointer(:), local_pointer(:)
1221

1322
call mpifx_init()
1423
call globalcomm%init()
1524

16-
! Create a new communicator for all ranks on a node first
25+
! Create a new communicator for all ranks that are on the same node first
1726
call globalcomm%split_type(MPI_COMM_TYPE_SHARED, globalcomm%rank, nodecomm)
1827

1928
if (nodecomm%lead) then
@@ -23,26 +32,37 @@ program test_win_shared_mem
2332
end if
2433
global_length = size_rank_0 + size_rank_other * (nodecomm%size - 1)
2534

35+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
36+
!! First example, global array, distributed with only one process on the node writing
37+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
38+
39+
! Allocate a global window on the node
2640
call win%allocate_shared(nodecomm, global_length, global_pointer)
2741

28-
call win%lock()
42+
call win%lock_all()
2943

3044
! Only rank 0 writes data into the array
3145
if (nodecomm%lead) then
3246
global_pointer(:) = sample_value
3347
end if
3448

3549
call win%sync()
36-
call win%unlock()
50+
call win%unlock_all()
3751

3852
! All ranks on the node will read the same value in the global array view
3953
if (any(global_pointer(1:global_length) /= sample_value)) then
40-
write(*, "(3(A,1X,I0,1X))") "ERROR! ID:", nodecomm%rank, "VALUE:", global_pointer(1), "EXPECTED:", sample_value
54+
write(*, "(3(A,1X,I0,1X))") "ERROR! ID:", nodecomm%rank, "VALUE:", global_pointer(1),&
55+
& "EXPECTED:", sample_value
4156
call mpifx_abort(globalcomm)
4257
end if
4358

4459
call win%free()
4560

61+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
62+
!! Second example, global array, lead rank writing to all of it, then local parts being written by
63+
!! individual ranks on the node
64+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
65+
4666
! Initialize again with specific local length
4767
call win%allocate_shared(nodecomm, global_length, global_pointer, local_length, local_pointer)
4868

@@ -57,7 +77,8 @@ program test_win_shared_mem
5777

5878
! All ranks on the node will read the same value in their local view
5979
if (any(local_pointer(1:local_length) /= sample_value)) then
60-
write(*, "(2(A,1X,I0,1X))") "ERROR! ID:", nodecomm%rank, "VALUE:", local_pointer(1), "EXPECTED:", sample_value
80+
write(*, "(2(A,1X,I0,1X))") "ERROR! ID:", nodecomm%rank, "VALUE:", local_pointer(1),&
81+
& "EXPECTED:", sample_value
6182
call mpifx_abort(globalcomm)
6283
end if
6384

@@ -66,25 +87,32 @@ program test_win_shared_mem
6687

6788
call win%fence()
6889

69-
! All ranks should now read the correct global values
90+
! All ranks should now be able to read the correct global values
7091
if (any(global_pointer(1:size_rank_0) /= 0)) then
71-
write(*, "(2(A,1X,I0,1X))") "ERROR! ID:", nodecomm%rank, "VALUE:", global_pointer(1), "EXPECTED:", 0
92+
write(*, "(2(A,1X,I0,1X))") "ERROR! ID:", nodecomm%rank, "VALUE:", global_pointer(1),&
93+
& "EXPECTED:", 0
7294
call mpifx_abort(globalcomm)
7395
end if
7496
do rank = 1, nodecomm%size - 1
7597
ii = size_rank_0 + 1 + size_rank_other * (rank - 1)
7698
if (any(global_pointer(ii:ii+size_rank_other-1) /= rank)) then
77-
write(*, "(2(A,1X,I0,1X))") "ERROR! ID:", nodecomm%rank, "VALUE:", global_pointer(ii), "EXPECTED:", rank
99+
write(*, "(2(A,1X,I0,1X))") "ERROR! ID:", nodecomm%rank, "VALUE:", global_pointer(ii),&
100+
& "EXPECTED:", rank
78101
call mpifx_abort(globalcomm)
79102
end if
80103
end do
81104

82105
call win%free()
83106

107+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
108+
!! 32 bit sized indexing as a test
109+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
110+
84111
! Initialize again with int32 sizes
85112
global_length_int32 = global_length
86113
local_length_int32 = local_length
87-
call win%allocate_shared(nodecomm, global_length_int32, global_pointer, local_length_int32, local_pointer)
114+
call win%allocate_shared(nodecomm, global_length_int32, global_pointer, local_length_int32,&
115+
& local_pointer)
88116

89117
call win%free()
90118
call mpifx_finalize()

0 commit comments

Comments
 (0)