25
26 IMPLICIT NONE
27 INTEGER, INTENT(IN) :: NSLAVES, N, MYID_NODES
28 INTEGER, INTENT(IN) :: NRHS_loc, LRHS_loc
29 INTEGER, INTENT(IN) :: NRHS_COL
30 INTEGER, INTENT(IN) :: COMM_NODES
31 INTEGER, INTENT(IN) :: MAP_RHS_loc(max(1,NRHS_loc))
32 INTEGER, INTENT(IN) :: IRHS_loc(NRHS_loc)
33 INTEGER(8), INTENT(IN) :: RHS_loc_size
34 REAL, INTENT(IN) :: RHS_loc(RHS_loc_size)
35 INTEGER, INTENT(IN) :: NB_FS_IN_RHSCOMP, LD_RHSCOMP
36 INTEGER, INTENT(IN) :: POSINRHSCOMP_FWD(N)
37 REAL, INTENT(OUT) :: RHSCOMP(LD_RHSCOMP, NRHS_COL)
38 INTEGER :: KEEP(500)
39 LOGICAL, INTENT(IN) :: LSCAL
40 type scaling_data_t
41 sequence
42 REAL, dimension(:), pointer :: SCALING
43 REAL, dimension(:), pointer :: SCALING_LOC
44 end type scaling_data_t
45 type(scaling_data_t), INTENT(IN) :: scaling_data_dr
46 LOGICAL, INTENT(IN) :: LPOK
47 INTEGER, INTENT(IN) :: LP
48 INTEGER, INTENT(INOUT) :: INFO(2)
49 INTEGER(8), INTENT(OUT):: NB_BYTES_LOC
50 include 'mpif.h'
51 INTEGER :: IERR_MPI
52 LOGICAL :: OMP_FLAG
53
54
55 INTEGER :: allocok
56 INTEGER :: MAXRECORDS
57 INTEGER, ALLOCATABLE, DIMENSION(:) :: NBROWSTOSEND
58 INTEGER, ALLOCATABLE, DIMENSION(:) :: NEXTROWTOSEND
59 REAL, ALLOCATABLE, DIMENSION(:,:) :: BUFR
60 INTEGER, ALLOCATABLE, DIMENSION(:) :: BUFRECI
61 REAL, ALLOCATABLE, DIMENSION(:) :: BUFRECR
62 LOGICAL, ALLOCATABLE, DIMENSION(:) :: IS_SEND_ACTIVE, TOUCHED
63 INTEGER, ALLOCATABLE, DIMENSION(:) :: MPI_REQI, MPI_REQR
64 INTEGER, ALLOCATABLE, DIMENSION(:) :: IRHS_loc_sorted
65 INTEGER :: Iloc
66 INTEGER :: Iloc_sorted
67 INTEGER :: IREQ
68 INTEGER :: IMAP, IPROC_MAX
69 INTEGER :: IFS
70 INTEGER :: MAX_ACTIVE_SENDS
71 INTEGER :: NB_ACTIVE_SENDS
72 INTEGER :: NB_FS_TOUCHED
73 INTEGER :: NBROWSTORECV
74 REAL, PARAMETER :: ZERO = 0.0e0
75
76 nb_bytes_loc = 0_8
77 ALLOCATE( nbrowstosend(nslaves),
78 & nextrowtosend(nslaves),
79 & irhs_loc_sorted(nrhs_loc),
80 & stat=allocok )
81 IF (allocok > 0) THEN
82 info(1) = -13
83 info(2) = nslaves+nslaves+nrhs_loc
84 ENDIF
85 nb_bytes_loc = int(2*nslaves+nrhs_loc,8)*keep(34)
87 & mpi_integer, mpi_sum,
88 & comm_nodes, ierr_mpi )
89 IF (allocok .GT. 0) RETURN
90 nbrowstosend(1:nslaves) = 0
91 DO iloc = 1, nrhs_loc
92 IF (irhs_loc(iloc) .GE. 1 .AND.
93 & irhs_loc(iloc) .LE. n) THEN
94 imap = map_rhs_loc(iloc)
95 nbrowstosend(imap+1) = nbrowstosend(imap+1)+1
96 ENDIF
97 ENDDO
98 nextrowtosend(1)=1
99 DO imap=1, nslaves-1
100 nextrowtosend(imap+1)=nextrowtosend(imap)+nbrowstosend(imap)
101 ENDDO
102 nbrowstosend=0
103 DO iloc = 1, nrhs_loc
104 IF (irhs_loc(iloc) .GE. 1 .AND.
105 & irhs_loc(iloc) .LE. n) THEN
106 imap = map_rhs_loc(iloc)
107 iloc_sorted = nextrowtosend(imap+1)+nbrowstosend(imap+1)
108 irhs_loc_sorted(iloc_sorted) = iloc
109 nbrowstosend(imap+1)=nbrowstosend(imap+1)+1
110 ENDIF
111 ENDDO
113 max_active_sends =
min(10, nslaves)
114 IF (keep(72) .EQ.1 ) THEN
115 maxrecords = 15
116 ELSE
117 maxrecords =
min(200000,2000000/nrhs_col)
118 maxrecords =
min(maxrecords,
119 & 50000000 / max_active_sends / nrhs_col)
120 maxrecords =
max(maxrecords, 50)
121 ENDIF
122 ALLOCATE(bufr(maxrecords*nrhs_col,
123 & max_active_sends),
124 & mpi_reqi(max_active_sends),
125 & mpi_reqr(max_active_sends),
126 & is_send_active(max_active_sends),
127 & bufreci(maxrecords),
128 & bufrecr(maxrecords*nrhs_col),
129 & touched(nb_fs_in_rhscomp),
130 & stat=allocok)
131 IF (allocok .GT. 0) THEN
132 IF (lp .GT. 0) WRITE(lp, '(A)')
133 & 'Error: Allocation problem in SMUMPS_SCATTER_DIST_RHS'
134 info(1)=-13
135 info(2)=nrhs_col*maxrecords*max_active_sends+
136 & 3*max_active_sends+maxrecords*(1+nrhs_col)
137 & + nb_fs_in_rhscomp
138 ENDIF
139 nb_bytes_loc=nb_bytes_loc +
140 & keep(34) * ( int(2*max_active_sends,8) + int(maxrecords,8) ) +
141 & keep(34) * (int(max_active_sends,8) + int(nb_fs_in_rhscomp,8)) +
142 & keep(35) * (
143 & int( maxrecords,8)*int(nrhs_col,8)*int(max_active_sends,8)
144 & + int(maxrecords,8) * int(nrhs_col,8) )
146 & mpi_integer, mpi_sum,
147 & comm_nodes, ierr_mpi )
148 IF (allocok .NE. 0) RETURN
149 nb_active_sends = 0
150 DO ireq = 1, max_active_sends
151 is_send_active(ireq) = .false.
152 ENDDO
153 nb_fs_touched = 0
154 DO ifs = 1, nb_fs_in_rhscomp
155 touched(ifs) = .false.
156 ENDDO
157 iproc_max=maxloc(nbrowstosend,dim=1)-1
158 DO WHILE (nbrowstosend(iproc_max+1) .NE. 0)
159 IF (iproc_max .EQ. myid_nodes) THEN
161 ELSE
163 ENDIF
166 iproc_max=maxloc(nbrowstosend,dim=1)-1
167 ENDDO
168 DO WHILE ( nbrowstorecv .NE. 0)
171 ENDDO
172 DO WHILE (nb_active_sends .NE. 0)
174 ENDDO
176 RETURN
177 CONTAINS
179 INTEGER :: IPROC
180 DO iproc = 0, nslaves-1
181 CALL mpi_reduce( nbrowstosend(iproc+1), nbrowstorecv,
182 & 1, mpi_integer,
183 & mpi_sum, iproc, comm_nodes, ierr_mpi )
184 ENDDO
187 IMPLICIT NONE
188 include 'mumps_tags.h'
189 INTEGER :: MPI_STATUS(MPI_STATUS_SIZE), MSGSOU
190 INTEGER :: NBRECORDS
191 LOGICAL :: FLAG
192 CALL mpi_iprobe( mpi_any_source, distrhsi, comm_nodes,
193 & flag, mpi_status, ierr_mpi )
194 IF (flag) THEN
195 msgsou = mpi_status( mpi_source )
197 & nbrecords, ierr_mpi)
198 CALL mpi_recv(bufreci(1), nbrecords, mpi_integer,
199 & msgsou, distrhsi,
200 & comm_nodes, mpi_status, ierr_mpi)
201 CALL mpi_recv(bufrecr(1), nbrecords*nrhs_col,
202 & mpi_real,
203 & msgsou, distrhsr,
204 & comm_nodes, mpi_status, ierr_mpi)
206 & bufreci, bufrecr)
207 ENDIF
208 RETURN
211 & (nbrecords, bufreci_arg, bufrecr_arg)
212 IMPLICIT NONE
213 INTEGER, INTENT(IN) :: NBRECORDS
214 INTEGER, INTENT(INOUT) :: BUFRECI_ARG(NBRECORDS)
215 REAL, INTENT(IN) :: BUFRECR_ARG(NBRECORDS,
216 & NRHS_COL)
217 INTEGER :: I, K, IRHSCOMP, IFIRSTNOTTOUCHED, ILASTNOTTOUCHED
218 ifirstnottouched = nbrecords+1
219 ilastnottouched = 0
220 DO i = 1, nbrecords
221 IF (bufreci(i) .LE. 0) THEN
222 WRITE(*,*) "Internal error 1 in SMUMPS_DR_TRY_RECV",
223 & i, bufreci(i), bufreci(1)
225 ENDIF
226 irhscomp=posinrhscomp_fwd(bufreci(i))
227 bufreci_arg(i)=irhscomp
228 IF ( .NOT. touched(irhscomp) ) THEN
229 ifirstnottouched=
min(ifirstnottouched,i)
230 ilastnottouched=
max(ilastnottouched,i)
231 ENDIF
232 ENDDO
233 omp_flag = .false.
234
235
236 IF (omp_flag) THEN
237
238 DO k = 1, nrhs_col
239 DO i = ifirstnottouched, ilastnottouched
240 irhscomp=bufreci_arg(i)
241 IF (.NOT. touched(irhscomp)) THEN
242 rhscomp(irhscomp,k)=zero
243 ENDIF
244 ENDDO
245 DO i = 1, nbrecords
246 irhscomp=bufreci_arg(i)
247 rhscomp(irhscomp,k) = rhscomp(irhscomp,k) +
248 & bufrecr_arg(i,k)
249 ENDDO
250 ENDDO
251
252 ELSE
253 DO k = 1, nrhs_col
254 DO i = ifirstnottouched, ilastnottouched
255 irhscomp=bufreci_arg(i)
256 IF (.NOT. touched(irhscomp)) THEN
257 rhscomp(irhscomp,k)=zero
258 ENDIF
259 ENDDO
260 DO i = 1, nbrecords
261 irhscomp=bufreci_arg(i)
262 rhscomp(irhscomp,k) = rhscomp(irhscomp,k) +
263 & bufrecr_arg(i,k)
264 ENDDO
265 ENDDO
266 ENDIF
267 DO i = 1, nbrecords
268 irhscomp = bufreci_arg(i)
269 IF (.NOT. touched(irhscomp)) THEN
270 nb_fs_touched = nb_fs_touched + 1
271 touched(irhscomp) = .true.
272 ENDIF
273 ENDDO
274 nbrowstorecv = nbrowstorecv - nbrecords
275 RETURN
278 INTEGER :: NBRECORDS, I, K, IFIRSTNOTTOUCHED
279 INTEGER :: Iloc
280 INTEGER :: Iglob
281 INTEGER :: IRHSCOMP
282 INTEGER(8) :: ISHIFT
283 IF ( nbrowstosend(myid_nodes+1) .EQ. 0) THEN
284 WRITE(*,*) "Internal error in SMUMPS_DR_ASSEMBLE_LOCAL"
286 ENDIF
287 nbrecords=
min(maxrecords, nbrowstosend(myid_nodes+1))
288 ifirstnottouched=nbrecords+1
289 DO i = 1, nbrecords
290 irhscomp = posinrhscomp_fwd(irhs_loc(
291 & irhs_loc_sorted(nextrowtosend(myid_nodes+1)+i-1)))
292 IF (.NOT. touched(irhscomp)) THEN
293 ifirstnottouched=i
294 EXIT
295 ENDIF
296 ENDDO
297 IF (lscal) THEN
298
299
300
301
302 DO k = 1, nrhs_col
303 ishift = (k-1) * lrhs_loc
304 DO i = ifirstnottouched, nbrecords
305 irhscomp = posinrhscomp_fwd(irhs_loc(
306 & irhs_loc_sorted(nextrowtosend(myid_nodes+1)+i-1)))
307 IF (.NOT. touched(irhscomp)) THEN
308 rhscomp(irhscomp,k)=zero
309 ENDIF
310 ENDDO
311 DO i = 1, nbrecords
312 iloc = irhs_loc_sorted(nextrowtosend(myid_nodes+1)+i-1)
313 iglob = irhs_loc(iloc)
314 irhscomp = posinrhscomp_fwd(iglob)
315 rhscomp(irhscomp,k) = rhscomp(irhscomp,k)+
316 & rhs_loc(iloc+ishift)*
317 & scaling_data_dr%SCALING_LOC(iloc)
318 ENDDO
319 ENDDO
320
321 ELSE
322
323
324
325
326 DO k = 1, nrhs_col
327 ishift = (k-1) * lrhs_loc
328 DO i = ifirstnottouched, nbrecords
329 irhscomp = posinrhscomp_fwd(irhs_loc(
330 & irhs_loc_sorted(nextrowtosend(myid_nodes+1)+i-1)))
331 IF (.NOT. touched(irhscomp)) THEN
332 rhscomp(irhscomp,k)=zero
333 ENDIF
334 ENDDO
335 DO i = 1, nbrecords
336 iloc = irhs_loc_sorted(nextrowtosend(myid_nodes+1)+i-1)
337 iglob = irhs_loc(iloc)
338 irhscomp = posinrhscomp_fwd(iglob)
339 rhscomp(irhscomp,k) = rhscomp(irhscomp,k)+
340 & rhs_loc(iloc+ishift)
341 ENDDO
342 ENDDO
343
344 ENDIF
345 DO i = 1, nbrecords
346 irhscomp = posinrhscomp_fwd(irhs_loc(
347 & irhs_loc_sorted(nextrowtosend(myid_nodes+1)+i-1)))
348 IF (.NOT. touched(irhscomp)) THEN
349 nb_fs_touched = nb_fs_touched + 1
350 touched(irhscomp) = .true.
351 ENDIF
352 ENDDO
353 nextrowtosend(myid_nodes+1)=nextrowtosend(myid_nodes+1)+
354 & nbrecords
355 nbrowstosend(myid_nodes+1)=nbrowstosend(myid_nodes+1)-
356 & nbrecords
357 nbrowstorecv = nbrowstorecv - nbrecords
358 RETURN
361 INTEGER, INTENT(OUT) :: IBUF
362 INTEGER :: I
363 ibuf = -1
364 IF (nb_active_sends .NE. max_active_sends) THEN
365 DO i=1, max_active_sends
366 IF (.NOT. is_send_active(i)) THEN
367 ibuf = i
368 EXIT
369 ENDIF
370 ENDDO
371 ENDIF
372 RETURN
375 INTEGER :: MPI_STATUS(MPI_STATUS_SIZE)
376 INTEGER :: I
377 LOGICAL :: FLAG
378 IF (nb_active_sends .GT. 0) THEN
379 DO i=1, max_active_sends
380 IF (is_send_active(i)) THEN
381 CALL mpi_test( mpi_reqr(i), flag, mpi_status, ierr_mpi )
382 IF (flag) THEN
383 CALL mpi_wait(mpi_reqi(i), mpi_status, ierr_mpi)
384 nb_active_sends = nb_active_sends - 1
385 is_send_active(i)=.false.
386 IF (nb_active_sends .EQ. 0) THEN
387 RETURN
388 ENDIF
389 ENDIF
390 ENDIF
391 ENDDO
392 ENDIF
393 RETURN
396 IMPLICIT NONE
397 INTEGER, INTENT(IN) :: IPROC_ARG
398 include 'mumps_tags.h'
399 INTEGER :: NBRECORDS, IBUF, I, K
400 INTEGER(8) :: IPOSRHS
401 INTEGER :: IPOSBUF
402 IF (iproc_arg .EQ. myid_nodes) THEN
403 WRITE(*,*) "Internal error 1 in SMUMPS_DR_TRY_SEND"
405 ENDIF
406 IF (nbrowstosend(iproc_arg+1) .EQ. 0) THEN
407 WRITE(*,*) "Internal error 2 in SMUMPS_DR_TRY_SEND"
409 ENDIF
411 IF (ibuf .GT. 0) THEN
412 nbrecords =
min(maxrecords,nbrowstosend(iproc_arg+1))
413
414
415
416
417
418
419 IF (lscal) THEN
420
421
422 DO k=1, nrhs_col
423 DO i = 1, nbrecords
424 iposbuf = (k-1)*nbrecords
425 iposrhs = int(k-1,8)*int(lrhs_loc,8)
426 iloc = irhs_loc_sorted(nextrowtosend(iproc_arg+1)+i-1)
427 bufr( iposbuf + i, ibuf )
428 & = rhs_loc( iposrhs + iloc ) *
429 & scaling_data_dr%SCALING_LOC(iloc)
430 ENDDO
431 ENDDO
432
433 ELSE
434
435
436 DO k=1, nrhs_col
437 DO i = 1, nbrecords
438 iposbuf = (k-1)*nbrecords
439 iposrhs = int(k-1,8)*int(lrhs_loc,8)
440 iloc = irhs_loc_sorted(nextrowtosend(iproc_arg+1)+i-1)
441 bufr( iposbuf + i, ibuf )
442 & = rhs_loc( iposrhs + iloc )
443 ENDDO
444 ENDDO
445
446 ENDIF
447 DO i = 1, nbrecords
448 iloc = irhs_loc_sorted(nextrowtosend(iproc_arg+1)+i-1)
449 irhs_loc_sorted(nextrowtosend(iproc_arg+1)+i-1)
450 & = irhs_loc(iloc)
451 ENDDO
452 CALL mpi_isend( irhs_loc_sorted(nextrowtosend(iproc_arg+1)),
453 & nbrecords, mpi_integer, iproc_arg, distrhsi,
454 & comm_nodes, mpi_reqi(ibuf), ierr_mpi )
455 CALL mpi_isend( bufr(1,ibuf), nbrecords*nrhs_col,
456 & mpi_real,
457 & iproc_arg, distrhsr,
458 & comm_nodes, mpi_reqr(ibuf), ierr_mpi )
459 nextrowtosend(iproc_arg+1)=nextrowtosend(iproc_arg+1)+
460 & nbrecords
461 nbrowstosend(iproc_arg+1)=nbrowstosend(iproc_arg+1)-nbrecords
462 nb_active_sends = nb_active_sends + 1
463 is_send_active(ibuf)=.true.
464 ENDIF
465 RETURN
468 INTEGER :: K, IFS
469 IF ( nb_fs_touched .NE. nb_fs_in_rhscomp ) THEN
470
471
472
473 DO k = 1, nrhs_col
474 DO ifs = 1, nb_fs_in_rhscomp
475 IF ( .NOT. touched(ifs) ) THEN
476 rhscomp( ifs, k) = zero
477 ENDIF
478 ENDDO
479 DO ifs = nb_fs_in_rhscomp +1, ld_rhscomp
480 rhscomp(ifs, k) = zero
481 ENDDO
482 ENDDO
483
484 ELSE
485
486
487
488
489
490
491
492
493
494 DO k = 1, nrhs_col
495 DO ifs = nb_fs_in_rhscomp +1, ld_rhscomp
496 rhscomp(ifs, k) = zero
497 ENDDO
498 ENDDO
499
500 ENDIF
501 RETURN
subroutine mpi_allreduce(sendbuf, recvbuf, cnt, datatype, operation, comm, ierr)
subroutine smumps_dr_try_free_send()
subroutine smumps_dr_empty_rows()
subroutine smumps_dr_try_recv()
subroutine smumps_dr_assemble_local()
subroutine smumps_dr_try_send(iproc_arg)
subroutine smumps_dr_build_nbrowstorecv()