LCOV - code coverage report
Current view: top level - experimental/test - test_msf.c (source / functions) Hit Total Coverage
Test: LAGraph code coverage report. Commit id: 50cd0c8. Current time (UTC): 2025-07-25T16:32:50Z Lines: 127 127 100.0 %
Date: 2025-07-25 16:38:41 Functions: 3 3 100.0 %

          Line data    Source code
       1             : //------------------------------------------------------------------------------
       2             : // LAGraph/experimental/test/test_msf.c: test cases for Min Spanning Forest
       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 Timothy A. Davis, Texas A&M University
      15             : 
      16             : //------------------------------------------------------------------------------
      17             : 
      18             : // todo: write a simple msf method, as LG_check_msf, and compare its results
      19             : // with LAGraph_msf
      20             : 
      21             : #include <stdio.h>
      22             : #include <acutest.h>
      23             : 
      24             : #include <LAGraphX.h>
      25             : #include <LAGraph_test.h>
      26             : 
      27             : char msg [LAGRAPH_MSG_LEN] ;
      28             : LAGraph_Graph G = NULL, G_C = NULL;
      29             : GrB_Matrix A = NULL ;
      30             : GrB_Matrix S = NULL ;
      31             : GrB_Matrix S_C = NULL ;
      32             : GrB_Matrix C = NULL ;
      33             : GrB_Matrix Ans = NULL ;
      34             : #define LEN 512
      35             : char filename [LEN+1] ;
      36             : 
      37             : typedef struct
      38             : {
      39             :     bool symmetric ;
      40             :     const char *name ;
      41             :     uint64_t ans_n;
      42             :     const uint64_t *ans_i;
      43             :     const uint64_t *ans_j;
      44             :     double ans_w;
      45             : }
      46             : matrix_info ;
      47             : const uint64_t A_mtx_i [] = {1, 2, 3, 4, 5, 6};
      48             : const uint64_t A_mtx_j [] = {0, 0, 1, 1, 1, 0};
      49             : const uint64_t mtx8u_i [] = {1, 2, 3, 4, 5, 6};
      50             : const uint64_t mtx8u_j [] = {4, 3, 0, 6, 2, 3};
      51             : const uint64_t mtx8_i [] = {1, 2, 3, 4, 5, 6};
      52             : const uint64_t mtx8_j [] = {4, 3, 0, 6, 2, 3};
      53             : const matrix_info files [ ] =
      54             : {
      55             :     { 1, "A.mtx", 6, A_mtx_i, A_mtx_j, NAN},
      56             :     { 1, "jagmesh7.mtx", 1137, NULL, NULL, NAN},
      57             :     { 0, "west0067.mtx", 66, NULL, NULL, -63.9103636}, // unsymmetric
      58             :     { 1, "bcsstk13.mtx", 2002, NULL, NULL, -27812381075940.4},
      59             :     { 0, "matrix_int8.mtx", 6, mtx8_i, mtx8_j, -120.0},
      60             :     { 0, "matrix_uint8.mtx", 6, mtx8u_i, mtx8u_j, 8.0},
      61             :     { 1, "karate.mtx", 33, NULL, NULL, NAN},
      62             :     { 1, "ldbc-cdlp-undirected-example.mtx", 7, NULL, NULL, NAN},
      63             :     { 1, "ldbc-undirected-example-bool.mtx", 8, NULL, NULL, NAN},
      64             :     { 1, "ldbc-undirected-example-unweighted.mtx", 8, NULL, NULL, NAN},
      65             :     { 1, "ldbc-undirected-example.mtx", 8, NULL, NULL, NAN},
      66             :     { 1, "ldbc-wcc-example.mtx", 9, NULL, NULL, NAN},
      67             :     { 0, "" },
      68             : } ;
      69             : 
      70             : //****************************************************************************
      71           1 : void test_msf (void)
      72             : {
      73             :     #if LG_SUITESPARSE_GRAPHBLAS_V10
      74           1 :     LAGraph_Init (msg) ;
      75           1 :     bool burble = false ;
      76           1 :     GrB_Scalar zeroB = NULL;
      77           1 :     GrB_Scalar_new(&zeroB, GrB_BOOL);
      78           1 :     GrB_Scalar_setElement_BOOL(zeroB, false);
      79           1 :     for (int k = 0 ; ; k++)
      80          12 :     {
      81             : 
      82             :         // load the matrix as A
      83          13 :         const char *aname = files [k].name ;
      84          13 :         bool symmetric = files [k].symmetric ;
      85          13 :         uint64_t branches = 0;
      86          13 :         if (strlen (aname) == 0) break;
      87          12 :         printf ("\n================================== %s:\n", aname) ;
      88          12 :         TEST_CASE (aname) ;
      89          12 :         snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
      90          12 :         FILE *f = fopen (filename, "r") ;
      91          12 :         TEST_CHECK (f != NULL) ;
      92          12 :         OK (LAGraph_MMRead (&A, f, msg)) ;
      93          12 :         fclose (f) ;
      94             : 
      95             :         // ensure A is uint64
      96          12 :         GrB_Index n = 0;
      97          12 :         OK (GrB_Matrix_nrows (&n, A)) ;
      98             : 
      99             :         // construct a directed graph G with adjacency matrix S
     100          12 :         TEST_CHECK (S == NULL) ;
     101             : 
     102          12 :         OK (LAGraph_Matrix_Print (A, LAGraph_SHORT, stdout, msg)) ;
     103          12 :         bool sanitize = (!symmetric) ;
     104             : 
     105          12 :         if (files[k].ans_i && files[k].ans_j)
     106             :         {
     107           3 :             OK (GrB_Matrix_new(&Ans, GrB_BOOL, n, n)) ;
     108           3 :             OK (GxB_Matrix_build_Scalar(
     109             :                 Ans, files[k].ans_i, files[k].ans_j, zeroB, files[k].ans_n
     110             :             )) ;
     111             :         }
     112             : 
     113          36 :         for (int jit = 0 ; jit <= 1 ; jit++)
     114             :         {
     115          24 :             if (jit) printf ("\nJIT is enabled\n") ; else printf ("\nJIT is disabled\n") ;
     116             : 
     117             :             // connected components
     118          24 :             GrB_Vector cc0 = NULL, cc1 = NULL, cc2 = NULL;
     119             : 
     120          24 :             OK (GxB_Global_Option_set (GxB_JIT_C_CONTROL,
     121             :                 jit ? GxB_JIT_ON : GxB_JIT_OFF)) ;
     122             :             // compute the min spanning forest
     123          24 :             C = NULL ;
     124          24 :             OK (LG_SET_BURBLE (burble)) ;
     125          24 :             int result = LAGraph_msf (&C, &cc0, A, sanitize, msg) ;
     126          24 :             OK (LG_SET_BURBLE (false)) ;
     127             : 
     128          24 :             printf ("result: %d\n", result) ;
     129          24 :             OK(result);
     130          24 :             GrB_Matrix_nvals(&branches, C);
     131          24 :             TEST_CHECK(branches == files[k].ans_n);
     132          24 :             LAGraph_PrintLevel pr = (n <= 100) ? LAGraph_COMPLETE : LAGraph_SHORT ;
     133             :             
     134          24 :             OK (GrB_Matrix_new(&S, GrB_BOOL, n, n)) ;
     135          24 :             OK (GrB_Matrix_assign_BOOL(
     136             :                 S, A, NULL, (bool) true, GrB_ALL, n, GrB_ALL, n, GrB_DESC_S)) ;
     137          24 :             if(!symmetric)
     138             :             {
     139           6 :                 OK (GrB_Matrix_eWiseAdd_BinaryOp(
     140             :                     S, NULL, NULL, GxB_ANY_BOOL, S, S, GrB_DESC_T1)) ;
     141             :             }
     142          24 :             OK(LAGraph_New(&G, &S, LAGraph_ADJACENCY_UNDIRECTED, msg));
     143             :  
     144             :             //Check that the graph has all the same ccs.
     145          24 :             OK (LAGr_ConnectedComponents(&cc1, G, msg)) ;
     146          24 :             bool ok = false ;
     147          24 :             OK (GrB_Vector_new(&cc2, GrB_UINT64, n)) ;
     148             :             // cc1 and cc0 should have the same structure as cc2. 
     149             :             // make their values equal and then compare them.
     150             :             // msf does not guarentee that the lower node is used as componentId
     151          24 :             OK (GxB_Vector_extract_Vector(cc2, NULL, NULL, cc0, cc1, NULL)) ;
     152          24 :             OK (LAGraph_Vector_IsEqual(&ok, cc2, cc0, msg)) ;
     153             : 
     154             : //          if(!ok)
     155             : //          {
     156             : //              GxB_print(cc2, GxB_SHORT);
     157             : //              GxB_print(cc0, GxB_SHORT);
     158             : //          }
     159          24 :             TEST_ASSERT(ok) ;
     160             :             // check result C for A.mtx
     161          24 :             if (files[k].ans_i && files[k].ans_j)
     162             :             {
     163           6 :                 OK (GrB_Matrix_eWiseMult_BinaryOp(
     164             :                     Ans, NULL, GxB_LOR_BOOL, GrB_ONEB_BOOL, Ans, C, NULL)) ;
     165           6 :                 OK (GrB_Matrix_eWiseMult_BinaryOp(
     166             :                     Ans, NULL, GxB_LOR_BOOL, GrB_ONEB_BOOL, Ans, C, GrB_DESC_T1
     167             :                 )) ;
     168           6 :                 OK (GrB_Matrix_reduce_BOOL(
     169             :                     &ok, NULL, GrB_LAND_MONOID_BOOL, Ans, NULL));
     170           6 :                 TEST_CHECK (ok) ;
     171             :             }
     172             : 
     173          24 :             printf ("\nmsf:\n") ;
     174          24 :             double tot_weight, ans_w = files[k].ans_w;
     175          24 :             OK (GrB_Matrix_reduce_FP64(&tot_weight, NULL, GrB_PLUS_MONOID_FP64, C, NULL)) ;
     176          24 :             TEST_CHECK (isnan(files[k].ans_w) || 
     177             :                     fabs(tot_weight - ans_w) <= 1E-10 * fabs(ans_w)) ;           
     178          24 :             OK (LAGraph_Matrix_Print (C, pr, stdout, msg)) ;
     179          24 :             OK (LAGraph_Delete (&G, msg)) ;
     180          24 :             OK (GrB_free (&cc0)) ;
     181          24 :             OK (GrB_free (&cc1)) ;
     182          24 :             OK (GrB_free (&cc2)) ;
     183          24 :             OK (GrB_free (&C)) ;
     184             : 
     185          24 :             printf ("JIT test is done\n") ;
     186             :         }
     187          12 :         OK (GrB_free(&Ans)) ;
     188          12 :         OK (GrB_free (&A)) ;
     189             :     }
     190           1 :     GrB_free(&zeroB);
     191           1 :     LAGraph_Finalize (msg) ;
     192             :     #endif
     193           1 : }
     194             : 
     195             : //------------------------------------------------------------------------------
     196             : // infinity test
     197             : //------------------------------------------------------------------------------
     198             : 
     199           1 : void test_inf_msf (void)
     200             : {
     201           1 :     LAGraph_Init (msg) ;
     202           1 :     bool burble = false ;
     203           1 :     GrB_Scalar zeroB = NULL;
     204           1 :     GrB_Scalar_new(&zeroB, GrB_BOOL);
     205           1 :     GrB_Scalar_setElement_BOOL(zeroB, false);
     206             : 
     207             :     // load the matrix as A
     208           1 :     const char *aname = "bcsstk13.mtx" ;
     209           1 :     bool symmetric = 1 ;
     210           1 :     printf ("\n================================== %s:\n", aname) ;
     211           1 :     TEST_CASE (aname) ;
     212           1 :     snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
     213           1 :     FILE *f = fopen (filename, "r") ;
     214           1 :     TEST_CHECK (f != NULL) ;
     215           1 :     OK (LAGraph_MMRead (&A, f, msg)) ;
     216           1 :     fclose (f) ;
     217             : 
     218           1 :     GrB_Index n = 0;
     219           1 :     OK (GrB_Matrix_nrows (&n, A)) ;
     220           1 :     OK (GrB_Matrix_new(&S, GrB_BOOL, n, n)) ;
     221             : 
     222             :     // Make A be iso infinity and S iso true.
     223           1 :     OK (GrB_Matrix_assign_FP64(
     224             :         A, A, NULL, INFINITY, GrB_ALL, n, GrB_ALL, n, GrB_DESC_S)) ;
     225           1 :     OK (GrB_Matrix_assign_BOOL(
     226             :         S, A, NULL, (bool) true, GrB_ALL, n, GrB_ALL, n, GrB_DESC_S)) ;
     227             : 
     228             :     // compute the min spanning forest
     229           1 :     S_C = C = NULL ;
     230           1 :     OK (LG_SET_BURBLE (burble)) ;
     231           1 :     int result = LAGraph_msf (&C, NULL, A, false, msg) ;
     232           1 :     OK (LG_SET_BURBLE (false)) ;
     233           1 :     printf ("result: %d\n", result) ;
     234           1 :     OK(result);
     235             : 
     236           1 :     OK (LG_SET_BURBLE (burble)) ;
     237           1 :     result = LAGraph_msf (&S_C, NULL, S, false, msg) ;
     238           1 :     OK (LG_SET_BURBLE (false)) ;
     239           1 :     printf ("result: %d\n", result) ;
     240           1 :     OK(result);
     241             : 
     242           1 :     bool ok = false ;
     243             :     // check structure is equal.
     244           1 :     OK (LAGraph_Matrix_IsEqualOp(&ok, C, S_C, GrB_ONEB_BOOL, msg));
     245           1 :     TEST_CHECK(ok);
     246           1 :     OK (GrB_free (&S)) ;
     247           1 :     OK (GrB_free (&S_C)) ;
     248           1 :     OK (GrB_free (&C)) ;
     249           1 :     OK (GrB_free (&A)) ;
     250           1 :     GrB_free(&zeroB);
     251           1 :     LAGraph_Finalize (msg) ;
     252           1 : }
     253             : 
     254             : //------------------------------------------------------------------------------
     255             : // test_errors
     256             : //------------------------------------------------------------------------------
     257             : 
     258           1 : void test_errors (void)
     259             : {
     260           1 :     LAGraph_Init (msg) ;
     261             : 
     262             :     #if LG_SUITESPARSE_GRAPHBLAS_V10
     263             :     // C and A are NULL
     264           1 :     int result = LAGraph_msf (NULL, NULL, NULL, true, msg) ;
     265           1 :     TEST_CHECK (result == GrB_NULL_POINTER) ;
     266             : 
     267             :     // A must be square
     268           1 :     OK (GrB_Matrix_new (&A, GrB_UINT64, 3, 4)) ;
     269           1 :     result = LAGraph_msf (&C, NULL, A, true, msg) ;
     270           1 :     TEST_CHECK (result == GrB_DIMENSION_MISMATCH) ;
     271           1 :     OK (GrB_free (&A)) ;
     272             : 
     273             :     // A must real
     274           1 :     OK (GrB_Matrix_new (&A, GxB_FC32, 4, 4)) ;
     275           1 :     result = LAGraph_msf (&C, NULL, A, true, msg) ;
     276           1 :     TEST_CHECK (result == GrB_DOMAIN_MISMATCH) ;
     277             :     
     278             :     #else 
     279             :     // Not implemented
     280             :     OK (GrB_Matrix_new (&A, GrB_BOOL, 4, 4)) ;
     281             :     int result = LAGraph_msf (&C, NULL, A, true, msg) ;
     282             :     TEST_CHECK (result == GrB_NOT_IMPLEMENTED) ;
     283             :     #endif
     284             : 
     285           1 :     OK (GrB_free (&A)) ;
     286           1 :     LAGraph_Finalize (msg) ;
     287           1 : }
     288             : 
     289             : //****************************************************************************
     290             : 
     291             : TEST_LIST = {
     292             :     #if LG_SUITESPARSE_GRAPHBLAS_V10
     293             :     {"msf", test_msf},
     294             :     {"inf_msf", test_inf_msf},
     295             :     #endif
     296             :     {"msf_errors", test_errors},
     297             :     {NULL, NULL}
     298             : };

Generated by: LCOV version 1.14