1C
2C  This file is part of MUMPS 5.1.2, released
3C  on Mon Oct  2 07:37:01 UTC 2017
4C
5C
6C  Copyright 1991-2017 CERFACS, CNRS, ENS Lyon, INP Toulouse, Inria,
7C  University of Bordeaux.
8C
9C  This version of MUMPS is provided to you free of charge. It is
10C  released under the CeCILL-C license:
11C  http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
12C
13      SUBROUTINE CMUMPS_ANA_DISTM(MYID, N, STEP, FRERE, FILS,
14     &     NA, LNA, NE, DAD, ND, PROCNODE, SLAVEF,
15     &     NRLADU, NIRADU, NIRNEC, NRLNEC,
16     &     NRLNEC_ACTIVE,
17     &     NIRADU_OOC, NIRNEC_OOC,
18     &     MAXFR, OPSA,
19     &     KEEP,KEEP8, LOCAL_M, LOCAL_N, SBUF_RECOLD,
20     &     SBUF_SEND, SBUF_REC, OPS_SUBTREE, NSTEPS,
21     &     I_AM_CAND,NMB_PAR2, ISTEP_TO_INIV2, CANDIDATES,
22     &     IFLAG, IERROR
23     &     ,MAX_FRONT_SURFACE_LOCAL
24     &     ,MAX_SIZE_FACTOR, ENTRIES_IN_FACTORS_LOC
25     &     ,ENTRIES_IN_FACTORS_LOC_MASTERS, ROOT_yes
26     &     ,ROOT_NPROW, ROOT_NPCOL
27     &     )
28      IMPLICIT NONE
29      LOGICAL, intent(in) :: ROOT_yes
30      INTEGER, intent(in) :: ROOT_NPROW, ROOT_NPCOL
31      INTEGER  MYID, N, LNA, IFLAG, IERROR
32      INTEGER  NIRADU, NIRNEC
33      INTEGER(8) NRLADU, NRLNEC, NRLNEC_ACTIVE
34      INTEGER(8) NRLADU_CURRENT, NRLADU_ROOT_3
35      INTEGER NIRADU_OOC, NIRNEC_OOC
36      INTEGER MAXFR, NSTEPS
37      INTEGER(8) MAX_FRONT_SURFACE_LOCAL
38      INTEGER STEP(N)
39      INTEGER FRERE(NSTEPS), FILS(N), NA(LNA), NE(NSTEPS),
40     &        ND(NSTEPS), PROCNODE(NSTEPS), DAD(NSTEPS)
41      INTEGER  SLAVEF, KEEP(500), LOCAL_M, LOCAL_N
42      INTEGER(8) KEEP8(150)
43      INTEGER(8) ENTRIES_IN_FACTORS_LOC,
44     &          ENTRIES_IN_FACTORS_LOC_MASTERS
45      INTEGER  SBUF_SEND, SBUF_REC
46      INTEGER(8) SBUF_RECOLD
47      INTEGER  NMB_PAR2
48      INTEGER  ISTEP_TO_INIV2( KEEP(71) )
49      LOGICAL  I_AM_CAND(NMB_PAR2)
50      INTEGER  CANDIDATES( SLAVEF+1, NMB_PAR2 )
51      REAL OPSA
52      DOUBLE PRECISION OPSA_LOC
53      INTEGER(8) MAX_SIZE_FACTOR
54      REAL OPS_SUBTREE
55      DOUBLE PRECISION OPS_SBTR_LOC
56      INTEGER, ALLOCATABLE, DIMENSION(:) :: TNSTK, IPOOL, LSTKI
57      INTEGER(8), ALLOCATABLE, DIMENSION(:) :: LSTKR
58      LOGICAL  OUTER_SENDS_FR
59      INTEGER(8) SBUFS_CB, SBUFR_CB
60      INTEGER SBUFR, SBUFS
61      INTEGER BLOCKING_RHS
62      INTEGER ITOP,NELIM,NFR
63      INTEGER(8) ISTKR, LSTK
64      INTEGER ISTKI,  STKI, ISTKI_OOC
65      INTEGER K,NSTK, IFATH
66      INTEGER INODE, LEAF, NBROOT, IN
67      INTEGER LEVEL, MAXITEMPCB
68      INTEGER(8) CURRENT_ACTIVE_MEM, MAXTEMPCB
69      LOGICAL UPDATE, UPDATEF, MASTER, MASTERF, INSSARBR
70      INTEGER LEVELF, NCB, SIZECBI
71      INTEGER(8) NCB8
72      INTEGER(8) NFR8, NELIM8
73      INTEGER(8) SIZECB, SIZECBINFR, SIZECB_SLAVE
74      INTEGER SIZEHEADER, SIZEHEADER_OOC, XSIZE_OOC
75      INTEGER EXTRA_PERM_INFO_OOC
76      INTEGER NBROWMAX, NSLAVES_LOC, NSLAVES_PASSED,
77     &         NELIMF, NFRF, NCBF,
78     &         NBROWMAXF, LKJIB,
79     &         LKJIBT, NBR, NBCOLFAC
80      INTEGER(8) LEV3MAXREC, CBMAXR, CBMAXS
81      INTEGER ALLOCOK
82      INTEGER PANEL_SIZE
83      LOGICAL COMPRESSCB
84      DOUBLE PRECISION OPS_NODE, OPS_NODE_MASTER, OPS_NODE_SLAVE
85      INTEGER(8) ENTRIES_NODE_UPPER_PART, ENTRIES_NODE_LOWER_PART
86      INCLUDE 'mumps_headers.h'
87      INTEGER WHAT
88      INTEGER(8) IDUMMY8
89      INTRINSIC min, int, real
90      INTEGER CMUMPS_OOC_GET_PANEL_SIZE
91      EXTERNAL CMUMPS_OOC_GET_PANEL_SIZE
92      INTEGER MUMPS_PROCNODE, MUMPS_TYPENODE
93      LOGICAL MUMPS_IN_OR_ROOT_SSARBR
94      INTEGER MUMPS_BLOC2_GET_NSLAVESMAX
95      EXTERNAL MUMPS_MAX_SURFCB_NBROWS, MUMPS_BLOC2_GET_NSLAVESMAX
96      EXTERNAL MUMPS_PROCNODE, MUMPS_TYPENODE,
97     &         MUMPS_IN_OR_ROOT_SSARBR
98      logical :: FORCE_CAND, CONCERNED, UPDATES, STACKCB, MASTERSON
99      integer :: IFSON, LEVELSON
100      IF (KEEP(50).eq.2) THEN
101        EXTRA_PERM_INFO_OOC = 1
102      ELSE IF (KEEP(50).eq.0) THEN
103        EXTRA_PERM_INFO_OOC = 2
104      ELSE
105        EXTRA_PERM_INFO_OOC = 0
106      ENDIF
107      COMPRESSCB=( KEEP(215).EQ.0 .AND. KEEP(50).NE.0 )
108      MAX_FRONT_SURFACE_LOCAL=0_8
109      MAX_SIZE_FACTOR=0_8
110      ALLOCATE( LSTKR(NSTEPS), TNSTK(NSTEPS), IPOOL(NSTEPS),
111     &          LSTKI(NSTEPS) , stat=ALLOCOK)
112      if (ALLOCOK .GT. 0) THEN
113        IFLAG  =-7
114        IERROR = 4*NSTEPS
115        RETURN
116      endif
117      LKJIB = max(KEEP(5),KEEP(6))
118      OUTER_SENDS_FR = (KEEP(263).NE.0)
119      IF ( OUTER_SENDS_FR ) THEN
120         LKJIB = max(LKJIB, KEEP(420))
121      ENDIF
122      IF ( KEEP(486).NE.0 ) THEN
123         LKJIB = max(LKJIB,KEEP(488))
124      ENDIF
125      TNSTK = NE
126      LEAF = NA(1)+1
127      IPOOL(1:LEAF-1) = NA(3:3+LEAF-2)
128      NBROOT = NA(2)
129#if defined(OLD_OOC_NOPANEL)
130      XSIZE_OOC=XSIZE_OOC_NOPANEL
131#else
132      IF (KEEP(50).EQ.0) THEN
133              XSIZE_OOC=XSIZE_OOC_UNSYM
134      ELSE
135              XSIZE_OOC=XSIZE_OOC_SYM
136      ENDIF
137#endif
138      SIZEHEADER_OOC = XSIZE_OOC+6
139      SIZEHEADER = XSIZE_IC + 6
140      ISTKR      = 0_8
141      ISTKI      = 0
142      ISTKI_OOC  = 0
143      OPSA_LOC   = 0.0D0
144      ENTRIES_IN_FACTORS_LOC = 0_8
145      ENTRIES_IN_FACTORS_LOC_MASTERS = 0_8
146      OPS_SBTR_LOC = 0.0D0
147      NRLADU     = 0_8
148      NIRADU     = 0
149      NIRADU_OOC = 0
150      NRLADU_CURRENT = 0_8
151      NRLADU_ROOT_3 = 0_8
152      NRLNEC_ACTIVE = 0_8
153      NRLNEC     = 0_8
154      NIRNEC     = 0
155      NIRNEC_OOC = 0
156      MAXFR      = 0
157      ITOP       = 0
158      MAXTEMPCB  = 0_8
159      MAXITEMPCB = 0
160      SBUFS_CB   = 1_8
161      SBUFS      = 1
162      SBUFR_CB   = 1_8
163      SBUFR      = 1
164      IF (KEEP(38) .NE. 0 .AND. KEEP(60).EQ.0) THEN
165        INODE  = KEEP(38)
166        NRLADU_ROOT_3 = int(LOCAL_M,8)*int(LOCAL_N,8)
167        NRLADU = NRLADU_ROOT_3
168        NRLNEC_ACTIVE = NRLADU_CURRENT
169        MAX_SIZE_FACTOR=max(MAX_SIZE_FACTOR,NRLADU_ROOT_3)
170        NRLNEC = NRLADU
171        IF (MUMPS_PROCNODE(PROCNODE(STEP(INODE)),SLAVEF)
172     &                                       .EQ. MYID) THEN
173          NIRADU     = SIZEHEADER+2*(ND(STEP(INODE))+KEEP(253))
174          NIRADU_OOC = SIZEHEADER_OOC+2*(ND(STEP(INODE))+KEEP(253))
175        ELSE
176          NIRADU     = SIZEHEADER
177          NIRADU_OOC = SIZEHEADER_OOC
178        ENDIF
179        NIRNEC     = NIRADU
180        NIRNEC_OOC = NIRADU_OOC
181      ENDIF
182      IF((KEEP(24).eq.0).OR.(KEEP(24).eq.1)) THEN
183         FORCE_CAND=.FALSE.
184      ELSE
185         FORCE_CAND=(mod(KEEP(24),2).eq.0)
186      END IF
187 90   CONTINUE
188      IF (LEAF.NE.1) THEN
189         LEAF = LEAF - 1
190         INODE = IPOOL(LEAF)
191      ELSE
192         WRITE(MYID+6,*) ' ERROR 1 in CMUMPS_ANA_DISTM '
193         CALL MUMPS_ABORT()
194      ENDIF
195 95   CONTINUE
196      NFR    = ND(STEP(INODE))+KEEP(253)
197      NFR8   = int(NFR,8)
198      NSTK   = NE(STEP(INODE))
199      NELIM = 0
200        IN = INODE
201 100    NELIM = NELIM + 1
202      NELIM8=int(NELIM,8)
203        IN = FILS(IN)
204        IF (IN .GT. 0 ) GOTO 100
205      IFSON = -IN
206      IFATH = DAD(STEP(INODE))
207      MASTER = MUMPS_PROCNODE(PROCNODE(STEP(INODE)),SLAVEF)
208     &           .EQ. MYID
209      LEVEL  = MUMPS_TYPENODE(PROCNODE(STEP(INODE)),SLAVEF)
210      INSSARBR = MUMPS_IN_OR_ROOT_SSARBR(PROCNODE(STEP(INODE)),
211     &        SLAVEF)
212      UPDATE=.FALSE.
213       if(.NOT.FORCE_CAND) then
214         UPDATE = ( (MASTER.AND.(LEVEL.NE.3) ).OR. LEVEL.EQ.2 )
215       else
216         if(MASTER.and.(LEVEL.ne.3)) then
217            UPDATE = .TRUE.
218         else if(LEVEL.eq.2) then
219            if ( I_AM_CAND(ISTEP_TO_INIV2(STEP(INODE)))) THEN
220              UPDATE = .TRUE.
221            end if
222         end if
223       end if
224      NCB      = NFR-NELIM
225      NCB8     = int(NCB,8)
226      SIZECBINFR = NCB8*NCB8
227      IF (KEEP(50).EQ.0) THEN
228        SIZECB = SIZECBINFR
229      ELSE
230        IFATH = DAD(STEP(INODE))
231        IF ( IFATH.NE.KEEP(38) .AND. COMPRESSCB ) THEN
232          SIZECB    = (NCB8*(NCB8+1_8))/2_8
233        ELSE
234          SIZECB    = SIZECBINFR
235        ENDIF
236      ENDIF
237      SIZECBI      = 2* NCB  + SIZEHEADER
238      IF (LEVEL.NE.2) THEN
239        NSLAVES_LOC     = -99999999
240        SIZECB_SLAVE = -99999997_8
241        NBROWMAX        = NCB
242      ELSE
243        IF (KEEP(48) .EQ. 5) THEN
244          WHAT = 5
245          IF (FORCE_CAND) THEN
246            NSLAVES_LOC=CANDIDATES(SLAVEF+1,
247     &                    ISTEP_TO_INIV2(STEP(INODE)))
248          ELSE
249            NSLAVES_LOC=SLAVEF-1
250          ENDIF
251          NSLAVES_PASSED=NSLAVES_LOC
252        ELSE
253          WHAT = 2
254          NSLAVES_PASSED=SLAVEF
255          NSLAVES_LOC   =SLAVEF-1
256        ENDIF
257         CALL MUMPS_MAX_SURFCB_NBROWS(WHAT, KEEP,KEEP8,
258     &     NCB, NFR, NSLAVES_PASSED, NBROWMAX, SIZECB_SLAVE
259     &    )
260      ENDIF
261      IF (KEEP(60).GT.1) THEN
262         IF (MASTER .AND. INODE.EQ.KEEP(38)) THEN
263          NIRADU     = NIRADU+SIZEHEADER+2*(ND(STEP(INODE))+KEEP(253))
264          NIRADU_OOC = NIRADU_OOC+SIZEHEADER_OOC+
265     &                 2*(ND(STEP(INODE))+KEEP(253))
266         ENDIF
267      ENDIF
268      IF (LEVEL.EQ.3) THEN
269         IF (
270     &     KEEP(60).LE.1
271     &      ) THEN
272           NRLNEC = max(NRLNEC,NRLADU+ISTKR+
273     &                 int(LOCAL_M,8)*int(LOCAL_N,8))
274           NRLADU_CURRENT = int(LOCAL_M,8)*int(LOCAL_N,8)
275           NRLNEC_ACTIVE = max(NRLNEC_ACTIVE,NRLADU_ROOT_3 +
276     &                        NRLADU_CURRENT+ISTKR)
277         ENDIF
278         IF (MASTER) THEN
279            IF (NFR.GT.MAXFR) MAXFR = NFR
280         ENDIF
281      ENDIF
282      IF(KEEP(86).EQ.1)THEN
283         IF(MASTER.AND.(.NOT.MUMPS_IN_OR_ROOT_SSARBR(
284     &        PROCNODE(STEP(INODE)), SLAVEF))
285     &     )THEN
286            IF(LEVEL.EQ.1)THEN
287               MAX_FRONT_SURFACE_LOCAL=max(MAX_FRONT_SURFACE_LOCAL,
288     &              NFR8*NFR8)
289            ELSEIF(LEVEL.EQ.2)THEN
290               IF(KEEP(50).EQ.0)THEN
291                 MAX_FRONT_SURFACE_LOCAL=max(MAX_FRONT_SURFACE_LOCAL,
292     &                 NFR8*NELIM8)
293               ELSE
294                 MAX_FRONT_SURFACE_LOCAL=max(MAX_FRONT_SURFACE_LOCAL,
295     &                 NELIM8*NELIM8)
296                 IF (KEEP(219).NE.0.AND.KEEP(50).EQ.2) THEN
297                  MAX_FRONT_SURFACE_LOCAL=max(MAX_FRONT_SURFACE_LOCAL,
298     &                  NELIM8*(NELIM8+1_8))
299                 ENDIF
300               ENDIF
301            ENDIF
302         ENDIF
303      ENDIF
304      IF (LEVEL.EQ.2) THEN
305        IF (MASTER) THEN
306          IF (KEEP(50).EQ.0) THEN
307             SBUFS = max(SBUFS, NFR*LKJIB+LKJIB+4)
308          ELSE
309             SBUFS = max(SBUFS, NELIM*LKJIB+NELIM+6)
310          ENDIF
311        ELSEIF (UPDATE) THEN
312            if (KEEP(50).EQ.0) THEN
313              SBUFR   = max(SBUFR, NFR*LKJIB+LKJIB+4)
314            else
315              SBUFR = max( SBUFR, NELIM*LKJIB+NELIM+6 )
316              IF (KEEP(50).EQ.1) THEN
317                LKJIBT  = LKJIB
318              ELSE
319                LKJIBT  = min( NELIM, LKJIB * 2 )
320              ENDIF
321              SBUFS = max(SBUFS,
322     &                        LKJIBT*NBROWMAX+6)
323              SBUFR = max( SBUFR, NBROWMAX*LKJIBT+6 )
324            endif
325        ENDIF
326      ENDIF
327      IF ( UPDATE ) THEN
328          IF ( (MASTER) .AND. (LEVEL.EQ.1) ) THEN
329            NIRADU     = NIRADU + 2*NFR + SIZEHEADER
330            NIRADU_OOC = NIRADU_OOC + 2*NFR + SIZEHEADER_OOC
331            PANEL_SIZE = CMUMPS_OOC_GET_PANEL_SIZE(
332     &      2_8*int(KEEP(226),8), NFR, KEEP(227), KEEP(50))
333            NIRADU_OOC = NIRADU_OOC +
334     &      EXTRA_PERM_INFO_OOC*(2+NELIM + NELIM/PANEL_SIZE+1)
335            IF (KEEP(50).EQ.0) THEN
336             NRLADU_CURRENT = int(NELIM,8)*int(2*NFR-NELIM,8)
337             NRLADU = NRLADU + NRLADU_CURRENT
338             MAX_SIZE_FACTOR=max(MAX_SIZE_FACTOR,NRLADU_CURRENT)
339            ELSE
340             NRLADU_CURRENT = int(NELIM,8)*int(NFR,8)
341             NRLADU = NRLADU + NRLADU_CURRENT
342             MAX_SIZE_FACTOR=max(MAX_SIZE_FACTOR,NRLADU_CURRENT)
343            ENDIF
344            SIZECBI        = 2* NCB  + 6 + 3
345          ELSEIF (LEVEL.EQ.2) THEN
346            IF (MASTER) THEN
347              NIRADU     = NIRADU+SIZEHEADER +SLAVEF-1+2*NFR
348              NIRADU_OOC = NIRADU_OOC+SIZEHEADER_OOC +SLAVEF-1+2*NFR
349              IF (KEEP(50).EQ.0) THEN
350                NBCOLFAC=NFR
351              ELSE
352                NBCOLFAC=NELIM
353              ENDIF
354              PANEL_SIZE = CMUMPS_OOC_GET_PANEL_SIZE(
355     &        2_8*int(KEEP(226),8), NBCOLFAC, KEEP(227), KEEP(50))
356              NIRADU_OOC = NIRADU_OOC +
357     &        EXTRA_PERM_INFO_OOC*(2+NELIM + NELIM/PANEL_SIZE+1)
358              NRLADU_CURRENT = int(NBCOLFAC,8)*int(NELIM,8)
359              NRLADU = NRLADU + NRLADU_CURRENT
360              MAX_SIZE_FACTOR=max(MAX_SIZE_FACTOR,NRLADU_CURRENT)
361               SIZECB     = 0_8
362               SIZECBINFR = 0_8
363               SIZECBI    = NCB + 5 +  SLAVEF - 1
364            ELSE
365             SIZECB=SIZECB_SLAVE
366             SIZECBINFR = SIZECB
367             NIRADU       = NIRADU+4+NELIM+NBROWMAX
368             NIRADU_OOC   = NIRADU_OOC+4+NELIM+NBROWMAX
369             IF (KEEP(50).EQ.0) THEN
370               NRLADU_CURRENT   =  int(NELIM,8)*int(NBROWMAX,8)
371               NRLADU   = NRLADU + NRLADU_CURRENT
372             ELSE
373               NRLADU_CURRENT   = int(NELIM,8)*int(NCB/NSLAVES_LOC,8)
374               NRLADU   = NRLADU + NRLADU_CURRENT
375             ENDIF
376             MAX_SIZE_FACTOR=max(MAX_SIZE_FACTOR,NRLADU_CURRENT)
377             SIZECBI       = 4 + NBROWMAX + NCB
378             IF (KEEP(50).NE.0) THEN
379                     SIZECBI=SIZECBI+NSLAVES_LOC+
380     &                                  XTRA_SLAVES_SYM
381             ELSE
382                     SIZECBI=SIZECBI+NSLAVES_LOC+
383     &                                  XTRA_SLAVES_UNSYM
384             ENDIF
385            ENDIF
386         ENDIF
387         NIRNEC = max0(NIRNEC,
388     &             NIRADU+ISTKI+SIZECBI+MAXITEMPCB)
389         NIRNEC_OOC = max0(NIRNEC_OOC,
390     &             NIRADU_OOC+ISTKI_OOC+SIZECBI+MAXITEMPCB +
391     &             (XSIZE_OOC-XSIZE_IC) )
392         CURRENT_ACTIVE_MEM = ISTKR+SIZECBINFR
393         IF (NSTK .NE. 0 .AND. INSSARBR .AND.
394     &     KEEP(234).NE.0 .AND. KEEP(55).EQ.0) THEN
395           CURRENT_ACTIVE_MEM = CURRENT_ACTIVE_MEM - LSTKR(ITOP)
396         ENDIF
397         IF (KEEP(50).NE.0.AND.UPDATE.AND.LEVEL.EQ.1) THEN
398             CURRENT_ACTIVE_MEM = CURRENT_ACTIVE_MEM +
399     &              int(NELIM,8)*int(NCB,8)
400         ENDIF
401         IF (MASTER .AND.  KEEP(219).NE.0.AND.
402     &       KEEP(50).EQ.2.AND.LEVEL.EQ.2) THEN
403             CURRENT_ACTIVE_MEM = CURRENT_ACTIVE_MEM + int(NELIM,8)
404         ENDIF
405         IF (SLAVEF.EQ.1) THEN
406           NRLNEC = max(NRLNEC,NRLADU+CURRENT_ACTIVE_MEM)
407           NRLNEC_ACTIVE = max(NRLNEC_ACTIVE,NRLADU_CURRENT+
408     &             NRLADU_ROOT_3+CURRENT_ACTIVE_MEM)
409         ELSE
410           NRLNEC = max(NRLNEC,NRLADU+CURRENT_ACTIVE_MEM+MAXTEMPCB)
411           NRLNEC_ACTIVE = max(NRLNEC_ACTIVE,NRLADU_CURRENT+
412     &             NRLADU_ROOT_3+CURRENT_ACTIVE_MEM+MAXTEMPCB)
413         ENDIF
414         IF (NFR.GT.MAXFR) MAXFR = NFR
415         IF (NSTK.GT.0) THEN
416            DO 70 K=1,NSTK
417               LSTK = LSTKR(ITOP)
418               ISTKR = ISTKR - LSTK
419               IF (K==1 .AND. INSSARBR.AND.KEEP(234).NE.0
420     &            .AND.KEEP(55).EQ.0) THEN
421               ELSE
422                 CURRENT_ACTIVE_MEM = CURRENT_ACTIVE_MEM - LSTK
423               ENDIF
424               STKI = LSTKI( ITOP )
425               ISTKI = ISTKI - STKI
426               ISTKI_OOC = ISTKI_OOC - STKI - (XSIZE_OOC-XSIZE_IC)
427               ITOP = ITOP - 1
428               IF (ITOP.LT.0) THEN
429                  write(*,*) MYID,
430     &            ': ERROR 2 in CMUMPS_ANA_DISTM. ITOP = ',ITOP
431                  CALL MUMPS_ABORT()
432               ENDIF
433 70         CONTINUE
434         ENDIF
435      ELSE IF (LEVEL.NE.3) THEN
436         DO WHILE (IFSON.GT.0)
437            UPDATES=.FALSE.
438            MASTERSON = MUMPS_PROCNODE(PROCNODE(STEP(IFSON)),SLAVEF)
439     &                  .EQ.MYID
440            LEVELSON  = MUMPS_TYPENODE(PROCNODE(STEP(IFSON)),SLAVEF)
441            if(.NOT.FORCE_CAND) then
442               UPDATES =((MASTERSON.AND.(LEVELSON.NE.3)).OR.
443     &                   LEVELSON.EQ.2)
444            else
445               if(MASTERSON.and.(LEVELSON.ne.3)) then
446                  UPDATES = .TRUE.
447               else if(LEVELSON.eq.2) then
448                  if ( I_AM_CAND(ISTEP_TO_INIV2(STEP(IFSON)))) then
449                    UPDATES = .TRUE.
450                  end if
451               end if
452            end if
453            IF (UPDATES) THEN
454              LSTK = LSTKR(ITOP)
455              ISTKR = ISTKR - LSTK
456              STKI = LSTKI( ITOP )
457              ISTKI = ISTKI - STKI
458              ISTKI_OOC = ISTKI_OOC - STKI - (XSIZE_OOC-XSIZE_IC)
459              ITOP = ITOP - 1
460              IF (ITOP.LT.0) THEN
461                write(*,*) MYID,
462     &          ': ERROR 2 in CMUMPS_ANA_DISTM. ITOP = ',ITOP
463                CALL MUMPS_ABORT()
464              ENDIF
465            ENDIF
466            IFSON = FRERE(STEP(IFSON))
467         END DO
468      ENDIF
469      IF (
470     &        ( (INODE.NE.KEEP(20)).OR.(KEEP(60).EQ.0) )
471     &       .AND.
472     &        ( (INODE.NE.KEEP(38)).OR.(KEEP(60).LE.1) )
473     &      )
474     &  THEN
475            ENTRIES_NODE_LOWER_PART = int(NFR-NELIM,8) * int(NELIM,8)
476            IF ( KEEP(50).EQ.0 ) THEN
477              ENTRIES_NODE_UPPER_PART = int(NFR,8) * int(NELIM,8)
478            ELSE
479              ENTRIES_NODE_UPPER_PART =
480     &        (int(NELIM,8)*int(NELIM+1,8))/2_8
481            ENDIF
482            IF (KEEP(50).EQ.2 .AND. LEVEL.EQ.3) THEN
483              CALL MUMPS_GET_FLOPS_COST(NFR,
484     &           NELIM, NELIM, 0,
485     &           1,OPS_NODE)
486            ELSE
487              CALL MUMPS_GET_FLOPS_COST(NFR,
488     &           NELIM, NELIM,KEEP(50),
489     &           1,OPS_NODE)
490            ENDIF
491            IF (LEVEL.EQ.2) THEN
492              CALL MUMPS_GET_FLOPS_COST(NFR,
493     &           NELIM, NELIM,KEEP(50),
494     &           2,OPS_NODE_MASTER)
495              OPS_NODE_SLAVE=OPS_NODE-OPS_NODE_MASTER
496            ENDIF
497      ELSE
498           OPS_NODE = 0.0D0
499           ENTRIES_NODE_UPPER_PART = 0_8
500           ENTRIES_NODE_LOWER_PART = 0_8
501      ENDIF
502      IF ( MASTER )  THEN
503        ENTRIES_IN_FACTORS_LOC_MASTERS =
504     &                     ENTRIES_IN_FACTORS_LOC_MASTERS +
505     &                            ENTRIES_NODE_UPPER_PART +
506     &                            ENTRIES_NODE_LOWER_PART
507      ENDIF
508      IF (UPDATE.OR.LEVEL.EQ.3) THEN
509         IF ( LEVEL .EQ. 3 ) THEN
510            IF (ROOT_yes) THEN
511              CALL MUMPS_UPDATE_FLOPS_ROOT( OPSA_LOC, KEEP(50), NFR,
512     &             NFR, ROOT_NPROW, ROOT_NPCOL, MYID )
513              ENTRIES_IN_FACTORS_LOC = ENTRIES_IN_FACTORS_LOC +
514     &                            ENTRIES_NODE_UPPER_PART /
515     &                            int(ROOT_NPROW*ROOT_NPCOL,8)
516              IF (MASTER) THEN
517                ENTRIES_IN_FACTORS_LOC = ENTRIES_IN_FACTORS_LOC +
518     &                                 mod(ENTRIES_NODE_UPPER_PART,
519     &                                 int(SLAVEF,8))
520              ENDIF
521            ENDIF
522         ELSE IF (MASTER .AND. LEVEL.EQ.2) THEN
523            OPSA_LOC = OPSA_LOC + OPS_NODE_MASTER
524            ENTRIES_IN_FACTORS_LOC = ENTRIES_IN_FACTORS_LOC +
525     &                      ENTRIES_NODE_UPPER_PART +
526     &                      mod(ENTRIES_NODE_LOWER_PART,
527     &                          int(NSLAVES_LOC,8))
528         ELSE IF (MASTER .AND. LEVEL.EQ.1) THEN
529            OPSA_LOC = OPSA_LOC + dble(OPS_NODE)
530            ENTRIES_IN_FACTORS_LOC = ENTRIES_IN_FACTORS_LOC +
531     &                               ENTRIES_NODE_UPPER_PART +
532     &                               ENTRIES_NODE_LOWER_PART
533         ELSE IF (UPDATE) THEN
534            OPSA_LOC = OPSA_LOC +
535     &            dble(OPS_NODE_SLAVE)/dble(NSLAVES_LOC)
536            ENTRIES_IN_FACTORS_LOC = ENTRIES_IN_FACTORS_LOC
537     &                 + ENTRIES_NODE_LOWER_PART /
538     &                 int(NSLAVES_LOC,8)
539         ENDIF
540         IF (MUMPS_IN_OR_ROOT_SSARBR(PROCNODE(STEP(INODE)),
541     &        SLAVEF) .OR. NE(STEP(INODE))==0) THEN
542           IF (LEVEL == 1) THEN
543             OPS_SBTR_LOC = OPS_SBTR_LOC + OPS_NODE
544           ELSE
545             CALL MUMPS_GET_FLOPS_COST(NFR,
546     &           NELIM, NELIM,KEEP(50),
547     &           1,OPS_NODE)
548             OPS_SBTR_LOC = OPS_SBTR_LOC + OPS_NODE
549           ENDIF
550         ENDIF
551        ENDIF
552      IF (IFATH .EQ. 0) THEN
553         NBROOT = NBROOT - 1
554         IF (NBROOT.EQ.0) GOTO 115
555         GOTO 90
556      ELSE
557         NFRF = ND(STEP(IFATH))+KEEP(253)
558         IF (DAD(STEP(IFATH)).EQ.0) THEN
559           NELIMF = NFRF
560         ELSE
561           NELIMF = 0
562           IN = IFATH
563           DO WHILE (IN.GT.0)
564              IN = FILS(IN)
565              NELIMF = NELIMF+1
566           ENDDO
567         ENDIF
568         NCBF = NFRF - NELIMF
569         LEVELF = MUMPS_TYPENODE(PROCNODE(STEP(IFATH)),SLAVEF)
570         MASTERF= MUMPS_PROCNODE(PROCNODE(STEP(IFATH)),SLAVEF).EQ.MYID
571         UPDATEF= .FALSE.
572         if(.NOT.FORCE_CAND) then
573            UPDATEF= ((MASTERF.AND.(LEVELF.NE.3)).OR.LEVELF.EQ.2)
574         else
575            if(MASTERF.and.(LEVELF.ne.3)) then
576               UPDATEF = .TRUE.
577            else if (LEVELF.eq.2) then
578               if ( I_AM_CAND(ISTEP_TO_INIV2(STEP(IFATH)))) THEN
579                 UPDATEF = .TRUE.
580               end if
581            end if
582         end if
583         CONCERNED  = UPDATEF .OR. UPDATE
584         IF (LEVELF .NE. 2) THEN
585           NBROWMAXF = -999999
586         ELSE
587           IF (KEEP(48) .EQ. 5) THEN
588               WHAT = 4
589               IF (FORCE_CAND) THEN
590                 NSLAVES_LOC=CANDIDATES(SLAVEF+1,
591     &               ISTEP_TO_INIV2(STEP(IFATH)))
592               ELSE
593                 NSLAVES_LOC=SLAVEF-1
594               ENDIF
595           ELSE
596               WHAT = 1
597               NSLAVES_LOC=SLAVEF
598           ENDIF
599           CALL MUMPS_MAX_SURFCB_NBROWS( WHAT, KEEP, KEEP8,
600     &     NCBF, NFRF, NSLAVES_LOC, NBROWMAXF, IDUMMY8
601     &          )
602         ENDIF
603         IF(LEVEL.EQ.1.AND.UPDATE.AND.
604     &      (UPDATEF.OR.LEVELF.EQ.2)
605     &      .AND.LEVELF.NE.3) THEN
606             IF ( INSSARBR .AND. KEEP(234).NE.0) THEN
607               NRLNEC_ACTIVE = max(NRLNEC_ACTIVE,NRLADU_CURRENT+
608     &           NRLADU_ROOT_3+CURRENT_ACTIVE_MEM)
609               NRLNEC = max(NRLNEC,NRLADU+CURRENT_ACTIVE_MEM)
610             ELSE
611               NRLNEC_ACTIVE = max(NRLNEC_ACTIVE,NRLADU_CURRENT+
612     &           NRLADU_ROOT_3+CURRENT_ACTIVE_MEM+SIZECB)
613               NRLNEC = max(NRLNEC,NRLADU+CURRENT_ACTIVE_MEM+SIZECB)
614             ENDIF
615         ENDIF
616         IF (UPDATE .AND. LEVEL.EQ.2 .AND. .NOT. MASTER) THEN
617             NRLNEC =
618     &         max(NRLNEC,NRLADU+CURRENT_ACTIVE_MEM+NRLADU_CURRENT)
619             NRLNEC_ACTIVE = max(NRLNEC_ACTIVE,2_8*NRLADU_CURRENT+
620     &         NRLADU_ROOT_3+CURRENT_ACTIVE_MEM)
621         ENDIF
622        IF (LEVELF.EQ.3) THEN
623          IF (LEVEL.EQ.1) THEN
624            LEV3MAXREC = int(min(NCB,LOCAL_M),8) *
625     &                   int(min(NCB,LOCAL_N),8)
626          ELSE
627            LEV3MAXREC = min(SIZECB,
628     &                 int(min(NBROWMAX,LOCAL_M),8)
629     &                *int(min(NCB,LOCAL_N),8))
630          ENDIF
631          MAXTEMPCB  = max(MAXTEMPCB, LEV3MAXREC)
632          MAXITEMPCB = max(MAXITEMPCB,SIZECBI+SIZEHEADER)
633          SBUFR_CB   = max(SBUFR_CB, LEV3MAXREC+int(SIZECBI,8))
634          NIRNEC = max(NIRNEC,NIRADU+ISTKI+
635     &    min(NCB,LOCAL_M)+ min(NCB,LOCAL_N)+SIZEHEADER)
636          NIRNEC_OOC = max(NIRNEC_OOC,NIRADU_OOC+ISTKI_OOC+
637     &    min(NCB,LOCAL_M)+ min(NCB,LOCAL_N)+SIZEHEADER)
638        ENDIF
639        IF (CONCERNED) THEN
640         IF (LEVELF.EQ.2) THEN
641           IF (UPDATE.AND.(LEVEL.NE.2.OR..NOT.MASTER)) THEN
642             IF(MASTERF)THEN
643                 NBR = min(NBROWMAXF,NBROWMAX)
644             ELSE
645                 NBR = min(max(NELIMF,NBROWMAXF),NBROWMAX)
646             ENDIF
647             IF (KEEP(50).EQ.0) THEN
648               CBMAXS = int(NBR,8)*int(NCB,8)
649             ELSE
650               CBMAXS = int(NBR,8)*int(NCB,8) -
651     &                  (int(NBR,8)*int(NBR-1,8))/2_8
652             ENDIF
653           ELSE
654              CBMAXS = 0_8
655           END IF
656           IF (MASTERF) THEN
657             IF (LEVEL.EQ.1) THEN
658                IF (.NOT.UPDATE) THEN
659                  NBR = min(NELIMF, NCB)
660                ELSE
661                  NBR = 0
662                ENDIF
663             ELSE
664                NBR = min(NELIMF, NBROWMAX)
665             ENDIF
666             IF (KEEP(50).EQ.0) THEN
667                CBMAXR = int(NBR,8)*NCB8
668             ELSE
669                CBMAXR = int(NBR,8)*int(min(NCB,NELIMF),8)-
670     &                   (int(NBR,8)*int(NBR-1,8))/2_8
671                CBMAXR = min(CBMAXR, int(NELIMF,8)*int(NELIMF+1,8)/2_8)
672                CBMAXR = min(CBMAXR, SIZECB)
673                IF ((LEVEL.EQ.1).AND.(.NOT. COMPRESSCB)) THEN
674                  CBMAXR = min(CBMAXR,(NCB8*(NCB8+1_8))/2_8)
675                ENDIF
676             ENDIF
677           ELSE IF (UPDATEF) THEN
678              NBR = min(NBROWMAXF,NBROWMAX)
679              CBMAXR = int(NBR,8) * NCB8
680              IF (KEEP(50).NE.0) THEN
681                CBMAXR = CBMAXR - (int(NBR,8)*(int(NBR-1,8)))/2_8
682              ENDIF
683           ELSE
684              CBMAXR = 0_8
685           ENDIF
686         ELSEIF (LEVELF.EQ.3) THEN
687           CBMAXR = LEV3MAXREC
688           IF (UPDATE.AND. .NOT. (MASTER.AND.LEVEL.EQ.2)) THEN
689             CBMAXS = LEV3MAXREC
690           ELSE
691             CBMAXS = 0_8
692           ENDIF
693         ELSE
694           IF (MASTERF) THEN
695             CBMAXS = 0_8
696             NBR = min(NFRF,NBROWMAX)
697             IF ((LEVEL.EQ.1).AND.UPDATE) THEN
698                NBR = 0
699             ENDIF
700             CBMAXR = int(NBR,8)*int(min(NFRF,NCB),8)
701             IF (LEVEL.EQ.2)
702     &       CBMAXR = min(CBMAXR, SIZECB_SLAVE)
703             IF ( KEEP(50).NE.0 )  THEN
704              CBMAXR = min(CBMAXR,(int(NFRF,8)*int(NFRF+1,8))/2_8)
705             ELSE
706              CBMAXR = min(CBMAXR,int(NFRF,8)*int(NFRF,8))
707             ENDIF
708           ELSE
709             CBMAXR = 0_8
710             CBMAXS = SIZECB
711           ENDIF
712         ENDIF
713         IF (UPDATE) THEN
714           CBMAXS = min(CBMAXS, SIZECB)
715           IF ( .not. ( LEVELF .eq. 1 .AND. UPDATEF ) )THEN
716              SBUFS_CB = max(SBUFS_CB, CBMAXS+int(SIZECBI,8))
717           ENDIF
718         ENDIF
719         STACKCB = .FALSE.
720         IF (UPDATEF) THEN
721          STACKCB = .TRUE.
722          SIZECBI     = 2 * NFR + SIZEHEADER
723          IF (LEVEL.EQ.1) THEN
724             IF (KEEP(50).NE.0.AND.LEVELF.NE.3
725     &           .AND.COMPRESSCB) THEN
726                 SIZECB = (NCB8*(NCB8+1_8))/2_8
727             ELSE
728                 SIZECB = NCB8*NCB8
729             ENDIF
730             IF (MASTER) THEN
731               SIZECBI     = 2+ XSIZE_IC
732             ELSE IF (LEVELF.EQ.1) THEN
733               SIZECB  = min(CBMAXR,SIZECB)
734               SIZECBI    = 2 * NCB +  9
735               SBUFR_CB   = max(SBUFR_CB, int(SIZECBI,8)+SIZECB)
736               SIZECBI    =  2 * NCB + SIZEHEADER
737             ELSE
738               SIZECBI    = 2 * NCB +  9
739               SBUFR_CB   = max(SBUFR_CB,
740     &                      min(SIZECB,CBMAXR) + int(SIZECBI,8))
741               MAXTEMPCB  = max(MAXTEMPCB, min(SIZECB,CBMAXR))
742               SIZECBI    =  2 * NCB + SIZEHEADER
743               MAXITEMPCB = max(MAXITEMPCB, SIZECBI)
744               SIZECBI     = 0
745               SIZECB      = 0_8
746             ENDIF
747          ELSE
748             SIZECB = SIZECB_SLAVE
749             MAXTEMPCB  = max(MAXTEMPCB, min(CBMAXR,SIZECB) )
750             MAXITEMPCB = max(MAXITEMPCB,NBROWMAX+NCB+SIZEHEADER)
751             IF (.NOT.
752     &        (UPDATE.AND.(.NOT.MASTER).AND.(NSLAVES_LOC.EQ.1))
753     &          )
754     &       SBUFR_CB = max(SBUFR_CB,
755     &            min(CBMAXR,SIZECB) + int(NBROWMAX + NCB + 6,8))
756             IF (MASTER) THEN
757              SIZECBI     =  NCB + 5 +  SLAVEF - 1 + XSIZE_IC
758              SIZECB  = 0_8
759             ELSE IF (UPDATE) THEN
760              SIZECBI      =  NFR + 6 + SLAVEF - 1 + XSIZE_IC
761              IF (KEEP(50).EQ.0) THEN
762                SIZECBI = SIZECBI + NBROWMAX + NFR +
763     &                    SIZEHEADER
764              ELSE
765                SIZECBI = SIZECBI + NBROWMAX + NFR +
766     &                    SIZEHEADER+ NSLAVES_LOC
767              ENDIF
768             ELSE
769              SIZECB      = 0_8
770              SIZECBI     = 0
771             ENDIF
772          ENDIF
773         ELSE
774           IF (LEVELF.NE.3) THEN
775               STACKCB     = .TRUE.
776               SIZECB      = 0_8
777               SIZECBI     = 0
778               IF ( (LEVEL.EQ.1) .AND. (LEVELF.NE.1) ) THEN
779                  IF (COMPRESSCB) THEN
780                      SIZECB  = (NCB8*(NCB8+1_8))/2_8
781                  ELSE
782                      SIZECB  = NCB8*NCB8
783                  ENDIF
784                  SIZECBI     = 2 * NCB + SIZEHEADER
785               ELSE IF (LEVEL.EQ.2) THEN
786                 IF (MASTER) THEN
787                   SIZECBI     =  NCB + 5 +  SLAVEF - 1 + XSIZE_IC
788                 ELSE
789                   SIZECB  = SIZECB_SLAVE
790                   SIZECBI = SIZECBI + NBROWMAX + NFR + SIZEHEADER
791                 ENDIF
792               ENDIF
793           ENDIF
794         ENDIF
795         IF (STACKCB) THEN
796           IF (FRERE(STEP(INODE)).EQ.0) THEN
797                  write(*,*) ' ERROR 3 in CMUMPS_ANA_DISTM'
798                  CALL MUMPS_ABORT()
799           ENDIF
800           ITOP = ITOP + 1
801           IF ( ITOP .GT. NSTEPS ) THEN
802             WRITE(*,*) 'ERROR 4 in CMUMPS_ANA_DISTM '
803           ENDIF
804           LSTKI(ITOP) = SIZECBI
805           ISTKI=ISTKI + SIZECBI
806           ISTKI_OOC = ISTKI_OOC + SIZECBI + (XSIZE_OOC-XSIZE_IC)
807           LSTKR(ITOP) = SIZECB
808           ISTKR = ISTKR + LSTKR(ITOP)
809           NRLNEC = max(NRLNEC,NRLADU+ISTKR+MAXTEMPCB)
810           NIRNEC = max0(NIRNEC,NIRADU+ISTKI+MAXITEMPCB)
811           NIRNEC_OOC = max0(NIRNEC_OOC,NIRADU_OOC+ISTKI_OOC+
812     &          MAXITEMPCB +
813     &          (XSIZE_OOC-XSIZE_IC) )
814         ENDIF
815        ENDIF
816         TNSTK(STEP(IFATH)) = TNSTK(STEP(IFATH)) - 1
817         IF ( TNSTK(STEP(IFATH)) .EQ. 0 ) THEN
818            INODE = IFATH
819            GOTO 95
820         ELSE
821            GOTO 90
822         ENDIF
823      ENDIF
824 115  CONTINUE
825      BLOCKING_RHS = KEEP(84)
826      IF (KEEP(84).EQ.0) BLOCKING_RHS=1
827      NRLNEC = max(NRLNEC,
828     &         NRLADU+int(4*KEEP(127)*abs(BLOCKING_RHS),8))
829      IF (BLOCKING_RHS .LT. 0) THEN
830        BLOCKING_RHS = - 2 * BLOCKING_RHS
831      ENDIF
832      NRLNEC_ACTIVE = max(NRLNEC_ACTIVE, MAX_SIZE_FACTOR+
833     &                    int(4*KEEP(127)*BLOCKING_RHS,8))
834      SBUF_RECOLD = max(int(SBUFR,8),SBUFR_CB)
835      SBUF_RECOLD = max(SBUF_RECOLD,
836     &        MAXTEMPCB+int(MAXITEMPCB,8)) + 10_8
837      SBUF_REC = max(SBUFR, int(min(100000_8,SBUFR_CB)))
838      SBUF_REC = SBUF_REC   + 17
839      SBUF_REC = SBUF_REC + 2 * KEEP(127) + SLAVEF - 1 + 7
840      SBUF_SEND = max(SBUFS, int(min(100000_8,SBUFR_CB)))
841      SBUF_SEND = SBUF_SEND + 17
842      IF(KEEP(219).NE.0.AND.KEEP(50) .EQ. 2) THEN
843         SBUF_RECOLD = SBUF_RECOLD+int(KEEP(108)+1,8)
844         SBUF_REC = SBUF_REC+KEEP(108)+1
845         SBUF_SEND = SBUF_SEND+KEEP(108)+1
846      ENDIF
847      IF (SLAVEF.EQ.1) THEN
848         SBUF_RECOLD = 1_8
849         SBUF_REC = 1
850         SBUF_SEND= 1
851      ENDIF
852      DEALLOCATE( LSTKR, TNSTK, IPOOL,
853     &          LSTKI )
854      OPS_SUBTREE = real(OPS_SBTR_LOC)
855      OPSA        = real(OPSA_LOC)
856      KEEP(66)    = int(OPSA_LOC/1000000.d0)
857      RETURN
858      END SUBROUTINE CMUMPS_ANA_DISTM
859