Octopus
mpi_test.F90
Go to the documentation of this file.
1!! Copyright (C) 2022 S. Ohlmann
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
21module mpi_test_oct_m
22 use global_oct_m
23 use math_oct_m
25 use mpi_oct_m
27 implicit none
28 private
29
30 public :: test_mpiwrappers
31
32contains
33
34 subroutine test_mpiwrappers
35 if (test_scatterv()) then
36 write(message(1), *) "scatterv: PASS"
37 else
38 write(message(1), *) "scatterv: FAIL"
39 end if
40 call messages_info(1)
41
42 if (test_gatherv()) then
43 write(message(1), *) "gatherv: PASS"
44 else
45 write(message(1), *) "gatherv: FAIL"
46 end if
47 call messages_info(1)
48
49 if (test_allgatherv()) then
50 write(message(1), *) "allgatherv: PASS"
51 else
52 write(message(1), *) "allgatherv: FAIL"
53 end if
54 call messages_info(1)
55
56 if (test_alltoallv()) then
57 write(message(1), *) "alltoallv: PASS"
58 else
59 write(message(1), *) "alltoallv: FAIL"
60 end if
61 call messages_info(1)
62 end subroutine test_mpiwrappers
63
64 logical function test_scatterv()
65 real(real64), allocatable :: sendbuf(:), irecvbuf(:), lrecvbuf(:)
66 integer, allocatable :: sendcnts(:), recvcounts(:)
67 integer(int32), allocatable :: isdispls(:)
68 integer(int64), allocatable :: lsdispls(:)
69 integer, parameter :: N = 10003
70 integer :: ii
71 logical :: equal, allequal
72
73 safe_allocate(sendcnts(1:mpi_world%size))
74 safe_allocate(isdispls(1:mpi_world%size))
75 safe_allocate(lsdispls(1:mpi_world%size))
76 safe_allocate(recvcounts(1:1))
77 do ii = 1, mpi_world%size
78 isdispls(ii) = (ii-1) * n / mpi_world%size
79 lsdispls(ii) = (ii-1) * n / mpi_world%size
80 sendcnts(ii) = ii * n / mpi_world%size - isdispls(ii)
81 end do
82 if (mpi_world%rank == 0) then
83 safe_allocate(sendbuf(1:n))
84 do ii = 1, n
85 sendbuf(ii) = ii
86 end do
87 end if
88 recvcounts(1) = sendcnts(mpi_world%rank+1)
89 safe_allocate(irecvbuf(1:recvcounts(1)))
90 safe_allocate(lrecvbuf(1:recvcounts(1)))
91
92 call mpi_world%scatterv(sendbuf, sendcnts, isdispls, mpi_double_precision, irecvbuf, recvcounts(1), mpi_double_precision, 0)
93 call mpi_world%scatterv(sendbuf, sendcnts, lsdispls, mpi_double_precision, lrecvbuf, recvcounts(1), mpi_double_precision, 0)
94
95 equal = all(is_close(irecvbuf, lrecvbuf))
96 call mpi_world%allreduce(equal, allequal, 1, mpi_logical, mpi_land)
97 test_scatterv = allequal
98
99 safe_deallocate_a(sendcnts)
100 safe_deallocate_a(isdispls)
101 safe_deallocate_a(lsdispls)
102 safe_deallocate_a(recvcounts)
103 if (mpi_world%rank == 0) then
104 safe_deallocate_a(sendbuf)
105 end if
106 safe_deallocate_a(irecvbuf)
107 safe_deallocate_a(lrecvbuf)
108 end function test_scatterv
109
110 logical function test_gatherv()
111 real(real64), allocatable :: sendbuf(:), irecvbuf(:), lrecvbuf(:)
112 integer, allocatable :: sendcnts(:), recvcounts(:)
113 integer(int32), allocatable :: irdispls(:)
114 integer(int64), allocatable :: lrdispls(:)
115 integer, parameter :: N = 10003
116 integer :: ii
117 logical :: equal
118
119 safe_allocate(recvcounts(1:mpi_world%size))
120 safe_allocate(irdispls(1:mpi_world%size))
121 safe_allocate(lrdispls(1:mpi_world%size))
122 safe_allocate(sendcnts(1:1))
123 do ii = 1, mpi_world%size
124 irdispls(ii) = (ii-1) * n / mpi_world%size
125 lrdispls(ii) = (ii-1) * n / mpi_world%size
126 recvcounts(ii) = ii * n / mpi_world%size - irdispls(ii)
127 end do
128 if (mpi_world%rank == 0) then
129 safe_allocate(irecvbuf(1:n))
130 safe_allocate(lrecvbuf(1:n))
131 end if
132 sendcnts(1) = recvcounts(mpi_world%rank+1)
133 safe_allocate(sendbuf(1:sendcnts(1)))
134 do ii = 1, sendcnts(1)
135 sendbuf(ii) = ii
136 end do
137
138 call mpi_world%gatherv(sendbuf, sendcnts(1), mpi_double_precision, irecvbuf, recvcounts, irdispls, mpi_double_precision, 0)
139 call mpi_world%gatherv(sendbuf, sendcnts(1), mpi_double_precision, lrecvbuf, recvcounts, lrdispls, mpi_double_precision, 0)
140
141 if (mpi_world%rank == 0) then
142 equal = all(is_close(irecvbuf, lrecvbuf))
143 end if
144 test_gatherv = equal
145
146 safe_deallocate_a(recvcounts)
147 safe_deallocate_a(irdispls)
148 safe_deallocate_a(lrdispls)
149 safe_deallocate_a(sendcnts)
150 if (mpi_world%rank == 0) then
151 safe_deallocate_a(irecvbuf)
152 safe_deallocate_a(lrecvbuf)
153 end if
154 safe_deallocate_a(sendbuf)
155 end function test_gatherv
156
157 logical function test_allgatherv()
158 real(real64), allocatable :: sendbuf(:), irecvbuf(:), lrecvbuf(:)
159 integer, allocatable :: sendcnts(:), recvcounts(:)
160 integer(int32), allocatable :: irdispls(:)
161 integer(int64), allocatable :: lrdispls(:)
162 integer, parameter :: n = 10003
163 integer :: ii
164 logical :: equal, allequal
165
166 safe_allocate(recvcounts(1:mpi_world%size))
167 safe_allocate(irdispls(1:mpi_world%size))
168 safe_allocate(lrdispls(1:mpi_world%size))
169 safe_allocate(sendcnts(1:1))
170 do ii = 1, mpi_world%size
171 irdispls(ii) = (ii-1) * n / mpi_world%size
172 lrdispls(ii) = (ii-1) * n / mpi_world%size
173 recvcounts(ii) = ii * n / mpi_world%size - irdispls(ii)
174 end do
175 safe_allocate(irecvbuf(1:n))
176 safe_allocate(lrecvbuf(1:n))
177 sendcnts(1) = recvcounts(mpi_world%rank+1)
178 safe_allocate(sendbuf(1:sendcnts(1)))
179 do ii = 1, sendcnts(1)
180 sendbuf(ii) = ii
181 end do
182
183 call mpi_world%allgatherv(sendbuf, sendcnts(1), mpi_double_precision, irecvbuf, recvcounts, irdispls, mpi_double_precision)
184 call mpi_world%allgatherv(sendbuf, sendcnts(1), mpi_double_precision, lrecvbuf, recvcounts, lrdispls, mpi_double_precision)
185
186 equal = all(is_close(irecvbuf, lrecvbuf))
187 call mpi_world%allreduce(equal, allequal, 1, mpi_logical, mpi_land)
188 test_allgatherv = allequal
189
190 safe_deallocate_a(recvcounts)
191 safe_deallocate_a(irdispls)
192 safe_deallocate_a(lrdispls)
193 safe_deallocate_a(sendcnts)
194 safe_deallocate_a(irecvbuf)
195 safe_deallocate_a(lrecvbuf)
196 safe_deallocate_a(sendbuf)
197 end function test_allgatherv
198
199 logical function test_alltoallv()
200 real(real64), allocatable :: sendbuf(:), irecvbuf(:), lrecvbuf(:)
201 integer, allocatable :: sendcnts(:), recvcounts(:)
202 integer(int32), allocatable :: isdispls(:), irdispls(:)
203 integer(int64), allocatable :: lsdispls(:), lrdispls(:)
204 integer, parameter :: n = 10003
205 integer :: ii
206 logical :: equal, allequal
207
208 safe_allocate(sendcnts(1:mpi_world%size))
209 safe_allocate(isdispls(1:mpi_world%size))
210 safe_allocate(lsdispls(1:mpi_world%size))
211 safe_allocate(irdispls(1:mpi_world%size))
212 safe_allocate(lrdispls(1:mpi_world%size))
213 safe_allocate(recvcounts(1:mpi_world%size))
214 do ii = 1, mpi_world%size
215 isdispls(ii) = (ii-1) * n / mpi_world%size
216 lsdispls(ii) = (ii-1) * n / mpi_world%size
217 sendcnts(ii) = ii * n / mpi_world%size - isdispls(ii)
218 end do
219 safe_allocate(sendbuf(1:n))
220 do ii = 1, n
221 sendbuf(ii) = ii
222 end do
223 call mpi_world%alltoall(sendcnts, 1, mpi_integer, recvcounts, 1, mpi_integer)
224 safe_allocate(irecvbuf(1:sum(recvcounts)))
225 safe_allocate(lrecvbuf(1:sum(recvcounts)))
226 irdispls(1) = 0
227 lrdispls(1) = 0
228 do ii = 2, mpi_world%size
229 irdispls(ii) = irdispls(ii-1) + recvcounts(ii-1)
230 lrdispls(ii) = lrdispls(ii-1) + recvcounts(ii-1)
231 end do
232
233 call mpi_world%alltoallv(sendbuf, sendcnts, isdispls, mpi_double_precision, &
234 irecvbuf, recvcounts, irdispls, mpi_double_precision)
235 call mpi_world%alltoallv(sendbuf, sendcnts, lsdispls, mpi_double_precision, &
236 lrecvbuf, recvcounts, lrdispls, mpi_double_precision)
237
238 equal = all(is_close(irecvbuf, lrecvbuf))
239 call mpi_world%allreduce(equal, allequal, 1, mpi_logical, mpi_land)
240 test_alltoallv = allequal
241
242 safe_deallocate_a(sendcnts)
243 safe_deallocate_a(isdispls)
244 safe_deallocate_a(lsdispls)
245 safe_deallocate_a(irdispls)
246 safe_deallocate_a(lrdispls)
247 safe_deallocate_a(recvcounts)
248 safe_deallocate_a(sendbuf)
249 safe_deallocate_a(irecvbuf)
250 safe_deallocate_a(lrecvbuf)
251 end function test_alltoallv
252end module mpi_test_oct_m
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
Definition: messages.F90:624
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:266
subroutine, public test_mpiwrappers
Definition: mpi_test.F90:128
logical function test_allgatherv()
Definition: mpi_test.F90:251
logical function test_gatherv()
Definition: mpi_test.F90:204
logical function test_scatterv()
Definition: mpi_test.F90:158
logical function test_alltoallv()
Definition: mpi_test.F90:293