FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_comm_f.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! Copyright (c) 2019 FrontISTR Commons
3 ! This software is released under the MIT License, see LICENSE.txt
4 !-------------------------------------------------------------------------------
5 
7 contains
8 
9  !C
10  !C***
11  !C*** hecmw_barrier
12  !C***
13  !C
14  subroutine hecmw_barrier (hecMESH)
15  use hecmw_util
16  implicit none
17  type (hecmwST_local_mesh) :: hecMESH
18 #ifndef HECMW_SERIAL
19  integer(kind=kint):: ierr
20  call mpi_barrier (hecmesh%MPI_COMM, ierr)
21 #endif
22  end subroutine hecmw_barrier
23 
24  subroutine hecmw_scatterv_dp(sbuf, sc, disp, rbuf, rc, root, comm)
25  use hecmw_util
26  implicit none
27  double precision :: sbuf(*) !send buffer
28  integer(kind=kint) :: sc(*) !send counts
29  integer(kind=kint) :: disp(*) !displacement
30  double precision :: rbuf(*) !receive buffer
31  integer(kind=kint) :: rc !receive counts
32  integer(kind=kint) :: root
33  integer(kind=kint) :: comm
34 #ifndef HECMW_SERIAL
35  integer(kind=kint) :: ierr
36  call mpi_scatterv( sbuf, sc, disp, mpi_double_precision, &
37  rbuf, rc, mpi_double_precision, &
38  root, comm, ierr )
39 #else
40  rbuf(1) = sbuf(1)
41 #endif
42  end subroutine hecmw_scatterv_dp
43 
44 #ifndef HECMW_SERIAL
45  function hecmw_operation_hec2mpi(operation)
46  use hecmw_util
47  implicit none
48  integer(kind=kint) :: hecmw_operation_hec2mpi
49  integer(kind=kint) :: operation
51  if (operation == hecmw_sum) then
52  hecmw_operation_hec2mpi = mpi_sum
53  elseif (operation == hecmw_prod) then
54  hecmw_operation_hec2mpi = mpi_prod
55  elseif (operation == hecmw_max) then
56  hecmw_operation_hec2mpi = mpi_max
57  elseif (operation == hecmw_min) then
58  hecmw_operation_hec2mpi = mpi_min
59  endif
60  end function hecmw_operation_hec2mpi
61 #endif
62 
63  subroutine hecmw_scatter_int_1(sbuf, rval, root, comm)
64  use hecmw_util
65  implicit none
66  integer(kind=kint) :: sbuf(*) !send buffer
67  integer(kind=kint) :: rval !receive value
68  integer(kind=kint) :: root
69  integer(kind=kint) :: comm
70 #ifndef HECMW_SERIAL
71  integer(kind=kint) :: ierr
72  call mpi_scatter( sbuf, 1, mpi_integer, &
73  & rval, 1, mpi_integer, root, comm, ierr )
74 #else
75  rval=sbuf(1)
76 #endif
77  end subroutine hecmw_scatter_int_1
78 
79  subroutine hecmw_gather_int_1(sval, rbuf, root, comm)
80  use hecmw_util
81  implicit none
82  integer(kind=kint) :: sval !send buffer
83  integer(kind=kint) :: rbuf(*) !receive buffer
84  integer(kind=kint) :: root
85  integer(kind=kint) :: comm
86 #ifndef HECMW_SERIAL
87  integer(kind=kint) :: ierr
88  call mpi_gather( sval, 1, mpi_integer, &
89  & rbuf, 1, mpi_integer, root, comm, ierr )
90 #else
91  rbuf(1)=sval
92 #endif
93  end subroutine hecmw_gather_int_1
94 
95  subroutine hecmw_allgather_int_1(sval, rbuf, comm)
96  use hecmw_util
97  implicit none
98  integer(kind=kint) :: sval !send buffer
99  integer(kind=kint) :: rbuf(*) !receive buffer
100  integer(kind=kint) :: comm
101 #ifndef HECMW_SERIAL
102  integer(kind=kint) :: ierr
103  call mpi_allgather( sval, 1, mpi_integer, &
104  & rbuf, 1, mpi_integer, comm, ierr )
105 #else
106  rbuf(1)=sval
107 #endif
108  end subroutine hecmw_allgather_int_1
109 
110  subroutine hecmw_scatterv_real(sbuf, scs, disp, &
111  & rbuf, rc, root, comm)
112  use hecmw_util
113  implicit none
114  real(kind=kreal) :: sbuf(*) !send buffer
115  integer(kind=kint) :: scs(*) !send counts
116  integer(kind=kint) :: disp(*) !displacement
117  real(kind=kreal) :: rbuf(*) !receive buffer
118  integer(kind=kint) :: rc !receive counts
119  integer(kind=kint) :: root
120  integer(kind=kint) :: comm
121 #ifndef HECMW_SERIAL
122  integer(kind=kint) :: ierr
123  call mpi_scatterv( sbuf, scs, disp, mpi_real8, &
124  & rbuf, rc, mpi_real8, root, comm, ierr )
125 #else
126  rbuf(1:rc)=sbuf(1:rc)
127 #endif
128  end subroutine hecmw_scatterv_real
129 
130  subroutine hecmw_gatherv_real(sbuf, sc, &
131  & rbuf, rcs, disp, root, comm)
132  use hecmw_util
133  implicit none
134  real(kind=kreal) :: sbuf(*) !send buffer
135  integer(kind=kint) :: sc !send counts
136  real(kind=kreal) :: rbuf(*) !receive buffer
137  integer(kind=kint) :: rcs(*) !receive counts
138  integer(kind=kint) :: disp(*) !displacement
139  integer(kind=kint) :: root
140  integer(kind=kint) :: comm
141 #ifndef HECMW_SERIAL
142  integer(kind=kint) :: ierr
143  call mpi_gatherv( sbuf, sc, mpi_real8, &
144  & rbuf, rcs, disp, mpi_real8, root, comm, ierr )
145 #else
146  rbuf(1:sc)=sbuf(1:sc)
147 #endif
148  end subroutine hecmw_gatherv_real
149 
150  subroutine hecmw_gatherv_int(sbuf, sc, &
151  & rbuf, rcs, disp, root, comm)
152  use hecmw_util
153  implicit none
154  integer(kind=kint) :: sbuf(*) !send buffer
155  integer(kind=kint) :: sc !send counts
156  integer(kind=kint) :: rbuf(*) !receive buffer
157  integer(kind=kint) :: rcs(*) !receive counts
158  integer(kind=kint) :: disp(*) !displacement
159  integer(kind=kint) :: root
160  integer(kind=kint) :: comm
161 #ifndef HECMW_SERIAL
162  integer(kind=kint) :: ierr
163  call mpi_gatherv( sbuf, sc, mpi_integer, &
164  & rbuf, rcs, disp, mpi_integer, root, comm, ierr )
165 #else
166  rbuf(1:sc)=sbuf(1:sc)
167 #endif
168  end subroutine hecmw_gatherv_int
169 
170  subroutine hecmw_allreduce_int_1(sval, rval, op, comm)
171  use hecmw_util
172  implicit none
173  integer(kind=kint) :: sval !send val
174  integer(kind=kint) :: rval !receive val
175  integer(kind=kint):: op, comm, ierr
176 #ifndef HECMW_SERIAL
177  call mpi_allreduce(sval, rval, 1, mpi_integer, &
178  & hecmw_operation_hec2mpi(op), comm, ierr)
179 #else
180  rval=sval
181 #endif
182  end subroutine hecmw_allreduce_int_1
183 
184  subroutine hecmw_alltoall_int(sbuf, sc, rbuf, rc, comm)
185  use hecmw_util
186  implicit none
187  integer(kind=kint) :: sbuf(*)
188  integer(kind=kint) :: sc
189  integer(kind=kint) :: rbuf(*)
190  integer(kind=kint) :: rc
191  integer(kind=kint) :: comm
192 #ifndef HECMW_SERIAL
193  integer(kind=kint) :: ierr
194  call mpi_alltoall( sbuf, sc, mpi_integer, &
195  & rbuf, rc, mpi_integer, comm, ierr )
196 #else
197  rbuf(1:sc)=sbuf(1:sc)
198 #endif
199  end subroutine hecmw_alltoall_int
200 
201  subroutine hecmw_allgatherv_int(sbuf, sc, rbuf, rcs, disp, comm)
202  use hecmw_util
203  implicit none
204  integer(kind=kint) :: sbuf(*) !send buffer
205  integer(kind=kint) :: sc !send count
206  integer(kind=kint) :: rbuf(*) !receive buffer
207  integer(kind=kint) :: rcs(*) !receive counts
208  integer(kind=kint) :: disp(*) !displacements
209  integer(kind=kint) :: comm
210 #ifndef HECMW_SERIAL
211  integer(kind=kint) :: ierr
212  call mpi_allgatherv( sbuf, sc, mpi_integer, &
213  & rbuf, rcs, disp, mpi_integer, comm, ierr )
214 #else
215  rbuf(disp(1)+1:disp(1)+sc) = sbuf(1:sc)
216 #endif
217  end subroutine hecmw_allgatherv_int
218 
219  subroutine hecmw_allgatherv_real(sbuf, sc, rbuf, rcs, disp, comm)
220  use hecmw_util
221  implicit none
222  real(kind=kreal) :: sbuf(*) !send buffer
223  integer(kind=kint) :: sc !send count
224  real(kind=kreal) :: rbuf(*) !receive buffer
225  integer(kind=kint) :: rcs(*) !receive counts
226  integer(kind=kint) :: disp(*) !displacements
227  integer(kind=kint) :: comm
228 #ifndef HECMW_SERIAL
229  integer(kind=kint) :: ierr
230  call mpi_allgatherv( sbuf, sc, mpi_real8, &
231  & rbuf, rcs, disp, mpi_real8, comm, ierr )
232 #else
233  rbuf(disp(1)+1:disp(1)+sc) = sbuf(1:sc)
234 #endif
235  end subroutine hecmw_allgatherv_real
236 
237  subroutine hecmw_alltoallv_int(sbuf, scs, sdisp, rbuf, rcs, rdisp, comm)
238  use hecmw_util
239  implicit none
240  integer(kind=kint) :: sbuf(*) !send buffer
241  integer(kind=kint) :: scs(*) !send counts
242  integer(kind=kint) :: sdisp(*) !send displacements
243  integer(kind=kint) :: rbuf(*) !receive buffer
244  integer(kind=kint) :: rcs(*) !receive counts
245  integer(kind=kint) :: rdisp(*) !receive displacements
246  integer(kind=kint) :: comm
247 #ifndef HECMW_SERIAL
248  integer(kind=kint) :: ierr
249  call mpi_alltoallv( sbuf, scs, sdisp, mpi_integer, &
250  & rbuf, rcs, rdisp, mpi_integer, comm, ierr )
251 #else
252  rbuf(rdisp(1)+1:rdisp(1)+rcs(1)) = sbuf(sdisp(1)+1:sdisp(1)+scs(1))
253 #endif
254  end subroutine hecmw_alltoallv_int
255 
256  subroutine hecmw_alltoallv_real(sbuf, scs, sdisp, rbuf, rcs, rdisp, comm)
257  use hecmw_util
258  implicit none
259  real(kind=kreal) :: sbuf(*) !send buffer
260  integer(kind=kint) :: scs(*) !send counts
261  integer(kind=kint) :: sdisp(*) !send displacements
262  real(kind=kreal) :: rbuf(*) !receive buffer
263  integer(kind=kint) :: rcs(*) !receive counts
264  integer(kind=kint) :: rdisp(*) !receive displacements
265  integer(kind=kint) :: comm
266 #ifndef HECMW_SERIAL
267  integer(kind=kint) :: ierr
268  call mpi_alltoallv( sbuf, scs, sdisp, mpi_real8, &
269  & rbuf, rcs, rdisp, mpi_real8, comm, ierr )
270 #else
271  rbuf(rdisp(1)+1:rdisp(1)+rcs(1)) = sbuf(sdisp(1)+1:sdisp(1)+scs(1))
272 #endif
273  end subroutine hecmw_alltoallv_real
274 
278  subroutine hecmw_allreduce_i_comm(val, n, ntag, comm)
279  use hecmw_util
280  implicit none
281  integer(kind=kint) :: n, ntag, comm
282  integer(kind=kint) :: val(*)
283 #ifndef HECMW_SERIAL
284  integer(kind=kint) :: ierr
285  ! MPI_IN_PLACE on the caller's buffer, no temporary: a result buffer would either land in
286  ! managed memory as an allocatable under -gpu=mem:managed -- CUDA-aware MPI (HPC-X UCC)
287  ! rejects asymmetric src/dst memory types -- or overflow the stack as an automatic array
288  ! where automatics are stack allocated (ifx, -Mstack_arrays) and n is a full vector length.
289  if (ntag .eq. hecmw_sum) call mpi_allreduce(mpi_in_place, val, n, mpi_integer, mpi_sum, comm, ierr)
290  if (ntag .eq. hecmw_max) call mpi_allreduce(mpi_in_place, val, n, mpi_integer, mpi_max, comm, ierr)
291  if (ntag .eq. hecmw_min) call mpi_allreduce(mpi_in_place, val, n, mpi_integer, mpi_min, comm, ierr)
292 #endif
293  end subroutine hecmw_allreduce_i_comm
294 
295  subroutine hecmw_allreduce_r_comm(val, n, ntag, comm)
296  use hecmw_util
297  implicit none
298  integer(kind=kint) :: n, ntag, comm
299  real(kind=kreal) :: val(*)
300 #ifndef HECMW_SERIAL
301  integer(kind=kint) :: ierr
302  ! MPI_IN_PLACE, no temporary -- see hecmw_allreduce_I_comm: an allocatable would trip the
303  ! CUDA-aware MPI asymmetric-memtype error, an automatic would overflow stacks.
304  if (ntag .eq. hecmw_sum) call mpi_allreduce(mpi_in_place, val, n, mpi_double_precision, mpi_sum, comm, ierr)
305  if (ntag .eq. hecmw_max) call mpi_allreduce(mpi_in_place, val, n, mpi_double_precision, mpi_max, comm, ierr)
306  if (ntag .eq. hecmw_min) call mpi_allreduce(mpi_in_place, val, n, mpi_double_precision, mpi_min, comm, ierr)
307 #endif
308  end subroutine hecmw_allreduce_r_comm
309 
311  subroutine hecmw_comm_size(comm, isize)
312  use hecmw_util
313  implicit none
314  integer(kind=kint) :: comm, isize
315 #ifndef HECMW_SERIAL
316  integer(kind=kint) :: ierr
317  call mpi_comm_size(comm, isize, ierr)
318 #else
319  isize = 1
320 #endif
321  end subroutine hecmw_comm_size
322 
323  subroutine hecmw_isend_int(sbuf, sc, dest, &
324  & tag, comm, req)
325  use hecmw_util
326  implicit none
327  integer(kind=kint) :: sbuf(*)
328  integer(kind=kint) :: sc
329  integer(kind=kint) :: dest
330  integer(kind=kint) :: tag
331  integer(kind=kint) :: comm
332  integer(kind=kint) :: req
333 #ifndef HECMW_SERIAL
334  integer(kind=kint) :: ierr
335  call mpi_isend(sbuf, sc, mpi_integer, &
336  & dest, tag, comm, req, ierr)
337 #endif
338  end subroutine hecmw_isend_int
339 
340  subroutine hecmw_isend_r(sbuf, sc, dest, &
341  & tag, comm, req)
342  use hecmw_util
343  implicit none
344  integer(kind=kint) :: sc
345  double precision, dimension(sc) :: sbuf
346  integer(kind=kint) :: dest
347  integer(kind=kint) :: tag
348  integer(kind=kint) :: comm
349  integer(kind=kint) :: req
350 #ifndef HECMW_SERIAL
351  integer(kind=kint) :: ierr
352  call mpi_isend(sbuf, sc, mpi_double_precision, &
353  & dest, tag, comm, req, ierr)
354 #endif
355  end subroutine hecmw_isend_r
356 
357  subroutine hecmw_irecv_int(rbuf, rc, source, &
358  & tag, comm, req)
359  use hecmw_util
360  implicit none
361  integer(kind=kint) :: rbuf(*)
362  integer(kind=kint) :: rc
363  integer(kind=kint) :: source
364  integer(kind=kint) :: tag
365  integer(kind=kint) :: comm
366  integer(kind=kint) :: req
367 #ifndef HECMW_SERIAL
368  integer(kind=kint) :: ierr
369  call mpi_irecv(rbuf, rc, mpi_integer, &
370  & source, tag, comm, req, ierr)
371 #endif
372  end subroutine hecmw_irecv_int
373 
374  subroutine hecmw_irecv_r(rbuf, rc, source, &
375  & tag, comm, req)
376  use hecmw_util
377  implicit none
378  integer(kind=kint) :: rc
379  double precision, dimension(rc) :: rbuf
380  integer(kind=kint) :: source
381  integer(kind=kint) :: tag
382  integer(kind=kint) :: comm
383  integer(kind=kint) :: req
384 #ifndef HECMW_SERIAL
385  integer(kind=kint) :: ierr
386  call mpi_irecv(rbuf, rc, mpi_double_precision, &
387  & source, tag, comm, req, ierr)
388 #endif
389  end subroutine hecmw_irecv_r
390 
391  subroutine hecmw_waitall(cnt, reqs, stats)
392  use hecmw_util
393  implicit none
394  integer(kind=kint) :: cnt
395  integer(kind=kint) :: reqs(*)
396  integer(kind=kint) :: stats(HECMW_STATUS_SIZE,*)
397 #ifndef HECMW_SERIAL
398  integer(kind=kint) :: ierr
399  call mpi_waitall(cnt, reqs, stats, ierr)
400 #endif
401  end subroutine hecmw_waitall
402 
403  subroutine hecmw_recv_int(rbuf, rc, source, &
404  & tag, comm, stat)
405  use hecmw_util
406  implicit none
407  integer(kind=kint) :: rbuf(*)
408  integer(kind=kint) :: rc
409  integer(kind=kint) :: source
410  integer(kind=kint) :: tag
411  integer(kind=kint) :: comm
412  integer(kind=kint) :: stat(HECMW_STATUS_SIZE)
413 #ifndef HECMW_SERIAL
414  integer(kind=kint) :: ierr
415  call mpi_recv(rbuf, rc, mpi_integer, &
416  & source, tag, comm, stat, ierr)
417 #endif
418  end subroutine hecmw_recv_int
419 
420  subroutine hecmw_recv_r(rbuf, rc, source, &
421  & tag, comm, stat)
422  use hecmw_util
423  implicit none
424  integer(kind=kint) :: rc
425  double precision, dimension(rc) :: rbuf
426  integer(kind=kint) :: source
427  integer(kind=kint) :: tag
428  integer(kind=kint) :: comm
429  integer(kind=kint) :: stat(HECMW_STATUS_SIZE)
430 #ifndef HECMW_SERIAL
431  integer(kind=kint) :: ierr
432  call mpi_recv(rbuf, rc, mpi_double_precision, &
433  & source, tag, comm, stat, ierr)
434 #endif
435  end subroutine hecmw_recv_r
436  !C
437  !C***
438  !C*** hecmw_allREDUCE
439  !C***
440  !C
441  subroutine hecmw_allreduce_dp(val,VALM,n,hec_op,comm )
442  use hecmw_util
443  implicit none
444  integer(kind=kint) :: n, hec_op,op, comm, ierr
445  double precision, dimension(n) :: val
446  double precision, dimension(n) :: VALM
447 #ifndef HECMW_SERIAL
448  select case( hec_op )
449  case ( hecmw_sum )
450  op = mpi_sum
451  case ( hecmw_prod )
452  op = mpi_prod
453  case ( hecmw_max )
454  op = mpi_max
455  case ( hecmw_min )
456  op = mpi_min
457  end select
458  call mpi_allreduce(val,valm,n,mpi_double_precision,op,comm,ierr)
459 #else
460  integer(kind=kint) :: i
461  do i=1,n
462  valm(i) = val(i)
463  end do
464 #endif
465  end subroutine hecmw_allreduce_dp
466 
467  subroutine hecmw_allreduce_dp1(s1,s2,hec_op,comm )
468  use hecmw_util
469  implicit none
470  integer(kind=kint) :: hec_op, comm
471  double precision :: s1, s2
472  double precision, dimension(1) :: val
473  double precision, dimension(1) :: VALM
474 #ifndef HECMW_SERIAL
475  val(1) = s1
476  valm(1) = s2
477  call hecmw_allreduce_dp(val,valm,1,hec_op,comm )
478  s1 = val(1)
479  s2 = valm(1)
480 #else
481  s2 = s1
482 #endif
483  end subroutine hecmw_allreduce_dp1
484  !C
485  !C***
486  !C*** hecmw_allREDUCE_R
487  !C***
488  !C
489  subroutine hecmw_allreduce_r (hecMESH, val, n, ntag)
490  use hecmw_util
491  implicit none
492  integer(kind=kint):: n, ntag
493  real(kind=kreal), dimension(n) :: val
494  type (hecmwST_local_mesh) :: hecMESH
495 #ifndef HECMW_SERIAL
496  integer(kind=kint):: ierr
497  real(kind=kreal), dimension(:), allocatable :: valm, sbuf
498 
499  allocate (valm(n), sbuf(n))
500  sbuf= val
501  valm= 0.d0
502  if (ntag .eq. hecmw_sum) then
503  call mpi_allreduce &
504  & (sbuf, valm, n, mpi_double_precision, mpi_sum, &
505  & hecmesh%MPI_COMM, ierr)
506  endif
507 
508  if (ntag .eq. hecmw_max) then
509  call mpi_allreduce &
510  & (sbuf, valm, n, mpi_double_precision, mpi_max, &
511  & hecmesh%MPI_COMM, ierr)
512  endif
513 
514  if (ntag .eq. hecmw_min) then
515  call mpi_allreduce &
516  & (sbuf, valm, n, mpi_double_precision, mpi_min, &
517  & hecmesh%MPI_COMM, ierr)
518  endif
519 
520  val= valm
521  deallocate (valm, sbuf)
522 #endif
523  end subroutine hecmw_allreduce_r
524 
525  subroutine hecmw_allreduce_r1 (hecMESH, s, ntag)
526  use hecmw_util
527  implicit none
528  integer(kind=kint):: ntag
529  real(kind=kreal) :: s
530  type (hecmwST_local_mesh) :: hecMESH
531 #ifndef HECMW_SERIAL
532  real(kind=kreal), dimension(1) :: val
533  val(1) = s
534  call hecmw_allreduce_r(hecmesh, val, 1, ntag )
535  s = val(1)
536 #endif
537  end subroutine hecmw_allreduce_r1
538 
539  !C
540  !C***
541  !C*** hecmw_allREDUCE_I
542  !C***
543  !C
544  subroutine hecmw_allreduce_i(hecMESH, val, n, ntag)
545  use hecmw_util
546  implicit none
547  integer(kind=kint):: n, ntag
548  integer(kind=kint), dimension(n) :: val
549  type (hecmwST_local_mesh) :: hecMESH
550 #ifndef HECMW_SERIAL
551  integer(kind=kint):: ierr
552  integer(kind=kint), dimension(:), allocatable :: VALM, sbuf
553 
554  allocate (valm(n), sbuf(n))
555  sbuf= val
556  valm= 0
557  if (ntag .eq. hecmw_sum) then
558  call mpi_allreduce &
559  & (sbuf, valm, n, mpi_integer, mpi_sum, &
560  & hecmesh%MPI_COMM, ierr)
561  endif
562 
563  if (ntag .eq. hecmw_max) then
564  call mpi_allreduce &
565  & (sbuf, valm, n, mpi_integer, mpi_max, &
566  & hecmesh%MPI_COMM, ierr)
567  endif
568 
569  if (ntag .eq. hecmw_min) then
570  call mpi_allreduce &
571  & (sbuf, valm, n, mpi_integer, mpi_min, &
572  & hecmesh%MPI_COMM, ierr)
573  endif
574 
575 
576  val= valm
577  deallocate (valm, sbuf)
578 #endif
579  end subroutine hecmw_allreduce_i
580 
581  subroutine hecmw_allreduce_i1 (hecMESH, s, ntag)
582  use hecmw_util
583  implicit none
584  integer(kind=kint):: ntag, s
585  type (hecmwST_local_mesh) :: hecMESH
586 #ifndef HECMW_SERIAL
587  integer(kind=kint), dimension(1) :: val
588 
589  val(1) = s
590  call hecmw_allreduce_i(hecmesh, val, 1, ntag )
591  s = val(1)
592 #endif
593  end subroutine hecmw_allreduce_i1
594 
595  subroutine hecmw_allreduce_l1 (hecMESH, flag, ntag)
596  use hecmw_util
597  implicit none
598  integer(kind=kint):: ntag
599  logical :: flag
600  type (hecmwST_local_mesh) :: hecMESH
601 #ifndef HECMW_SERIAL
602  integer(kind=kint):: ierr
603  logical :: flagM
604 
605  flagm = .false.
606  if (ntag .eq. hecmw_lor) then
607  call mpi_allreduce &
608  & (flag, flagm, 1, mpi_logical, mpi_lor, &
609  & hecmesh%MPI_COMM, ierr)
610  endif
611 
612  if (ntag .eq. hecmw_land) then
613  call mpi_allreduce &
614  & (flag, flagm, 1, mpi_logical, mpi_land, &
615  & hecmesh%MPI_COMM, ierr)
616  endif
617 
618  flag = flagm
619 #endif
620  end subroutine hecmw_allreduce_l1
621 
622  !C
623  !C***
624  !C*** hecmw_bcast_R
625  !C***
626  !C
627  subroutine hecmw_bcast_r (hecMESH, val, n, nbase)
628  use hecmw_util
629  implicit none
630  integer(kind=kint):: n, nbase
631  real(kind=kreal), dimension(n) :: val
632  type (hecmwST_local_mesh) :: hecMESH
633 #ifndef HECMW_SERIAL
634  integer(kind=kint):: ierr
635  call mpi_bcast (val, n, mpi_double_precision, nbase, hecmesh%MPI_COMM, ierr)
636 #endif
637  end subroutine hecmw_bcast_r
638 
639  subroutine hecmw_bcast_r_comm (val, n, nbase, comm)
640  use hecmw_util
641  implicit none
642  integer(kind=kint):: n, nbase
643  real(kind=kreal), dimension(n) :: val
644  integer(kind=kint):: comm
645 #ifndef HECMW_SERIAL
646  integer(kind=kint):: ierr
647  call mpi_bcast (val, n, mpi_double_precision, nbase, comm, ierr)
648 #endif
649  end subroutine hecmw_bcast_r_comm
650 
651  subroutine hecmw_bcast_r1 (hecMESH, s, nbase)
652  use hecmw_util
653  implicit none
654  integer(kind=kint):: nbase, ierr
655  real(kind=kreal) :: s
656  type (hecmwST_local_mesh) :: hecMESH
657 #ifndef HECMW_SERIAL
658  real(kind=kreal), dimension(1) :: val
659  val(1)=s
660  call mpi_bcast (val, 1, mpi_double_precision, nbase, hecmesh%MPI_COMM, ierr)
661  s = val(1)
662 #endif
663  end subroutine hecmw_bcast_r1
664 
665  subroutine hecmw_bcast_r1_comm (s, nbase, comm)
666  use hecmw_util
667  implicit none
668  integer(kind=kint):: nbase
669  real(kind=kreal) :: s
670  integer(kind=kint):: comm
671 #ifndef HECMW_SERIAL
672  integer(kind=kint):: ierr
673  real(kind=kreal), dimension(1) :: val
674  val(1)=s
675  call mpi_bcast (val, 1, mpi_double_precision, nbase, comm, ierr)
676  s = val(1)
677 #endif
678  end subroutine hecmw_bcast_r1_comm
679  !C
680  !C***
681  !C*** hecmw_bcast_I
682  !C***
683  !C
684  subroutine hecmw_bcast_i (hecMESH, val, n, nbase)
685  use hecmw_util
686  implicit none
687  integer(kind=kint):: n, nbase
688  integer(kind=kint), dimension(n) :: val
689  type (hecmwST_local_mesh) :: hecMESH
690 #ifndef HECMW_SERIAL
691  integer(kind=kint):: ierr
692  call mpi_bcast (val, n, mpi_integer, nbase, hecmesh%MPI_COMM, ierr)
693 #endif
694  end subroutine hecmw_bcast_i
695 
696  subroutine hecmw_bcast_i_comm (val, n, nbase, comm)
697  use hecmw_util
698  implicit none
699  integer(kind=kint):: n, nbase
700  integer(kind=kint), dimension(n) :: val
701  integer(kind=kint):: comm
702 #ifndef HECMW_SERIAL
703  integer(kind=kint):: ierr
704  call mpi_bcast (val, n, mpi_integer, nbase, comm, ierr)
705 #endif
706  end subroutine hecmw_bcast_i_comm
707 
708  subroutine hecmw_bcast_i1 (hecMESH, s, nbase)
709  use hecmw_util
710  implicit none
711  integer(kind=kint):: nbase, s
712  type (hecmwST_local_mesh) :: hecMESH
713 #ifndef HECMW_SERIAL
714  integer(kind=kint):: ierr
715  integer(kind=kint), dimension(1) :: val
716  val(1) = s
717  call mpi_bcast (val, 1, mpi_integer, nbase, hecmesh%MPI_COMM, ierr)
718  s = val(1)
719 #endif
720  end subroutine hecmw_bcast_i1
721 
722  subroutine hecmw_bcast_i1_comm (s, nbase, comm)
723  use hecmw_util
724  implicit none
725  integer(kind=kint):: nbase, s
726  integer(kind=kint):: comm
727 #ifndef HECMW_SERIAL
728  integer(kind=kint):: ierr
729  integer(kind=kint), dimension(1) :: val
730  val(1) = s
731  call mpi_bcast (val, 1, mpi_integer, nbase, comm, ierr)
732  s = val(1)
733 #endif
734  end subroutine hecmw_bcast_i1_comm
735  !C
736  !C***
737  !C*** hecmw_bcast_C
738  !C***
739  !C
740  subroutine hecmw_bcast_c (hecMESH, val, n, nn, nbase)
741  use hecmw_util
742  implicit none
743  integer(kind=kint):: n, nn, nbase
744  character(len=n) :: val(nn)
745  type (hecmwST_local_mesh) :: hecMESH
746 #ifndef HECMW_SERIAL
747  integer(kind=kint):: ierr
748  call mpi_bcast (val, n*nn, mpi_character, nbase, hecmesh%MPI_COMM,&
749  & ierr)
750 #endif
751  end subroutine hecmw_bcast_c
752 
753  subroutine hecmw_bcast_c_comm (val, n, nn, nbase, comm)
754  use hecmw_util
755  implicit none
756  integer(kind=kint):: n, nn, nbase
757  character(len=n) :: val(nn)
758  integer(kind=kint):: comm
759 #ifndef HECMW_SERIAL
760  integer(kind=kint):: ierr
761  call mpi_bcast (val, n*nn, mpi_character, nbase, comm,&
762  & ierr)
763 #endif
764  end subroutine hecmw_bcast_c_comm
765 
766  !C
767  !C***
768  !C*** hecmw_assemble_R
769  !C***
770  subroutine hecmw_assemble_r (hecMESH, val, n, m)
771  use hecmw_util
772  use hecmw_solver_sr
773 
774  implicit none
775  integer(kind=kint):: n, m
776  real(kind=kreal), dimension(m*n) :: val
777  type (hecmwST_local_mesh) :: hecMESH
778 #ifndef HECMW_SERIAL
779  integer(kind=kint):: ns, nr
780  real(kind=kreal), dimension(:), allocatable :: ws, wr
781 
782  if( hecmesh%n_neighbor_pe == 0 ) return
783 
784  ns = hecmesh%import_index(hecmesh%n_neighbor_pe)
785  nr = hecmesh%export_index(hecmesh%n_neighbor_pe)
786 
787  allocate (ws(m*ns), wr(m*nr))
789  & ( n, m, hecmesh%n_neighbor_pe, hecmesh%neighbor_pe, &
790  & hecmesh%import_index, hecmesh%import_item, &
791  & hecmesh%export_index, hecmesh%export_item, &
792  & ws, wr, val , hecmesh%MPI_COMM, hecmesh%my_rank)
793  deallocate (ws, wr)
794 #endif
795  end subroutine hecmw_assemble_r
796 
797  !C
798  !C***
799  !C*** hecmw_assemble_I
800  !C***
801  subroutine hecmw_assemble_i (hecMESH, val, n, m)
802  use hecmw_util
804 
805  implicit none
806  integer(kind=kint):: n, m
807  integer(kind=kint), dimension(m*n) :: val
808  type (hecmwST_local_mesh) :: hecMESH
809 #ifndef HECMW_SERIAL
810  integer(kind=kint):: ns, nr
811  integer(kind=kint), dimension(:), allocatable :: WS, WR
812 
813  if( hecmesh%n_neighbor_pe == 0 ) return
814 
815  ns = hecmesh%import_index(hecmesh%n_neighbor_pe)
816  nr = hecmesh%export_index(hecmesh%n_neighbor_pe)
817 
818  allocate (ws(m*ns), wr(m*nr))
820  & ( n, m, hecmesh%n_neighbor_pe, hecmesh%neighbor_pe, &
821  & hecmesh%import_index, hecmesh%import_item, &
822  & hecmesh%export_index, hecmesh%export_item, &
823  & ws, wr, val , hecmesh%MPI_COMM, hecmesh%my_rank)
824  deallocate (ws, wr)
825 #endif
826  end subroutine hecmw_assemble_i
827 
828  !C
829  !C***
830  !C*** hecmw_update_R
831  !C***
832  !C
833  subroutine hecmw_update_r (hecMESH, val, n, m)
834  use hecmw_util
835  use hecmw_solver_sr
836 
837  implicit none
838  integer(kind=kint):: n, m
839  real(kind=kreal), dimension(m*n) :: val
840  type (hecmwST_local_mesh) :: hecMESH
841 #ifndef HECMW_SERIAL
842  integer(kind=kint):: ns, nr
843  real(kind=kreal), dimension(:), allocatable :: ws, wr
844 
845  if( hecmesh%n_neighbor_pe == 0 ) return
846 
847  ns = hecmesh%export_index(hecmesh%n_neighbor_pe)
848  nr = hecmesh%import_index(hecmesh%n_neighbor_pe)
849 
850  allocate (ws(m*ns), wr(m*nr))
851  call hecmw_solve_send_recv &
852  & ( n, m, hecmesh%n_neighbor_pe, hecmesh%neighbor_pe, &
853  & hecmesh%import_index, hecmesh%import_item, &
854  & hecmesh%export_index, hecmesh%export_item, &
855  & ws, wr, val , hecmesh%MPI_COMM, hecmesh%my_rank)
856  deallocate (ws, wr)
857 #endif
858  end subroutine hecmw_update_r
859 
860  !C
861  !C***
862  !C*** hecmw_update_R_async
863  !C***
864  !C
865  !C REAL
866  !C
867  subroutine hecmw_update_r_async (hecMESH, val, n, m, ireq)
868  use hecmw_util
869  use hecmw_solver_sr
870  implicit none
871  integer(kind=kint):: n, m, ireq
872  real(kind=kreal), dimension(m*n) :: val
873  type (hecmwST_local_mesh) :: hecMESH
874 #ifndef HECMW_SERIAL
875  if( hecmesh%n_neighbor_pe == 0 ) return
876 
878  & ( n, m, hecmesh%n_neighbor_pe, hecmesh%neighbor_pe, &
879  & hecmesh%import_index, hecmesh%import_item, &
880  & hecmesh%export_index, hecmesh%export_item, &
881  & val , hecmesh%MPI_COMM, hecmesh%my_rank, ireq)
882 #endif
883  end subroutine hecmw_update_r_async
884 
885  !C
886  !C***
887  !C*** hecmw_update_R_wait
888  !C***
889  !C
890  !C REAL
891  !C
892  subroutine hecmw_update_r_wait (hecMESH, ireq)
893  use hecmw_util
894  use hecmw_solver_sr
895  implicit none
896  integer(kind=kint):: ireq
897  type (hecmwST_local_mesh) :: hecMESH
898 #ifndef HECMW_SERIAL
899  if( hecmesh%n_neighbor_pe == 0 ) return
900 
901  call hecmw_solve_isend_irecv_wait(hecmesh%n_dof, ireq )
902 #endif
903  end subroutine hecmw_update_r_wait
904 
905 
906  !C
907  !C***
908  !C*** hecmw_update_I
909  !C***
910  !C
911  subroutine hecmw_update_i (hecMESH, val, n, m)
912  use hecmw_util
914 
915  implicit none
916  integer(kind=kint):: n, m
917  integer(kind=kint), dimension(m*n) :: val
918  type (hecmwST_local_mesh) :: hecMESH
919 #ifndef HECMW_SERIAL
920  integer(kind=kint):: ns, nr
921  integer(kind=kint), dimension(:), allocatable :: WS, WR
922 
923  if( hecmesh%n_neighbor_pe == 0 ) return
924 
925  ns = hecmesh%export_index(hecmesh%n_neighbor_pe)
926  nr = hecmesh%import_index(hecmesh%n_neighbor_pe)
927 
928  allocate (ws(m*ns), wr(m*nr))
930  & ( n, m, hecmesh%n_neighbor_pe, hecmesh%neighbor_pe, &
931  & hecmesh%import_index, hecmesh%import_item, &
932  & hecmesh%export_index, hecmesh%export_item, &
933  & ws, wr, val , hecmesh%MPI_COMM, hecmesh%my_rank)
934  deallocate (ws, wr)
935 #endif
936  end subroutine hecmw_update_i
937 
938 end module m_hecmw_comm_f
subroutine hecmw_solve_send_recv_i(N, m, NEIBPETOT, NEIBPE, STACK_IMPORT, NOD_IMPORT, STACK_EXPORT, NOD_EXPORT, WS, WR, X, SOLVER_COMM, my_rank)
subroutine hecmw_solve_rev_send_recv_i(N, M, NEIBPETOT, NEIBPE, STACK_IMPORT, NOD_IMPORT, STACK_EXPORT, NOD_EXPORT, WS, WR, X, SOLVER_COMM, my_rank)
subroutine hecmw_solve_isend_irecv_wait(m, ireq)
subroutine hecmw_solve_isend_irecv(N, M, NEIBPETOT, NEIBPE, STACK_IMPORT, NOD_IMPORT, STACK_EXPORT, NOD_EXPORT, X, SOLVER_COMM, my_rank, ireq)
subroutine hecmw_solve_send_recv(N, m, NEIBPETOT, NEIBPE, STACK_IMPORT, NOD_IMPORT, STACK_EXPORT, NOD_EXPORT, WS, WR, X, SOLVER_COMM, my_rank)
subroutine hecmw_solve_rev_send_recv(N, M, NEIBPETOT, NEIBPE, STACK_IMPORT, NOD_IMPORT, STACK_EXPORT, NOD_EXPORT, WS, WR, X, SOLVER_COMM, my_rank)
I/O and Utility.
Definition: hecmw_util_f.F90:7
integer(kind=kint), parameter hecmw_land
integer(kind=kint), parameter hecmw_sum
integer(kind=kint), parameter hecmw_prod
integer(kind=kint), parameter hecmw_max
integer(kind=4), parameter kreal
integer(kind=kint), parameter hecmw_lor
integer(kind=kint), parameter hecmw_min
subroutine hecmw_assemble_r(hecMESH, val, n, m)
subroutine hecmw_bcast_c_comm(val, n, nn, nbase, comm)
subroutine hecmw_gatherv_real(sbuf, sc, rbuf, rcs, disp, root, comm)
subroutine hecmw_update_r(hecMESH, val, n, m)
subroutine hecmw_isend_int(sbuf, sc, dest, tag, comm, req)
subroutine hecmw_scatterv_real(sbuf, scs, disp, rbuf, rc, root, comm)
subroutine hecmw_allgatherv_int(sbuf, sc, rbuf, rcs, disp, comm)
subroutine hecmw_alltoallv_real(sbuf, scs, sdisp, rbuf, rcs, rdisp, comm)
subroutine hecmw_recv_int(rbuf, rc, source, tag, comm, stat)
subroutine hecmw_bcast_r_comm(val, n, nbase, comm)
subroutine hecmw_allgatherv_real(sbuf, sc, rbuf, rcs, disp, comm)
subroutine hecmw_bcast_c(hecMESH, val, n, nn, nbase)
subroutine hecmw_isend_r(sbuf, sc, dest, tag, comm, req)
subroutine hecmw_allreduce_i1(hecMESH, s, ntag)
subroutine hecmw_gather_int_1(sval, rbuf, root, comm)
subroutine hecmw_bcast_i_comm(val, n, nbase, comm)
subroutine hecmw_allreduce_i(hecMESH, val, n, ntag)
subroutine hecmw_allreduce_r(hecMESH, val, n, ntag)
subroutine hecmw_bcast_i1(hecMESH, s, nbase)
subroutine hecmw_allgather_int_1(sval, rbuf, comm)
subroutine hecmw_allreduce_dp1(s1, s2, hec_op, comm)
subroutine hecmw_waitall(cnt, reqs, stats)
subroutine hecmw_assemble_i(hecMESH, val, n, m)
subroutine hecmw_comm_size(comm, isize)
Number of ranks in an explicit communicator (1 when serial).
subroutine hecmw_allreduce_dp(val, VALM, n, hec_op, comm)
subroutine hecmw_bcast_r(hecMESH, val, n, nbase)
subroutine hecmw_alltoallv_int(sbuf, scs, sdisp, rbuf, rcs, rdisp, comm)
subroutine hecmw_irecv_int(rbuf, rc, source, tag, comm, req)
subroutine hecmw_bcast_r1_comm(s, nbase, comm)
subroutine hecmw_scatter_int_1(sbuf, rval, root, comm)
subroutine hecmw_irecv_r(rbuf, rc, source, tag, comm, req)
subroutine hecmw_allreduce_l1(hecMESH, flag, ntag)
subroutine hecmw_bcast_i(hecMESH, val, n, nbase)
subroutine hecmw_update_r_async(hecMESH, val, n, m, ireq)
subroutine hecmw_allreduce_r_comm(val, n, ntag, comm)
subroutine hecmw_update_i(hecMESH, val, n, m)
subroutine hecmw_recv_r(rbuf, rc, source, tag, comm, stat)
subroutine hecmw_allreduce_r1(hecMESH, s, ntag)
subroutine hecmw_alltoall_int(sbuf, sc, rbuf, rc, comm)
subroutine hecmw_update_r_wait(hecMESH, ireq)
subroutine hecmw_bcast_r1(hecMESH, s, nbase)
subroutine hecmw_scatterv_dp(sbuf, sc, disp, rbuf, rc, root, comm)
subroutine hecmw_allreduce_int_1(sval, rval, op, comm)
subroutine hecmw_gatherv_int(sbuf, sc, rbuf, rcs, disp, root, comm)
subroutine hecmw_barrier(hecMESH)
subroutine hecmw_allreduce_i_comm(val, n, ntag, comm)
Allreduce over an explicit communicator (ntag = hecmw_sum / hecmw_max / hecmw_min)....
integer(kind=kint) function hecmw_operation_hec2mpi(operation)
subroutine hecmw_bcast_i1_comm(s, nbase, comm)