26 INTEGER,
POINTER :: permtab(:) => null()
27 INTEGER,
POINTER :: peritab(:) => null()
28 INTEGER,
POINTER :: rangtab(:) => null()
29 INTEGER,
POINTER :: treetab(:) => null()
30 INTEGER,
POINTER :: brother(:) => null()
31 INTEGER,
POINTER :: son(:) => null()
32 INTEGER,
POINTER :: nw(:) => null()
33 INTEGER,
POINTER :: (:) => null()
34 INTEGER,
POINTER :: last(:) => null()
35 INTEGER,
POINTER :: topnodes(:) => null()
36 INTEGER :: comm, comm_nodes, nprocs, nslaves, myid
37 INTEGER :: topstrat, substrat, ordtool, topvars
43 INTEGER,
POINTER :: irn_loc(:) => null()
44 INTEGER,
POINTER :: jcn_loc(:) => null()
47 INTEGER,
POINTER :: buf(:) => null()
57 TYPE(dmumps_struc) :: id
58 INTEGER,
TARGET :: WORK1(:), WORK2(:)
59 INTEGER :: NFSIZ(:), FILS(:), FRERE(:)
61 INTEGER,
POINTER :: IPE(:), NV(:),
62 & ne(:), na(:), node(:),
63 & nd(:), subord(:), namalg(:),
65 & saveirn(:), savejcn(:)
66 INTEGER :: MYID, , IERR, NEMIN, LDIAG
68 INTEGER(8),
PARAMETER :: K79REF=12000000_8
69 INTEGER,
PARAMETER :: LIDUMMY = 1
71 DOUBLE PRECISION :: TIMEB
72 nullify(ipe, nv, ne, na, node, nd, subord, namalg, ips,
73 & cumul, saveirn, savejcn)
80 prokg = (
mpg.GT.0) .AND. (myid .EQ. 0)
81 lpok = (
lp.GT.0) .AND. (id%ICNTL(4).GE.1)
83 ord%PERMTAB => work1(1 : id%N)
84 ord%PERITAB => work1(id%N+1 : 2*id%N)
85 ord%TREETAB => work1(2*id%N+1 : 3*id%N)
86 IF(id%KEEP(54) .NE. 3)
THEN
92 id%KEEP8(29) = id%KEEP8(28)
100 id%INFOG(7) = id%KEEP(245)
103 IF ( id%INFO(1) .LT. 0 )
RETURN
109 &
'(" ELAPSED time in parallel ordering =",F12.4)'
114 IF ( id%INFO(1) .LT. 0 )
RETURN
115 IF(id%MYID .EQ. 0)
THEN
117 & copy=.false., string=
'',
126 IF(id%KEEP(54) .NE. 3)
THEN
128 id%IRN_loc => saveirn
129 id%JCN_loc => savejcn
134 IF ( id%INFO(1) .LT. 0 )
RETURN
139 IF (myid .EQ. 0)
THEN
141 ne => work1(id%N+1 : 2*id%N)
142 na => work1(2*id%N+1 : 3*id%N)
143 node => work2(1 : id%N )
144 nd => work2(id%N+1 : 2*id%N)
145 subord => work2(2*id%N+1 : 3*id%N)
146 namalg => work2(3*id%N+1 : 4*id%N)
152 & na(1), nfsiz(1), node(1), id%INFOG(6), fils(1), frere(1),
153 & nd(1), nemin, subord(1), id%KEEP(60), id%KEEP(20),
154 & id%KEEP(38), namalg(1), id%KEEP(104), cumul(1),
155 & id%KEEP(50), id%ICNTL(13), id%KEEP(37), id%KEEP(197),
156 & id%NSLAVES, id%KEEP(250).EQ.1, .false., idummy, lidummy)
158 CALL dmumps_ana_m(ne(1), nd(1), id%INFOG(6), id%INFOG(5),
159 & id%KEEP(2), id%KEEP(50), id%KEEP8(101), id%KEEP(108),
160 & id%KEEP(5), id%KEEP(6), id%KEEP(226), id%KEEP(253))
161 IF ( id%KEEP(53) .NE. 0 )
THEN
165 IF ( (id%KEEP(48) == 4 .AND. id%KEEP8(21).GT.0_8)
167 & (id%KEEP (48)==5 .AND. id%KEEP8(21) .GT. 0_8 )
169 & (id%KEEP(24).NE.0.AND.id%KEEP8(21).GT.0_8) )
THEN
171 & id%KEEP(48), id%KEEP(50), id%NSLAVES)
173 IF ((id%KEEP(210).LT.0) .OR. (id%KEEP(210).GT.2))
175 IF ((id%KEEP(210).EQ.0) .AND. (id%KEEP(201).GT.0))
177 IF ((id%KEEP(210).EQ.0) .AND. (id%KEEP(201).EQ.0))
179 IF (id%KEEP(210).EQ.2) id%KEEP8(79)=huge(id%KEEP8(79))
180 IF ((id%KEEP(210).EQ.1) .AND. (id%KEEP8(79).LE.0_8))
THEN
181 id%KEEP8(79)=k79ref * int(id%NSLAVES,8)
183 IF ( (id%KEEP(79).EQ.0).OR.(id%KEEP(79).EQ.2).OR.
184 & (id%KEEP(79).EQ.3).OR.(id%KEEP(79).EQ.5).OR.
187 IF (id%KEEP(210).EQ.1)
THEN
189 IF ( id%KEEP(62).GE.
THEN
192 & nfsiz(1), idummy, lidummy, id%INFOG(6),
193 & id%NSLAVES, id%KEEP(1), id%KEEP8(1), splitroot,
194 &
mp, ldiag, id%INFOG(1), id%INFOG(2))
195 IF (id%INFOG(1).LT.0)
RETURN
199 splitroot = (((id%ICNTL(13).GT.0) .AND.
200 & (id%NSLAVES.GT.id%ICNTL(13))) .OR.
201 & (id%ICNTL(13).EQ.-1)) .AND. (id%KEEP(60).EQ.0)
205 & idummy, lidummy, id%INFOG(6),
206 & id%NSLAVES, id%KEEP(1), id%KEEP8(1),
207 & splitroot,
mp, ldiag, id%INFOG(1), id%INFOG(2))
208 IF (id%INFOG(1).LT.0)
RETURN
217#if defined(parmetis) || defined(parmetis3)
218 INTEGER :: , COLOR, BASE, WORKERS
221 IF(id%MYID .EQ. 0) id%KEEP(245) = id%ICNTL(29)
223 & mpi_integer, 0, id%COMM, ierr )
224 IF ((id%KEEP(245) .LT. 0) .OR. (id%KEEP(245) .GT. 2))
THEN
227 IF (id%KEEP(245) .EQ. 0)
THEN
229 IF(id%NSLAVES .LT. 2)
THEN
230 IF(
prokg)
WRITE(
mpg,
'("Warning: older versions
231 &of PT-SCOTCH require at least 2 processors.")')
237 ord%COMM_NODES = id%COMM_NODES
238 ord%NPROCS = id%NPROCS
239 ord%NSLAVES = id%NSLAVES
241 ord%IDO = (id%MYID .GE. 1) .OR. (id%KEEP(46) .EQ. 1)
244 &
'("Parallel ordering tool set to PT-SCOTCH.")'
247#if defined(parmetis) || defined(parmetis3)
251 workers =
min(id%NSLAVES,id%N/16)
255 IF (i .GT. workers)
EXIT
259 base = id%NPROCS-id%NSLAVES
260 ord%NPROCS = ord%NSLAVES + base
261 ido = (id%MYID .GE. base) .AND.
262 & (id%MYID .LE. base+ord%NSLAVES-1)
267 color = mpi_undefined
270 & ord%COMM_NODES, ierr )
276 &
'("Parallel ordering tool set to ParMETIS.")')
282 IF(id%MYID .EQ.0 )
THEN
284 &
'("No parallel ordering tools available.")')
286 &
'("Please install PT-SCOTCH or ParMETIS.")')
289 ELSE IF (id%KEEP(245) .EQ. 1)
THEN
291 IF(id%NSLAVES .LT. 2)
THEN
292 IF(
prokg)
WRITE(
mpg,
'("Warning: older versions
293 &of PT-SCOTCH require at least 2 processors.")')
299 ord%COMM_NODES = id%COMM_NODES
300 ord%NPROCS = id%NPROCS
301 ord%NSLAVES = id%NSLAVES
303 ord%IDO = (id%MYID .GE. 1) .OR. (id%KEEP(46) .EQ. 1)
305 &
'(" Using PT-SCOTCH for parallel ordering")')
310 IF(id%MYID .EQ.0 )
WRITE(
lp,
311 &
'(" PT-SCOTCH not available")')
314 ELSE IF (id%KEEP(245) .EQ. 2)
THEN
315#if defined(parmetis) || defined(parmetis3)
319 workers =
min(id%NSLAVES,id%N/16)
323 IF (i .GT. workers)
EXIT
327 base = id%NPROCS-id%NSLAVES
328 ord%NPROCS = ord%NSLAVES + base
329 ido = (id%MYID .GE. base) .AND.
330 & (id%MYID .LE. base+ord%NSLAVES-1)
335 color = mpi_undefined
344 &
'(" Using ParMETIS for parallel ordering")')
349 IF(id%MYID .EQ.0 )
WRITE(
lp,
350 &
'(" ParMETIS not available.")')
357 TYPE(dmumps_struc) :: id
360#if defined(parmetis) || defined(parmetis3)
363 IF (ord%ORDTOOL .EQ. 1)
THEN
365 CALL dmumps_ptscotch_ord(id, ord, work)
369 WRITE(
lp,*)
'PT-SCOTCH not available. Aborting...'
372 ELSE IF (ord%ORDTOOL .EQ. 2)
THEN
373#if defined(parmetis) || defined(parmetis3)
374 CALL dmumps_parmetis_ord(id, ord, work)
379 WRITE(
lp,*)
'ParMETIS not available. Aborting...'
385#if defined(parmetis) || defined(parmetis3)
386 SUBROUTINE dmumps_parmetis_ord(id, ord, WORK)
388 TYPE(dmumps_struc) :: id
390 INTEGER,
TARGET :: WORK(:)
391 INTEGER :: I, MYID, NPROCS, IERR, BASE, METIS_IDX_SIZE
392 INTEGER,
POINTER :: FIRST(:),
394 INTEGER :: BASEVAL, VERTLOCNBR,
396 INTEGER(8),
POINTER :: VERTLOCTAB(:)
397 INTEGER,
POINTER :: EDGELOCTAB(:), RCVCNTS(:)
398 INTEGER(8) :: EDGELOCNBR
399 INTEGER,
POINTER :: SIZES(:), ORDER(:)
400 nullify(first, last, swork, vertloctab, edgeloctab, rcvcnts,
405 IF(
size(work) .LT. id%N*3)
THEN
407 &
'("Insufficient workspace inside DMUMPS_PARMETIS_ORD")')
412 base = id%NPROCS-id%NSLAVES
418 CALL dmumps_graph_dist(id, ord, first,
419 & last, base, nprocs, work(1: 2*id%N), type=2)
420 vertlocnbr = last(myid+1)-first(myid+1) + 1
424 swork => work(id%N+1:3*id%N)
425 CALL dmumps_build_dist_graph(id, first, last, vertloctab,
428 edgelocnbr = vertloctab(vertlocnbr+1)-1_8
430 order => work(1:id%N)
435 CALL mumps_metis_idxsize(metis_idx_size)
436 IF (metis_idx_size.EQ.32)
THEN
437 IF (id%KEEP(10).EQ.1)
THEN
441 CALL mumps_parmetis_mixedto32(id, base, vertlocnbr, first,
442 & vertloctab, edgeloctab, baseval, options, order,
443 & sizes, ord%COMM_NODES, ierr)
445 ELSE IF (metis_idx_size.EQ.64)
THEN
446 CALL mumps_parmetis_mixedto64
447 & (id, base, vertlocnbr, first
448 & vertloctab, edgeloctab, baseval, options, order,
449 & sizes, ord%COMM_NODES, ierr)
452 &
"Internal error in PARMETIS wrappers, METIS_IDX_SIZE=",
465 IF ( id%INFO(1) .LT. 0 )
GOTO 20
466 CALL mpi_bcast(sizes(1), 2*ord%NSLAVES, mpi_integer,
467 & base, id%COMM, ierr)
468 ord%CBLKNBR = 2*ord%NSLAVES-1
473 rcvcnts(i) =
max(last(i)-first(i)+1,0)
476 IF(first(1) .LT. 0)
THEN
479 CALL mpi_allgatherv ( order(1), vertlocnbr, mpi_integer,
481 & rcvcnts(1), first(1), mpi_integer, id%COMM, ierr )
483 ord%PERITAB(ord%PERMTAB(i)) = i
488 CALL dmumps_build_treetab(ord%TREETAB, ord%RANGTAB,
489 & sizes, ord%CBLKNBR)
499 CALL dmumps_build_tree(ord)
509 END SUBROUTINE dmumps_parmetis_ord
512 SUBROUTINE dmumps_ptscotch_ord(id, ord, WORK)
515 include
'ptscotchf.h'
516 TYPE(dmumps_struc) :: id
518 INTEGER,
TARGET :: WORK(:)
519 INTEGER :: MYID, NPROCS, IERR
520 INTEGER,
POINTER :: FIRST(:),
522 INTEGER :: BASEVAL, VERTLOCNBR,
523 & base, scotch_int_size
524 INTEGER(8) :: EDGELOCNBR
525 INTEGER(8),
POINTER :: VERTLOCTAB(:)
526 INTEGER,
POINTER :: EDGELOCTAB(:)
527 INTEGER :: PTHREAD_NUMBER, NOMP
528 nullify(first, last, swork, vertloctab, edgeloctab)
529 IF (
size(work) .LT. id%N*3)
THEN
531 &
'("Insufficient workspace inside DMUMPS_PTSCOTCH_ORD")')
537 base = id%NPROCS-id%NSLAVES
544 CALL dmumps_graph_dist(id, ord, first,
545 & last, base, nprocs, work(1: 2*id%N), type=2)
546 vertlocnbr = last(myid+1)-first(myid+1) + 1
550 swork => work(id%N+1:3*id%N)
551 CALL dmumps_build_dist_graph(id, first, last, vertloctab,
553 IF(id%INFO(1).LT.0)
RETURN
554 edgelocnbr = vertloctab(vertlocnbr+1)-1_8
565 CALL mumps_scotch_intsize(scotch_int_size)
568 IF (nomp .GT. 0)
THEN
569 CALL mumps_scotch_get_pthread_number (pthread_number)
570 CALL mumps_scotch_set_pthread_number (nomp)
572 IF(scotch_int_size.EQ.32)
THEN
573 IF (id%KEEP(10).EQ.1)
THEN
577 CALL mumps_ptscotch_mixedto32(id, ord,
579 & vertlocnbr, vertloctab,
580 & edgelocnbr, edgeloctab,
584 CALL mumps_ptscotch_mixedto64(id, ord,
586 & vertlocnbr, vertloctab,
587 & edgelocnbr, edgeloctab,
590 IF (nomp .GT. 0)
THEN
591 CALL mumps_scotch_set_pthread_number (pthread_number)
599 IF ( id%INFO(1) .LT. 0 )
GOTO 11
600 CALL mpi_bcast (ord%CBLKNBR, 1, mpi_integer,
601 & base, id%COMM, ierr)
602 CALL mpi_bcast (ord%PERMTAB(1), id%N, mpi_integer,
603 & base, id%COMM, ierr)
604 CALL mpi_bcast (ord%PERITAB(1), id%N, mpi_integer,
605 & base, id%COMM, ierr)
606 CALL mpi_bcast (ord%RANGTAB(1), id%N+1, mpi_integer,
607 & base, id%COMM, ierr)
608 CALL mpi_bcast (ord%TREETAB(1), id%N, mpi_integer,
609 & base, id%COMM, ierr)
616 CALL dmumps_build_tree(ord)
631 END SUBROUTINE dmumps_ptscotch_ord
634 & ALIST, LIST, PEAKMEM, NNODES, CHECKMEM)
637 INTEGER :: nactive, rproc, anode, peakmem, nnodes
638 INTEGER :: alist(nnodes), list(nnodes)
640 TYPE(dmumps_struc) ::
id
641 LOGICAL,
OPTIONAL :: checkmem
642 INTEGER :: ipeakmem, big, max_nrows, min_nrows
644 INTEGER :: , nz_row, weight
647 IF(
present(checkmem))
THEN
653 IF(nactive .GE. rproc)
THEN
657 IF(nactive .EQ. 0)
THEN
661 IF(.NOT. icheckmem)
RETURN
663 IF(nactive .GT. 1)
THEN
664 max_nrows = ord%NW(alist(nactive-1))
665 min_nrows = ord%NW(alist(1))
671 weight = ord%NW(list(i))
672 IF(weight .GT. max_nrows) max_nrows = weight
673 IF(weight .LT. min_nrows) min_nrows = weight
678 IF(weight .GT. max_nrows) max_nrows = weight
679 IF(weight .LT. min_nrows) min_nrows = weight
680 IF(ord%BROTHER(i) .EQ. -1)
EXIT
683 toprows = ord%TOPNODES(2)+ord%RANGTAB(big+1)-ord%RANGTAB(big)
686 nz4=int(
id%KEEP8(28))
687 nz_row = 2*(nz4/
id%N)
688 IF(
id%KEEP(46) .EQ. 0)
THEN
693 hostmem = hostmem + 2*
toprows*nz_row
694 hostmem = hostmem +
nrl
700 submem = submem +
nrl*(nz_row+2)
701 submem = submem + 6*
nrl
702 ipeakmem =
max(hostmem, submem)
703 IF((ipeakmem .GT. peakmem) .AND.
704 & (peakmem .NE. 0))
THEN
720 IF(ord%SON(node) .EQ. -1)
THEN
726 IF(ord%BROTHER(curr) .NE. -1)
THEN
728 curr = ord%BROTHER(curr)
739 TYPE(dmumps_struc) ::
740 INTEGER,
ALLOCATABLE :: ALIST(:), AWEIGHTS(:), LIST(:), WORK(:)
741 INTEGER :: NNODES, BIG, , ND, NACTIVE, RPROC, ANODE
752 ALLOCATE(alist(nnodes), aweights(nnodes), list(nnodes),
753 & work(0:nnodes+1), stat=allocok)
754 IF(allocok.GT.0)
THEN
756 id%INFO(2)=4*nnodes+2
759 IF (
id%INFO(1) .LT. 0 )
GO TO 90
762 IF (ord%TREETAB(i).EQ.-1)
THEN
764 IF(nactive.LE.nnodes)
THEN
766 aweights(nactive) = ord%NW(i)
770 IF((ord%CBLKNBR .EQ. 1) .OR.
771 & (nactive.GT.nnodes) .OR.
774 ord%TOPNODES(2) = ord%RANGTAB(ord%CBLKNBR+1) - ord%RANGTAB(1)
775 ord%TOPNODES(3) = ord%RANGTAB(1)
776 ord%TOPNODES(4) = ord%RANGTAB(ord%CBLKNBR+1)-1
784 & aweights(1:nactive),
791 IF(nactive .EQ. 0)
EXIT
794 IF((nk .GT. (rproc-nactive+1)) .OR. (nk .EQ. 0))
THEN
802 & rproc, alist, list, peakmem, nnodes, checkmem=.true.)
805 IF(nactive.GT.0)
THEN
806 list(anode+1:anode+nactive) = alist(1:nactive)
807 anode = anode+nactive
811 ord%TOPNODES(1) = ord%TOPNODES(1)+1
812 ord%TOPNODES(2) = ord%TOPNODES(2) +
813 & ord%RANGTAB(big+1) - ord%RANGTAB(big)
814 ord%TOPNODES(2+2*(ord%TOPNODES(1)-1)+1) = ord%RANGTAB(big)
815 ord%TOPNODES(2+2*(ord%TOPNODES(1)-1)+2) =
816 & ord%RANGTAB(big+1)-1
818 alist(nactive) = curr
819 aweights(nactive) = ord%NW(curr)
821 IF(ord%BROTHER(curr) .EQ. -1)
EXIT
823 curr = ord%BROTHER(curr)
824 alist(nactive) = curr
825 aweights(nactive) = ord%NW(curr)
830 & aweights(1:nactive),
834 aweights(i) = ord%NW(list(i))
839 IF (
id%KEEP(46) .EQ. 1)
THEN
849 IF(ord%SON(nd) .NE. -1)
THEN
852 IF((ord%SON(nd) .EQ. -1) .AND.
853 & (ord%BROTHER(nd).EQ.-1))
THEN
855 ELSE IF(ord%BROTHER(nd) .EQ. -1)
THEN
862 ord%FIRST(base+i) = ord%RANGTAB(nd)
863 ord%LAST(base+i) = ord%RANGTAB(curr+1)-1
865 DO i=anode+1,
id%NSLAVES
866 ord%FIRST(base+i) =
id%N+1
867 ord%LAST(base+i) =
id%N
869 DEALLOCATE(list, alist, aweights, work)
875 TYPE(dmumps_struc) :: id
877 INTEGER,
POINTER :: GPE(:), GNV(:)
878 INTEGER,
TARGET :: WORK(:)
880 INTEGER(8),
POINTER :: IPE(:), IPET(:),
881 & buf_pe1(:), buf_pe2(:), tmp1(:)
882 INTEGER,
POINTER :: PE(:),
883 & LENG(:), I_HALO_MAP(:)
884 INTEGER,
POINTER :: NDENSE(:), LAST(:),
885 & DEGREE(:), W(:), PERM(:),
886 & listvar_schur(:), next(:),
887 & head(:), nv(:), elen(:),
889 INTEGER,
POINTER :: MYLIST(:),
892 & nvt(:), buf_nv1(:),
893 & buf_nv2(:), rootperm(:),
894 & tmp2(:), bwork(:), ncliques(:)
895 INTEGER :: MYNCLIQUES, MYMAXVARS, ICLIQUES,
897 INTEGER(8) :: MYNVARS, TOTNVARS
898 INTEGER(8),
POINTER :: LVARPT(:)
899 INTEGER :: HIDX, NCMPA, I, J, SIZE_SCHUR, MYID,
900 & nprocs, ierr, nrows_loc, glob_idx, tmp,
901 & ntvar, tgsize, maxs, rhandpe,
902 & rhandnv, ridx, proc, job, k
903 INTEGER(8) :: PFREES, PFS_SAVE, PELEN, PFREET, PFT_SAVE
904 INTEGER :: STATUSPE(MPI_STATUS_SIZE)
905 INTEGER :: (MPI_STATUS_SIZE)
906 INTEGER :: STATUSCLIQUES(MPI_STATUS_SIZE)
907 INTEGER,
PARAMETER :: ITAG=30
910 nullify(pe, ipe, leng, i_halo_map, ncliques)
911 nullify(ndense, last, degree, w, perm, listvar_schur,
912 & next, head, nv, elen, lstvar)
913 nullify(mylist, lvarpt,
914 & lperm, liperm, ipet, nvt, buf_pe1, buf_pe2,
915 & buf_nv1, buf_nv2, rootperm, tmp1, tmp2, bwork)
918 IF(
size(work) .LT. 4*id%N)
THEN
919 WRITE(
lp,*)
'Insufficient workspace in DMUMPS_PARSYMFACT'
922 head => work( 1 : id%N)
923 elen => work( id%N+1 : 2*id%N)
924 leng => work(2*id%N+1 : 3*id%N)
925 perm => work(3*id%N+1 : 4*id%N)
930 nrows_loc = ord%LAST(myid+1)-ord%FIRST(myid+1)+1
933 bwork => work(1 : 2*id%N)
935 & i_halo_map, top_graph, bwork)
938 IF(id%INFO(1).lt.0)
RETURN
941 tmp = tmp-(ord%LAST(i)-ord%FIRST(i)+1)
943 tmp = ceiling(dble(tmp)*1.10d0)
945 tmp =
max(
max(tmp, hidx),1)
949 size_schur = hidx - nrows_loc
966 listvar_schur(i) = nrows_loc+i
970 pfrees = ipe(nrows_loc+1)
972 pelen = pfrees-1 + 2_8*int(nrows_loc+ord%TOPNODES(2),8)
976 IF(size_schur.EQ.0)
THEN
982 & hidx, pelen, ipe(1), pfrees, leng(1), pe(1), nv(1),
983 & elen(1), last(1), ncmpa, degree(1), head(1), next(1),
984 & w(1), perm(1), listvar_schur(1), size_schur, agg6)
989 IF(ipe(i) .GT. 0)
THEN
990 mymaxvars =
max(mymaxvars,leng(i))
991 mynvars = mynvars+leng(i)
992 myncliques = myncliques+1
995 CALL mpi_reduce(mynvars, totnvars, 1, mpi_integer8,
996 & mpi_sum, 0, id%COMM, ierr)
999 CALL mpi_gather(myncliques, 1, mpi_integer, ncliques(1), 1,
1000 & mpi_integer, 0, id%COMM, ierr)
1001 IF(id%MYID.EQ.0)
THEN
1002 totncliques = sum(ncliques)
1010 IF(ipe(i) .GT. 0)
THEN
1011 icliques = icliques+1
1012 lvarpt(icliques+1) = lvarpt(icliques)+leng(i)
1014 lstvar(lvarpt(icliques)+j) =
1015 & i_halo_map(pe(ipe(i)+j)-nrows_loc)
1020 DO i=1, ncliques(proc+1)
1021 icliques = icliques+1
1022 CALL mpi_recv(k, 1, mpi_integer, proc, itag, id%COMM,
1023 & statuscliques, ierr)
1024 lvarpt(icliques+1) = lvarpt(icliques)+k
1025 CALL mpi_recv(lstvar(lvarpt(icliques)), k, mpi_integer,
1026 & proc, itag, id%COMM, statuscliques, ierr)
1029 lperm => work(3*id%N+1 : 4*id%N)
1030 ntvar = ord%TOPNODES(2)
1033 & top_graph, totncliques, lstvar, lvarpt, ipet, pe,
1035 tgsize = ord%TOPNODES(2)+totncliques
1036 pfreet = ipet(tgsize+1)
1044 IF(ipe(i) .GT. 0)
THEN
1046 mylist(j) = i_halo_map(pe(ipe(i)+j-1)-nrows_loc)
1048 CALL mpi_send(leng(i), 1, mpi_integer, 0, itag,
1050 CALL mpi_send(mylist(1), leng(i), mpi_integer, 0, itag,
1057 IF(myid .EQ. 0)
THEN
1077 listvar_schur(i) = ntvar+i
1083 &
lp, copy=.true., string=
'J2:PERM',
1089 pelen =
max(pfreet+int(tgsize,8),1_8)
1091 & tgsize, pelen, ipet(1), pfreet, leng(1), pe(1),
1092 & nvt(1), elen(1), last(1), ncmpa, degree(1), head(1),
1093 & next(1), w(1), perm(1), listvar_schur(1), totncliques,
1100 IF(myid .EQ. 0)
THEN
1103 IF((ord%LAST(i)-ord%FIRST(i)+1) .GT. maxs)
1104 & maxs = (ord%LAST(i)-ord%FIRST(i)+1)
1124 NULLIFY(buf_pe1, buf_nv1)
1128 CALL mpi_irecv(buf_pe2(1), ord%LAST(proc+2)-
1129 & ord%FIRST(proc+2)+1, mpi_integer8, proc+1, proc+1,
1130 & id%COMM, rhandpe, ierr)
1131 CALL mpi_irecv(buf_nv2(1), ord%LAST(proc+2)-
1132 & ord%FIRST(proc+2)+1, mpi_integer, proc+1, proc+1,
1133 & id%COMM, rhandnv, ierr)
1134 DO i=1, ord%LAST(proc+1)-ord%FIRST(proc+1)+1
1135 glob_idx = ord%PERITAB
1136 IF(buf_pe1(i) .GT. 0)
THEN
1138 rootperm(ridx) = glob_idx
1139 gnv(glob_idx) = buf_nv1(i)
1140 ELSE IF (buf_pe1(i) .EQ. 0)
THEN
1142 gnv(glob_idx) = buf_nv1(i)
1144 gpe(glob_idx) = -ord%PERITAB(-buf_pe1(i)+
1145 & ord%FIRST(proc+1)-1)
1146 gnv(glob_idx) = buf_nv1(i)
1149 CALL mpi_wait(rhandpe, statuspe, ierr)
1150 CALL mpi_wait(rhandnv, statusnv, ierr)
1151 IF(proc .NE. 0)
THEN
1157 NULLIFY(buf_pe2, buf_nv2)
1162 DO i=1, ord%LAST(proc+1)-ord%FIRST(proc+1)+1
1163 glob_idx = ord%PERITAB(i+ord%FIRST(proc+1)-1)
1164 IF(buf_pe1(i) .GT. 0)
THEN
1166 rootperm(ridx) = glob_idx
1167 gnv(glob_idx) = buf_nv1(i)
1168 ELSE IF (buf_pe1(i) .EQ. 0)
THEN
1170 gnv(glob_idx) = buf_nv1(i)
1172 gpe(glob_idx) = -ord%PERITAB(-buf_pe1(i)+
1173 & ord%FIRST(proc+1)-1)
1174 gnv(glob_idx) = buf_nv1(i)
1178 glob_idx = liperm(i)
1179 IF(ipet(i) .EQ. 0)
THEN
1181 gnv(glob_idx) = nvt(i)
1183 gpe(glob_idx) = -liperm(-ipet(i))
1184 gnv(glob_idx) = nvt(i)
1188 glob_idx = rootperm(i)
1189 gpe(glob_idx) = -liperm(-ipet(ntvar+i))
1192 CALL mpi_send(ipe(1), ord%LAST(myid+1)-ord%FIRST(myid+1)+1,
1193 & mpi_integer8, 0, myid, id%COMM, ierr)
1194 CALL mpi_send(nv(1), ord%LAST(myid+1)-ord%FIRST(myid+1)+1,
1195 & mpi_integer, 0, myid, id%COMM, ierr)
1208 NULLIFY(head, elen, leng, perm)
1213 TYPE(dmumps_struc) :: id
1214 INTEGER,
POINTER :: TOPNODES(:), LPERM(:), LIPERM(:)
1216 INTEGER :: I, J, K, GIDX
1224 DO i=topnodes(1), 1, -1
1225 DO j=topnodes(2*i+1), topnodes(2*i+2)
1226 gidx = ord%PERITAB(j)
1235 & top_graph, NCLIQUES, LSTVAR, LVARPT, IPE, PE, LENG, ELEN)
1237 TYPE(dmumps_struc) :: id
1238 TYPE(GRAPH_TYPE) :: top_graph
1239 INTEGER,
POINTER :: LPERM(:), LSTVAR(:),
1240 & pe(:), leng(:), elen(:)
1241 INTEGER(8) :: LVARPT(:)
1243 INTEGER(8),
POINTER :: IPE(:)
1244 INTEGER :: I, IDX, NLOCVARS
1245 INTEGER(8) :: INNZ, PNT, SAVEPNT
1255 DO innz=1, top_graph%NZ_LOC
1256 IF((lperm(top_graph%JCN_LOC(innz)) .NE. 0) .AND.
1257 & (top_graph%JCN_LOC(innz) .NE. top_graph%IRN_LOC(innz)))
1259 leng(lperm(top_graph%IRN_LOC(innz))) =
1260 & leng(lperm(top_graph%IRN_LOC(innz))) + 1
1264 DO innz=lvarpt(i), lvarpt(i+1)-1
1265 elen(lperm(lstvar(innz))) = elen(lperm(lstvar(innz)))+1
1266 leng(nlocvars+i) = leng(nlocvars+i)+1
1270 DO i=1, nlocvars+ncliques
1271 ipe(i+1) = ipe(i)+int(leng(i),8)+int(elen(i),8)
1274 & int(nlocvars,8)+int(ncliques,8),
1280 DO innz=lvarpt(i), lvarpt(i+1)-1
1281 idx = lperm(lstvar(innz))
1282 pe(ipe(idx)+int(elen(idx),8)) = nlocvars+i
1283 pe(ipe(nlocvars+i)+int(leng(nlocvars+i),8)) = idx
1284 elen(lperm(lstvar(innz))) = elen(lperm(lstvar(innz)))+1
1285 leng(nlocvars+i) = leng(nlocvars+i)+1
1288 DO innz=1, top_graph%NZ_LOC
1289 IF((lperm(top_graph%JCN_LOC(innz)) .NE. 0) .AND.
1290 & (top_graph%JCN_LOC(innz) .NE. top_graph%IRN_LOC(innz)))
1292 pe(ipe(lperm(top_graph%IRN_LOC(innz)))+
1293 & elen(lperm(top_graph%IRN_LOC(innz))) +
1294 & leng(lperm(top_graph%IRN_LOC(innz)))) =
1295 & lperm(top_graph%JCN_LOC(innz))
1296 leng(lperm(top_graph%IRN_LOC(innz))) =
1297 & leng(lperm(top_graph%IRN_LOC(innz))) + 1
1300 DO i=1, nlocvars+ncliques
1301 leng(i) = leng(i)+elen(i)
1305 lperm(1:nlocvars+ncliques) = 0
1306 DO i=1, nlocvars+ncliques
1307 DO innz=ipe(i), ipe(i+1)-1
1308 IF(lperm(pe(innz)) .EQ. i)
THEN
1319 ipe(nlocvars+ncliques+1) = savepnt
1322#if defined(parmetis) || defined(parmetis3)
1323 SUBROUTINE dmumps_build_treetab(TREETAB, RANGTAB, SIZES, CBLKNBR)
1324 INTEGER,
POINTER :: TREETAB(:), RANGTAB(:), SIZES(:)
1325 INTEGER :: CBLKNBR,allocok
1326 INTEGER :: LCHILD, RCHILD, K, I
1327 INTEGER,
POINTER :: PERM(:)
1328 ALLOCATE(perm(cblknbr),stat=allocok)
1329 if(allocok.GT.0)
then
1330 write(*,*)
"Allocation error of PERM in DMUMPS_BUILD_TREETAB"
1333 treetab(cblknbr) = -1
1334 IF(cblknbr .EQ. 1)
THEN
1338 rangtab(2)= sizes(1)+1
1341 lchild = cblknbr - (cblknbr+1)/2
1344 perm(cblknbr) = cblknbr
1345 perm(lchild) = cblknbr+1
1346 perm(rchild) = cblknbr+1 - (2*k)
1347 treetab(rchild) = cblknbr
1348 treetab(lchild) = cblknbr
1349 IF(cblknbr .GT. 3)
THEN
1350 CALL rec_treetab(treetab, perm, (cblknbr-1)/2,
1351 & lchild, cblknbr, 2*k+1)
1352 CALL rec_treetab(treetab, perm, (cblknbr-1)/2,
1353 & rchild, cblknbr, 2*k)
1357 rangtab(i+1) = rangtab(i)+sizes(perm(i))
1362 RECURSIVE SUBROUTINE rec_treetab(TREETAB, PERM, SUBNODES,
1363 & ROOTN, CBLKNBR, K)
1364 INTEGER,
POINTER :: TREETAB(:), PERM(:)
1365 INTEGER :: SUBNODES, ROOTN, K, CBLKNBR
1366 INTEGER :: LCHILD, RCHILD
1367 LCHILD = rootn - (subnodes+1)/2
1369 perm(lchild) = cblknbr+1 - (2*k+1)
1370 perm(rchild) = cblknbr+1 - (2*k)
1371 treetab(rchild) = rootn
1372 treetab(lchild) = rootn
1373 IF(subnodes .GT. 3)
THEN
1374 CALL rec_treetab(treetab, perm, (subnodes-1)/2, lchild,
1376 CALL rec_treetab(treetab, perm, (subnodes-1)/2, rchild,
1379 END SUBROUTINE rec_treetab
1380 END SUBROUTINE dmumps_build_treetab
1382#if defined(ptscotch) || defined(parmetis) || defined(parmetis3)
1383 SUBROUTINE dmumps_build_dist_graph(id, FIRST, LAST, IPE,
1386 TYPE(dmumps_struc) :: id
1387 INTEGER(8),
POINTER :: IPE(:)
1388 INTEGER,
POINTER :: FIRST(:), LAST(:), PE(:),
1390 INTEGER :: IERR, MYID, NPROCS
1391 INTEGER :: I, PROC, J, LOC_ROW
1392 INTEGER(8) :: LOCNNZ, INNZ, NEW_LOCNNZ, OFFDIAG,
1393 & rcvpnt, pnt, savepnt, dups, totdups
1394 INTEGER :: NROWS_LOC
1395 INTEGER :: STATUS(MPI_STATUS_SIZE)
1396 INTEGER,
POINTER :: (:)
1397 INTEGER(8),
POINTER :: MSGCNT(:), SNDCNT(:), RCVCNT(:)
1398 INTEGER,
POINTER :: RDISPL(:), BUFLEVEL(:),
1399 & sipes(:,:), leng(:)
1400 INTEGER,
POINTER :: TSENDI(:),
1401 & tsendj(:), rcvbuf(:)
1402 TYPE(
arrpnt),
POINTER :: APNT(:)
1403 INTEGER :: BUFSIZE, SOURCE, MAXS, allocok
1404 INTEGER,
PARAMETER :: ITAG=30
1406 DOUBLE PRECISION :: SYMMETRY
1407 INTEGER(KIND=8) :: TLEN
1408#if defined(DETERMINISTIC_PARALLEL_GRAPH)
1411 nullify(maptab, sndcnt, rcvcnt)
1412 nullify(rdispl, msgcnt, sipes, leng, buflevel)
1413 nullify(tsendi, tsendj, rcvbuf, apnt)
1418 &
'("Insufficient workspace inside BUILD_SCOTCH_GRAPH")')
1430 ALLOCATE(apnt(nprocs), stat=allocok)
1431 IF(allocok.GT.0)
THEN
1436 IF ( id%INFO(1) .LT. 0 )
GO TO 90
1439 bufsize = id%KEEP(39)
1440 locnnz = id%KEEP8(29)
1441 nrows_loc = last(myid+1)-first(myid+1)+1
1442 maptab => work( 1 : id%N)
1443 leng => work(id%N+1 : 2*id%N)
1446 IF((last(i)-first(i)+1) .GT. maxs)
THEN
1447 maxs = last(i)-first(i)+1
1449 DO j=first(i), last(i)
1453 ALLOCATE(sipes(
max(1,maxs), nprocs), stat=allocok)
1454 IF(allocok.GT.0)
THEN
1456 id%INFO(2)=
max(1,maxs)*nprocs
1459 IF ( id%INFO(1) .LT. 0 )
GO TO 90
1463 IF(id%IRN_loc(innz) .NE. id%JCN_loc(innz))
THEN
1465 proc = maptab(id%IRN_loc(innz))
1466 loc_row = id%IRN_loc(innz)-first(proc)+1
1467 sipes(loc_row, proc) = sipes(loc_row, proc)+1
1468 sndcnt(proc) = sndcnt(proc)+1
1469 proc = maptab(id%JCN_loc(innz))
1470 loc_row = id%JCN_loc(innz)-first(proc)+1
1471 sipes(loc_row, proc) = sipes(loc_row, proc)+1
1472 sndcnt(proc) = sndcnt(proc)+1
1475 CALL mpi_allreduce (offdiag, id%KEEP8(127), 1, mpi_integer8,
1476 & mpi_sum, id%COMM, ierr)
1477 id%KEEP8(127) = id%KEEP8(127)+3*id%N
1478 id%KEEP8(126) = id%KEEP8(127)-2*id%N
1479 CALL mpi_alltoall(sndcnt(1), 1, mpi_integer8, rcvcnt(1), 1,
1480 & mpi_integer8, id%COMM, ierr)
1484 & mpi_integer, mpi_sum, id%COMM, ierr )
1489 ipe(i+1) = ipe(i) + int(leng(i),8)
1490 tlen = tlen+int(leng(i),8)
1499 & rcvbuf, msgcnt, buflevel, id%COMM)
1502 new_locnnz = new_locnnz+rcvcnt(i)
1503 msgcnt(i) = rcvcnt(i)/int(bufsize,8)
1508 IF(mod(innz,int(bufsize,8)/10_8) .EQ. 0)
THEN
1509 CALL mpi_iprobe( mpi_any_source, itag, id%COMM,
1510 & flag, status, ierr )
1512 source = status(mpi_source)
1513 CALL mpi_recv(rcvbuf(1), 2*bufsize, mpi_integer, source,
1514 & itag, id%COMM, status, ierr)
1516 msgcnt(source+1)=msgcnt(source+1)-1
1517 rcvpnt = rcvpnt + bufsize
1520 IF(id%IRN_loc(innz) .NE. id%JCN_loc(innz))
THEN
1521 proc = maptab(id%IRN_loc(innz))
1522 apnt(proc)%BUF(2*buflevel(proc)+1) = id%IRN_loc(innz)-
1524 apnt(proc)%BUF(2*buflevel(proc)+2) = id%JCN_loc(innz)
1525 buflevel(proc) = buflevel(proc)+1
1526 IF(buflevel(proc) .EQ. bufsize)
THEN
1528 & pe, leng, rcvbuf, msgcnt, buflevel, id%COMM)
1530 proc = maptab(id%JCN_loc(innz))
1531 apnt(proc)%BUF(2*buflevel(proc)+1) = id%JCN_loc(innz)-
1533 apnt(proc)%BUF(2*buflevel(proc)+2) = id%IRN_loc(innz)
1534 buflevel(proc) = buflevel(proc)+1
1535 IF(buflevel(proc) .EQ. bufsize)
THEN
1537 & pe, leng, rcvbuf, msgcnt, buflevel, id%COMM)
1542 & rcvbuf, msgcnt, buflevel, id%COMM)
1548 DO innz=ipe(i),ipe(i+1)-1
1549 IF(maptab(pe(innz)) .EQ. i)
THEN
1552 maptab(pe(innz)) = i
1560 CALL mpi_reduce( dups, totdups, 1, mpi_integer8, mpi_sum,
1561 & 0, id%COMM, ierr )
1562 IF(myid .EQ. 0)
THEN
1563 symmetry = dble(totdups)/(dble(id%KEEP8(28))-dble(id%N))
1564 symmetry =
min(symmetry,1.0d0)
1565 IF(id%KEEP(50) .GE. 1) symmetry = 1.d0
1566 IF(
prokg)
WRITE(
mpg,
'(" Structural symmetry is:",i3,"%")')
1567 & ceiling(symmetry*100.d0)
1568 id%INFOG(8) = ceiling(symmetry*100.0d0)
1570 ipe(nrows_loc+1) = savepnt
1574#if defined(DETERMINISTIC_PARALLEL_GRAPH)
1575 DO i=1, last(myid+1)-first(myid+1)+1
1576 l = int(ipe(i+1)-ipe(i))
1578 & pe(ipe(i):ipe(i+1)-1),
1580 CALL dmumps_mergeswap1(l, work(:),
1581 & pe(ipe(i):ipe(i+1)-1))
1586 END SUBROUTINE dmumps_build_dist_graph
1589 & I_HALO_MAP, top_graph, WORK)
1591 TYPE(dmumps_struc) :: id
1593 TYPE(GRAPH_TYPE) :: top_graph
1594 INTEGER(8),
POINTER :: IPE(:)
1595 INTEGER,
POINTER :: PE(:), LENG(:),
1596 & i_halo_map(:), work(:)
1598 INTEGER :: IERR, MYID, NPROCS
1599 INTEGER :: I, PROC, J, LOC_ROW
1600 INTEGER(8) :: LOCNNZ, INNZ, NEW_LOCNNZ, TOP_CNT, TIDX,
1602 INTEGER :: IIDX,JJDX
1603 INTEGER :: HALO_SIZE, NROWS_LOC, DUPS
1604 INTEGER :: STATUS(MPI_STATUS_SIZE)
1605 INTEGER(8),
POINTER :: MSGCNT(:), SNDCNT(:), RCVCNT(:)
1606 INTEGER,
POINTER :: MAPTAB(:),
1607 & HALO_MAP(:), BUFLEVEL(:)
1608 INTEGER,
POINTER :: RDISPL(:),
1610 INTEGER,
POINTER :: TSENDI(:),
1611 & tsendj(:), rcvbuf(:)
1612 TYPE(
arrpnt),
POINTER :: APNT(:)
1613 INTEGER :: BUFSIZE, SOURCE, MAXS, allocok
1614 INTEGER(8) :: PNT, SAVEPNT
1615 INTEGER,
PARAMETER :: ITAG=30
1616 INTEGER(KIND=8) :: TLEN
1618 nullify(maptab, sndcnt, rcvcnt, halo_map)
1619 nullify(rdispl, msgcnt, sipes, buflevel)
1620 nullify(tsendi, tsendj, rcvbuf, apnt)
1625 &
'("Insufficient workspace inside BUILD_LOC_GRAPH")')
1628 maptab => work( 1 : id%N)
1629 halo_map => work(id%N+1 : 2*id%N)
1639 ALLOCATE(apnt(nprocs), stat=allocok)
1640 IF(allocok.GT.0)
THEN
1645 IF ( id%INFO(1) .LT. 0 )
GO TO 90
1649 locnnz = id%KEEP8(29)
1650 nrows_loc = ord%LAST(myid+1)-ord%FIRST(myid+1)+1
1654 IF((ord%LAST(i)-ord%FIRST(i)+1) .GT. maxs)
THEN
1655 maxs = ord%LAST(i)-ord%FIRST(i)+1
1657 DO j=ord%FIRST(i), ord%LAST(i)
1658 maptab(ord%PERITAB(j)) = i
1661 ALLOCATE(sipes(
max(1,maxs), nprocs), stat=allocok)
1662 IF(allocok.GT.0)
THEN
1664 id%INFO(2)=
max(1,maxs
1667 IF ( id%INFO(1) .LT. 0 )
GO TO 90
1671 IF(id%IRN_loc(innz) .NE. id%JCN_loc(innz))
THEN
1672 proc = maptab(id%IRN_loc(innz))
1673 IF(proc .EQ. 0)
THEN
1676 iidx = ord%PERMTAB(id%IRN_loc(innz))
1677 loc_row = iidx-ord%FIRST(proc)+1
1678 sipes(loc_row, proc) = sipes(loc_row, proc)+1
1679 sndcnt(proc) = sndcnt(proc)+1
1681 proc = maptab(id%JCN_loc(innz))
1682 IF(proc .EQ. 0)
THEN
1685 iidx = ord%PERMTAB(id%JCN_loc(innz))
1686 loc_row = iidx-ord%FIRST(proc)+1
1687 sipes(loc_row, proc) = sipes(loc_row, proc)+1
1688 sndcnt(proc) = sndcnt(proc)+1
1692 CALL mpi_alltoall(sndcnt(1), 1, mpi_integer8, rcvcnt(1), 1,
1693 & mpi_integer8, id%COMM, ierr)
1694 i = ceiling(dble(maxs)*1.20d0)
1701 & mpi_integer, mpi_sum, id%COMM, ierr )
1703 i = ceiling(dble(nrows_loc+1)*1.20d0)
1710 ipe(i+1) = ipe(i) + int(leng(i),8)
1711 tlen = tlen+int(leng(i),8)
1722 & leng, rcvbuf, msgcnt, buflevel, id%COMM)
1725 new_locnnz = new_locnnz + rcvcnt(i)
1726 msgcnt(i) = rcvcnt(i)/int(bufsize,8)
1729 & 2_8*int(nrows_loc+ord%TOPNODES(2),8),1_8),
1736 IF(mod(innz,int(bufsize/10,8)) .EQ. 0)
THEN
1737 CALL mpi_iprobe( mpi_any_source, itag, id%COMM,
1738 & flag, status, ierr )
1740 source = status(mpi_source)
1741 CALL mpi_recv(rcvbuf(1), 2*bufsize, mpi_integer, source,
1742 & itag, id%COMM, status, ierr)
1744 msgcnt(source+1)=msgcnt(source+1)-1
1745 rcvpnt = rcvpnt + bufsize
1748 IF(id%IRN_loc(innz) .NE. id%JCN_loc(innz))
THEN
1749 proc = maptab(id%IRN_loc(innz))
1750 IF((maptab(id%JCN_loc(innz)).NE.proc) .AND.
1751 & (maptab(id%JCN_loc(innz)).NE.0) .AND.
1756 IF(proc .EQ. 0)
THEN
1758 tsendi(tidx) = id%IRN_loc(innz)
1759 tsendj(tidx) = id%JCN_loc(innz)
1761 iidx = ord%PERMTAB(id%IRN_loc(innz))
1762 jjdx = ord%PERMTAB(id%JCN_loc(innz))
1763 apnt(proc)%BUF(2*buflevel(proc)+1)=iidx-ord%FIRST(proc)+1
1764 IF( (jjdx .GE. ord%FIRST(proc)) .AND.
1765 & (jjdx .LE. ord%LAST(proc)) )
THEN
1766 apnt(proc)%BUF(2*buflevel(proc)+2) =
1767 & jjdx-ord%FIRST(proc)+1
1769 apnt(proc)%BUF(2*buflevel(proc)+2) = -id%JCN_loc(innz)
1771 buflevel(proc) = buflevel(proc)+1
1772 IF(buflevel(proc) .EQ. bufsize)
THEN
1774 & pe, leng, rcvbuf, msgcnt, buflevel, id%COMM)
1777 proc = maptab(id%JCN_loc(innz))
1778 IF(proc .EQ. 0)
THEN
1780 tsendi(tidx) = id%JCN_loc(innz)
1781 tsendj(tidx) = id%IRN_loc(innz)
1783 iidx = ord%PERMTAB(id%JCN_loc(innz))
1784 jjdx = ord%PERMTAB(id%IRN_loc(innz))
1785 apnt(proc)%BUF(2*buflevel(proc)+1) =
1786 & iidx-ord%FIRST(proc)+1
1787 IF( (jjdx .GE. ord%FIRST(proc)) .AND.
1788 & (jjdx .LE. ord%LAST(proc)) )
THEN
1789 apnt(proc)%BUF(2*buflevel(proc)+2) =
1790 & jjdx-ord%FIRST(proc)+1
1792 apnt(proc)%BUF(2*buflevel(proc)+2) = -id%IRN_loc(innz)
1794 buflevel(proc) = buflevel(proc)+1
1795 IF(buflevel(proc) .EQ. bufsize)
THEN
1797 & pe, leng, rcvbuf, msgcnt, buflevel, id%COMM)
1803 & rcvbuf, msgcnt, buflevel, id%COMM)
1811 DO innz=ipe(i),ipe(i+1)-1
1812 IF(pe(innz) .LT. 0)
THEN
1813 IF(halo_map(-pe(innz)) .EQ. 0)
THEN
1814 halo_size = halo_size+1
1815 halo_map(-pe(innz)) = nrows_loc+halo_size
1817 pe(innz) = halo_map(-pe(innz))
1819 IF(maptab(pe(innz)) .EQ. i)
THEN
1823 maptab(pe(innz)) = i
1831 ipe(nrows_loc+1) = savepnt
1837 IF(halo_map(i) .GT. 0)
THEN
1839 i_halo_map(halo_map(i)-nrows_loc) = i
1841 IF(j .EQ. halo_size)
EXIT
1846 leng(nrows_loc+1:nrows_loc+halo_size) = 0
1851 ipe(nrows_loc+2:nrows_loc+halo_size+1) = ipe(nrows_loc+1)
1852 gsize = nrows_loc + halo_size
1853 CALL mpi_gather(top_cnt, 1, mpi_integer8, rcvcnt(1), 1,
1854 & mpi_integer8, 0, id%COMM, ierr)
1856 new_locnnz = sum(rcvcnt)
1857 top_graph%NZ_LOC = new_locnnz
1858 top_graph%COMM = id%COMM
1865 IF ( id%INFO(1) .LT. 0 )
GO TO 90
1867 ALLOCATE(top_graph%IRN_LOC(1), top_graph%JCN_LOC(1),
1869 IF(allocok.GT.0)
THEN
1874 IF ( id%INFO(1) .LT. 0 )
GO TO 90
1877 top_graph%IRN_LOC(1:top_cnt) = tsendi(1:top_cnt)
1878 top_graph%JCN_LOC(1:top_cnt) = tsendj(1:top_cnt)
1880 DO WHILE (rcvcnt(proc) .GT. 0)
1881 i = int(
min(int(bufsize,8), rcvcnt(proc)))
1882 CALL mpi_recv(top_graph%IRN_LOC(top_cnt+1), i,
1883 & mpi_integer, proc-1, itag, id%COMM, status, ierr)
1884 CALL mpi_recv(top_graph%JCN_LOC(top_cnt+1), i,
1885 & mpi_integer, proc-1, itag, id%COMM, status, ierr)
1886 rcvcnt(proc) = rcvcnt(proc)-i
1891 DO WHILE (top_cnt .GT. 0)
1892 i = int(
min(int(bufsize,8), top_cnt))
1893 CALL mpi_send(tsendi(top_cnt-i+1), i,
1894 & mpi_integer, 0, itag, id%COMM, ierr)
1895 CALL mpi_send(tsendj(top_cnt-i+1), i,
1896 & mpi_integer, 0, itag, id%COMM, ierr)
1908 & LENG, RCVBUF, MSGCNT, SNDCNT, COMM)
1910 INTEGER :: , PROC, COMM, allocok
1913 INTEGER,
POINTER :: RCVBUF(:), LENG(:), PE(:)
1914 INTEGER :: SNDCNT(:)
1915 INTEGER(8) :: MSGCNT(:), IPE(:)
1916 LOGICAL,
SAVE :: INIT = .true.
1917 INTEGER,
POINTER,
SAVE :: SPACE(:,:,:)
1918 LOGICAL,
POINTER,
SAVE :: PENDING(:)
1919 INTEGER,
POINTER,
SAVE :: REQ(:), CPNT(:)
1920 INTEGER :: IERR, MYID, I, SOURCE
1921 INTEGER(8) :: TOTMSG
1922 LOGICAL :: FLAG, TFLAG
1923 INTEGER :: STATUS(MPI_STATUS_SIZE)
1924 INTEGER :: TSTATUS(MPI_STATUS_SIZE)
1925 INTEGER,
PARAMETER :: ITAG=30, ftag=31
1926 INTEGER,
POINTER :: TMPI(:), RCVCNT(:)
1930 ALLOCATE(space(2*bufsize, 2, nprocs), stat=allocok)
1931 IF(allocok.GT.0)
THEN
1932 write(*,*)
"Allocation error of SPACE in DMUMPS_SEND_BUF"
1935 ALLOCATE(rcvbuf(2*bufsize), stat=allocok)
1936 IF(allocok.GT.0)
THEN
1937 write(*,*)
"Allocation error of RCVBUF in DMUMPS_SEND_BUF"
1940 ALLOCATE(pending(nprocs), cpnt(nprocs), stat=allocok)
1941 IF(allocok.GT.0)
THEN
1942 write(*,*)
"Allocation error of PENDING/CPNT"
1943 & ,
" in DMUMPS_SEND_BUF"
1946 ALLOCATE(req(nprocs), stat=allocok)
1947 IF(allocok.GT.0)
THEN
1948 write(*,*)
"Allocation error of REQ in DMUMPS_SEND_BUF"
1953 apnt(i)%BUF => space(:,1,i)
1959 IF(proc .EQ. -1)
THEN
1960 totmsg = sum(msgcnt)
1962 IF(totmsg .EQ. 0)
EXIT
1963 CALL mpi_recv(rcvbuf(1), 2*bufsize, mpi_integer,
1964 & mpi_any_source, itag, comm, status, ierr)
1966 source = status(mpi_source)
1968 msgcnt(source+1)=msgcnt(source+1)-1
1972 CALL mpi_wait(req(i), tstatus, ierr)
1975 ALLOCATE(rcvcnt(nprocs), stat=allocok)
1976 IF(allocok.GT.0)
THEN
1977 write(*,*)
"Allocation error of RCVCNT in DMUMPS_SEND_BUF"
1980 CALL mpi_alltoall(sndcnt(1), 1, mpi_integer, rcvcnt(1), 1,
1981 & mpi_integer, comm, ierr)
1983 IF(sndcnt(i) .GT. 0)
THEN
1984 tmpi => apnt(i)%BUF(:)
1985 CALL mpi_isend(tmpi(1), 2*sndcnt(i), mpi_integer, i-1,
1986 & ftag, comm, req(i), ierr)
1990 IF(rcvcnt(i) .GT. 0)
THEN
1991 CALL mpi_recv(rcvbuf(1), 2*rcvcnt(i), mpi_integer, i-1,
1992 & ftag, comm, status, ierr)
1998 IF(sndcnt(i) .GT. 0)
THEN
1999 CALL mpi_wait(req(i), tstatus, ierr)
2003 DEALLOCATE(pending, cpnt)
2005 DEALLOCATE(rcvbuf, rcvcnt)
2006 nullify(space, pending, cpnt, req, rcvbuf, rcvcnt)
2010 IF(pending(proc))
THEN
2012 CALL mpi_test(req(proc), tflag, tstatus, ierr)
2014 pending(proc) = .false.
2018 & flag, status, ierr )
2020 source = status(mpi_source)
2021 CALL mpi_recv(rcvbuf(1), 2*bufsize, mpi_integer,
2022 & source, itag, comm, status, ierr)
2025 msgcnt(source+1)=msgcnt(source+1)-1
2030 tmpi => apnt(proc)%BUF(:)
2031 CALL mpi_isend(tmpi(1), 2*bufsize, mpi_integer, proc-1,
2032 & itag, comm, req(proc), ierr)
2033 pending(proc) = .true.
2034 cpnt(proc) = mod(cpnt(proc),2)+1
2035 apnt(proc)%BUF => space(:,cpnt(proc),proc)
2042 INTEGER :: RCVBUF(:), PE(:), LENG(:)
2043 INTEGER(8) :: IPE(:)
2044 INTEGER :: I, ROW, COL
2045 DO i=1, 2*bufsize, 2
2048 pe(ipe(row)+leng(row)) = col
2049 leng(row) = leng(row) + 1
2053#if defined(ptscotch) || defined(parmetis) || defined(parmetis3)
2054 SUBROUTINE dmumps_build_tree(ord)
2061 ord%NW(i) = ord%NW(i)+ord%RANGTAB(i+1) - ord%RANGTAB(i)
2062 IF (ord%TREETAB(i) .NE. -1)
THEN
2063 IF (ord%SON(ord%TREETAB(i)) .EQ. -1)
THEN
2064 ord%SON(ord%TREETAB(i)) = i
2066 ord%BROTHER(i) = ord%SON(ord%TREETAB(i))
2067 ord%SON(ord%TREETAB(i)) = i
2069 ord%NW(ord%TREETAB(i)) = ord%NW(ord%TREETAB(i))+ ord%NW(i
2073 END SUBROUTINE dmumps_build_tree
2074 SUBROUTINE dmumps_graph_dist(id, ord, FIRST,
2075 & LAST, BASE, NPROCS, WORK, TYPE)
2077 TYPE(dmumps_struc) :: id
2079 INTEGER :: FIRST(:), LAST(:), BASE, NPROCS, TYPE
2080 INTEGER,
TARGET :: WORK(:)
2081 INTEGER,
POINTER :: TMP(:), NZ_ROW(:)
2082 INTEGER :: I, IERR, P, F, J
2083 INTEGER(8) :: LOCNNZ
2090 share = int(id%N/ord%NSLAVES,8)
2092 first(base+i) = (i-1)*int(share)+1
2093 last (base+i) = (i)*int(share)
2095 last(base+ord%NSLAVES) =
max(last(base+ord%NSLAVES), id%N)
2096 DO i = ord%NSLAVES+1, id%NSLAVES+1
2097 first(base+i) = id%N+1
2100 ELSE IF (type.EQ.2)
THEN
2102 nz_row => work(id%N+1:2*id%N)
2105 locnnz = id%KEEP8(29)
2107 IF(id%IRN_loc(innz) .NE. id%JCN_loc(innz))
THEN
2108 tmp(id%IRN_loc(innz)) = tmp(id%IRN_loc(innz))+1
2109 locoffdiag = locoffdiag+1
2110 IF(id%SYM.GT.0)
THEN
2111 tmp(id%JCN_loc(innz)) = tmp(id%JCN_loc(innz))+1
2112 locoffdiag = locoffdiag+1
2117 & mpi_integer, mpi_sum, id%COMM, ierr)
2119 & mpi_integer8, mpi_sum, id%COMM, ierr)
2121 share = (offdiag-1_8)/int(ord%NSLAVES,8) + 1_8
2126 t = t+int(nz_row(i),8)
2128 & (t .GE. share) .OR.
2129 & ((id%N-i).EQ.(ord%NSLAVES-p-1)) .OR.
2133 IF(p.EQ.ord%NSLAVES)
THEN
2145 DO j=p+1, nprocs+1-base
2146 first(base+j) = id%N+1
2151 END SUBROUTINE dmumps_graph_dist
2154 INTEGER :: I, LP, ISWAP, N
2155 INTEGER :: L(0:), A1(:), A2(:)
2159 IF ((lp==0).OR.(i>n))
EXIT
2177#if defined(DETERMINISTIC_PARALLEL_GRAPH)
2178 SUBROUTINE dmumps_mergeswap1(N, L, A)
2179 INTEGER :: I, LP, ISWAP, N
2180 INTEGER :: L(0:), A(:)
2184 IF ((lp==0).OR.(i>n))
EXIT
2198 END SUBROUTINE dmumps_mergeswap1
2202 INTEGER :: K(:), L(0:)
2203 INTEGER :: P, Q, S, T
2208 IF (k(p) <= k(p+1))
THEN
2217 IF (l(n+1) == 0)
THEN
2220 l(n+1) = iabs(l(n+1))
2229 IF(k(p) .GT. k(q))
GOTO 600
2234 IF (p .GT. 0)
GOTO 300
2245 l(s) = sign(q, l(s))
2248 IF (q .GT. 0)
GOTO 300
2261 l(s) = sign(p, l(s))
2268 INTEGER,
POINTER :: a(:)
2270 IF(
associated(a))
THEN
2277#if defined(parmetis) || defined(parmetis3)
2278 SUBROUTINE mumps_parmetis_mixedto32(id, BASE, VERTLOCNBR, FIRST,
2279 & VERTLOCTAB, EDGELOCTAB, BASEVAL, OPTIONS, ORDER,
2280 & SIZES, COMM, IERR)
2282 TYPE(dmumps_struc) ::
id
2283 INTEGER :: first(:), edgeloctab(:), options(:)
2284 INTEGER :: sizes(:), order(:)
2285 INTEGER(8) :: vertloctab(:)
2286 INTEGER :: vertlocnbr, baseval, ierr, comm, base
2287 INTEGER,
POINTER :: vertloctab_i4(:)
2288 IF( vertloctab(vertlocnbr+1).GT.huge(vertlocnbr))
THEN
2291 & vertloctab(vertlocnbr+1),
id%INFO(2))
2294 nullify(vertloctab_i4)
2299 IF (
id%INFO(1) .LT. 0 )
RETURN
2301 & vertlocnbr+1, vertloctab_i4(1))
2302 CALL mumps_parmetis(first(1+base), vertloctab_i4(1),
2303 & edgeloctab(1), baseval, options(1), order(1),
2304 & sizes(1), comm, ierr)
2310 END SUBROUTINE mumps_parmetis_mixedto32
2311 SUBROUTINE mumps_parmetis_mixedto64
2312 & (
id, base, vertlocnbr, first,
2313 & vertloctab, edgeloctab, baseval, options, order,
2314 & sizes, comm, ierr)
2316 TYPE(dmumps_struc) ::
id
2317 INTEGER :: first(:), edgeloctab(:), options(:)
2318 INTEGER :: sizes(:), order(:)
2319 INTEGER(8) :: vertloctab(:)
2320 INTEGER :: vertlocnbr, baseval, ierr, comm, base
2321 INTEGER(8),
POINTER :: first_i8(:), edgeloctab_i8(:),
2322 & sizes_i8(:), order_i8(:)
2323#
if defined(parmetis)
2324 INTEGER(8),
POINTER :: options_i8(:)
2325 INTEGER(8) :: baseval_i8
2327 IF (
id%KEEP(10).NE.1)
THEN
2330 IF (
id%INFO(1) .LT. 0 )
RETURN
2333 baseval_i8 = int(baseval,8)
2336 nullify(first_i8, edgeloctab_i8, sizes_i8, order_i8)
2337 IF (
id%KEEP(10).EQ.1)
THEN
2338 CALL mumps_parmetis_64(first(1+base), vertloctab(1),
2340 & baseval, options(1),
2342 & sizes(1), comm, ierr)
2346 IF (
id%INFO(1) .LT. 0 )
GOTO 5
2348 & vertloctab(vertlocnbr+1)-1_8,
2350 IF (
id%INFO(1) .LT. 0 )
GOTO 5
2353 IF (
id%INFO(1) .LT. 0 )
GOTO 5
2356 IF (
id%INFO(1) .LT. 0 )
GOTO 5
2360 IF (
id%INFO(1) .LT. 0 )
RETURN
2363 & vertloctab(vertlocnbr+1)-1_8
2364 CALL mumps_parmetis_64(first_i8(1+base), vertloctab(1),
2366#if defined(parmetis3)
2367 & baseval, options(1),
2369 & baseval_i8, options_i8(1),
2372 & sizes_i8(1), comm, ierr)
2379 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2380 IF (
id%KEEP(10) .NE. 1 )
THEN
2382 &
size(order), order(1))
2384 &
size(sizes), sizes(1))
2391#if defined(parmetis)
2395 END SUBROUTINE mumps_parmetis_mixedto64
2397#if defined(ptscotch)
2398 SUBROUTINE mumps_ptscotch_mixedto32(id, ord,
2400 & VERTLOCNBR, VERTLOCTAB,
2401 & EDGELOCNBR, EDGELOCTAB,
2404 include
'ptscotchf.h'
2405 TYPE(dmumps_struc) ::
id
2407 INTEGER :: baseval, vertlocnbr
2408 INTEGER(8) :: edgelocnbr
2409 INTEGER(8) :: vertloctab(:)
2410 INTEGER :: edgeloctab(:)
2412 INTEGER,
POINTER :: vertloctab_i4(:)
2413 INTEGER :: edgelocnbr_i4, myworkid
2414 DOUBLE PRECISION :: graphdat(scotch_dgraphdim),
2415 & ordedat(scotch_dorderdim), stradat(scotch_stratdim),
2416 & cordedat(scotch_orderdim)
2417 CHARACTER strstring*1024
2418 nullify(vertloctab_i4)
2422 & ord%COMM_NODES,
id%MYID )
2423 IF (
id%INFO(1) .LT. 0 )
RETURN
2425 & vertlocnbr+1, vertloctab_i4(1))
2426 edgelocnbr_i4 = int(edgelocnbr)
2427 IF(ord%SUBSTRAT .NE. 0)
THEN
2428 strstring=
'n{sep=m{asc=b{width=3,strat=q{strat=f}},'//
2429 &
'low=q{strat=h},vert=1000,dvert=100,dlevl=0,'//
2430 &
'proc=1,seq=q{strat=m{type=h,vert=100,'//
2431 &
'low=h{pass=10},asc=b{width=3,bnd=f{bal=0.2},'//
2432 &
'org=h{pass=10}f{bal=0.2}}}}},ole=s,ose=s,osq=s}'
2439 CALL mumps_dgraphinit(graphdat, ord%COMM_NODES, ierr)
2444 & ord%COMM_NODES,
id%MYID )
2445 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2446 CALL scotchfdgraphbuild(graphdat, baseval, vertlocnbr,
2447 & vertlocnbr, vertloctab_i4(1), vertloctab_i4(2),
2448 & vertloctab_i4(1), vertloctab_i4(1), edgelocnbr_i4,
2449 & edgelocnbr_i4, edgeloctab(1), edgeloctab(1),
2450 & edgeloctab(1), ierr)
2455 & ord%COMM_NODES,
id%MYID )
2456 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2457 CALL scotchfstratinit
2462 & ord%COMM_NODES,
id%MYID )
2463 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2464 IF(ord%SUBSTRAT .NE. 0)
THEN
2465 CALL scotchfstratdgraphorder(stradat, strstring, ierr)
2471 & ord%COMM_NODES,
id%MYID )
2472 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2473 CALL scotchfdgraphorderinit(graphdat, ordedat, ierr)
2478 & ord%COMM_NODES,
id%MYID )
2479 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2480 CALL scotchfdgraphordercompute(graphdat, ordedat, stradat,
2486 & ord%COMM_NODES,
id%MYID )
2487 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2488 IF(myworkid .EQ. 0)
THEN
2489 CALL scotchfdgraphcorderinit(graphdat, cordedat,
2490 & ord%PERMTAB(1), ord%PERITAB(1), ord%CBLKNBR,
2491 & ord%RANGTAB(1), ord%TREETAB(1), ierr)
2497 & ord%COMM_NODES,
id%MYID )
2499 IF(myworkid .EQ. 0)
THEN
2500 CALL scotchfdgraphordergather(graphdat, ordedat,
2506 CALL scotchfdgraphordergather(graphdat, ordedat,
2513 & ord%COMM_NODES,
id%MYID )
2514 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2516 &
CALL scotchfdgraphcorderexit(graphdat, cordedat)
2517 CALL scotchfdgraphorderexit(graphdat, ordedat)
2518 CALL scotchfstratexit(stradat)
2519 CALL scotchfdgraphexit(graphdat)
2523 END SUBROUTINE mumps_ptscotch_mixedto32
2524 SUBROUTINE mumps_ptscotch_mixedto64(id, ord,
2526 & VERTLOCNBR, VERTLOCTAB,
2527 & EDGELOCNBR, EDGELOCTAB,
2530 include
'ptscotchf.h'
2531 TYPE(dmumps_struc) ::
2533 INTEGER :: baseval, vertlocnbr
2535 INTEGER(8) :: vertloctab(:)
2536 INTEGER :: edgeloctab(:)
2539 DOUBLE PRECISION :: graphdat(scotch_dgraphdim),
2540 & ordedat(scotch_dorderdim), stradat(scotch_stratdim),
2541 & cordedat(scotch_orderdim)
2542 CHARACTER strstring*1024
2543 INTEGER(8),
POINTER :: edgeloctab_i8(:), permtab_i8(:),
2544 & peritab_i8(:), rangtab_i8(:), treetab_i8(:)
2545 INTEGER(8) :: cblknbr_i8, vertlocnbr_i8, baseval_i8
2546 if(ord%substrat .NE. 0) then
2547 strstring=
'n{sep=m{asc=b{width=3,strat=q{strat=f}},'//
2548 &
'low=q{strat=h},vert=1000,dvert=100,dlevl=0,'//
2549 &
'proc=1,seq=q{strat=m{type=h,vert=100,'//
2550 &
'low=h{pass=10},asc=b{width=3,bnd=f{bal=0.2},'//
2551 &
'org=h{pass=10}f{bal=0.2}}}}},ole=s,ose=s,osq=s}'
2558 nullify(edgeloctab_i8, permtab_i8, peritab_i8,
2559 & rangtab_i8, treetab_i8)
2560 IF (
id%KEEP(10).NE.1)
THEN
2562 & vertloctab(vertlocnbr+1)-1_8,
2564 IF (
id%INFO(1) .LT. 0 )
GOTO 5
2565 IF (myworkid .EQ. 0)
THEN
2568 IF (
id%INFO(1) .LT. 0 )
GOTO 5
2571 IF (
id%INFO(1) .LT. 0 )
GOTO 5
2574 IF (
id%INFO(1) .LT. 0 )
GOTO 5
2580 & ord%COMM_NODES,
id%MYID )
2581 IF (
id%INFO(1) .LT. 0 )
RETURN
2583 & vertloctab(vertlocnbr+1)-1_8, edgeloctab_i8(1))
2584 baseval_i8 = int(baseval,8)
2585 vertlocnbr_i8 = int(vertlocnbr,8)
2587 CALL mumps_dgraphinit(graphdat, ord%COMM_NODES, ierr)
2592 & ord%COMM_NODES,
id%MYID )
2593 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2594 IF (
id%KEEP(10).NE.1)
THEN
2595 CALL scotchfdgraphbuild(graphdat, baseval_i8, vertlocnbr_i8,
2596 & vertlocnbr_i8, vertloctab(1), vertloctab(2),
2597 & vertloctab(1), vertloctab(1), edgelocnbr,
2598 & edgelocnbr, edgeloctab_i8(1), edgeloctab_i8(1),
2599 & edgeloctab_i8(1), ierr)
2601 CALL scotchfdgraphbuild(graphdat, baseval, vertlocnbr,
2602 & vertlocnbr, vertloctab(1), vertloctab(2),
2603 & vertloctab(1), vertloctab(1), edgelocnbr,
2604 & edgelocnbr, edgeloctab(1), edgeloctab(1),
2605 & edgeloctab(1), ierr)
2611 & ord%COMM_NODES,
id%MYID )
2612 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2613 CALL scotchfstratinit(stradat, ierr)
2618 & ord%COMM_NODES,
id%MYID )
2619 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2620 IF(ord%SUBSTRAT .NE. 0)
THEN
2621 CALL scotchfstratdgraphorder(stradat, strstring, ierr)
2627 & ord%COMM_NODES,
id%MYID )
2628 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2629 CALL scotchfdgraphorderinit(graphdat, ordedat, ierr)
2634 & ord%COMM_NODES,
id%MYID )
2635 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2636 CALL scotchfdgraphordercompute(graphdat
2642 & ord%COMM_NODES,
id%MYID )
2643 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2644 IF(myworkid .EQ. 0)
THEN
2645 IF (
id%KEEP(10).NE.1)
THEN
2646 CALL scotchfdgraphcorderinit(graphdat, cordedat,
2647 & permtab_i8(1), peritab_i8(1), cblknbr_i8, rangtab_i8(1),
2648 & treetab_i8(1), ierr)
2650 CALL scotchfdgraphcorderinit(graphdat, cordedat,
2651 & ord%PERMTAB(1), ord%PERITAB(1), ord%CBLKNBR,
2652 & ord%RANGTAB(1),ord%TREETAB(1), ierr)
2659 & ord%COMM_NODES,
id%MYID )
2660 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2661 IF(myworkid .EQ. 0)
THEN
2662 CALL scotchfdgraphordergather(graphdat, ordedat,
2668 CALL scotchfdgraphordergather(graphdat, ordedat,
2675 & ord%COMM_NODES,
id%MYID )
2676 IF (
id%INFO(1) .LT. 0 )
GOTO 10
2677 CALL scotchfdgraphorderexit(graphdat, ordedat)
2678 CALL scotchfstratexit(stradat)
2679 CALL scotchfdgraphexit(graphdat)
2681 IF (
id%KEEP(10).NE.1)
THEN
2683 IF(myworkid .EQ. 0)
THEN
2684 CALL scotchfdgraphcorderexit(graphdat, cordedat)
2686 &
size(ord%PERMTAB), ord%PERMTAB(1))
2688 &
size(ord%PERITAB), ord%PERITAB(1))
2690 &
size(ord%TREETAB), ord%TREETAB(1))
2692 &
size(ord%RANGTAB), ord%RANGTAB(1))
2693 ord%CBLKNBR = int(cblknbr_i8)
2701 END SUBROUTINE mumps_ptscotch_mixedto64
subroutine mumps_symqamd_new(job, thresh, ndense, n, iwlen, pe, pfree, len, iw, nv, elen, last, ncmpa, degree, head, next, w, perm, complem_list, size_complem_list, agg6)
subroutine mumps_propinfo(icntl, info, comm, id)
subroutine dmumps_ana_m(ne, nd, nsteps, maxfr, maxelim, k50, sizefac_tot, maxnpiv, k5, k6, panel_size, k253)
subroutine dmumps_cutnodes(n, frere, fils, nfsiz, sizeofblocks, lsizeofblocks, nsteps, nslaves, keep, keep8, splitroot, mp, ldiag, info1, info2)
subroutine dmumps_set_k821_surface(keep821, keep2, keep48, keep50, nslaves)
subroutine dmumps_ana_lnew(n, ipe, nv, ips, ne, na, nfsiz, node, nsteps, fils, frere, nd, nemin, subord, keep60, keep20, keep38, namalg, namalgmax, cumul, keep50, icntl13, keep37, keep197, nslaves, allow_amalg_tiny_nodes, blkon, sizeofblocks, lsizeofblocks)
if(complex_arithmetic) id
subroutine mpi_recv(buf, cnt, datatype, source, tag, comm, status, ierr)
subroutine mpi_isend(buf, cnt, datatype, dest, tag, comm, ireq, ierr)
subroutine mpi_test(ireq, flag, status, ierr)
subroutine mpi_iprobe(source, tag, comm, flag, status, ierr)
subroutine mpi_wait(ireq, status, ierr)
subroutine mpi_reduce(sendbuf, recvbuf, cnt, datatype, op, root, comm, ierr)
subroutine mpi_comm_split(comm, color, key, comm2, ierr)
subroutine mpi_send(buf, cnt, datatype, dest, tag, comm, ierr)
subroutine mpi_allreduce(sendbuf, recvbuf, cnt, datatype, operation, comm, ierr)
subroutine mpi_alltoall(sendbuf, sendcnt, sendtype, recvbuf, recvcnt, recvtype, comm, ierr)
subroutine mpi_reduce_scatter(sendbuf, recvbuf, rcvcnt, datatype, op, comm, ierr)
subroutine mpi_barrier(comm, ierr)
subroutine mpi_comm_size(comm, size, ierr)
subroutine mpi_bcast(buffer, cnt, datatype, root, comm, ierr)
subroutine mpi_gather(sendbuf, cnt, datatype, recvbuf, reccnt, rectype, root, comm, ierr)
subroutine mpi_comm_free(comm, ierr)
subroutine mpi_irecv(buf, cnt, datatype, source, tag, comm, ireq, ierr)
subroutine mpi_comm_rank(comm, rank, ierr)
subroutine dmumps_get_subtrees(ord, id)
subroutine dmumps_do_par_ord(id, ord, work)
logical function dmumps_stop_descent(id, ord, nactive, anode, rproc, alist, list, peakmem, nnodes, checkmem)
subroutine dmumps_send_buf(apnt, proc, nprocs, bufsize, ipe, pe, leng, rcvbuf, msgcnt, sndcnt, comm)
subroutine dmumps_build_loc_graph(id, ord, gsize, ipe, pe, leng, i_halo_map, top_graph, work)
subroutine dmumps_set_par_ord(id, ord)
integer function dmumps_cnt_kids(node, ord)
subroutine dmumps_make_loc_idx(id, topnodes, lperm, liperm, ord)
subroutine dmumps_mergeswap(n, l, a1, a2)
integer function mumps_getsize(a)
subroutine dmumps_assemble_msg(bufsize, rcvbuf, ipe, pe, leng)
subroutine dmumps_parsymfact(id, ord, gpe, gnv, work)
subroutine dmumps_assemble_top_graph(id, nlocvars, lperm, top_graph, ncliques, lstvar, lvarpt, ipe, pe, leng, elen)
subroutine dmumps_mergesort(n, k, l)
subroutine mumps_i8realloc8(array, minsize, info, lp, force, copy, string, memcnt, errcode)
subroutine mumps_i8realloc(array, minsize, info, lp, force, copy, string, memcnt, errcode)
subroutine mumps_idealloc(a1, a2, a3, a4, a5, a6, a7, memcnt)
subroutine mumps_i8dealloc(a1, a2, a3, a4, a5, a6, a7, memcnt)
subroutine mumps_irealloc8(array, minsize, info, lp, force, copy, string, memcnt, errcode)