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  ! VALM is an automatic (host) array on purpose: an allocatable would land in
286  ! managed memory under -gpu=mem:managed, making MPI_allreduce src=host/dst=managed
287  ! -- CUDA-aware MPI (HPC-X UCC) rejects asymmetric src/dst memory types.
288  integer(kind=kint) :: VALM(n)
289  valm = 0
290  if (ntag .eq. hecmw_sum) call mpi_allreduce(val, valm, n, mpi_integer, mpi_sum, comm, ierr)
291  if (ntag .eq. hecmw_max) call mpi_allreduce(val, valm, n, mpi_integer, mpi_max, comm, ierr)
292  if (ntag .eq. hecmw_min) call mpi_allreduce(val, valm, n, mpi_integer, mpi_min, comm, ierr)
293  val(1:n) = valm(1:n)
294 #endif
295  end subroutine hecmw_allreduce_i_comm
296 
297  subroutine hecmw_allreduce_r_comm(val, n, ntag, comm)
298  use hecmw_util
299  implicit none
300  integer(kind=kint) :: n, ntag, comm
301  real(kind=kreal) :: val(*)
302 #ifndef HECMW_SERIAL
303  integer(kind=kint) :: ierr
304  ! VALM automatic (host) -- see hecmw_allreduce_I_comm: an allocatable would be
305  ! managed under -gpu=mem:managed and trip the CUDA-aware MPI asymmetric-memtype error.
306  real(kind=kreal) :: valm(n)
307  valm = 0.d0
308  if (ntag .eq. hecmw_sum) call mpi_allreduce(val, valm, n, mpi_double_precision, mpi_sum, comm, ierr)
309  if (ntag .eq. hecmw_max) call mpi_allreduce(val, valm, n, mpi_double_precision, mpi_max, comm, ierr)
310  if (ntag .eq. hecmw_min) call mpi_allreduce(val, valm, n, mpi_double_precision, mpi_min, comm, ierr)
311  val(1:n) = valm(1:n)
312 #endif
313  end subroutine hecmw_allreduce_r_comm
314 
316  subroutine hecmw_comm_size(comm, isize)
317  use hecmw_util
318  implicit none
319  integer(kind=kint) :: comm, isize
320 #ifndef HECMW_SERIAL
321  integer(kind=kint) :: ierr
322  call mpi_comm_size(comm, isize, ierr)
323 #else
324  isize = 1
325 #endif
326  end subroutine hecmw_comm_size
327 
328  subroutine hecmw_isend_int(sbuf, sc, dest, &
329  & tag, comm, req)
330  use hecmw_util
331  implicit none
332  integer(kind=kint) :: sbuf(*)
333  integer(kind=kint) :: sc
334  integer(kind=kint) :: dest
335  integer(kind=kint) :: tag
336  integer(kind=kint) :: comm
337  integer(kind=kint) :: req
338 #ifndef HECMW_SERIAL
339  integer(kind=kint) :: ierr
340  call mpi_isend(sbuf, sc, mpi_integer, &
341  & dest, tag, comm, req, ierr)
342 #endif
343  end subroutine hecmw_isend_int
344 
345  subroutine hecmw_isend_r(sbuf, sc, dest, &
346  & tag, comm, req)
347  use hecmw_util
348  implicit none
349  integer(kind=kint) :: sc
350  double precision, dimension(sc) :: sbuf
351  integer(kind=kint) :: dest
352  integer(kind=kint) :: tag
353  integer(kind=kint) :: comm
354  integer(kind=kint) :: req
355 #ifndef HECMW_SERIAL
356  integer(kind=kint) :: ierr
357  call mpi_isend(sbuf, sc, mpi_double_precision, &
358  & dest, tag, comm, req, ierr)
359 #endif
360  end subroutine hecmw_isend_r
361 
362  subroutine hecmw_irecv_int(rbuf, rc, source, &
363  & tag, comm, req)
364  use hecmw_util
365  implicit none
366  integer(kind=kint) :: rbuf(*)
367  integer(kind=kint) :: rc
368  integer(kind=kint) :: source
369  integer(kind=kint) :: tag
370  integer(kind=kint) :: comm
371  integer(kind=kint) :: req
372 #ifndef HECMW_SERIAL
373  integer(kind=kint) :: ierr
374  call mpi_irecv(rbuf, rc, mpi_integer, &
375  & source, tag, comm, req, ierr)
376 #endif
377  end subroutine hecmw_irecv_int
378 
379  subroutine hecmw_irecv_r(rbuf, rc, source, &
380  & tag, comm, req)
381  use hecmw_util
382  implicit none
383  integer(kind=kint) :: rc
384  double precision, dimension(rc) :: rbuf
385  integer(kind=kint) :: source
386  integer(kind=kint) :: tag
387  integer(kind=kint) :: comm
388  integer(kind=kint) :: req
389 #ifndef HECMW_SERIAL
390  integer(kind=kint) :: ierr
391  call mpi_irecv(rbuf, rc, mpi_double_precision, &
392  & source, tag, comm, req, ierr)
393 #endif
394  end subroutine hecmw_irecv_r
395 
396  subroutine hecmw_waitall(cnt, reqs, stats)
397  use hecmw_util
398  implicit none
399  integer(kind=kint) :: cnt
400  integer(kind=kint) :: reqs(*)
401  integer(kind=kint) :: stats(HECMW_STATUS_SIZE,*)
402 #ifndef HECMW_SERIAL
403  integer(kind=kint) :: ierr
404  call mpi_waitall(cnt, reqs, stats, ierr)
405 #endif
406  end subroutine hecmw_waitall
407 
408  subroutine hecmw_recv_int(rbuf, rc, source, &
409  & tag, comm, stat)
410  use hecmw_util
411  implicit none
412  integer(kind=kint) :: rbuf(*)
413  integer(kind=kint) :: rc
414  integer(kind=kint) :: source
415  integer(kind=kint) :: tag
416  integer(kind=kint) :: comm
417  integer(kind=kint) :: stat(HECMW_STATUS_SIZE)
418 #ifndef HECMW_SERIAL
419  integer(kind=kint) :: ierr
420  call mpi_recv(rbuf, rc, mpi_integer, &
421  & source, tag, comm, stat, ierr)
422 #endif
423  end subroutine hecmw_recv_int
424 
425  subroutine hecmw_recv_r(rbuf, rc, source, &
426  & tag, comm, stat)
427  use hecmw_util
428  implicit none
429  integer(kind=kint) :: rc
430  double precision, dimension(rc) :: rbuf
431  integer(kind=kint) :: source
432  integer(kind=kint) :: tag
433  integer(kind=kint) :: comm
434  integer(kind=kint) :: stat(HECMW_STATUS_SIZE)
435 #ifndef HECMW_SERIAL
436  integer(kind=kint) :: ierr
437  call mpi_recv(rbuf, rc, mpi_double_precision, &
438  & source, tag, comm, stat, ierr)
439 #endif
440  end subroutine hecmw_recv_r
441  !C
442  !C***
443  !C*** hecmw_allREDUCE
444  !C***
445  !C
446  subroutine hecmw_allreduce_dp(val,VALM,n,hec_op,comm )
447  use hecmw_util
448  implicit none
449  integer(kind=kint) :: n, hec_op,op, comm, ierr
450  double precision, dimension(n) :: val
451  double precision, dimension(n) :: VALM
452 #ifndef HECMW_SERIAL
453  select case( hec_op )
454  case ( hecmw_sum )
455  op = mpi_sum
456  case ( hecmw_prod )
457  op = mpi_prod
458  case ( hecmw_max )
459  op = mpi_max
460  case ( hecmw_min )
461  op = mpi_min
462  end select
463  call mpi_allreduce(val,valm,n,mpi_double_precision,op,comm,ierr)
464 #else
465  integer(kind=kint) :: i
466  do i=1,n
467  valm(i) = val(i)
468  end do
469 #endif
470  end subroutine hecmw_allreduce_dp
471 
472  subroutine hecmw_allreduce_dp1(s1,s2,hec_op,comm )
473  use hecmw_util
474  implicit none
475  integer(kind=kint) :: hec_op, comm
476  double precision :: s1, s2
477  double precision, dimension(1) :: val
478  double precision, dimension(1) :: VALM
479 #ifndef HECMW_SERIAL
480  val(1) = s1
481  valm(1) = s2
482  call hecmw_allreduce_dp(val,valm,1,hec_op,comm )
483  s1 = val(1)
484  s2 = valm(1)
485 #else
486  s2 = s1
487 #endif
488  end subroutine hecmw_allreduce_dp1
489  !C
490  !C***
491  !C*** hecmw_allREDUCE_R
492  !C***
493  !C
494  subroutine hecmw_allreduce_r (hecMESH, val, n, ntag)
495  use hecmw_util
496  implicit none
497  integer(kind=kint):: n, ntag
498  real(kind=kreal), dimension(n) :: val
499  type (hecmwST_local_mesh) :: hecMESH
500 #ifndef HECMW_SERIAL
501  integer(kind=kint):: ierr
502  real(kind=kreal), dimension(:), allocatable :: valm, sbuf
503 
504  allocate (valm(n), sbuf(n))
505  sbuf= val
506  valm= 0.d0
507  if (ntag .eq. hecmw_sum) then
508  call mpi_allreduce &
509  & (sbuf, valm, n, mpi_double_precision, mpi_sum, &
510  & hecmesh%MPI_COMM, ierr)
511  endif
512 
513  if (ntag .eq. hecmw_max) then
514  call mpi_allreduce &
515  & (sbuf, valm, n, mpi_double_precision, mpi_max, &
516  & hecmesh%MPI_COMM, ierr)
517  endif
518 
519  if (ntag .eq. hecmw_min) then
520  call mpi_allreduce &
521  & (sbuf, valm, n, mpi_double_precision, mpi_min, &
522  & hecmesh%MPI_COMM, ierr)
523  endif
524 
525  val= valm
526  deallocate (valm, sbuf)
527 #endif
528  end subroutine hecmw_allreduce_r
529 
530  subroutine hecmw_allreduce_r1 (hecMESH, s, ntag)
531  use hecmw_util
532  implicit none
533  integer(kind=kint):: ntag
534  real(kind=kreal) :: s
535  type (hecmwST_local_mesh) :: hecMESH
536 #ifndef HECMW_SERIAL
537  real(kind=kreal), dimension(1) :: val
538  val(1) = s
539  call hecmw_allreduce_r(hecmesh, val, 1, ntag )
540  s = val(1)
541 #endif
542  end subroutine hecmw_allreduce_r1
543 
544  !C
545  !C***
546  !C*** hecmw_allREDUCE_I
547  !C***
548  !C
549  subroutine hecmw_allreduce_i(hecMESH, val, n, ntag)
550  use hecmw_util
551  implicit none
552  integer(kind=kint):: n, ntag
553  integer(kind=kint), dimension(n) :: val
554  type (hecmwST_local_mesh) :: hecMESH
555 #ifndef HECMW_SERIAL
556  integer(kind=kint):: ierr
557  integer(kind=kint), dimension(:), allocatable :: VALM, sbuf
558 
559  allocate (valm(n), sbuf(n))
560  sbuf= val
561  valm= 0
562  if (ntag .eq. hecmw_sum) then
563  call mpi_allreduce &
564  & (sbuf, valm, n, mpi_integer, mpi_sum, &
565  & hecmesh%MPI_COMM, ierr)
566  endif
567 
568  if (ntag .eq. hecmw_max) then
569  call mpi_allreduce &
570  & (sbuf, valm, n, mpi_integer, mpi_max, &
571  & hecmesh%MPI_COMM, ierr)
572  endif
573 
574  if (ntag .eq. hecmw_min) then
575  call mpi_allreduce &
576  & (sbuf, valm, n, mpi_integer, mpi_min, &
577  & hecmesh%MPI_COMM, ierr)
578  endif
579 
580 
581  val= valm
582  deallocate (valm, sbuf)
583 #endif
584  end subroutine hecmw_allreduce_i
585 
586  subroutine hecmw_allreduce_i1 (hecMESH, s, ntag)
587  use hecmw_util
588  implicit none
589  integer(kind=kint):: ntag, s
590  type (hecmwST_local_mesh) :: hecMESH
591 #ifndef HECMW_SERIAL
592  integer(kind=kint), dimension(1) :: val
593 
594  val(1) = s
595  call hecmw_allreduce_i(hecmesh, val, 1, ntag )
596  s = val(1)
597 #endif
598  end subroutine hecmw_allreduce_i1
599 
600  subroutine hecmw_allreduce_l1 (hecMESH, flag, ntag)
601  use hecmw_util
602  implicit none
603  integer(kind=kint):: ntag
604  logical :: flag
605  type (hecmwST_local_mesh) :: hecMESH
606 #ifndef HECMW_SERIAL
607  integer(kind=kint):: ierr
608  logical :: flagM
609 
610  flagm = .false.
611  if (ntag .eq. hecmw_lor) then
612  call mpi_allreduce &
613  & (flag, flagm, 1, mpi_logical, mpi_lor, &
614  & hecmesh%MPI_COMM, ierr)
615  endif
616 
617  if (ntag .eq. hecmw_land) then
618  call mpi_allreduce &
619  & (flag, flagm, 1, mpi_logical, mpi_land, &
620  & hecmesh%MPI_COMM, ierr)
621  endif
622 
623  flag = flagm
624 #endif
625  end subroutine hecmw_allreduce_l1
626 
627  !C
628  !C***
629  !C*** hecmw_bcast_R
630  !C***
631  !C
632  subroutine hecmw_bcast_r (hecMESH, val, n, nbase)
633  use hecmw_util
634  implicit none
635  integer(kind=kint):: n, nbase
636  real(kind=kreal), dimension(n) :: val
637  type (hecmwST_local_mesh) :: hecMESH
638 #ifndef HECMW_SERIAL
639  integer(kind=kint):: ierr
640  call mpi_bcast (val, n, mpi_double_precision, nbase, hecmesh%MPI_COMM, ierr)
641 #endif
642  end subroutine hecmw_bcast_r
643 
644  subroutine hecmw_bcast_r_comm (val, n, nbase, comm)
645  use hecmw_util
646  implicit none
647  integer(kind=kint):: n, nbase
648  real(kind=kreal), dimension(n) :: val
649  integer(kind=kint):: comm
650 #ifndef HECMW_SERIAL
651  integer(kind=kint):: ierr
652  call mpi_bcast (val, n, mpi_double_precision, nbase, comm, ierr)
653 #endif
654  end subroutine hecmw_bcast_r_comm
655 
656  subroutine hecmw_bcast_r1 (hecMESH, s, nbase)
657  use hecmw_util
658  implicit none
659  integer(kind=kint):: nbase, ierr
660  real(kind=kreal) :: s
661  type (hecmwST_local_mesh) :: hecMESH
662 #ifndef HECMW_SERIAL
663  real(kind=kreal), dimension(1) :: val
664  val(1)=s
665  call mpi_bcast (val, 1, mpi_double_precision, nbase, hecmesh%MPI_COMM, ierr)
666  s = val(1)
667 #endif
668  end subroutine hecmw_bcast_r1
669 
670  subroutine hecmw_bcast_r1_comm (s, nbase, comm)
671  use hecmw_util
672  implicit none
673  integer(kind=kint):: nbase
674  real(kind=kreal) :: s
675  integer(kind=kint):: comm
676 #ifndef HECMW_SERIAL
677  integer(kind=kint):: ierr
678  real(kind=kreal), dimension(1) :: val
679  val(1)=s
680  call mpi_bcast (val, 1, mpi_double_precision, nbase, comm, ierr)
681  s = val(1)
682 #endif
683  end subroutine hecmw_bcast_r1_comm
684  !C
685  !C***
686  !C*** hecmw_bcast_I
687  !C***
688  !C
689  subroutine hecmw_bcast_i (hecMESH, val, n, nbase)
690  use hecmw_util
691  implicit none
692  integer(kind=kint):: n, nbase
693  integer(kind=kint), dimension(n) :: val
694  type (hecmwST_local_mesh) :: hecMESH
695 #ifndef HECMW_SERIAL
696  integer(kind=kint):: ierr
697  call mpi_bcast (val, n, mpi_integer, nbase, hecmesh%MPI_COMM, ierr)
698 #endif
699  end subroutine hecmw_bcast_i
700 
701  subroutine hecmw_bcast_i_comm (val, n, nbase, comm)
702  use hecmw_util
703  implicit none
704  integer(kind=kint):: n, nbase
705  integer(kind=kint), dimension(n) :: val
706  integer(kind=kint):: comm
707 #ifndef HECMW_SERIAL
708  integer(kind=kint):: ierr
709  call mpi_bcast (val, n, mpi_integer, nbase, comm, ierr)
710 #endif
711  end subroutine hecmw_bcast_i_comm
712 
713  subroutine hecmw_bcast_i1 (hecMESH, s, nbase)
714  use hecmw_util
715  implicit none
716  integer(kind=kint):: nbase, s
717  type (hecmwST_local_mesh) :: hecMESH
718 #ifndef HECMW_SERIAL
719  integer(kind=kint):: ierr
720  integer(kind=kint), dimension(1) :: val
721  val(1) = s
722  call mpi_bcast (val, 1, mpi_integer, nbase, hecmesh%MPI_COMM, ierr)
723  s = val(1)
724 #endif
725  end subroutine hecmw_bcast_i1
726 
727  subroutine hecmw_bcast_i1_comm (s, nbase, comm)
728  use hecmw_util
729  implicit none
730  integer(kind=kint):: nbase, s
731  integer(kind=kint):: comm
732 #ifndef HECMW_SERIAL
733  integer(kind=kint):: ierr
734  integer(kind=kint), dimension(1) :: val
735  val(1) = s
736  call mpi_bcast (val, 1, mpi_integer, nbase, comm, ierr)
737  s = val(1)
738 #endif
739  end subroutine hecmw_bcast_i1_comm
740  !C
741  !C***
742  !C*** hecmw_bcast_C
743  !C***
744  !C
745  subroutine hecmw_bcast_c (hecMESH, val, n, nn, nbase)
746  use hecmw_util
747  implicit none
748  integer(kind=kint):: n, nn, nbase
749  character(len=n) :: val(nn)
750  type (hecmwST_local_mesh) :: hecMESH
751 #ifndef HECMW_SERIAL
752  integer(kind=kint):: ierr
753  call mpi_bcast (val, n*nn, mpi_character, nbase, hecmesh%MPI_COMM,&
754  & ierr)
755 #endif
756  end subroutine hecmw_bcast_c
757 
758  subroutine hecmw_bcast_c_comm (val, n, nn, nbase, comm)
759  use hecmw_util
760  implicit none
761  integer(kind=kint):: n, nn, nbase
762  character(len=n) :: val(nn)
763  integer(kind=kint):: comm
764 #ifndef HECMW_SERIAL
765  integer(kind=kint):: ierr
766  call mpi_bcast (val, n*nn, mpi_character, nbase, comm,&
767  & ierr)
768 #endif
769  end subroutine hecmw_bcast_c_comm
770 
771  !C
772  !C***
773  !C*** hecmw_assemble_R
774  !C***
775  subroutine hecmw_assemble_r (hecMESH, val, n, m)
776  use hecmw_util
777  use hecmw_solver_sr
778 
779  implicit none
780  integer(kind=kint):: n, m
781  real(kind=kreal), dimension(m*n) :: val
782  type (hecmwST_local_mesh) :: hecMESH
783 #ifndef HECMW_SERIAL
784  integer(kind=kint):: ns, nr
785  real(kind=kreal), dimension(:), allocatable :: ws, wr
786 
787  if( hecmesh%n_neighbor_pe == 0 ) return
788 
789  ns = hecmesh%import_index(hecmesh%n_neighbor_pe)
790  nr = hecmesh%export_index(hecmesh%n_neighbor_pe)
791 
792  allocate (ws(m*ns), wr(m*nr))
794  & ( n, m, hecmesh%n_neighbor_pe, hecmesh%neighbor_pe, &
795  & hecmesh%import_index, hecmesh%import_item, &
796  & hecmesh%export_index, hecmesh%export_item, &
797  & ws, wr, val , hecmesh%MPI_COMM, hecmesh%my_rank)
798  deallocate (ws, wr)
799 #endif
800  end subroutine hecmw_assemble_r
801 
802  !C
803  !C***
804  !C*** hecmw_assemble_I
805  !C***
806  subroutine hecmw_assemble_i (hecMESH, val, n, m)
807  use hecmw_util
809 
810  implicit none
811  integer(kind=kint):: n, m
812  integer(kind=kint), dimension(m*n) :: val
813  type (hecmwST_local_mesh) :: hecMESH
814 #ifndef HECMW_SERIAL
815  integer(kind=kint):: ns, nr
816  integer(kind=kint), dimension(:), allocatable :: WS, WR
817 
818  if( hecmesh%n_neighbor_pe == 0 ) return
819 
820  ns = hecmesh%import_index(hecmesh%n_neighbor_pe)
821  nr = hecmesh%export_index(hecmesh%n_neighbor_pe)
822 
823  allocate (ws(m*ns), wr(m*nr))
825  & ( n, m, hecmesh%n_neighbor_pe, hecmesh%neighbor_pe, &
826  & hecmesh%import_index, hecmesh%import_item, &
827  & hecmesh%export_index, hecmesh%export_item, &
828  & ws, wr, val , hecmesh%MPI_COMM, hecmesh%my_rank)
829  deallocate (ws, wr)
830 #endif
831  end subroutine hecmw_assemble_i
832 
833  !C
834  !C***
835  !C*** hecmw_update_R
836  !C***
837  !C
838  subroutine hecmw_update_r (hecMESH, val, n, m)
839  use hecmw_util
840  use hecmw_solver_sr
841 
842  implicit none
843  integer(kind=kint):: n, m
844  real(kind=kreal), dimension(m*n) :: val
845  type (hecmwST_local_mesh) :: hecMESH
846 #ifndef HECMW_SERIAL
847  integer(kind=kint):: ns, nr
848  real(kind=kreal), dimension(:), allocatable :: ws, wr
849 
850  if( hecmesh%n_neighbor_pe == 0 ) return
851 
852  ns = hecmesh%export_index(hecmesh%n_neighbor_pe)
853  nr = hecmesh%import_index(hecmesh%n_neighbor_pe)
854 
855  allocate (ws(m*ns), wr(m*nr))
856  call hecmw_solve_send_recv &
857  & ( n, m, hecmesh%n_neighbor_pe, hecmesh%neighbor_pe, &
858  & hecmesh%import_index, hecmesh%import_item, &
859  & hecmesh%export_index, hecmesh%export_item, &
860  & ws, wr, val , hecmesh%MPI_COMM, hecmesh%my_rank)
861  deallocate (ws, wr)
862 #endif
863  end subroutine hecmw_update_r
864 
865  !C
866  !C***
867  !C*** hecmw_update_R_async
868  !C***
869  !C
870  !C REAL
871  !C
872  subroutine hecmw_update_r_async (hecMESH, val, n, m, ireq)
873  use hecmw_util
874  use hecmw_solver_sr
875  implicit none
876  integer(kind=kint):: n, m, ireq
877  real(kind=kreal), dimension(m*n) :: val
878  type (hecmwST_local_mesh) :: hecMESH
879 #ifndef HECMW_SERIAL
880  if( hecmesh%n_neighbor_pe == 0 ) return
881 
883  & ( n, m, hecmesh%n_neighbor_pe, hecmesh%neighbor_pe, &
884  & hecmesh%import_index, hecmesh%import_item, &
885  & hecmesh%export_index, hecmesh%export_item, &
886  & val , hecmesh%MPI_COMM, hecmesh%my_rank, ireq)
887 #endif
888  end subroutine hecmw_update_r_async
889 
890  !C
891  !C***
892  !C*** hecmw_update_R_wait
893  !C***
894  !C
895  !C REAL
896  !C
897  subroutine hecmw_update_r_wait (hecMESH, ireq)
898  use hecmw_util
899  use hecmw_solver_sr
900  implicit none
901  integer(kind=kint):: ireq
902  type (hecmwST_local_mesh) :: hecMESH
903 #ifndef HECMW_SERIAL
904  if( hecmesh%n_neighbor_pe == 0 ) return
905 
906  call hecmw_solve_isend_irecv_wait(hecmesh%n_dof, ireq )
907 #endif
908  end subroutine hecmw_update_r_wait
909 
910 
911  !C
912  !C***
913  !C*** hecmw_update_I
914  !C***
915  !C
916  subroutine hecmw_update_i (hecMESH, val, n, m)
917  use hecmw_util
919 
920  implicit none
921  integer(kind=kint):: n, m
922  integer(kind=kint), dimension(m*n) :: val
923  type (hecmwST_local_mesh) :: hecMESH
924 #ifndef HECMW_SERIAL
925  integer(kind=kint):: ns, nr
926  integer(kind=kint), dimension(:), allocatable :: WS, WR
927 
928  if( hecmesh%n_neighbor_pe == 0 ) return
929 
930  ns = hecmesh%export_index(hecmesh%n_neighbor_pe)
931  nr = hecmesh%import_index(hecmesh%n_neighbor_pe)
932 
933  allocate (ws(m*ns), wr(m*nr))
935  & ( n, m, hecmesh%n_neighbor_pe, hecmesh%neighbor_pe, &
936  & hecmesh%import_index, hecmesh%import_item, &
937  & hecmesh%export_index, hecmesh%export_item, &
938  & ws, wr, val , hecmesh%MPI_COMM, hecmesh%my_rank)
939  deallocate (ws, wr)
940 #endif
941  end subroutine hecmw_update_i
942 
943 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)