96 & DBLARR, LDBLARR, INTARR, LINTARR,
97 & PTRAIW, PTRARW, KEEP,KEEP8, MYID, COMM, NBRECORDS,
99 & A, LA, root, PROCNODE_STEPS, SLAVEF, PERM, STEP,
100 & ICNTL, INFO, NSEND8, NLOCAL8,
101 & ISTEP_TO_INIV2, CANDIDATES
107 INTEGER(8) :: NZ_loc8
108 TYPE (SMUMPS_STRUC) :: id
109 INTEGER(8) :: LDBLARR, LINTARR
110 REAL DBLARR( LDBLARR )
111 INTEGER INTARR( LINTARR )
112 INTEGER(8),
INTENT(IN) :: PTRAIW( N ), PTRARW( N )
114 INTEGER(8) KEEP8(150)
118 INTEGER ISTEP_TO_INIV2(KEEP(71))
119 INTEGER CANDIDATES(+1, max(1,KEEP(56)))
121 TYPE (SMUMPS_ROOT_STRUC) :: root
122 INTEGER PROCNODE_STEPS((28)), PERM( N ), STEP( N )
123 INTEGER INFO( 80 ), ICNTL(60)
124 INTEGER MUMPS_PROCNODE, MUMPS_TYPENODE, numroc,
126 EXTERNAL mumps_procnode, mumps_typenode, numroc,
128 include
'mumps_tags.h'
130 INTEGER :: IERR, MSGSOU
131 INTEGER :: STATUS(MPI_STATUS_SIZE)
133 PARAMETER( ZERO = 0.0e0 )
134 INTEGER,
ALLOCATABLE,
DIMENSION(:,:) :: IW4
135 INTEGER END_MSG_2_RECV
137 INTEGER(8) :: I18, IA8
139 INTEGER TYPE_NODE, DEST, DEST_SHR
140 INTEGER IOLD, JOLD, IARR, ISEND,
142 INTEGER allocok, TYPESPLIT, T4MASTER, INIV2, NCAND
143 LOGICAL , EARLYT3ROOTINS
145 INTEGER(8) :: PTR_ROOT
146 INTEGER LOCAL_M, LOCAL_N,
147 INTEGER IROW_GRID, JCOL_GRID, IPOSROOT, JPOSROOT,
150 INTEGER KPROBE, FREQPROBE
151 INTEGER(8) :: IS18, IIW8, IS8, IAS8
153 INTEGER,
ALLOCATABLE,
DIMENSION(:,:,:) :: BUFI
154 REAL,
ALLOCATABLE,
DIMENSION(:,:,:) :: BUFR
155 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: BUFRECI
156 REAL,
ALLOCATABLE,
DIMENSION(:) :: BUFRECR
157 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: IACT, IREQI, IREQR
158 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: SEND_ACTIVE
160 INTEGER(8),
INTENT(OUT) :: NSEND8, NLOCAL8
161 INTEGER MASTER_NODE, ISTEP
162 LOGICAL :: DOIT, OMP_FLAG, OMP_FLAG_P
163 INTEGER NOMP, NOMP_P, IOMP, P2
168 end_msg_2_recv = slavef
169 ALLOCATE( iact(slavef), stat=allocok)
170 IF ( allocok .GT. 0 )
THEN
173 &
'** Error allocating IACT in matrix distribution'
179 ALLOCATE( ireqi(slavef), stat=allocok)
180 IF ( allocok .GT. 0 )
THEN
183 &
'** Error allocating IREQI in matrix distribution'
189 ALLOCATE( ireqr(slavef), stat=allocok)
190 IF ( allocok .GT. 0 )
THEN
193 &
'** Error allocating IREQR in matrix distribution'
199 ALLOCATE( send_active(slavef), stat=allocok)
200 IF ( allocok .GT. 0 )
THEN
203 &
'** Error allocating SEND_ACTIVE in matrix distribution'
209 ALLOCATE( bufi( nbrecords * 2 + 1, 2, slavef ), stat=allocok)
210 IF ( allocok .GT. 0 )
THEN
213 &
'** Error allocating int buffer for matrix distribution'
216 info(2) = ( nbrecords * 2 + 1 ) * slavef * 2
219 ALLOCATE( bufr( nbrecords, 2, slavef), stat = allocok)
220 IF ( allocok .GT. 0 )
THEN
223 &
'** Error allocating real buffer for matrix distribution'
226 info(2) = nbrecords * slavef * 2
229 ALLOCATE( bufreci( nbrecords * 2 + 1 ), stat = allocok )
230 IF ( allocok .GT. 0 )
THEN
233 &
'** Error allocating int recv buffer for matrix distribution'
236 info(2) = nbrecords * 2 + 1
239 ALLOCATE( bufrecr( nbrecords ), stat = allocok )
240 IF ( allocok .GT. 0 )
THEN
243 &
'** Error allocating int recv buffer for matrix distribution'
249 ALLOCATE( iw4( n, 2 ), stat = allocok )
250 IF ( allocok .GT. 0 )
THEN
251 WRITE(lp,*)
'** Error allocating IW4 for matrix distribution'
257 IF ( info(1) .LT. 0 )
GOTO 100
262 IF ( ia8 .GT. 0_8 )
THEN
264 iw4( i, 1 ) = intarr( i18 )
265 iw4( i, 2 ) = -intarr( i18 + 1_8 )
266 intarr( i18 + 2_8 ) = i
269 earlyt3rootins = keep(200) .EQ.0
270 & .OR. ( keep(200) .LT. 0 .AND. keep(400) .EQ. 0 )
271 IF ( keep(38) .NE. 0 .AND. earlyt3rootins )
THEN
275 local_m = -19999; local_n = -29999; ptr_root = -99999_8
284 send_active( i ) = .false.
288 freqprobe = max(1,nbrecords/10)
289 IF (slavef .EQ. 1) freqprobe = huge(freqprobe)
292 omp_flag = keep(399).EQ.1 .AND. nomp .GE.2 .AND. slavef.EQ.1
294!$omp& t4master, t4_master_concerned,
309 IF ( nomp_p .GE. 16 )
THEN
312 ELSE IF (nomp_p.GE.8)
THEN
315 ELSE IF (nomp_p.GE.4)
THEN
318 ELSE IF (nomp_p.GE.2)
THEN
326 IF ( iomp .LT. nomp_p )
THEN
328 IF ( slavef .GT. 1 )
THEN
331 IF ( kprobe .eq. freqprobe )
THEN
333 CALL mpi_iprobe( mpi_any_source, arr_int, comm,
334 & flag, status, ierr )
336 msgsou = status( mpi_source )
337 CALL mpi_recv( bufreci(1), nbrecords * 2 + 1,
339 & msgsou, arr_int, comm, status, ierr )
340 CALL mpi_recv( bufrecr(1), nbrecords,
342 & msgsou, arr_real, comm, status, ierr )
344 & bufreci, bufrecr, nbrecords, n, iw4(1,1),
345 & keep,keep8, local_m, local_n, root, ptr_root,
347 & end_msg_2_recv, myid, procnode_steps, slavef,
348 & ptraiw, ptrarw, perm, step,
349 & intarr, lintarr, dblarr, ldblarr
355 iold = id%IRN_loc(k8)
356 jold = id%JCN_loc(k8)
357 IF ( (iold.GT.n).OR.(jold.GT.n).OR.(iold.LT.1)
358 & .OR.(jold.LT.1) )
THEN
362 IF (iold.EQ.jold)
THEN
364 ELSE IF (perm(iold).LT.perm(jold))
THEN
369 doit = ( iomp .EQ. ibits(iarr, p2-1, p2))
374 IF (iold.EQ.jold)
THEN
378 ELSE IF (perm(iold).LT.perm(jold))
THEN
380 IF ( keep(50) .NE. 0 )
THEN
391 istep = abs(step(iarr))
393 & procnode_steps(istep), keep(199) )
394 t4_master_concerned = .false.
397 IF ((keep(52).EQ.7).OR.(keep(52).EQ.8))
THEN
398 val = val * id%ROWSCA(iold)*id%COLSCA(jold)
400 IF ( type_node .eq. 1 )
THEN
402 IF (dest.EQ.myid)
THEN
403 nlocal8 = nlocal8 + 1_8
404 IF (isend.EQ.jsend)
THEN
406 dblarr(ia8) = dblarr(ia8) + val
407 ELSE IF (isend.GE.0)
THEN
409 ishift = intarr(is18) + iw4(iarr,2)
410 intarr(is18+ishift+2) = jsend
411 dblarr(ptrarw(iarr)+ishift) = val
412 iw4(iarr,2) = iw4(iarr,2) - 1
415 intarr(ptraiw(iarr)+ishift+2) = jsend
416 dblarr(ptrarw(iarr)+ishift) = val
417 iw4(iarr,1) = iw4(iarr,1) - 1
418 IF ( iw4(iarr,1) .EQ. 0
419 & .AND. step(iarr) > 0 )
THEN
421 & intarr( ptraiw(iarr) + 3 ),
422 & dblarr( ptrarw(iarr) + 1 ),
423 & intarr( ptraiw(iarr) ), 1,
424 & intarr( ptraiw(iarr) ) )
429 ELSE IF ( type_node .eq. 2 )
THEN
430 IF ( isend .LT. 0 )
THEN
435 iniv2 = istep_to_iniv2(istep)
436 IF ( keep(79) .GT. 0)
THEN
439 IF ( (typesplit.EQ.5).OR.(typesplit.EQ.6))
THEN
440 t4_master_concerned = .true.
441 t4master=candidates(candidates(slavef+1,iniv2)+1,iniv2)
445 arrow_root = arrow_root + 1
446 IF (earlyt3rootins)
THEN
447 IF ( isend < 0 )
THEN
448 iposroot = root%RG2L_ROW(jsend)
449 jposroot = root%RG2L_ROW(iarr )
451 iposroot = root%RG2L_ROW(iarr )
452 jposroot = root%RG2L_ROW(jsend)
454 irow_grid = mod( ( iposroot-1 )/root%MBLOCK, root%NPROW )
455 jcol_grid = mod( ( jposroot-1 )/root%NBLOCK, root%NPCOL )
456 dest = irow_grid * root%NPCOL + jcol_grid
460 IF ( omp_flag_p )
THEN
461 IF ( earlyt3rootins )
THEN
462 ilocroot = root%MBLOCK * ( ( iposroot - 1 ) /
463 & ( root%MBLOCK * root%NPROW ) )
464 & + mod( iposroot - 1, root%MBLOCK ) + 1
465 jlocroot = root%NBLOCK * ( ( jposroot - 1 ) /
466 & ( root%NBLOCK * root%NPCOL ) )
467 & + mod( jposroot - 1, root%NBLOCK ) + 1
468 IF (keep(60)==0)
THEN
469 a( ptr_root + int(jlocroot-1,8) * int(local_m,8)
470 & + int(ilocroot-1,8)) = a( ptr_root
471 & + int(jlocroot - 1,8) * int(local_m,8)
472 & + int(ilocroot - 1,8) )
475 root%SCHUR_POINTER( int(jlocroot-1,8)
476 & * int(root%SCHUR_LLD,8)
477 & + int(ilocroot,8) )
478 & = root%SCHUR_POINTER( int(jlocroot - 1,8)
479 & * int(root%SCHUR_LLD,8)
484 IF (isend.EQ.jsend)
THEN
486 dblarr(ia8) = dblarr(ia8) + val
487 ELSE IF (isend.GE.0)
THEN
489 ishift = intarr(is18) + iw4(iarr,2)
490 iw4(iarr,2) = iw4(iarr,2) - 1
491 iiw8 = is18 + ishift + 2
497 is8 = ptraiw(iarr)+iw4(iarr,1)+2
499 ias8 = ptrarw(iarr)+iw4(iarr,1)
500 iw4(iarr,1) = iw4(iarr,1) - 1
502 IF ( iw4(iarr,1) .EQ. 0
503 & .AND. step(iarr) > 0 )
THEN
505 & intarr( ptraiw(iarr) + 3 ),
506 & dblarr( ptrarw(iarr) + 1 ),
507 & intarr( ptraiw(iarr) ), 1,
508 & intarr( ptraiw(iarr) ) )
515 IF (dest .eq. -1)
THEN
516 nlocal8 = nlocal8 + 1_8
517 nsend8 = nsend8 + int(slavef -1,8)
518 ELSE IF (dest .EQ. -2)
THEN
519 nlocal8 = nlocal8 + 1_8
520 nsend8 = nsend8 + int(slavef -1,8)
522 IF (dest .eq.myid )
THEN
523 nlocal8 = nlocal8 + 1_8
525 nsend8 = nsend8 + 1_8
528 IF ( dest.EQ.-1)
THEN
529 iniv2 = istep_to_iniv2(istep)
530 ncand = candidates(slavef+1,iniv2)
531 IF (keep(79) .GT. 0)
THEN
533 dest=candidates(i,iniv2)
535 IF (i.EQ.ncand+1) cycle
536 dest_shr=dest;isend_shr=isend
537 jsend_shr=jsend;val_shr=val
542 dest=candidates(i,iniv2)
543 dest_shr=dest;isend_shr=isend
544 jsend_shr=jsend;val_shr=val
549 dest_shr=dest;isend_shr=isend
550 jsend_shr=jsend;val_shr=val
552 IF (t4_master_concerned)
THEN
554 dest_shr=dest;isend_shr=isend
555 jsend_shr=jsend;val_shr=val
558 ELSE IF (dest .GE. 0)
THEN
559 dest_shr=dest;isend_shr=isend
560 jsend_shr=jsend;val_shr=val
562 IF (t4_master_concerned)
THEN
564 dest_shr=dest;isend_shr=isend
565 jsend_shr=jsend;val_shr=val
568 ELSE IF (dest .EQ. -2)
THEN
571 dest_shr=dest;isend_shr=isend
572 jsend_shr=jsend;val_shr=val
582 DO WHILE ( end_msg_2_recv .NE. 0 )
583 CALL mpi_recv( bufreci(1), nbrecords * 2 + 1, mpi_integer,
584 & mpi_any_source, arr_int, comm, status, ierr )
585 msgsou = status( mpi_source )
586 CALL mpi_recv( bufrecr(1), nbrecords, mpi_real,
587 & msgsou, arr_real, comm, status, ierr )
589 & bufreci, bufrecr, nbrecords, n, iw4(1,1),
590 & keep,keep8, local_m, local_n, root, ptr_root,
592 & end_msg_2_recv, myid, procnode_steps, slavef,
593 & ptraiw, ptrarw, perm, step,
594 & intarr, lintarr, dblarr, ldblarr
598 IF ( send_active( i ) )
THEN
599 CALL mpi_wait( ireqi( i ), status, ierr )
600 CALL mpi_wait( ireqr( i ), status, ierr )
603 keep(49) = arrow_root
605 IF (
ALLOCATED(iw4))
DEALLOCATE( iw4 )
606 IF (
ALLOCATED(bufi))
DEALLOCATE( bufi )
607 IF (
ALLOCATED(bufr))
DEALLOCATE( bufr )
608 IF (
ALLOCATED(bufreci))
DEALLOCATE( bufreci )
609 IF (
ALLOCATED(bufrecr))
DEALLOCATE( bufrecr )
610 IF (
ALLOCATED(iact))
DEALLOCATE( iact )
611 IF (
ALLOCATED(ireqi))
DEALLOCATE( ireqi )
612 IF (
ALLOCATED(ireqr))
DEALLOCATE( ireqr )
613 IF (
ALLOCATED(send_active))
DEALLOCATE( send_active )
618 INTEGER ISLAVE, IBEG, IEND, NBREC, IREQ
619 INTEGER TAILLE_SEND_I, TAILLE_SEND_R
621 IF ( dest_shr .eq. -3 )
THEN
629 DO islave = ibeg, iend
630 nbrec = bufi(1,iact(islave),islave)
631 IF ( dest_shr .eq. -3 )
THEN
632 bufi(1,iact(islave),islave) = - nbrec
634 IF ( dest_shr .eq. -3 .or. nbrec + 1 > nbrecords )
THEN
635 DO WHILE ( send_active( islave ) )
636 CALL mpi_test( ireqr( islave ), flag, status, ierr )
637 IF ( .NOT. flag )
THEN
638 CALL mpi_iprobe( mpi_any_source, arr_int, comm,
639 & flag, status, ierr )
641 msgsou = status(mpi_source)
642 CALL mpi_recv( bufreci(1), 2*nbrecords+1,
643 & mpi_integer, msgsou, arr_int, comm,
645 CALL mpi_recv( bufrecr(1), nbrecords,
647 & arr_real, comm, status, ierr )
649 & bufreci, bufrecr, nbrecords, n, iw4(1,1),
650 & keep,keep8, local_m, local_n, root, ptr_root,
652 & end_msg_2_recv, myid, procnode_steps, slavef,
653 & ptraiw, ptrarw, perm, step,
654 & intarr, lintarr, dblarr, ldblarr
658 CALL mpi_wait( ireqi( islave ), status, ierr )
659 send_active( islave ) = .false.
662 IF ( islave - 1 .ne. myid )
THEN
663 taille_send_i = nbrec * 2 + 1
664 taille_send_r = nbrec
665 CALL mpi_isend( bufi(1, iact(islave), islave ),
667 & mpi_integer, islave - 1, arr_int, comm,
668 & ireqi( islave ), ierr )
669 CALL mpi_isend( bufr(1, iact(islave), islave ),
671 & mpi_real, islave - 1, arr_real, comm,
672 & ireqr( islave ), ierr )
673 send_active( islave ) = .true.
677 iact( islave ) = 3 - iact( islave )
678 bufi( 1, iact( islave ), islave ) = 0
680 IF ( dest_shr .ne. -3 )
THEN
681 ireq = bufi(1,iact(islave),islave) + 1
682 bufi(1,iact(islave),islave) = ireq
683 bufi(ireq*2,iact(islave),islave) = isend_shr
684 bufi(ireq*2+1,iact(islave),islave) = jsend_shr
685 bufr(ireq,iact(islave),islave ) = val_shr
688 IF ( send_local )
THEN
691 & bufi(1,3-iact(islave),islave),
692 & bufr(1,3-iact(islave),islave),
693 & nbrecords, n, iw4(1,1),
694 & keep,keep8, local_m, local_n, root, ptr_root,
696 & end_msg_2_recv, myid, procnode_steps, slavef,
697 & ptraiw, ptrarw, perm, step,
698 & intarr, lintarr, dblarr, ldblarr
705 & ( bufi, bufr, nbrecords, n, iw4,
706 & keep,keep8, local_m, local_n, root, ptr_root, a, la,
707 & end_msg_2_recv, myid, procnode_steps,
709 & ptraiw, ptrarw, perm, step,
710 & intarr, lintarr, dblarr, ldblarr )
713 TYPE (SMUMPS_ROOT_STRUC) :: root
714 INTEGER NBRECORDS, N, MYID, SLAVEF
715 INTEGER BUFI( NBRECORDS * 2 + 1 )
716 REAL BUFR( NBRECORDS )
719 INTEGER(8) KEEP8(150)
721 INTEGER(8) :: PTRAIW( N ), PTRARW( N )
722 INTEGER :: PERM( N ), STEP( )
723 INTEGER PROCNODE_STEPS( KEEP(28) )
724 INTEGER(8),
INTENT(IN) :: LINTARR, LDBLARR
725 INTEGER INTARR( LINTARR )
726 INTEGER LOCAL_M, LOCAL_N
727 INTEGER(8) :: PTR_ROOT, LA
728 REAL A( LA ), DBLARR( LDBLARR )
729 INTEGER MUMPS_TYPENODE, MUMPS_PROCNODE
730 EXTERNAL mumps_typenode, mumps_procnode
731 INTEGER IREC, NB_REC, NODE_TYPE, IPROC
732 INTEGER IPOSROOT, JPOSROOT, ILOCROOT,
733INTEGER(8) :: IA8, IS18, IIW8, IS8, IAS8
734 INTEGER ISHIFT, IARR, JARR
736 LOGICAL :: EARLYT3ROOTINS
738 earlyt3rootins = keep(200) .EQ.0
739 & .OR. ( keep(200) .LT. 0 .AND. keep(400) .EQ. 0 )
741 IF ( nb_rec .LE. 0 )
THEN
742 end_msg_2_recv = end_msg_2_recv - 1
745 IF ( nb_rec .eq. 0 )
GOTO 100
747 iarr = bufi( irec * 2 )
748 jarr = bufi( irec * 2 + 1 )
750 node_type = mumps_typenode(
751 & procnode_steps(abs(step(abs( iarr )))),
753 IF ( node_type .eq. 3 .AND. earlyt3rootins )
THEN
754 IF ( iarr .GT. 0 )
THEN
755 iposroot = root%RG2L_ROW( iarr )
756 jposroot = root%RG2L_COL( jarr )
758 iposroot = root%RG2L_ROW( jarr )
759 jposroot = root%RG2L_COL( -iarr )
761 ilocroot = root%MBLOCK * ( ( iposroot - 1 ) /
762 & ( root%MBLOCK * root%NPROW ) )
763 & + mod( iposroot - 1, root%MBLOCK ) + 1
764 jlocroot = root%NBLOCK * ( ( jposroot - 1 ) /
765 & ( root%NBLOCK * root%NPCOL ) )
766 & + mod( jposroot - 1, root%NBLOCK ) + 1
767 IF (keep(60)==0)
THEN
768 a( ptr_root + int(jlocroot-1,8) * int(local_m,8)
769 & + int(ilocroot-1,8)) = a( ptr_root
770 & + int(jlocroot - 1,8) * int(local_m,8)
771 & + int(ilocroot - 1,8) )
774 root%SCHUR_POINTER( int(jlocroot-1,8)
775 & * int(root%SCHUR_LLD,8)
776 & + int(ilocroot,8) )
777 & = root%SCHUR_POINTER( int(jlocroot - 1,8)
778 & * int(root%SCHUR_LLD,8)
782 ELSE IF (iarr.GE.0)
THEN
783 IF (iarr.EQ.jarr)
THEN
785 dblarr(ia8) = dblarr(ia8) + val
788 ishift = intarr(is18) + iw4(iarr,2)
789 iw4(iarr,2) = iw4(iarr,2) - 1
790 iiw8 = is18 + ishift + 2
798 is8 = ptraiw(iarr)+iw4(iarr,1)+2
800 ias8 = ptrarw(iarr)+iw4(iarr,1)
801 iw4(iarr,1) = iw4(iarr,1) - 1
803 IF ( iw4(iarr,1) .EQ. 0
804 & .AND. step(iarr) > 0 )
THEN
805 iproc = mumps_procnode( procnode_steps(step(iarr)),
807 IF ( iproc .EQ. myid )
THEN
808 taille = intarr( ptraiw(iarr) )
810 & intarr( ptraiw(iarr) + 3 ),
811 & dblarr( ptrarw(iarr) + 1 ),
812 & taille, 1, taille )