LCOV - code coverage report
Current view: top level - experimental/test - LG_check_kcore.c (source / functions) Hit Total Coverage
Test: LAGraph code coverage report. Commit id: cc56ed4. Current time (UTC): 2024-08-30T17:14:30Z Lines: 65 65 100.0 %
Date: 2024-08-30 17:16:41 Functions: 1 1 100.0 %

          Line data    Source code
       1             : //------------------------------------------------------------------------------
       2             : // LG_check_kcore: construct the kcore of a graph (simple method)
       3             : //------------------------------------------------------------------------------
       4             : 
       5             : // LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved.
       6             : // SPDX-License-Identifier: BSD-2-Clause
       7             : //
       8             : // For additional details (including references to third party source code and
       9             : // other files) see the LICENSE file or contact permission@sei.cmu.edu. See
      10             : // Contributors.txt for a full list of contributors. Created, in part, with
      11             : // funding and support from the U.S. Government (see Acknowledgments.txt file).
      12             : // DM22-0790
      13             : 
      14             : // Contributed by Pranav Konduri, Texas A&M University
      15             : 
      16             : //------------------------------------------------------------------------------
      17             : 
      18             : // An implementation of the BZ algorithm (2003) for k-core decomposition.
      19             : // This method is for testing only, to check the result of other, faster methods.
      20             : // Do not benchmark this method; it is simple by design.
      21             : 
      22             : #define LG_FREE_ALL                             \
      23             : {                                               \
      24             :     LAGraph_Free ((void **) &vert, msg) ;       \
      25             :     LAGraph_Free ((void **) &deg, msg) ;        \
      26             :     LAGraph_Free ((void **) &bin, msg) ;        \
      27             :     LAGraph_Free ((void **) &pos, msg) ;        \
      28             :     LAGraph_Free ((void **) &Ap, msg) ;         \
      29             :     LAGraph_Free ((void **) &Aj, msg) ;         \
      30             :     LAGraph_Free ((void **) &Ax, msg) ;         \
      31             : }
      32             : 
      33             : #include "LG_internal.h"
      34             : #include "LG_test.h"
      35             : #include "LG_test.h"
      36             : #include "LG_Xtest.h"
      37             : 
      38           4 : int LG_check_kcore
      39             : (
      40             :     // outputs:
      41             :     GrB_Vector *decomp,     // kcore decomposition
      42             :     uint64_t *kmax,         // max kcore- if kfinal == -1, kmax = -1
      43             :     // inputs
      44             :     LAGraph_Graph G,        // input graph
      45             :     int64_t kfinal,         // max k to check for graph.
      46             :     char *msg
      47             : )
      48             : {
      49             : 
      50             :     //--------------------------------------------------------------------------
      51             :     // check inputs
      52             :     //--------------------------------------------------------------------------
      53             : 
      54           4 :     LG_CLEAR_MSG ;
      55           4 :     uint64_t *vert = NULL, *pos = NULL, *bin = NULL, *deg = NULL ;
      56           4 :     uint64_t maxDeg = 0;
      57           4 :     GrB_Index *Ap = NULL, *Aj = NULL, *Ai = NULL ;
      58           4 :     void *Ax = NULL ;
      59             :     GrB_Index Ap_size, Aj_size, Ax_size, n, ncols, Ap_len, Aj_len, Ax_len ;
      60           4 :     LG_ASSERT (kmax != NULL, GrB_NULL_POINTER) ;
      61           4 :     LG_TRY (LAGraph_CheckGraph (G, msg)) ;
      62           4 :     LG_ASSERT (G->nself_edges == 0, LAGRAPH_NO_SELF_EDGES_ALLOWED) ;
      63           4 :     LG_ASSERT_MSG ((G->kind == LAGraph_ADJACENCY_UNDIRECTED ||
      64             :        (G->kind == LAGraph_ADJACENCY_DIRECTED &&
      65             :         G->is_symmetric_structure == LAGraph_TRUE)),
      66             :         LAGRAPH_SYMMETRIC_STRUCTURE_REQUIRED,
      67             :         "G->A must be known to be symmetric") ;
      68           4 :     GRB_TRY (GrB_Matrix_nrows (&n, G->A)) ; //set n to number of rows
      69           4 :     GRB_TRY (GrB_Matrix_ncols (&ncols, G->A)) ;
      70             : 
      71             :     //--------------------------------------------------------------------------
      72             :     // export the matrix in CSR form
      73             :     //--------------------------------------------------------------------------
      74             : 
      75             :     size_t typesize ;
      76           4 :     LG_TRY (LG_check_export (G, &Ap, &Aj, &Ax, &Ap_len, &Aj_len, &Ax_len,
      77             :         &typesize, msg)) ;
      78             : 
      79             :     //--------------------------------------------------------------------------
      80             :     // compute the k-core
      81             :     //--------------------------------------------------------------------------
      82             :     //printf ("\n================================== COMPUTING BZ_KCORE: ==================================\n") ;
      83             :     //printf("ap_len = %ld, aj_len = %ld, ax_len = %ld\n", Ap_len, Aj_len, Ax_len) ;
      84             : 
      85             :     //create the arrays
      86             : 
      87           4 :     LAGraph_Malloc((void **) &deg, n, sizeof(uint64_t), msg) ;
      88           4 :     LAGraph_Malloc((void **) &vert, n, sizeof(uint64_t), msg) ;
      89           4 :     LAGraph_Malloc((void **) &pos, n, sizeof(uint64_t), msg) ;
      90             :     //core = AGraph_Malloc(n, sizeof(uint64_t)) ;
      91             : 
      92         206 :     for(uint64_t i = 0; i < n; i++){
      93         202 :         deg[i] = Ap[i+1] - Ap[i];
      94         202 :         if (deg[i] > maxDeg)
      95          12 :             maxDeg = deg[i];
      96             :     }
      97             : 
      98             :     //setup output vector
      99           4 :     GrB_Type int_type  = (maxDeg > INT32_MAX) ? GrB_INT64 : GrB_INT32 ;
     100           4 :     GRB_TRY (GrB_Vector_new(decomp, int_type, n)) ;
     101           4 :     GrB_IndexUnaryOp valueGE = (maxDeg > INT32_MAX) ? GrB_VALUEGE_INT64 : GrB_VALUEGE_INT32 ;
     102             : 
     103             :     //setup bin array
     104           4 :     LAGraph_Calloc((void **) &bin, maxDeg + 1, sizeof(uint64_t), msg) ;
     105             : 
     106         206 :     for(uint64_t i = 0; i < n; i++){
     107         202 :         bin[deg[i]]++;
     108             :     }
     109             : 
     110           4 :     uint64_t start = 0;
     111          74 :     for(uint64_t d = 0; d < maxDeg + 1; d++){
     112          70 :         uint64_t num = bin[d];
     113          70 :         bin[d] = start;
     114          70 :         start = start + num;
     115             :     }
     116             : 
     117             :     //Do bin-sort
     118             :     //vert -- contains the vertices in sorted order of degree
     119             :     //pos -- contains the positon of a vertex in vert array
     120         206 :     for(uint64_t i = 0; i < n; i++){
     121         202 :         pos[i] = bin[ deg[i] ];
     122         202 :         vert[pos[i]] = i;
     123         202 :         bin[deg[i]] ++;
     124             :     }
     125             : 
     126          70 :     for(uint64_t d = maxDeg; d >= 1; d --)
     127          66 :         bin[d] = bin[d-1];
     128           4 :     bin[0] = 0;
     129             : 
     130           4 :     uint64_t level = 0;
     131             : 
     132             :     //Compute k-core
     133         206 :     for(uint64_t i = 0; i < n; i++){
     134             :         //get the vertex to check
     135         202 :         uint64_t v = vert[i];
     136             : 
     137             :         //set the element in the output vector: if doing KCALL, then add deg.
     138             :         //If not, just set to kfinal's value.
     139         202 :         if((int64_t) deg[v] >= kfinal){
     140         201 :             if(kfinal == -1){
     141         101 :                 GRB_TRY(GrB_Vector_setElement(*decomp, deg[v], v)) ;
     142             :             }
     143             :             else{
     144         100 :                 GRB_TRY(GrB_Vector_setElement(*decomp, kfinal, v)) ;
     145             :             }
     146             :         }
     147             : 
     148         202 :         if(bin[deg[v]] == i){
     149          12 :             level = deg[v];
     150             :         }
     151             : 
     152         202 :         uint64_t start = Ap[v];
     153         202 :         int64_t original_deg = Ap[v+1] - Ap[v]; //original deg before decremented
     154        1662 :         for(uint64_t j = 0; j < original_deg; j++){
     155        1460 :             uint64_t u = Aj[start + j]; //a neighbor node of v
     156             : 
     157             :             //if we need to lower the neighbor's deg value, and relocate in bin
     158        1460 :             if(deg[u] > deg[v]){
     159         462 :                 uint64_t du = deg[u];
     160         462 :                 uint64_t pu = pos[u];
     161         462 :                 uint64_t pw = bin[du];
     162         462 :                 uint64_t w = vert[pw]; //the vertex situated at the beginning of the bin
     163             : 
     164             :                 //swap around the vertices- w goes to the end, u goes to the beginning
     165         462 :                 if(u != w){
     166         296 :                     pos[u] = pw; vert[pu] = w;
     167         296 :                     pos[w] = pu; vert[pw] = u;
     168             :                 }
     169             : 
     170             :                 //increase starting index of bin @ du
     171         462 :                 bin[du]++;
     172             :                 //decrease degree of u
     173         462 :                 deg[u]--;
     174             :             }
     175             :         }
     176             :     }
     177             : 
     178           4 :     LG_FREE_ALL;
     179           4 :     (*kmax) = level ;
     180           4 :     GRB_TRY (GrB_Vector_wait(*decomp, GrB_MATERIALIZE));
     181           4 :     return (GrB_SUCCESS);
     182             : }

Generated by: LCOV version 1.14