LCOV - code coverage report
Current view: top level - /builds/ug4-project/ugcore/ug4-new/plugins/SuperLU6/external/superlu/SRC - dcolumn_dfs.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 86 0
Test Date: 2026-06-01 23:54:59 Functions: 0.0 % 1 0

            Line data    Source code
       1              : /*! \file
       2              : Copyright (c) 2003, The Regents of the University of California, through
       3              : Lawrence Berkeley National Laboratory (subject to receipt of any required 
       4              : approvals from U.S. Dept. of Energy) 
       5              : 
       6              : All rights reserved. 
       7              : 
       8              : The source code is distributed under BSD license, see the file License.txt
       9              : at the top-level directory.
      10              : */
      11              : 
      12              : /*! @file dcolumn_dfs.c
      13              :  * \brief Performs a symbolic factorization
      14              :  *
      15              :  * <pre>
      16              :  * -- SuperLU routine (version 3.0) --
      17              :  * Univ. of California Berkeley, Xerox Palo Alto Research Center,
      18              :  * and Lawrence Berkeley National Lab.
      19              :  * October 15, 2003
      20              :  *
      21              :  * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
      22              :  *
      23              :  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
      24              :  * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
      25              :  *
      26              :  * Permission is hereby granted to use or copy this program for any
      27              :  * purpose, provided the above notices are retained on all copies.
      28              :  * Permission to modify the code and to distribute modified code is
      29              :  * granted, provided the above notices are retained, and a notice that
      30              :  * the code was modified is included with the above copyright notice.
      31              :  * </pre>
      32              : */
      33              : 
      34              : #include "slu_ddefs.h"
      35              : 
      36              : /*! \brief What type of supernodes we want */
      37              : #define T2_SUPER
      38              : 
      39              : 
      40              : /*! \brief
      41              :  *
      42              :  * <pre>
      43              :  * Purpose
      44              :  * =======
      45              :  *   DCOLUMN_DFS performs a symbolic factorization on column jcol, and
      46              :  *   decide the supernode boundary.
      47              :  *
      48              :  *   This routine does not use numeric values, but only use the RHS 
      49              :  *   row indices to start the dfs.
      50              :  *
      51              :  *   A supernode representative is the last column of a supernode.
      52              :  *   The nonzeros in U[*,j] are segments that end at supernodal
      53              :  *   representatives. The routine returns a list of such supernodal 
      54              :  *   representatives in topological order of the dfs that generates them.
      55              :  *   The location of the first nonzero in each such supernodal segment
      56              :  *   (supernodal entry location) is also returned.
      57              :  *
      58              :  * Local parameters
      59              :  * ================
      60              :  *   nseg: no of segments in current U[*,j]
      61              :  *   jsuper: jsuper=SLU_EMPTY if column j does not belong to the same
      62              :  *      supernode as j-1. Otherwise, jsuper=nsuper.
      63              :  *
      64              :  *   marker2: A-row --> A-row/col (0/1)
      65              :  *   repfnz: SuperA-col --> PA-row
      66              :  *   parent: SuperA-col --> SuperA-col
      67              :  *   xplore: SuperA-col --> index to L-structure
      68              :  *
      69              :  * Return value
      70              :  * ============
      71              :  *     0  success;
      72              :  *   > 0  number of bytes allocated when run out of space.
      73              :  * </pre>
      74              :  */
      75              : int
      76            0 : dcolumn_dfs(
      77              :            const int  m,         /* in - number of rows in the matrix */
      78              :            const int  jcol,      /* in */
      79              :            int        *perm_r,   /* in */
      80              :            int        *nseg,     /* modified - with new segments appended */
      81              :            int        *lsub_col, /* in - defines the RHS vector to start the dfs */
      82              :            int        *segrep,   /* modified - with new segments appended */
      83              :            int        *repfnz,   /* modified */
      84              :            int_t      *xprune,   /* modified */
      85              :            int        *marker,   /* modified */
      86              :            int        *parent,   /* working array */
      87              :            int_t      *xplore,   /* working array */
      88              :            GlobalLU_t *Glu       /* modified */
      89              :            )
      90              : {
      91              : 
      92              :     int     jcolp1, jcolm1, jsuper, nsuper;
      93              :     int     krep, krow, kmark, kperm;
      94              :     int     *marker2;           /* Used for small panel LU */
      95              :     int     fsupc;              /* First column of a snode */
      96              :     int     myfnz;              /* First nonz column of a U-segment */
      97              :     int     chperm, chmark, chrep, kchild;
      98              :     int_t   xdfs, maxdfs, nextl, k;
      99              :     int     kpar, oldrep;
     100              :     int_t   jptr, jm1ptr;
     101              :     int_t   ito, ifrom, istop;  /* Used to compress row subscripts */
     102              :     int     *xsup, *supno;
     103              :     int_t   *lsub, *xlsub;
     104              :     int_t   nzlmax, mem_error;
     105              :     int     maxsuper;
     106              :     
     107            0 :     xsup    = Glu->xsup;
     108            0 :     supno   = Glu->supno;
     109            0 :     lsub    = Glu->lsub;
     110            0 :     xlsub   = Glu->xlsub;
     111            0 :     nzlmax  = Glu->nzlmax;
     112              : 
     113            0 :     maxsuper = sp_ienv(3);
     114            0 :     jcolp1  = jcol + 1;
     115            0 :     jcolm1  = jcol - 1;
     116            0 :     nsuper  = supno[jcol];
     117              :     jsuper  = nsuper;
     118            0 :     nextl   = xlsub[jcol];
     119            0 :     marker2 = &marker[2*m];
     120              : 
     121              :     /* For each nonzero in A[*,jcol] do dfs */
     122            0 :     for (k = 0; lsub_col[k] != SLU_EMPTY; k++) {
     123              : 
     124              :         krow = lsub_col[k];
     125            0 :         lsub_col[k] = SLU_EMPTY;
     126            0 :         kmark = marker2[krow];          
     127              : 
     128              :         /* krow was visited before, go to the next nonz */
     129            0 :         if ( kmark == jcol ) continue; 
     130              : 
     131              :         /* For each unmarked nbr krow of jcol
     132              :          *      krow is in L: place it in structure of L[*,jcol]
     133              :          */
     134            0 :         marker2[krow] = jcol;
     135            0 :         kperm = perm_r[krow];
     136              : 
     137            0 :         if ( kperm == SLU_EMPTY ) {
     138            0 :             lsub[nextl++] = krow;       /* krow is indexed into A */
     139            0 :             if ( nextl >= nzlmax ) {
     140            0 :                 mem_error = dLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu);
     141            0 :                 if ( mem_error ) return (mem_error);
     142            0 :                 lsub = Glu->lsub;
     143              :             }
     144            0 :             if ( kmark != jcolm1 ) jsuper = SLU_EMPTY;/* Row index subset testing */
     145              :         } else {
     146              :             /*  krow is in U: if its supernode-rep krep
     147              :              *  has been explored, update repfnz[*]
     148              :              */
     149            0 :             krep = xsup[supno[kperm]+1] - 1;
     150            0 :             myfnz = repfnz[krep];
     151              : 
     152            0 :             if ( myfnz != SLU_EMPTY ) { /* Visited before */
     153            0 :                 if ( myfnz > kperm ) repfnz[krep] = kperm;
     154              :                 /* continue; */
     155              :             }
     156              :             else {
     157              :                 /* Otherwise, perform dfs starting at krep */
     158              :                 oldrep = SLU_EMPTY;
     159            0 :                 parent[krep] = oldrep;
     160            0 :                 repfnz[krep] = kperm;
     161            0 :                 xdfs = xlsub[krep];
     162            0 :                 maxdfs = xprune[krep];
     163              : 
     164              :                 do {
     165              :                     /* 
     166              :                      * For each unmarked kchild of krep 
     167              :                      */
     168            0 :                     while ( xdfs < maxdfs ) {
     169              : 
     170            0 :                         kchild = lsub[xdfs];
     171            0 :                         xdfs++;
     172            0 :                         chmark = marker2[kchild];
     173              : 
     174            0 :                         if ( chmark != jcol ) { /* Not reached yet */
     175            0 :                             marker2[kchild] = jcol;
     176            0 :                             chperm = perm_r[kchild];
     177              : 
     178              :                             /* Case kchild is in L: place it in L[*,k] */
     179            0 :                             if ( chperm == SLU_EMPTY ) {
     180            0 :                                 lsub[nextl++] = kchild;
     181            0 :                                 if ( nextl >= nzlmax ) {
     182              :                                     mem_error =
     183            0 :                                          dLUMemXpand(jcol,nextl,LSUB,&nzlmax,Glu);
     184            0 :                                     if ( mem_error ) return (mem_error);
     185            0 :                                     lsub = Glu->lsub;
     186              :                                 }
     187            0 :                                 if ( chmark != jcolm1 ) jsuper = SLU_EMPTY;
     188              :                             } else {
     189              :                                 /* Case kchild is in U: 
     190              :                                  *   chrep = its supernode-rep. If its rep has 
     191              :                                  *   been explored, update its repfnz[*]
     192              :                                  */
     193            0 :                                 chrep = xsup[supno[chperm]+1] - 1;
     194            0 :                                 myfnz = repfnz[chrep];
     195            0 :                                 if ( myfnz != SLU_EMPTY ) { /* Visited before */
     196            0 :                                     if ( myfnz > chperm )
     197            0 :                                         repfnz[chrep] = chperm;
     198              :                                 } else {
     199              :                                     /* Continue dfs at super-rep of kchild */
     200            0 :                                     xplore[krep] = xdfs;        
     201              :                                     oldrep = krep;
     202              :                                     krep = chrep; /* Go deeper down G(L^t) */
     203            0 :                                     parent[krep] = oldrep;
     204            0 :                                     repfnz[krep] = chperm;
     205            0 :                                     xdfs = xlsub[krep];     
     206            0 :                                     maxdfs = xprune[krep];
     207              :                                 } /* else */
     208              : 
     209              :                            } /* else */
     210              : 
     211              :                         } /* if */
     212              : 
     213              :                     } /* while */
     214              : 
     215              :                     /* krow has no more unexplored nbrs;
     216              :                      *    place supernode-rep krep in postorder DFS.
     217              :                      *    backtrack dfs to its parent
     218              :                      */
     219            0 :                     segrep[*nseg] = krep;
     220            0 :                     ++(*nseg);
     221            0 :                     kpar = parent[krep]; /* Pop from stack, mimic recursion */
     222            0 :                     if ( kpar == SLU_EMPTY ) break; /* dfs done */
     223              :                     krep = kpar;
     224            0 :                     xdfs = xplore[krep];
     225            0 :                     maxdfs = xprune[krep];
     226              : 
     227              :                 } while ( kpar != SLU_EMPTY );  /* Until empty stack */
     228              : 
     229              :             } /* else */
     230              : 
     231              :         } /* else */
     232              : 
     233              :     } /* for each nonzero ... */
     234              : 
     235              :     /* Check to see if j belongs in the same supernode as j-1 */
     236            0 :     if ( jcol == 0 ) { /* Do nothing for column 0 */
     237            0 :         nsuper = supno[0] = 0;
     238              :     } else {
     239            0 :         fsupc = xsup[nsuper];
     240            0 :         jptr = xlsub[jcol];     /* Not compressed yet */
     241            0 :         jm1ptr = xlsub[jcolm1];
     242              : 
     243              : #ifdef T2_SUPER
     244            0 :         if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = SLU_EMPTY;
     245              : #endif
     246              :         /* Make sure the number of columns in a supernode doesn't
     247              :            exceed threshold. */
     248            0 :         if ( jcol - fsupc >= maxsuper ) jsuper = SLU_EMPTY;
     249              : 
     250              :         /* If jcol starts a new supernode, reclaim storage space in
     251              :          * lsub from the previous supernode. Note we only store
     252              :          * the subscript set of the first and last columns of
     253              :          * a supernode. (first for num values, last for pruning)
     254              :          */
     255            0 :         if ( jsuper == SLU_EMPTY ) {    /* starts a new supernode */
     256            0 :             if ( (fsupc < jcolm1-1) ) {      /* >= 3 columns in nsuper */
     257              : #ifdef CHK_COMPRESS
     258              :                 printf("  Compress lsub[] at super %d-%d\n", fsupc, jcolm1);
     259              : #endif
     260            0 :                 ito = xlsub[fsupc+1];
     261            0 :                 xlsub[jcolm1] = ito;
     262            0 :                 istop = ito + jptr - jm1ptr;
     263            0 :                 xprune[jcolm1] = istop; /* Initialize xprune[jcol-1] */
     264            0 :                 xlsub[jcol] = istop;
     265            0 :                 for (ifrom = jm1ptr; ifrom < nextl; ++ifrom, ++ito)
     266            0 :                     lsub[ito] = lsub[ifrom];
     267              :                 nextl = ito;            /* = istop + length(jcol) */
     268              :             }
     269            0 :             nsuper++;
     270            0 :             supno[jcol] = nsuper;
     271              :         } /* if a new supernode */
     272              : 
     273              :     }   /* else: jcol > 0 */ 
     274              :     
     275              :     /* Tidy up the pointers before exit */
     276            0 :     xsup[nsuper+1] = jcolp1;
     277            0 :     supno[jcolp1]  = nsuper;
     278            0 :     xprune[jcol]   = nextl;     /* Initialize upper bound for pruning */
     279            0 :     xlsub[jcolp1]  = nextl;
     280              : 
     281            0 :     return 0;
     282              : }
        

Generated by: LCOV version 2.0-1