15 & ( job, thresh, ndense,
16 & n, iwlen, pe, pfree, len, iw, nv,
17 & elen, last, ncmpa, degree, head, next, w,
18 & perm, complem_list, size_complem_list,
21 INTEGER,
INTENT(IN) :: N, SIZE_COMPLEM_LIST
22 INTEGER(8),
INTENT(IN) :: IWLEN
23 INTEGER,
INTENT(IN) :: THRESH
24 LOGICAL,
INTENT(IN) :: AGG6
25 INTEGER,
INTENT (IN) :: COMPLEM_LIST(max(1,SIZE_COMPLEM_LIST))
26 INTEGER,
INTENT(INOUT) :: JOB
27 INTEGER,
INTENT(INOUT) :: LEN(N), IW(IWLEN)
28 INTEGER(8),
INTENT(INOUT) :: PFREE
29 INTEGER(8),
INTENT(INOUT) :: PE(N)
30 INTEGER,
INTENT(INOUT) :: PERM(N)
31 INTEGER,
INTENT(OUT) :: NCMPA
32 INTEGER,
INTENT(OUT) :: NV(N), LAST(N)
33 INTEGER,
INTENT(INOUT) :: ELEN(N)
34 INTEGER,
INTENT(OUT) :: NDENSE(N), DEGREE(N),
35 & HEAD(N), NEXT(N), W(N)
36 INTEGER THRESM, NDME, PERMeqN
37 INTEGER NBD,NBED, NBDM, LASTD, NELME
39 INTEGER :: FDEG, ThresMin, ThresPrev, IBEGSchur,
44 INTEGER :: DEG, DEGME, DEXT, DMAX, E, ELENME, ELN, I,
45 & ILAST, INEXT, J, JLAST, JNEXT, K, KNT1, KNT2, KNT3,
46 & LENJ, LN, ME, MINDEG, NEL,
47 & NLEFT, NVI, NVJ, NVPIV, SLENME, WE, WFLG, WNVI, X
48 INTEGER KNT1_UPDATED, KNT2_UPDATED
49 INTEGER(8) MAXMEM, MEM, NEWMEM
51 INTEGER(8) :: HASH, HMOD
52 INTEGER(8) :: P, P1, P2, P3, PDST, PEND, PJ, PME, PME1, PME2,
54 INTRINSIC max,
min, mod
63 thd_agg = max(128,
min(n/2048, 1024))
64 IF ( size_complem_list < 0 .OR. size_complem_list > n )
THEN
65 WRITE(*,*)
"Internal MUMPS_SYMQAMD_NEW", size_complem_list,n
73 schuron = (size_complem_list > 0)
74 IF ((job.EQ.1) .AND. (.NOT.schuron) .AND. (n .GT. 0))
THEN
76 ibegschur = n-size_complem_list+1
77 IF (thresm.GT.n) thresm = n
78 IF (thresm.LT.0) thresm = 0
81 IF ( perm(i) .GE. ibegschur)
THEN
83 IF (len(i) .EQ.0)
THEN
95 thresm = max(int(31*n/32),thresm)
96 thresm = max(thresm,1)
97 thresmin = max( 3*thresm / 4, 1)
100 thresmininit = thresmin/4
101 IF (thresm.GT.0)
THEN
102 IF ((thresm.GT.n).OR.(thresm.LT.2))
THEN
115 maxint_n=huge(wflg)-n
118 hmod = int(max(1, n-1),kind=8)
131 DO i = 1,size_complem_list
135 dmax = max(dmax, len(x))
137 nel = nel + size_complem_list
148 IF (elen(i).LT.0) cycle
150 IF (perm(i).EQ.n)
THEN
155 IF ( (deg .GT. 0).OR.(perm(i).EQ.n+1) )
THEN
156 IF ( (thresm.GT.0) .AND.
157 & (fdeg .GT.thresm) )
THEN
159 IF (fdeg.NE.n+1)
THEN
160 degree(i) = degree(i)+n+2
163 IF (inext .NE. 0) last(inext) = i
167 IF (lastd.EQ.0) lastd=i
186 IF (inext .NE. 0) last(inext) = i
197 IF ((nbd.EQ.0).AND.(thresm.GT.0)) thresm = n
198 30
IF (nel .LT. n)
THEN
199 DO 40 deg = mindeg, n
201 IF (me .GT. 0)
GO TO 50
204 IF ( (deg.NE.n) .AND.
205 & (deg.GT.thresm+1) .AND. (nbd.GT.0) )
THEN
209 IF (degree(me).LE.n)
THEN
211 IF (inext .NE. 0) last(inext) = 0
216 IF (degree(me).GT.n+1)
THEN
217 IF (wflg .GT. maxint_n)
THEN
219 IF (w(x) .NE. 0) w(x) = 1
226 IF (inext .NE. 0)
THEN
234 p2 = p1 + int(len(me) -1,8)
239 IF (w(e).EQ.wflg)
GOTO 55
241 IF (pe(e).LT.0_8)
THEN
244 IF (w(x) .EQ.wflg)
GOTO 55
246 IF ( pe(x) .LT. 0 )
GOTO 53
249 IF (elen(e).LT.0)
THEN
250 ndense(e) = ndense(e) - nv(me)
256 DO 54 pme = pme1, pme1+len(e)-1
258 IF ((elen(x).GE.0).AND.(w(x).NE.wflg))
THEN
259 ndense(me) = ndense(me) + nv(x)
264 ndense(me) = ndense(me) + nv(e)
270 len(me) = int(pln-p1)
271 elen(me) = int(peln-p1)
272 ndme = ndense(me)+nv(me)
273 IF (ndense(me).EQ.0) ndense(me) =1
274 degree(me) = ndense(me)
276 mindeg =
min(deg,mindeg)
278 IF (jnext.NE. 0) last(jnext) = me
283 IF (degree(me).GT.(n+1) )
GOTO 51
286 IF (thresm.LT.n)
THEN
287 thresmin = max(thresm+thresmin,thresprev+thresmin/2+1)
288 thresmin =
min(thresmin, n)
289 thresprev = thresprev+(n-thresprev)/2+thresmininit
291 & thresm + int(sqrt(dble(thresmin)))+ thresmininit ,
293 thresm =
min(thresm,n)
294 thresmin =
min(thresm, thresmin)
300 IF (degree(me).EQ.n+1)
THEN
301 IF (nbd.NE.nbed)
THEN
302 write(6,*)
' ERROR in MUMPS_SYMQAMD_NEW ',
303 &
' quasi dense rows remains'
307 DO i = 1,size_complem_list
309 elen(x) = -(n-size_complem_list+i)
317 IF ((pe(x).GT.0_8) .AND. (elen(x).LT.0))
THEN
318 pe(x) = int(-complem_list(1),8)
319 ELSEIF (degree(x).EQ.n+1)
THEN
330 write(6,*)
'Internal ERROR 2 detected in QAMD'
331 write(6,*)
' NEL not equal to N: N, NEL =',n,nel
334 IF (me.NE. complem_list(1))
THEN
335 DO i=1, size_complem_list
336 pe(complem_list(i)) = int(-complem_list(1),8)
338 pe(complem_list(1)) = 0_8
339 nv( complem_list(1))= nv(me)
341 elen( complem_list(1)) = elen(me)
348 elen(me) = - (nel + 1)
354 IF (elenme .EQ. 0)
THEN
357 DO 60 p = pme1, pme1 + int(len(me) - 1,8)
365 IF (degree(i).LE.n)
THEN
368 IF (inext .NE. 0) last(inext) = ilast
369 IF (ilast .NE. 0)
THEN
372 head(perm(i)) = inext
375 ndense(me) = ndense(me) + nvi
383 slenme = len(me) - elenme
385 DO 120 knt1 = 1, elenme + 1
386 knt1_updated = knt1_updated +1
387 IF (knt1 .GT. elenme)
THEN
399 knt2_updated = knt2_updated+1
404 IF (pfree .GT. iwlen)
THEN
406 len(me) = len(me) - knt1_updated
408 IF (len(me) .EQ. 0) pe(me) = 0_8
410 len(e) = ln - knt2_updated
412 IF (len(e) .EQ. 0) pe(e) = 0_8
417 pe(j) = int(iw(pn),8)
425 IF (psrc .LE. pend)
THEN
429 iw(pdst) = int(pe(j))
433 DO 90 knt3 = 0, lenj - 2
434 iw(pdst + knt3) = iw(psrc + knt3)
436 pdst = pdst + int(lenj - 1,8)
437 psrc = psrc + int(lenj - 1,8)
442 DO 100 psrc = pme1, pfree - 1
455 IF (degree(i).LE.n)
THEN
458 IF (inext .NE. 0) last(inext) = ilast
459 IF (ilast .NE. 0)
THEN
462 head(perm(i)) = inext
465 ndense(me) = ndense(me) + nvi
475 newmem = pfree - pme1
477 maxmem = max(maxmem, mem)
481 len(me) = int(pme2 - pme1 + 1_8)
482 IF (wflg .GT. maxint_n)
THEN
484 IF (w(x) .NE. 0) w(x) = 1
488 DO 150 pme = pme1, pme2
490 IF (degree(i).GT.n)
GOTO 150
495 DO 140 p = pe(i), pe(i) + int(eln - 1,8)
498 IF (we .GE. wflg)
THEN
500 ELSE IF (we .NE. 0)
THEN
501 we = degree(e) + wnvi - ndense(e)
507 agg6_loc = (agg6 .OR. (degree(me) .LT. thd_agg))
508 DO 180 pme = pme1, pme2
510 IF (degree(i).GT.n)
GOTO 180
512 p2 = p1 + elen(i) - 1
519 IF (dext .GT. 0)
THEN
523 hash = hash + int(e,kind=8)
524 ELSE IF (.NOT. agg6_loc .AND. dext .EQ. 0)
THEN
527 hash = hash + int(e,kind=8)
528 ELSE IF (agg6_loc .AND. (dext .EQ. 0) .AND.
529 & ((ndense(me).EQ.nbd).OR.(ndense(e).EQ.0)))
THEN
532 ELSE IF (agg6_loc .AND. dext.EQ.0)
THEN
535 hash = hash + int(e,kind=8)
538 elen(i) = int(pn - p1 + 1_8)
540 DO 170 p = p2 + 1, p1 + len(i) - 1
544 IF (degree(j).LE.n) deg=deg+nvj
547 hash = hash + int(j,kind=8)
550 IF (((elen(i).EQ.1).AND.(p3.EQ.pn))
552 & (agg6_loc.AND.(deg .EQ. 0).AND.(ndense(me).EQ.nbd))
563 degree(i) =
min(deg+nbd-ndense(me),
568 len(i) = int(pn - p1 + 1)
569 hash = mod(hash, hmod) + 1_8
578 last(i) = int(hash,kind=kind(last))
582 dmax = max(dmax, degme)
584 IF (wflg .GT. maxint_n)
THEN
586 IF (w(x) .NE. 0) w(x) = 1
590 DO 250 pme = pme1, pme2
592 IF ( (nv(i).LT.0) .AND. (degree(i).LE.n) )
THEN
593 hash = int(last(i),kind=8)
595 IF (j .EQ. 0)
GO TO 250
603 IF (i .EQ. 0)
GO TO 250
605 IF (next(i) .NE. 0)
THEN
609 DO 210 p = pe(i) + 1, pe(i) + int(ln - 1,8)
616 IF (len(j) .NE. ln)
GO TO 240
617 IF (elen(j) .NE. eln)
GO TO 240
618 DO 230 p = pe(j) + 1, pe(j) + int(ln - 1,8)
619 IF (w(iw(p)) .NE. wflg)
GO TO 240
621 IF (perm(j).GT.perm(x))
THEN
623 nv(x) = nv(x) + nv(j)
628 nv(j) = nv(x) + nv(j)
643 IF (i .NE. 0)
GO TO 200
647 IF ( (thresm .GT. 0).AND.(thresm.LT.n) )
THEN
648 thresm = max(thresmin, thresm-nvpiv)
652 DO 260 pme = pme1, pme2
657 IF (degree(i).LE.n)
THEN
658 deg =
min(degree(i)+ degme - nvi, nleft - nvi)
661 IF (thresm.GT.0)
THEN
662 IF (perm(i) .GT. thresm)
THEN
664 degree(i) = degree(i)+n+2
668 p2 = p1 + int(elen(i) - 1, 8)
672 ndense(e) = ndense(e) + nvi
679 IF (inext .NE. 0) last(inext) = i
683 IF (lastd.EQ.0) lastd=i
686 IF (.NOT.idense)
THEN
689 IF (inext .NE. 0) last(inext) = i
694 mindeg =
min(mindeg, fdeg)
700 nv(me) = nvpiv + degme
701 len(me) = int(p - pme1)
702 IF (len(me) .EQ. 0)
THEN
706 IF (newmem .NE. 0)
THEN
708 mem = mem - newmem + int(len(me),8)
714 IF (elen(i) .EQ. 0)
THEN
717 IF (elen(j) .GE. 0)
THEN
725 IF (elen(j) .GE. 0)
THEN
728 IF (elen(j) .EQ. 0)
THEN
743 IF (.NOT.schuron)
THEN
744 IF (permeqn.GT.0) perm(permeqn) = n
750 & ( n, ipe, iw, liw8,
751 & perm, sizeofblocks,
752 & keep60, listvar_schur, size_schur, keep378,
754 & porder, iwtmp1, iwtmp2, iwtmp3, iwtmp4,
758 INTEGER,
INTENT(IN) :: N
759 INTEGER(8),
INTENT(IN) :: LIW8
760 INTEGER(8),
INTENT(IN) :: IPE(N+1)
761 INTEGER,
INTENT(IN) :: SizeOfBlocks(N)
762 INTEGER,
INTENT(INOUT) :: PERM(N)
763 INTEGER,
INTENT(IN) :: IW(LIW8)
764 INTEGER,
INTENT(OUT) :: COLCOUNT(N)
765 INTEGER,
INTENT(OUT) :: PARENT(N)
766 INTEGER,
INTENT(IN) :: KEEP60, SIZE_SCHUR
767 INTEGER,
INTENT(IN) :: LISTVAR_SCHUR(SIZE_SCHUR)
768 INTEGER,
INTENT(IN) :: KEEP378
769 INTEGER,
INTENT(INOUT) :: INFO(2)
770 INTEGER,
INTENT(OUT):: PORDER(N), IWTMP1(N), IWTMP2(N)
771 INTEGER,
INTENT(OUT):: IWTMP3(N), IWTMP4(N), IWTMP5(N)
772 INTEGER :: I, KEEP378_loc
773 LOGICAL :: SizeOfBlocks_provided
774 sizeofblocks_provided = (sizeofblocks(1).NE.-1)
775 IF (keep378.NE.0) keep378_loc=1
780 & n, ipe, iw, liw8, iwtmp1, perm, parent,
782 IF (info(1).LT.0)
RETURN
784 & iwtmp1, iwtmp2, iwtmp3,
786 IF (info(1).LT.0)
RETURN
788 & n, liw8, ipe, iw, parent, porder, colcount,
789 & sizeofblocks_provided, sizeofblocks, keep378_loc,
790 & iwtmp1, iwtmp2, iwtmp3, iwtmp4, iwtmp5,
792 IF (info(1).LT.0)
RETURN
793 IF (keep60.NE.0)
THEN
795 & n, parent, colcount, perm,
796 & listvar_schur, size_schur )
899 & n, ljcn, iptr, jcn, parent, porder, cc,
900 & SizeOfBlocks_provided, SizeOfBlocks, KEEP378,
901 & fst_desc, iporder, prev_p, prev_nbr, setpath,
904 integer,
intent(in) :: n
905 integer(8),
intent(in) :: ljcn
906 integer(8),
intent(in) :: iptr(n+1)
907 integer,
intent(in) :: jcn(ljcn)
908 integer,
intent(inout) :: parent(n), porder(n)
909 integer,
intent(in) :: SizeOfBlocks(n)
910 logical,
intent(in) :: SizeOfBlocks_provided
911 integer,
intent(in) :: KEEP378
912 integer,
intent(out) :: cc(n)
913 integer,
intent(inout):: INFO(2)
914 integer,
intent(out) :: fst_desc(n), iporder(n), prev_p(n)
915 integer,
intent(out) :: prev_nbr(n), setpath(n)
916 integer :: i, curr, fd, j, jidx, k
918 integer :: f, ref, p_leaf, q, jj
920 iporder(porder(j)) = j
927 if(fst_desc(curr) .eq. -1)
then
928 if (sizeofblocks_provided)
then
929 cc(curr) = sizeofblocks(curr)
935 if (fst_desc(curr) .gt. 0)
exit
937 if (parent(curr) .eq. 0)
exit
947 j = abs(porder(jidx))
950 &
write(6,*)
" ========= jidx,j= ", jidx,j,
" is a rootnode "
952 if(parent(j) .ne. 0)
then
953 if (keep378.eq.1)
then
954 if (cc(parent(j)) .lt. 0)
then
955 porder(iporder(parent(j)))= -parent(j)
959 cc(parent(j)) = cc(parent(j)) - sizeofblocks(j)
961 cc(parent(j)) = cc(parent(j))-1
964 do iidx8=iptr(j), iptr(j+1)-1
966 if (iporder(i).le.jidx) cycle
967 if(prev_nbr(i) .eq. 0)
then
970 ref = iporder(prev_nbr(i))
972 if(iporder(fst_desc(j)) .gt. ref)
then
973 if (keep378.eq.1)
then
974 porder(iporder(j))= -j
976 if (sizeofblocks_provided)
then
977 cc(j) = cc(j) + sizeofblocks(i)
982 if (p_leaf .ne. 0)
then
984 if (sizeofblocks_provided)
then
985 cc(q) = cc(q) - sizeofblocks(i)
994 if (parent(j).ne.0) setpath(j)=parent(j)
998 if(parent(j) .ne. 0) cc(parent(j)) = cc(parent(j)) + cc(j)
1000 if (keep378.eq.1)
then
1003 porder(i) = abs(porder(i))
1005 if (parent(porder(i)).ne.0)
then
1006 do while (porder(j) .gt. 0)
1008 if (parent(abs(porder(j-1))).eq.0)
exit
1012 parent(porder(i)) = parent(porder(j-1))
1014 parent(porder(k)) = -porder(i)
1019 porder(n) = abs(porder(n))
1023 if (cc(f).eq.0)
then
1024 parent(i) = parent(f)
1030 if (parent(i).gt.0)
then
1031 parent(i) = -parent(i)
1038 integer :: setpath(:), p_leaf,
setfind
1039 integer :: q, c, tmp
1041 do while (setpath(q) .ne.q)