874 IMPLICIT NONE
875 TYPE(CMUMPS_STRUC) :: id
876 TYPE(ORD_TYPE) :: ord
877 INTEGER, POINTER :: GPE(:), GNV(:)
878 INTEGER, TARGET :: WORK(:)
879 TYPE(GRAPH_TYPE) :: top_graph
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(:),
888 & LSTVAR(:)
889 INTEGER, POINTER :: MYLIST(:),
890 & LPERM(:),
891 & LIPERM(:),
892 & NVT(:), BUF_NV1(:),
893 & BUF_NV2(:), ROOTPERM(:),
894 & TMP2(:), BWORK(:), NCLIQUES(:)
895 INTEGER :: MYNCLIQUES, MYMAXVARS, ICLIQUES,
896 & TOTNCLIQUES
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 :: STATUSNV(MPI_STATUS_SIZE)
906 INTEGER :: STATUSCLIQUES(MPI_STATUS_SIZE)
907 INTEGER, PARAMETER :: ITAG=30
908 LOGICAL :: AGG6
909 INTEGER :: THRESH
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 CMUMPS_PARSYMFACT'
921 ELSE
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)
926 END IF
927 CALL cmumps_get_subtrees(ord,
id)
928 CALL mumps_idealloc(ord%SON, ord%BROTHER, ord%NW,
929 & ord%RANGTAB, memcnt=memcnt)
930 nrows_loc = ord%LAST(myid+1)-ord%FIRST(myid+1)+1
931 nrl = nrows_loc
932 toprows = ord%TOPNODES(2)
933 bwork => work(1 : 2*
id%N)
934 CALL cmumps_build_loc_graph(
id, ord, hidx, ipe, pe, leng,
935 & i_halo_map, top_graph, bwork)
938 IF(
id%INFO(1).lt.0)
RETURN
940 DO i=1, nprocs
941 tmp = tmp-(ord%LAST(i)-ord%FIRST(i)+1)
942 END DO
943 tmp = ceiling(real(tmp)*1.10e0)
944 IF(myid .EQ. 0) THEN
945 tmp =
max(
max(tmp, hidx),1)
946 ELSE
948 END IF
949 size_schur = hidx - nrows_loc
950 CALL mumps_realloc(ndense, tmp,
id%INFO, lp,
951 & memcnt=memcnt, errcode=-7)
952 CALL mumps_realloc(last, tmp,
id%INFO, lp,
953 & memcnt=memcnt, errcode=-7)
954 CALL mumps_realloc(next, tmp,
id%INFO, lp,
955 & memcnt=memcnt, errcode=-7)
956 CALL mumps_realloc(degree, tmp,
id%INFO, lp,
957 & memcnt=memcnt, errcode=-7)
958 CALL mumps_realloc(w, tmp,
id%INFO, lp,
959 & memcnt=memcnt, errcode=-7)
960 CALL mumps_realloc(nv, tmp,
id%INFO, lp,
961 & memcnt=memcnt, errcode=-7)
962 CALL mumps_realloc(listvar_schur,
max(size_schur,1),
id%INFO, lp,
963 & memcnt=memcnt, errcode=-7)
964 IF(memcnt .GT. maxmem) maxmem=memcnt
965 DO i=1, size_schur
966 listvar_schur(i) = nrows_loc+i
967 END DO
968 thresh = -1
969 agg6 = .false.
970 pfrees = ipe(nrows_loc+1)
971 pfs_save = pfrees
972 pelen = pfrees-1 + 2_8*int(nrows_loc+ord%TOPNODES(2),8)
973 DO i=1, hidx
974 perm(i) = i
975 END DO
976 IF(size_schur.EQ.0) THEN
977 job = 0
978 ELSE
979 job = 1
980 END IF
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)
985 myncliques = 0
986 mynvars = 0
987 mymaxvars = 0
988 DO i=1, hidx
989 IF(ipe(i) .GT. 0) THEN
990 mymaxvars =
max(mymaxvars,leng(i))
991 mynvars = mynvars+leng(i)
992 myncliques = myncliques+1
993 END IF
994 END DO
995 CALL mpi_reduce(mynvars, totnvars, 1, mpi_integer8,
996 & mpi_sum, 0,
id%COMM, ierr)
997 CALL mumps_realloc(ncliques, nprocs,
id%INFO,
998 & lp, string='NCLIQUES', memcnt=memcnt, errcode=-7)
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)
1003 CALL mumps_i8realloc(lvarpt, totncliques+1,
id%INFO,
1004 & lp, string='LVARPT', memcnt=memcnt, errcode=-7)
1005 CALL mumps_irealloc8(lstvar, totnvars,
id%INFO,
1006 & lp, string='LSTVAR', memcnt=memcnt, errcode=-7)
1007 lvarpt(1) = 1_8
1008 icliques = 0
1009 DO i=1, hidx
1010 IF(ipe(i) .GT. 0) THEN
1011 icliques = icliques+1
1012 lvarpt(icliques+1) = lvarpt(icliques)+leng(i)
1013 DO j=0, leng(i)-1
1014 lstvar(lvarpt(icliques)+j) =
1015 & i_halo_map(pe(ipe(i)+j)-nrows_loc)
1016 END DO
1017 END IF
1018 END DO
1019 DO proc=1, nprocs-1
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)
1027 END DO
1028 END DO
1029 lperm => work(3*
id%N+1 : 4*
id%N)
1030 ntvar = ord%TOPNODES(2)
1031 CALL cmumps_make_loc_idx(
id, ord%TOPNODES, lperm, liperm, ord)
1032 CALL cmumps_assemble_top_graph(
id, ord%TOPNODES(2), lperm,
1033 & top_graph, totncliques, lstvar, lvarpt, ipet, pe,
1034 & leng, elen)
1035 tgsize = ord%TOPNODES(2)+totncliques
1036 pfreet = ipet(tgsize+1)
1037 pft_save = pfreet
1038 nullify(lperm)
1039 ELSE
1040 CALL mumps_realloc(mylist, mymaxvars,
id%INFO,
1041 & lp, string='MYLIST', memcnt=memcnt, errcode=-7)
1042 IF(memcnt .GT. maxmem) maxmem=memcnt
1043 DO i=1, hidx
1044 IF(ipe(i) .GT. 0) THEN
1045 DO j=1, leng(i)
1046 mylist(j) = i_halo_map(pe(ipe(i)+j-1)-nrows_loc)
1047 END DO
1048 CALL mpi_send(leng(i), 1, mpi_integer, 0, itag,
1050 CALL mpi_send(mylist(1), leng(i), mpi_integer, 0, itag,
1052 END IF
1053 END DO
1054 END IF
1055 CALL mumps_idealloc(top_graph%IRN_LOC,
1056 & top_graph%JCN_LOC, ord%TOPNODES, memcnt=memcnt)
1057 IF(myid .EQ. 0) THEN
1058 CALL mumps_irealloc8(pe,
max(pfreet+int(tgsize,8),1_8),
id%INFO,
1059 & lp, copy=.true., string='J2:PE', memcnt=memcnt,
1060 & errcode=-7)
1061 CALL mumps_realloc(ndense,
max(tgsize,1),
id%INFO, lp,
1062 & string='J2:NDENSE', memcnt=memcnt, errcode=-7)
1063 CALL mumps_realloc(nvt,
max(tgsize,1),
id%INFO, lp,
1064 & string='J2:NVT', memcnt=memcnt, errcode=-7)
1065 CALL mumps_realloc(last,
max(tgsize,1),
id%INFO, lp,
1066 & string='J2:LAST', memcnt=memcnt, errcode=-7)
1067 CALL mumps_realloc(degree,
max(tgsize,1),
id%INFO, lp,
1068 & string='J2:DEGREE', memcnt=memcnt, errcode=-7)
1069 CALL mumps_realloc(next,
max(tgsize,1),
id%INFO, lp,
1070 & string='J2:NEXT', memcnt=memcnt, errcode=-7)
1071 CALL mumps_realloc(w,
max(tgsize,1),
id%INFO, lp,
1072 & string='J2:W', memcnt=memcnt, errcode=-7)
1073 CALL mumps_realloc(listvar_schur,
max(totncliques,1),
id%INFO,
1074 & lp, string='J2:LVSCH', memcnt=memcnt, errcode=-7)
1075 IF(memcnt .GT. maxmem) maxmem=memcnt
1076 DO i=1, totncliques
1077 listvar_schur(i) = ntvar+i
1078 END DO
1079 thresh = -1
1080 CALL mumps_realloc(head,
max(tgsize,1),
id%INFO,
1081 & lp, string='J2:HEAD', memcnt=memcnt, errcode=-7)
1082 CALL mumps_realloc(perm,
max(tgsize,1),
id%INFO,
1083 & lp, copy=.true., string='J2:PERM',
1084 & memcnt=memcnt, errcode=-7)
1085 IF(memcnt .GT. maxmem) maxmem=memcnt
1086 DO i=1, tgsize
1087 perm(i) = i
1088 END DO
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,
1094 & agg6)
1095 END IF
1098 CALL mumps_dealloc(listvar_schur, memcnt=memcnt)
1099 CALL mumps_dealloc(pe, memcnt=memcnt)
1100 IF(myid .EQ. 0) THEN
1101 maxs = nrows_loc
1102 DO i=2, nprocs
1103 IF((ord%LAST(i)-ord%FIRST(i)+1) .GT. maxs)
1104 & maxs = (ord%LAST(i)-ord%FIRST(i)+1)
1105 END DO
1106 CALL mumps_i8realloc(buf_pe1,
max(maxs,1),
id%INFO,
1107 & lp, string='BUF_PE1', memcnt=memcnt, errcode=-7)
1108 CALL mumps_i8realloc(buf_pe2,
max(maxs,1),
id%INFO,
1109 & lp, string='BUF_PE2', memcnt=memcnt, errcode=-7)
1110 CALL mumps_realloc(buf_nv1,
max(maxs,1),
id%INFO,
1111 & lp, string='BUF_NV1', memcnt=memcnt, errcode=-7)
1112 CALL mumps_realloc(buf_nv2,
max(maxs,1),
id%INFO,
1113 & lp, string='BUF_NV2', memcnt=memcnt, errcode=-7)
1114 CALL mumps_realloc(gpe,
id%N,
id%INFO,
1115 & lp, string='GPE', memcnt=memcnt, errcode=-7)
1116 CALL mumps_realloc(gnv,
id%N,
id%INFO,
1117 & lp, string='GNV', memcnt=memcnt, errcode=-7)
1118 CALL mumps_realloc(rootperm, totncliques,
id%INFO,
1119 & lp, string='ROOTPERM', memcnt=memcnt, errcode=-7)
1120 IF(memcnt .GT. maxmem) maxmem=memcnt
1121 ridx = 0
1122 tmp1 => buf_pe1
1123 tmp2 => buf_nv1
1124 NULLIFY(buf_pe1, buf_nv1)
1125 buf_pe1 => ipe
1126 buf_nv1 => nv
1127 DO proc=0, nprocs-2
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(i+ord%FIRST(proc+1)-1)
1136 IF(buf_pe1(i) .GT. 0) THEN
1137 ridx=ridx+1
1138 rootperm(ridx) = glob_idx
1139 gnv(glob_idx) = buf_nv1(i)
1140 ELSE IF (buf_pe1(i) .EQ. 0) THEN
1141 gpe(glob_idx) = 0
1142 gnv(glob_idx) = buf_nv1(i)
1143 ELSE
1144 gpe(glob_idx) = -ord%PERITAB(-buf_pe1(i)+
1145 & ord%FIRST(proc+1)-1)
1146 gnv(glob_idx) = buf_nv1(i)
1147 END IF
1148 END DO
1149 CALL mpi_wait(rhandpe, statuspe, ierr)
1150 CALL mpi_wait(rhandnv, statusnv, ierr)
1151 IF(proc .NE. 0) THEN
1152 tmp1 => buf_pe1
1153 tmp2 => buf_nv1
1154 END IF
1155 buf_pe1 => buf_pe2
1156 buf_nv1 => buf_nv2
1157 NULLIFY(buf_pe2, buf_nv2)
1158 buf_pe2 => tmp1
1159 buf_nv2 => tmp2
1160 NULLIFY(tmp1, tmp2)
1161 END DO
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
1165 ridx=ridx+1
1166 rootperm(ridx) = glob_idx
1167 gnv(glob_idx) = buf_nv1(i)
1168 ELSE IF (buf_pe1(i) .EQ. 0) THEN
1169 gpe(glob_idx) = 0
1170 gnv(glob_idx) = buf_nv1(i)
1171 ELSE
1172 gpe(glob_idx) = -ord%PERITAB(-buf_pe1(i)+
1173 & ord%FIRST(proc+1)-1)
1174 gnv(glob_idx) = buf_nv1(i)
1175 END IF
1176 END DO
1177 DO i=1, ntvar
1178 glob_idx = liperm(i)
1179 IF(ipet(i) .EQ. 0) THEN
1180 gpe(glob_idx) = 0
1181 gnv(glob_idx) = nvt(i)
1182 ELSE
1183 gpe(glob_idx) = -liperm(-ipet(i))
1184 gnv(glob_idx) = nvt(i)
1185 END IF
1186 END DO
1187 DO i=1, totncliques
1188 glob_idx = rootperm(i)
1189 gpe(glob_idx) = -liperm(-ipet(ntvar+i))
1190 END DO
1191 ELSE
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)
1196 END IF
1197 CALL mumps_dealloc(buf_nv1, buf_nv2, memcnt=memcnt)
1198 CALL mumps_i8dealloc(buf_pe1, buf_pe2, ipe, ipet,
1199 & tmp1, lvarpt, memcnt=memcnt)
1200 CALL mumps_dealloc(pe, i_halo_map, ndense,
1201 & last, degree, memcnt=memcnt)
1202 CALL mumps_dealloc(w, listvar_schur, next,
1203 & nv, memcnt=memcnt)
1204 CALL mumps_dealloc(lstvar, ncliques, mylist,
1205 & memcnt=memcnt)
1206 CALL mumps_dealloc(lperm, liperm, nvt, memcnt=memcnt)
1207 CALL mumps_dealloc(rootperm, tmp2, memcnt=memcnt)
1208 NULLIFY(head, elen, leng, perm)
1209 RETURN
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 mpi_wait(ireq, status, ierr)
subroutine mpi_reduce(sendbuf, recvbuf, cnt, datatype, op, root, comm, ierr)
subroutine mpi_barrier(comm, ierr)
subroutine mpi_irecv(buf, cnt, datatype, source, tag, comm, ireq, ierr)