chole
C CHOLE SOURCE PV090527 24/04/13 21:15:03 11827 * * * octobre 2022 version unifie chole chomod: normal et condensation superelement * IMPLICIT INTEGER(I-N) IMPLICIT REAL*8(A-H,O-Z) C TANT QUE OOOVAL(1,4) NE MARCHE PAS SUR CRAY PARAMETER (LPCRAY=10000) INTEGER OOOVAL,OOOLEN dimension ittime(4) POINTEUR LILIGN.MILIGN C C **** MISE SOUS FORME A=Lt D L DE LA MATRICE MMATRX C -INC PPARAM -INC CCOPTIO -INC CCREEL -INC SMMATRI -INC SMRIGID -INC CCASSIS -INC CCHOLE SEGMENT KIVPO(IIMAX) SEGMENT KIVLO(IIMAX) segment immt(nblig) segment ireser(nvstrm) external chole3i SAVE IPASV DATA IPASV/0/ * ngmpet dit si on tient en memoire (false) ou si on deborde (true) logical ngmpet C character*8 zen C equivalence (zen,izen) logical lsgdes,pasfait,ngdyn ireser=0 nbres=0 matric=xmatri maitre=0 nelrig=1 nligrp=nligra nligrd=nligra if (xmatri.ne.0) then segini xmatri endif nbnnmc=nbnnma matric=xmatri 10000 continue pasfait=.true. lsgdes=.false. * faire attention a respecter l'ordre des segdes par la suite call ooomru(1) condmax=0.d0 condmin=xgrand*xzprec ngmpet=.false. ngdyn=.true. call timespv(ittime,oothrd) kcour=(ittime(1)+ittime(2))/10 kcouri=kcour kcour=0 nbopit=0 iposm=0 C zen='CPU'//char(0) C le=4 nvaor=0 nbthro=nbthrs ithrd=0 if (nbthro.gt.1) then ithrd=1 call threadii call oooprl(1) endif nbthr=nbthro do ith=1,nbthr nbop(ith)=0 enddo stmult=1d-5 C nouvelle methode de gestion de l'espace memoire necessitee par la parallelisation C memoire vive totale MACTIT=OOOVAL(1,1) ** write(6,*) ' mactit igrand ',mactit,igrand C un bloc de memoire fera au plus macti/2 nvstrm=mactit/10 MMATRI=MMATRX SEGACT,MMATRI*MOD PRCHLV=PREC MILIGN=IILIGN SEGACT,MILIGN*MOD INO=ILIGN(/1) MDIAG=IDIAG SEGACT,MDIAG*MOD NBLIG=INO segini immt precc=prec INC=DIAG(/1) if (matric.eq.0) nbnnmc=inc+1 nvstrm=max(inc*inpdo,nvstrm) ** write(6,*) ' nvstrm ',nvstrm INCC=INC MIMIK=IIMIK MINCPO=IINCPO SEGACT,MINCPO,MIMIK IPLUMI=IMIK(/2)*2 +4 IL2=0 IIMAX=IJMAX+IPLUMI SEGINI KIVPO,KIVLO INEG=0 NBLAG=0 NENSLX=0 NVSTOC=0 NVSTOR=0 diagmax=XPETIT/XZPREC diagmin=xgrand do i=1,diag(/1) if (ittr(i).eq.0) diagmax=max(diagmax,abs(diag(i))) if (ittr(i).eq.0.and.abs(diag(i)).gt.xpetit/xzprec) > diagmin=min(diagmin,abs(diag(i))) enddo if (diagmax.le.xpetit/xzprec) then do i=1,diag(/1) diagmax=max(diagmax,abs(diag(i))) if (abs(diag(i)).gt.xpetit/xzprec) > diagmin=min(diagmin,abs(diag(i))) enddo endif diagmin=min(diagmin,diagmax) *** write (6,*) ' chole diagmin diagmax ',diagmin,diagmax,diag(/1) C C C C **** DEBUT DE LA TRIANGULARISATION. ON PREND NOEUD A NOEUD, C **** DECOMPACTAGE PUIS TRAVAIL SUR LES LIGNES DU NOEUDS C C **** LA LONGUEUR DE LA PLUS GRANDE LIGNE EST DONNEE PAR IMAX C C SP indicateurs pour impression message "stabilisation RESO..." isr=0 isrl=0 1 CONTINUE IVALMA=IJMAX+IPLUMI IL1=IL2+1 IMIN=IL1 * reserver de la place ou mettre les lignes superieures dans le cas debordement if (ngmpet) then if (ireser.eq.0) segini ireser endif DO 2 I=IL1,INO ngdyn=.true. ** imasq=0 LLIGN= ILIGN(I) SEGACT /ERR=32/LLIGN goto 31 32 continue ** write(6,*) ' segact llign erreur',i,il1,lsgdes if (.not.lsgdes) then ** write(6,*) ' lsgdes 1 ' lsgdes=.true. ***** ngmpet=.true. ** write(6,*) 'desactivation-1 ',1,il1-1 do it=il1-1,1,-1 segdes lign enddo else goto 3 endif SEGACT /ERR=3/LLIGN 31 continue NA= IMMMM(/1) * write (6,*) ' chole ligne noeud inconnues ',i,ipno(i),na NBPAR=NA+1 NVALL= NJMAX LMASQ=NVALL/MASDIM+2 goto 34 33 continue ** write(6,*) ' segini lign erreur',il1 if (.not.lsgdes) then ** write(6,*) ' lsgdes 2 ' lsgdes=.true. ***** ngmpet=.true. ** write(6,*) 'desactivation-2 ',1,il1-1 do it=il1-1,1,-1 segdes lign enddo else goto 3 endif ** write(6,*) 'deuxieme essai lign ok' 34 continue C recuperer la longueur du segment lglig=na*(nvall/na)**1.333333333333333333 NVSTOC=NVSTOC + NVALL IVALMA=IVALMA + NVALL nvaor = nvaor + xxva(/1) C C **** DECOMPACTAGE C IPA=1 DO 121 JPA=1,NA IVPO(JPA)=IPA KPA = IPPO(JPA+1)- IPPO(JPA) IPP = IPPO(JPA) IPPVV(JPA)=IPA-1 LPA = LDEB(JPA) LPA1 = LPA-IPA DO 122 MPA=1,KPA LL = LINC(MPA+IPP) IPLA = LL -LPA1 xxv=xxva(mpa+ipp) if (abs(xxv).gt.xpetit) then VAL(IPLA)= XXV IMASQ(IPLA/MASDIM+1)=1 if (ipla-ipa+1.ge.1) IMASQ((IPLA-ipa+1)/MASDIM+1)=1 endif 122 CONTINUE IPA=IPA+ IMMMM(JPA)-LPA + 1 Cpv IMMM(JPA)= IPNO(LPA) IMMM(JPA)=LPA IF(IMIN .GT. IPNO(LPA )) IMIN = IPNO(LPA) 121 CONTINUE * indexation de imasq ipln=lmasq/na iplp=lmasq/na do 123 ipl=lmasq/na,1,-1 if (imasq(ipl).gt.0) then imasq(ipl)=iplp*masdim ipln=ipl-1 else imasq(ipl)=-ipln*masdim iplp=ipl-1 endif 123 continue ** write (6,*) ' imasq ',lmasq/na ** write (6,*) (imasq(ipl),ipl=1,lmasq/na) C*** **** **** if (na.gt.0) then IPREL= IMMMM(1) IDERL= IMMMM(NA) lcara(2,i)=iprel lcara(3,i)=iderl endif IPPVV(NA+1)=IPA-1 SEGSUP LLIGN C* write (6,*) 'longueur ligne ',nvall C nb de ligne multiple du nb de threads C blocage ligne lecture-ecriture pour minimiser le cache C on note si on est au minimum de lignes nbthro=min(nbthrs,lglig/1200+1) if (i+1-il1.ge.nbthro.and.(.not.ngmpet)) then nbthro=min(nbthrs,i+1-il1) ngdyn=.true. if(i+1-il1.eq.nbthrs) ngdyn=.false. il2=i ** write(6,*) ' nbthro il1 il2 ',nbthro,il1,il2 GOTO 4 endif 2 CONTINUE IL2=INO GO TO 4 3 IL2=I-1 ** write(6,*) 'desactivation-4 ',llign segdes llign 4 CONTINUE nbthro=min(nbthrs,nbthro) nbthr=nbthro if(ireser.ne.0) segsup ireser C IF(IL2.GE.IL1) GO TO 40 C C **** APPEL AUX ERREURS MESSAGE PAS ASSEZ DE PLACE MEMOIRE C C ITYP=48 call ooodmp(0) if (ithrd.eq.1) then call threadis call oooprl(0) endif call ooomru(0) RETURN 40 CONTINUE IM=INC DO 352 IH=IL2 ,IL1,-1 IL=INC DO 354 JH=1, IMMM(/1) IM=MIN(IM, IMMM(JH)) IL=MIN(IL, IMMM(JH)) 354 CONTINUE IML=IL lcara(1,ih)=iml immt(ih)=ipno(im) 352 CONTINUE C 353 CONTINUE IL11= IPREL C C **** BOUCLE *5* TRAVAILLE SUR LE NOEUD I QUI EST EN LECTURE C C > il1,il2 lig1= ilign(imin) ipos=0 iper=imin ider=imin-1 iderac=imin-1 IL1i=il1 DO 5 I=IMIN ,IL2 LIG1= ILIGN(I) IF(I.LT.IL1) GO TO 7 C____________ C C ******* LE NOEUD I EST EN MEMOIRE IL EST TRIANGULE JUSQU'A C ******* IPREL IL FAUT CONTINUER TOUTE LES LIGNES PUIS CALCULER C ******* LE TERME DIAGONAL C LIGN=LIG1 DO 156 KHG=1,IMMM(/1) II=IPREL-1+KHG IMMM(KHG)=0 NN=IPPVV(KHG+1) NNM1=IPPVV(KHG) N=NN-NNM1 DIAG(II)=VAL(NN) if (n.eq.1) then if(ii-nbnnmc.gt.0) then re(ii-nbnnmc,ii-nbnnmc,1)=val(nn) goto 41 else goto 8 endif endif NMI=N-II * attention subtile difference noeud maitre et non maitre if (ii-nbnnmc.le.0) then IDEP=MAX(IL11,2-NMI) else IDEP=MAX(IL11,1-NMI) endif KIDEP=IDEP+NMI KI1=N-1 KQ=-NMI VAL(NN)=VAL(NN)+ > IPNO(1-NMI),IPPVV(1),KHG,IVPO(1),KIDEP,KI1,KQ,1+IPPVV(KHG), > PREC,nbop(1)) imasq(nn/masdim+1)=1 imasq(n/masdim+1)=1 if(ii-nbnnmc.gt.0) then re(ii-nbnnmc,ii-nbnnmc,1)=val(nn) goto 41 endif 8 CONTINUE diagref=max(abs(diag(ii)),diagmin) diagcmp=diagref*5d-12 IF( ITTR(II).EQ.0.AND. & ABS( VAL(NN)).GT.diagcmp) GO TO 12 IF( ITTR(II).NE.0.AND. & ABS( VAL(NN)).GT.diagcmp) GO TO 12 ** write(6,*) ' ittr val diagcmp ',ittr(ii),val(nn),diagcmp C il faut mettre une valeur plus grande sur les LX car on a un probleme de conditionnement C sur le calcul des reactions en cas de 2 relations presque identique C C **** ON VIENT DE DETECTER UN MODE D'ENSEMBLE C **** ON AJOUTE A LA STRUCTURE UN RESSORT EGAL A CELUI QUI EXISTAIT C **** AU PREALABLE SUR CETTE INCONNUE. C * write (6,*) ' chole mode d ensemble ittr ligne ', * > ittr(ii),ii,diag(ii),val(nn),diagref C on garde le signe car il fau un moins sur les ML vmaxi=diagref do ipv=1+ippvv(khg),nn vmaxi=max(vmaxi,abs(val(ipv))) enddo if( ittr(ii).NE.0) then VAL(NN)=val(nn)-1.30D0*diagref NENSLX=NENSLX+1 else val(nn)=vmaxi endif NENS=NENS+1 IMMM(KHG)=NENS 12 CONTINUE * stabilisation IF (ISTAB.NE.0) THEN * elimination des Nan if (.not.(abs(val(nn)).lt.xgrand*xzprec).and.pasfait) then pasfait=.false. val(nn)=xgrand*xzprec write (6,*) 'Nan dans chole ligne',ii endif * diagcmp=abs(diagmin)*1d-5+xpetit/xzprec if (val(nn).lt.-diagmax*1d-3.and.ittr(ii).eq.0) then val(nn)=abs(val(nn)) *** val(nn)=diagmax*1d-3 if (immm(khg).eq.0) NENS=NENS+1 IMMM(KHG)=NENS elseif (val(nn).le.diagcmp.and.ittr(ii).eq.0 ) then if (isr.eq.0.or.iimpi.gt.0) & write (6,*) ' stabilisation RESO ',ii,val(nn),diag(ii) isr=isr+1 val(nn)=max(diagcmp,-val(nn)) if (immm(khg).eq.0) NENS=NENS+1 IMMM(KHG)=NENS else if (ittr(ii).eq.0) diagmin=min(diagmin,abs(val(nn))) endif if (val(nn).ge.abs(diag(ii))*stmult.and.ittr(ii).ne.0) then if (isrl.eq.0.or.iimpi.gt.0) & write (6,*) ' stabilisation RESO lagrange ',ii,val(nn) isrl=isrl+1 val(nn)=-abs(diag(ii))*stmult if (immm(khg).eq.0) then NENS=NENS+1 NENSLX=NENSLX+1 endif IMMM(KHG)=NENS endif ENDIF DIAG(II)= VAL(NN) IF(abs(DIAG(II)).gt.xpetit) GO TO 41 DIAG(II)=diagmax if (ittr(ii).ne.0) diag(ii)=-diagmax VAL(NN)=DIAG(II) GO TO 41 C C **** ENVOI ERREUR MATRICE SINGUIERE C C ITYP=49 INTERR(1)=I if (ithrd.eq.1) then call threadis call oooprl(0) endif call ooomru(0) RETURN C C **** ON COMPTE LE NOMBRE DE TERMES DIAGONAUX NEGATIFS C ET LE NOMBRE DE MULTIPLICATEUR DE LAGRANGE C 41 IF(DIAG(II).LT.0.D0) INEG=INEG+1 IF( ITTR(II).NE.0) NBLAG=NBLAG+1 if (ii.le.nbnnmc) condmin=min(condmin,abs(diag(ii))) condmax=max(condmax,abs(diag(ii))) if (ii.le.nbnnmc) diag(ii)=1.d0/diag(ii) 156 CONTINUE NA=IMMM(/1) C C RECOMPACTAGE DE LIGN (DEJA ENTIEREMENT TRAITEE) C * write(6,*) 'chole ligne lpl',i,na,ippvv(2)-ippvv(1) if (na.gt.0) # NVALL, IPPVV(1),IZROSF,NA,PREC,imasq(1),iprel,iderl) lmasq=0 C on recree lign car la compacter en place emiette la memoire lig1=lign segini /err=1431/ lig1 goto 1432 1431 continue write(6,*) ' segini echoue' 1432 continue nbres=max(nbres,nvall) * deplacement fait ici maintenant, avec unrolling do 300 nbp=1,nbpar-1 kdif =kivpo(nbp)-kivlo(nbp) do iv=kivlo(nbp),kivlo(nbp+1)-4,4 lig1.val(iv)=val(iv+kdif ) lig1.val(iv+1)=val(iv+1+kdif ) lig1.val(iv+2)=val(iv+2+kdif ) lig1.val(iv+3)=val(iv+3+kdif ) enddo do iv1=iv,kivlo(nbp+1)-1 lig1.val(iv1)=val(iv1+kdif ) enddo 300 continue * do it=1,nvall * lig1.val(it)=val(it) * enddo do it=1,na lig1.immm(it)=immm(it) lig1.ippvv(it)=ippvv(it) enddo lig1.ippvv(na+1)=ippvv(na+1) lig1.iml=iml lig1.iprel=iprel lig1.iderl=iderl lig1.iml=iml lcara(2,i)=lig1.iprel lcara(3,i)=lig1.iderl lcara(1,i)=lig1.iml segsup lign lign=lig1 else segadj lign endif NVSTOR=NVSTOR+NVALL nvstrm=max(nvstrm,nvall*inpdo) DO 143 LHG=1,NBPAR IVPO(2*LHG-1)=KIVPO(LHG) IVPO(2*LHG) =KIVLO(LHG) 143 CONTINUE C Si la ligne est petite, il n'y a rien a gagner a paralleliser if (i.gt.1) then lig1=ilign(i-1) ** if(lsgdes) write(6,*) 'desactivation-5 ',i if (lsgdes) segdes lig1 iderac=min(iderac,i-2) endif C C **** ON TRIANGULARISE LES AUTRES LIGNES C il1=il1+1 if (il1.gt.il2) goto 5 LIG1=ILIGN(I) IL11=IPREL goto 7 C 72 continue 71 continue * passage en superlent if (ider.lt.il1-1.and..not.ngmpet) then ** write(6,*) 'ngmpet true ',iper,ider,il1,il2 ngmpet=.true. ** do ipv=1,iper-1 ** lig2=ilign(ipv) ** call oooeta(lig2,ieta,imod) ** if (ieta.eq.1) write(6,*) 'ligne active ',ipv,iper ** enddo endif if (iper.gt.ider) then write(6,*) ' 1 chole iper ider i il1 il2 ', > iper,ider,i,il1,il2 do ipv=1,ino lig2=ilign(ipv) call oooeta(lig2,ieta,imod) if (ipv.lt.il1.or.ipv.gt.il2) then if (ieta.eq.1) write(6,*) 'ligne active ',ipv endif enddo call ooodmp(0) if (ithrd.eq.1) then call threadis call oooprl(0) endif call ooomru(0) return endif C soit parce qu'on a fini, soit parce qu'on manque de memoire C il faut executer les lignes activees puis les desactiver C lancer les chole3 et attendre qu'ils soient finis if (ipos.ne.0) then ** write (6,*) ' lancement thread ',iper,ider,il1,il2 if (iper.gt.ider) then write (6,*) ' erreur interne chole ' endif nbthr=min(nbthr,il2-il1+1) ** write(6,*) 'nbthr ',nbthr,il2-il1+1 LILIGN=MILIGN * blocage pour rester dans le cache secondaire ipers=iper iders=ider ipas=1500 if(nbthr.eq.1) ipas=igrand * do 400 iper=ipers,iders,ipas 401 continue ider=min(iders,iper+ipas-1) do ith=1,nbthr-1 enddo do ith=nbthr-1,1,-1 call threadif(ith) enddo iper=iper+ipas ipas=ipas/2 ipas=max(ipas,750) if (iper.le.iders) goto 401 400 continue iper=ipers ider=iders endif C test ctrlC if (ierr.ne.0) goto 9999 iposm=max(iposm,ipos) ipos=0 iderf=ider-1 if (ider.ne.il1-1) iderf=ider if (lsgdes) then ** write(6,*) 'desactivation 7 iper iderf',iper,iderf do il=iderf,iper,-1 segdes lign C write (6,*) ' desactivation ligne ',il enddo endif iderac=min(iderac,iper-1) iper=ider+1 C write (6,*) ' iper ider il1 ',iper,ider,il1 if (iper.ne.il1) goto 7 goto 5 7 CONTINUE if (lsgdes) SEGACT/err=71/LIG1 ipos=ipos+1 ider=i if (i.gt.iderac) iderac=i if (i.eq.il1-1) goto 71 5 CONTINUE ** write (6,*) ' il1 il2 apres 5 ',il1,il2 if (lsgdes) then ** write(6,*) 'desactivation 8 il1 il2',il1,il2 DO I=min(il1,il2),max(il1,il2) enddo endif nbopt=0 do ith=1,nbthro nbopt=nbopt+nbop(ith) nbop(ith)=0 enddo nbopin=nbopt nbopit=nbopit+nbopin call timespv(ittime,oothrd) kcour=(ittime(1)+ittime(2))/10 iderac=min(iderac,il1-1) if (ireser.ne.0) segsup ireser IF(IL2.LT.INO) GO TO 1 C ON MET A JOUR LE NOMBRE DE TERMES DIAGONAUX NEGATIF C ON ENLEVE LE NOMBRE DE MULTIPLICATEUR DE LAGRANGE C INEG=INEG-NBLAG C on ne compte pas 2 fois les multiplicateurs qui vont etre C elimines lors de la resolution car mode d'ensemble INEG=INEG-(NBLAG-NENSLX) if (iimpi.ne.0.and.NENSLX.gt.0) WRITE(IOIMP,4820) NENSLX 4820 FORMAT(I12,' MODES D ENSEMBLE PORTANT SUR DES MULTIPLICATEURS', 1' DE LAGRANGE DETECTES') IF (IIMPI.EQ.1) WRITE(IOIMP,4821) NVSTOC 4821 FORMAT( ' NOMBRE DE VALEURS DANS LE PROFIL',I12) IF (IIMPI.EQ.1) WRITE(IOIMP,4822) NVSTOR 4822 FORMAT( ' NOMBRE DE VALEURS STOCKEES DANS LE PROFIL',I12) IF (IIMPI.EQ.1) WRITE(IOIMP,4825) Nbopit/1000000 4825 FORMAT( ' NOMBRE DE GIGA OPERATIONS FMA',I40) IF (IIMPI.EQ.1) WRITE(IOIMP,4823) NVaor 4823 FORMAT( ' NOMBRE DE VALEURS initiales',I9) C IF (IIMPI.EQ.1) WRITE(IOIMP,4824) nbopit/1d6/(kcour-kcouri) C 4824 FORMAT( ' Performance en Gigaflops ',F8.1) INTERR(1)=NVSTOR reaerr(1)=nvstor/inc**(4.D0/3.D0) reaerr(2)=2.D0*nbopit/1.D6/max(1,(kcour-kcouri)) reaerr(3)=condmax/condmin IPASV=1 call ooomru(0) if(lsgdes) then do ipv=1,ino segdes lign enddo endif SEGDES,MINCPO SEGDES,MIMIK SEGDES,MMATRI SEGDES,MILIGN MMATRX=MMATRI SEGSUP KIVPO,KIVLO segsup immt C write (6,*) ' chole ipos max ',iposm 9999 continue if (ithrd.eq.1) then call threadis call oooprl(0) endif if(iimpi.ne.0) write (6,*) > ' chole condmin condmax ',condmin,condmax,diag(/1) SEGDES,MDIAG ** write(6,*) 'kseq kpar',xkseq,xkpar RETURN END
© Cast3M 2003 - Tous droits réservés.
Mentions légales