17 & IELPTR_LOC8, RELPTR_LOC8,
18 & ELTVAR_LOC, ELTVAL_LOC,
20 & KEEP,KEEP8, MAXELT_SIZE,
21 & FRTPTR, FRTELT, A, LA, FILS,
27 INTEGER COMM, MYID, SLAVEF, MAXELT_SIZE, MSGLEN
28 INTEGER(8),
intent(IN) :: LA
30 INTEGER FRTELT( NELT ), FILS ( N )
33 INTEGER(8),
INTENT(IN) :: IELPTR_LOC8( NELT + 1 )
34 INTEGER(8),
INTENT(INOUT) :: RELPTR_LOC8( NELT + 1 )
35 INTEGER(8),
INTENT(IN) :: LINTARR, LDBLARR
36 INTEGER ELTVAR_LOC( LINTARR )
37 COMPLEX(kind=8) ELTVAL_LOC( LDBLARR )
38 COMPLEX(kind=8) A( LA )
39 TYPE(zmumps_struc) :: id
40 TYPE(zmumps_root_struc) :: root
44 include
'mumps_tags.h'
46 INTEGER :: STATUS(MPI_STATUS_SIZE)
49 INTEGER I, DEST, MAXELT_REAL_SIZE
50INTEGER NBRECORDS, NBUF
51 INTEGER(8) :: RECV_IELTPTR8
52 INTEGER(8) :: RECV_RELTPTR8
54 INTEGER(8) :: IELTPTR8, RELTPTR8
55 LOGICAL FINI, PROKG, I_AM_SLAVE, EARLYT3ROOTINS
56 INTEGER(8) :: PTR_ROOT
57 INTEGER LOCAL_M, LOCAL_N, LP, IBEG, IGLOB, JGLOB
59 INTEGER IELT, , NB_REC, IREC
60 INTEGER(8) :: K8, IVALPTR8
61 INTEGER ILOCROOT, JLOCROOT, IPOSROOT, JPOSROOT, IPTR
62 INTEGER JCOL_GRID, IROW_GRID
65 parameter( master = 0 )
68 parameter( zero = (0.0d0,0.0d0) )
69 INTEGER,
DIMENSION( :, : ),
ALLOCATABLE :: BUFI
70 COMPLEX(kind=8),
DIMENSION( :, : ),
ALLOCATABLE :: BUFR
71 COMPLEX(kind=8),
DIMENSION( : ),
ALLOCATABLE :: TEMP_ELT_R
72 INTEGER,
DIMENSION( : ),
ALLOCATABLE :: TEMP_ELT_I
73 INTEGER(8),
DIMENSION( : ),
ALLOCATABLE :: ELROOTPOS8
74 INTEGER,
DIMENSION( : ),
ALLOCATABLE,
TARGET :: RG2LALLOC
75 INTEGER,
DIMENSION( : ),
POINTER :: RG2L
78 i_am_slave = ( keep(46) .eq. 1 .or. myid .ne.master )
79 prokg = ( mpg > 0 .and. myid .eq. master )
80 prokg = (prokg.AND.(id%ICNTL(4).GE.2))
83 earlyt3rootins = keep(200) .EQ.0
84 & .OR. ( keep(200) .LT. 0 .AND. keep(400) .EQ. 0 )
85 IF ( myid .eq. master )
THEN
86 IF ( keep(46) .eq. 0 )
THEN
92 IF (na_elt8 < int(nbrecords,8))
THEN
93 nbrecords = int(na_elt8)
95 IF ( keep(50) .eq. 0 )
THEN
96 maxelt_real_size = maxelt_size * maxelt_size
98 maxelt_real_size = maxelt_size * (maxelt_size+1)/2
100 IF ( maxelt_real_size .GT. keep(39) )
THEN
101 nbrecords = maxelt_real_size
102 IF ( mpg .GT. 0 )
THEN
104 &
' ** Warning : For element distrib NBRECORDS set to ',
105 & maxelt_real_size,
' because one element is large'
108 ALLOCATE( bufi( 2*nbrecords+1, nbuf ), stat=allocok )
109 IF ( allocok .gt. 0 )
THEN
111 id%INFO(2) = 2*nbrecords + 1
114 ALLOCATE( bufr( nbrecords+1, nbuf ), stat=allocok )
115 IF ( allocok .gt. 0 )
THEN
117 id%INFO(2) = nbrecords + 1
120 IF ( keep(52) .ne. 0 )
THEN
121 ALLOCATE( temp_elt_r( maxelt_real_size ), stat =allocok )
122 IF ( allocok .gt. 0 )
THEN
124 id%INFO(2) = maxelt_real_size
128 ALLOCATE( temp_elt_i( maxelt_size ), stat=allocok )
129 IF ( allocok .gt. 0 )
THEN
131 id%INFO(2) = maxelt_size
134 IF ( keep(38) .ne. 0 )
THEN
135 nbelroot = frtptr(keep(38)+1)-frtptr(keep(38))
136 IF ( earlyt3rootins )
THEN
137 ALLOCATE( elrootpos8(
max(nbelroot,1) ),
139 IF ( allocok .gt. 0 )
THEN
141 id%INFO(2) = nbelroot
145 IF (keep(46) .eq. 0 )
THEN
146 ALLOCATE( rg2lalloc( n ), stat = allocok )
147 IF ( allocok .gt. 0 )
THEN
154 DO WHILE ( inode .GT. 0 )
155 rg2lalloc( inode ) = i
156 inode = fils( inode )
161 rg2l => root%RG2L_ROW
171 IF ( id%INFO(1) .LT. 0 )
RETURN
172 CALL mpi_bcast( nbrecords, 1, mpi_integer, master,
176 IF ( myid .eq. master )
THEN
181 ieltptr8 = int(id%ELTPTR( iel ),8)
182 sizei = int(int(id%ELTPTR( iel + 1 ),8) - ieltptr8)
183 IF ( keep( 50 ) .eq. 0 )
THEN
184 sizer = sizei * sizei
186 sizer = sizei * ( sizei + 1 ) / 2
188 dest = id%ELTPROC( iel )
189 IF ( dest .eq. -2 )
THEN
190 nbelroot = nbelroot + 1
191 frtelt( frtptr(keep(38)) + nbelroot - 1 ) = iel
192 elrootpos8( nbelroot ) = reltptr8
195 IF ( dest .ge. 0 .and. keep(46) .eq. 0 ) dest = dest + 1
196 IF ( keep(52) .ne. 0 )
THEN
198 & id%ELTVAR( ieltptr8 ), id%A_ELT( reltptr8 ),
199 & temp_elt_r(1), maxelt_real_size,
200 & id%ROWSCA(1), id%COLSCA(1), keep(50) )
202 IF ( dest .eq. 0 .or. ( dest .eq. -1 .and. keep(46) .ne. 0 ) )
204 eltvar_loc( recv_ieltptr8: recv_ieltptr8 + sizei - 1 )
205 & = id%ELTVAR( ieltptr8: ieltptr8 + sizei - 1 )
206 recv_ieltptr8 = recv_ieltptr8 + sizei
207 IF ( keep(52) .ne. 0 )
THEN
208 eltval_loc( recv_reltptr8: recv_reltptr8 + sizer - 1)
209 & = temp_elt_r( 1: sizer )
210 recv_reltptr8 = recv_reltptr8 + sizer
213 IF ( dest .NE. 0 .AND. dest. ne. -3 )
THEN
214 IF ( keep(52) .eq. 0 )
THEN
216 & id%ELTVAR(ieltptr8),
217 & id%A_ELT (reltptr8),
220 & dest, nbuf, nbrecords,
224 & id%ELTVAR(ieltptr8),
228 & dest, nbuf, nbrecords,
233 reltptr8 = reltptr8 + sizer
234 IF ( keep(46) .eq. 0 .OR. keep(52) .eq. 0 )
THEN
235 relptr_loc8( iel + 1 ) = reltptr8
237 relptr_loc8( iel + 1 ) = recv_reltptr8
240 IF ( keep(46) .eq. 0 .OR. keep(52) .eq. 0 )
THEN
241 keep8(26) = reltptr8 - 1_8
243 keep8(26) = recv_reltptr8 - 1_8
245 IF ( reltptr8 - 1_8 .NE. na_elt8 )
THEN
246 WRITE(*,*)
" ** Internal error in ZMUMPS_ELT_DISTRIB",
247 & reltptr8 - 1_8, na_elt8
256 & id%ELTVAR(ieltptr8),
257 & id%A_ELT (reltptr8),
260 & dest, nbuf, nbrecords,
262 IF ( keep(52) .NE. 0 )
DEALLOCATE( temp_elt_r )
264 fini = ( recv_ieltptr8 .eq. ielptr_loc8( nelt+1 )
265 & .and. recv_reltptr8 .eq. relptr_loc8( nelt+1 ) )
266 DO WHILE ( .not. fini )
268 & comm, status, ierr_mpi )
269 msgtag = status( mpi_tag )
270 SELECT CASE ( msgtag )
274 CALL mpi_recv( eltvar_loc( recv_ieltptr8 ), msglen,
275 & mpi_integer, master, elt_int,
276 & comm, status, ierr_mpi )
277 recv_ieltptr8 = recv_ieltptr8 + msglen
281 CALL mpi_recv( eltval_loc( recv_reltptr8 ), msglen,
282 & mpi_double_complex, master, elt_real,
283 & comm, status, ierr_mpi )
284 recv_reltptr8 = recv_reltptr8 + msglen
286 fini = ( recv_ieltptr8 .eq. ielptr_loc8( nelt+1 )
287 & .and. recv_reltptr8 .eq. relptr_loc8( nelt+1 ) )
290 IF ( keep(38) .NE. 0 .AND. earlyt3rootins )
THEN
291 IF ( i_am_slave .and. root%yes )
THEN
293 & local_m, local_n, ptr_root, la)
296 IF ( myid .NE. master )
THEN
297 ALLOCATE( bufi( nbrecords * 2 + 1, 1 ), stat = allocok )
298 IF ( allocok .GT. 0 )
THEN
300 id%INFO(2) = nbrecords * 2 + 1
303 ALLOCATE( bufr( nbrecords, 1 ) , stat = allocok )
304 IF ( allocok .GT. 0 )
THEN
306 id%INFO(2) = nbrecords
311 IF ( id%INFO(1) .LT. 0 )
RETURN
312 IF ( myid .eq. master )
THEN
313 DO iptr = frtptr(keep(38)), frtptr(keep(38)+1) - 1
314 ielt = frtelt( iptr )
315 sizei = id%ELTPTR( ielt + 1 ) - id%ELTPTR( ielt )
317 temp_elt_i( i ) = rg2l
318 & ( id%ELTVAR( id%ELTPTR(ielt) + i - 1 ) )
320 ivalptr8 = elrootpos8( iptr - frtptr(keep(38)) + 1 ) - 1
323 jglob = id%ELTVAR( id%ELTPTR( ielt ) + j - 1 )
324 IF ( keep(50).eq. 0 )
THEN
330 iglob = id%ELTVAR( id%ELTPTR( ielt ) + i - 1 )
331 IF ( keep(52) .eq. 0 )
THEN
332 val = id%A_ELT( ivalptr8 + k8 )
334 val = id%A_ELT( ivalptr8 + k8 ) *
335 & id%ROWSCA( iglob ) * id%COLSCA( jglob )
337 IF ( keep(50).eq.0 )
THEN
338 iposroot = temp_elt_i( i )
339 jposroot = temp_elt_i( j )
341 IF ( temp_elt_i(i) .GT. temp_elt_i(j) )
THEN
342 iposroot = temp_elt_i(i)
343 jposroot = temp_elt_i(j)
345 iposroot = temp_elt_i(j)
346 jposroot = temp_elt_i(i)
349 irow_grid = mod( ( iposroot - 1 )/root%MBLOCK,
351 jcol_grid = mod( ( jposroot - 1 )/root%NBLOCK,
353 IF ( keep(46) .eq. 0 )
THEN
354 dest = irow_grid * root%NPCOL + jcol_grid + 1
356 dest = irow_grid * root%NPCOL + jcol_grid
358 IF ( dest .eq. master )
THEN
359 ilocroot = root%MBLOCK * ( ( iposroot - 1 ) /
360 & ( root%MBLOCK * root%NPROW ) )
361 & + mod( iposroot - 1, root%MBLOCK ) + 1
362 jlocroot = root%NBLOCK * ( ( jposroot - 1 ) /
363 & ( root%NBLOCK * root%NPCOL ) )
364 & + mod( jposroot - 1, root%NBLOCK ) + 1
365 arrow_root = arrow_root + 1
366 IF (keep(60)==0)
THEN
368 & + int(jlocroot - 1,8) * int(local_m,8)
369 & + int(ilocroot - 1,8) )
371 & + int(jlocroot - 1,8) * int(local_m,8)
372 & + int(ilocroot - 1,8) )
375 root%SCHUR_POINTER( int(jlocroot-1,8)
376 & * int(root%SCHUR_LLD,8)
377 & + int(ilocroot,8) )
378 & = root%SCHUR_POINTER( int(jlocroot-1,8)
379 & * int(root%SCHUR_LLD,8)
380 & + int(ilocroot,8) )
385 & iposroot, jposroot, val, dest, bufi, bufr, nbrecords,
393 & bufi, bufr, nbrecords,
394 & nbuf, lp, comm, keep(46) )
397 DO WHILE ( .not. fini )
398 CALL mpi_recv( bufi(1,1), 2*nbrecords+1,
399 & mpi_integer, master,
401 & comm, status, ierr_mpi )
403 arrow_root = arrow_root + nb_rec
404 IF (nb_rec.LE.0)
THEN
408 IF (nb_rec.EQ.0)
EXIT
409 CALL mpi_recv( bufr(1,1), nbrecords, mpi_double_complex,
411 & comm, status, ierr_mpi )
413 iposroot = bufi( irec * 2, 1 )
414 jposroot = bufi( irec * 2 + 1, 1 )
415 val = bufr( irec, 1 )
416 ilocroot = root%MBLOCK * ( ( iposroot - 1 ) /
417 & ( root%MBLOCK * root%NPROW ) )
418 & + mod( iposroot - 1, root%MBLOCK ) + 1
419 jlocroot = root%NBLOCK * ( ( jposroot - 1 ) /
420 & ( root%NBLOCK * root%NPCOL ) )
421 & + mod( jposroot - 1, root%NBLOCK ) + 1
422 IF (keep(60).eq.0)
THEN
423 a( ptr_root + int(jlocroot-1,8) * int(local_m,8)
424 & + int(ilocroot-1,8))
425 & = a( ptr_root + int(jlocroot-1,8) * int(local_m,8)
429 root%SCHUR_POINTER(int(jlocroot-1,8)
430 & * int(root%SCHUR_LLD,8)
431 & + int(ilocroot,8) )
432 & = root%SCHUR_POINTER( int(jlocroot - 1,8)
433 & * int(root%SCHUR_LLD,8)
443 IF ( myid .eq. master )
THEN
446 IF (
allocated(elrootpos8))
DEALLOCATE(elrootpos8)
447 IF (keep(38).ne.0)
THEN
448 IF (keep(46) .eq. 0 )
THEN
449 DEALLOCATE(rg2lalloc)
452 DEALLOCATE( temp_elt_i )
454 keep(49) = arrow_root