51 INTEGER,
PUBLIC,
PARAMETER :: dp = selected_real_kind(12, 307)
54 CHARACTER(len=20) :: label =
'undef' 55 INTEGER :: istate = -1
56 REAL(dp) :: t0 = 0.0_dp
57 REAL(dp) :: dt_work = 0.0_dp
61 MODULE PROCEDURE test_abort_cmsl_f
62 MODULE PROCEDURE test_abort_msl_f
63 END INTERFACE test_abort
66 MODULE PROCEDURE icmp_2d
67 MODULE PROCEDURE icmp_3d
71 MODULE PROCEDURE id_map_i2, id_map_i4, id_map_i8
74 REAL(dp) :: sync_dt_sum = 0.0_dp
75 LOGICAL,
PARAMETER :: debug = .false.
76 LOGICAL :: verbose = .false.
78 PUBLIC :: init_mpi, finish_mpi
79 PUBLIC :: timer, treset, tstart, tstop, treport, mysync
80 PUBLIC :: id_map, icmp, factorize, regular_deco
81 PUBLIC :: test_abort, set_verbose, get_verbose
85 CHARACTER(len=*),
PARAMETER :: context =
'init_mpi: ' 88 IF (ierror /= mpi_success)
CALL test_abort(context//
'MPI_INIT failed', &
90 END SUBROUTINE init_mpi
93 CHARACTER(len=*),
PARAMETER :: context =
'finish_mpi: ' 95 CALL mpi_finalize(ierror)
96 IF (ierror /= mpi_success)
CALL test_abort(context//
'MPI_FINALIZE failed', &
99 END SUBROUTINE finish_mpi
101 SUBROUTINE set_verbose(verb)
102 LOGICAL,
INTENT(in) :: verb
104 END SUBROUTINE set_verbose
106 SUBROUTINE get_verbose(verb)
107 LOGICAL,
INTENT(out) :: verb
109 END SUBROUTINE get_verbose
111 PURE SUBROUTINE treset(t, label)
112 TYPE(timer),
INTENT(inout) :: t
113 CHARACTER(len=*),
INTENT(in) :: label
118 END SUBROUTINE treset
121 TYPE(timer),
INTENT(inout) :: t
122 IF (debug)
WRITE(0,*)
'tstart: ',t%label
126 END SUBROUTINE tstart
129 TYPE(timer),
INTENT(inout) :: t
131 IF (debug)
WRITE(0,*)
'tstop: ',t%label
133 t%dt_work = t%dt_work + (t1 - t%t0)
139 SUBROUTINE treport(t,extra_label,comm)
140 TYPE(timer),
INTENT(in) :: t
141 CHARACTER(len=*),
INTENT(in) :: extra_label
142 INTEGER,
INTENT(in) :: comm
144 CHARACTER(len=*),
PARAMETER :: context =
'treport: ' 145 REAL(dp) :: work_sum, work_max, work_avg, e
147 REAL(dp),
ALLOCATABLE :: rbuf(:)
148 INTEGER :: nprocs, rank, ierror
151 CALL mpi_comm_rank(comm, rank, ierror)
152 IF (ierror /= mpi_success) &
153 CALL test_abort(context//
'MPI_COMM_RANK failed', &
156 CALL mpi_comm_size(comm, nprocs, ierror)
157 IF (ierror /= mpi_success) &
158 CALL test_abort(context//
'MPI_COMM_RANK failed', &
161 ALLOCATE(rbuf(0:nprocs-1))
163 CALL mpi_gather(sbuf, 1, mpi_double_precision, &
164 & rbuf, 1, mpi_double_precision, &
166 IF (ierror /= mpi_success)
CALL test_abort(context//
'MPI_GATHER failed', &
171 IF (rbuf(0) /= sbuf)
CALL test_abort(context//
'internal error (1)', &
174 IF (any(rbuf < 0.0_dp))
CALL test_abort(context//
'internal error (2)', &
178 work_max = maxval(rbuf)
179 work_avg = work_sum /
REAL(nprocs, dp)
180 e = work_avg / (work_max + 1.e-20_dp)
182 IF (verbose)
WRITE(0,
'(A,I4,2X,A16,3F18.8)') &
183 'nprocs, label, wmax, wavg, e =', &
184 nprocs, extra_label//
':'//t%label, &
185 work_max, work_avg, e
188 END SUBROUTINE treport
191 CHARACTER(len=*),
PARAMETER :: context =
'mysync: ' 197 CALL mpi_barrier(mpi_comm_world, ierror)
198 IF (ierror /= mpi_success)
CALL test_abort(context//
'MPI_BARRIER failed', &
202 dt = (mpi_wtime() - t0)
203 sync_dt_sum = sync_dt_sum + dt
205 END SUBROUTINE mysync
207 REAL(dp) FUNCTION work_time()
208 work_time = mpi_wtime() - sync_dt_sum
210 END FUNCTION work_time
212 PURE SUBROUTINE id_map_i2(map)
213 INTEGER(i2),
INTENT(out) :: map(:,:)
215 INTEGER :: i, j, m, n
221 map(i,j) = int((j - 1) * m + i,
i2)
225 END SUBROUTINE id_map_i2
227 PURE SUBROUTINE id_map_i4(map)
228 INTEGER(i4),
INTENT(out) :: map(:,:)
230 INTEGER :: i, j, m, n
236 map(i,j) = int((j - 1) * m + i,
i4)
240 END SUBROUTINE id_map_i4
242 PURE SUBROUTINE id_map_i8(map)
243 INTEGER(i8),
INTENT(out) :: map(:,:)
245 INTEGER :: i, j, m, n
251 map(i,j) = int((j - 1) * m + i,
i8)
255 END SUBROUTINE id_map_i8
257 SUBROUTINE test_abort_msl_f(msg, source, line)
258 CHARACTER(*),
INTENT(in) :: msg
259 CHARACTER(*),
INTENT(in) :: source
260 INTEGER,
VALUE,
INTENT(in) :: line
261 CALL test_abort_cmsl_f(mpi_comm_world, msg, source, line)
262 END SUBROUTINE test_abort_msl_f
264 SUBROUTINE test_abort_cmsl_f(comm, msg, source, line)
265 INTEGER,
INTENT(in):: comm
266 CHARACTER(*),
INTENT(in) :: msg
267 CHARACTER(*),
INTENT(in) :: source
268 INTEGER,
VALUE,
INTENT(in) :: line
271 SUBROUTINE c_abort() bind(c, name='abort')
272 END SUBROUTINE c_abort
278 WRITE (0,
'(3a,i0,2a)')
'Fatal error in ', source,
', line ', line, &
281 CALL mpi_initialized(flag, ierror)
282 IF (ierror == mpi_success .AND. flag) &
283 CALL mpi_abort(comm, 1, ierror)
285 END SUBROUTINE test_abort_cmsl_f
287 SUBROUTINE icmp_2d(label, f,g, rank)
288 CHARACTER(len=*),
PARAMETER :: context =
'ftest_common::icmp_2d: ' 289 CHARACTER(len=*),
INTENT(in) :: label
290 INTEGER,
INTENT(in) :: f(:,:)
291 INTEGER,
INTENT(in) :: g(:,:)
292 INTEGER,
INTENT(in) :: rank
294 INTEGER :: i, j, n1, n2
298 IF (
SIZE(g,1) /= n1 .OR.
SIZE(g,2) /= n2) &
299 CALL test_abort(context//
'shape mismatch error', &
305 IF (f(i,j) /= g(i,j))
THEN 306 WRITE(0,
'(2a,4(a,i0))') context, label,
' test failed: i=', &
307 i,
', j=', j,
', f(i,j)=', f(i,j),
', g(i,j)=', g(i,j)
308 CALL test_abort(context//label//
' test failed', &
314 IF (verbose)
WRITE(0,*) rank,
':',context//label//
' passed' 315 END SUBROUTINE icmp_2d
317 SUBROUTINE icmp_3d(label, f,g, rank)
318 CHARACTER(len=*),
PARAMETER :: context =
'ftest_common::icmp_3d: ' 319 CHARACTER(len=*),
INTENT(in) :: label
320 INTEGER,
INTENT(in) :: f(:,:,:)
321 INTEGER,
INTENT(in) :: g(:,:,:)
322 INTEGER,
INTENT(in) :: rank
324 INTEGER :: i1,
i2, i3, n1, n2, n3
329 IF (
SIZE(g,1) /= n1 .OR.
SIZE(g,2) /= n2 .OR.
SIZE(g,3) /= n3) &
330 CALL test_abort(context//label//
'shape mismatch', __file__, __line__)
335 IF (f(i1,
i2,i3) /= g(i1,
i2,i3))
THEN 336 WRITE(0,*) context,label,&
337 ' test failed: i1, i2, i3, f(i1,i2,i3), g(i1,i2,i3) =', &
338 i1,
i2, i3, f(i1,
i2,i3), g(i1,
i2,i3)
339 CALL test_abort(context//label//
' test failed', &
346 IF (verbose)
WRITE(0,*) rank,
':',context//label//
' passed' 347 END SUBROUTINE icmp_3d
349 SUBROUTINE factorize(c, a, b)
350 INTEGER,
INTENT(in) :: c
351 INTEGER,
INTENT(out) :: a, b
355 IF (c<1)
CALL test_abort(
'factorize: invalid process space', &
358 IF (c <= 3 .OR. c == 5 .OR. c == 7)
THEN 365 x0 = int(sqrt(0.5 *
REAL(c)) + 0.5)
367 f_loop:
DO i = a, 1, -1
368 IF (mod(c,i) == 0)
THEN 375 END SUBROUTINE factorize
377 SUBROUTINE regular_deco(g_cn, c0, cn)
378 INTEGER,
INTENT(in) :: g_cn
379 INTEGER,
INTENT(out) :: c0(0:), cn(0:)
388 IF (tn<0)
CALL test_abort(
'(tn<0)', __file__, __line__)
389 IF (tn>g_cn)
CALL test_abort(
'regular_deco: too many task for such a core& 406 c0(it) = c0(it-1) + cn(it-1)
408 IF (c0(tn-1)+cn(tn-1) /= g_cn) &
409 CALL test_abort(
'regular_deco: internal error 1', &
412 END SUBROUTINE regular_deco
414 END MODULE ftest_common