From 1e9aebc39f250ead73472710e6a1c5bb7f2189d5 Mon Sep 17 00:00:00 2001 From: peicasey Date: Wed, 19 Mar 2025 10:39:11 -0500 Subject: [PATCH 1/4] demo basics --- .../edgeBetweennessCentrality_demo.c | 119 ++++++++++++++++++ .../test/test_edgeBetweennessCentrality.c | 4 - 2 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 experimental/benchmark/edgeBetweennessCentrality_demo.c diff --git a/experimental/benchmark/edgeBetweennessCentrality_demo.c b/experimental/benchmark/edgeBetweennessCentrality_demo.c new file mode 100644 index 0000000000..2a185dc8f9 --- /dev/null +++ b/experimental/benchmark/edgeBetweennessCentrality_demo.c @@ -0,0 +1,119 @@ +#include "LAGraphX.h" +#include "LG_internal.h" +#include + +#define LAGRAPH_CATCH(info) \ +{ \ + GrB_free (¢rality) ; \ + GrB_free (&A) ; \ + LAGraph_Delete (&G, msg) ; \ + return (info) ; \ +} + +int main (int argc, char **argv) +{ + double difference(GrB_Matrix bc, double* gap_result, GrB_Index rows, GrB_Index cols) ; + + double difference(GrB_Matrix bc, double* gap_result, GrB_Index rows, GrB_Index cols) + { + // GrB_Matrix diff = NULL; + GrB_Matrix diff = NULL, gap_bc = NULL; + OK(GrB_Matrix_new(&gap_bc, GrB_FP64, rows, cols)); + + // Populate gap_bc with values from gap_result + for (GrB_Index i = 0; i < rows; i++) { + for (GrB_Index j = 0; j < cols; j++) { + // if (*(gap_result + i * cols + j) != 0) printf(" (%ld, %ld) %g\n", i, j, *(gap_result + i * cols + j)); + OK(GrB_Matrix_setElement_FP64(gap_bc, *(gap_result + i * cols + j), i, j)); + } + } + + // Compute diff = max(abs(gap_bc - bc)) + OK(GrB_Matrix_new(&diff, GrB_FP64, rows, cols)); + OK(GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, gap_bc, bc, NULL)); + OK(GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL)); + + double err = 0; + OK(GrB_reduce(&err, NULL, GrB_MAX_MONOID_FP64, diff, NULL)); + + OK(GrB_free(&diff)); + OK(GrB_free(&gap_bc)); + + return err; + } + + //-------------------------------------------------------------------------- + // startup LAGraph and GraphBLAS + //-------------------------------------------------------------------------- + + char msg [LAGRAPH_MSG_LEN] ; // for error messages from LAGraph + LAGraph_Graph G = NULL ; + GrB_Matrix centrality = NULL, A = NULL ; + + // start GraphBLAS and LAGraph + LAGRAPH_TRY (LAGraph_Init (msg)) ; + + //-------------------------------------------------------------------------- + // read in the graph via a Matrix Market file from stdin + //-------------------------------------------------------------------------- + + if (argc < 2) + { + printf("Usage: %s \n", argv[0]); + return (GrB_INVALID_VALUE) ; + } + + FILE *f = fopen(argv[1], "r"); + if (f == NULL) + { + printf("Error: unable to open file %s\n", argv[1]); + return (GrB_INVALID_VALUE) ; + } + + double t = LAGraph_WallClockTime ( ) ; + LAGRAPH_TRY (LAGraph_MMRead (&A, f, msg)) ; + fclose(f); + LAGRAPH_TRY (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ; + t = LAGraph_WallClockTime ( ) - t ; + printf ("Time to read the graph: %g sec\n", t) ; + + printf ("\n==========================The input graph matrix G:\n") ; + LAGRAPH_TRY (LAGraph_Graph_Print (G, LAGraph_SHORT, stdout, msg)) ; + + //-------------------------------------------------------------------------- + // compute edge betweenness centrality + //-------------------------------------------------------------------------- + + t = LAGraph_WallClockTime ( ) ; + LAGRAPH_TRY (LAGr_EdgeBetweennessCentrality (¢rality, G, msg)) ; + t = LAGraph_WallClockTime ( ) - t ; + printf ("Time for LAGr_EdgeBetweennessCentrality: %g sec\n", t) ; + + //-------------------------------------------------------------------------- + // check the results using LG_check_edgeBetweennessCentrality + //-------------------------------------------------------------------------- + + GrB_Matrix reference_centrality = NULL; + LAGRAPH_TRY (LG_check_edgeBetweennessCentrality(&reference_centrality, G, msg)) ; + + double err = difference(centrality, reference_centrality, G->n, G->n) ; + printf ("Error between computed and reference centrality: %e\n", err) ; + if (err < 1e-4) + { + printf ("Test passed.\n") ; + } + else + { + printf ("Test failure!\n") ; + } + + //-------------------------------------------------------------------------- + // free everything and finish + //-------------------------------------------------------------------------- + + GrB_free (¢rality) ; + GrB_free (&reference_centrality) ; + LAGraph_Delete (&G, msg) ; + LAGRAPH_TRY (LAGraph_Finalize (msg)) ; + return (GrB_SUCCESS) ; +} diff --git a/experimental/test/test_edgeBetweennessCentrality.c b/experimental/test/test_edgeBetweennessCentrality.c index acec3cced8..f2c15018ed 100644 --- a/experimental/test/test_edgeBetweennessCentrality.c +++ b/experimental/test/test_edgeBetweennessCentrality.c @@ -47,13 +47,9 @@ double difference(GrB_Matrix bc, double* gap_result, GrB_Index rows, GrB_Index c } } - // GxB_print (bc, 5) ; - // GxB_print (gap_bc, 5) ; - // Compute diff = max(abs(gap_bc - bc)) OK(GrB_Matrix_new(&diff, GrB_FP64, rows, cols)); OK(GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, gap_bc, bc, NULL)); - // GxB_print (diff, 5) ; OK(GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL)); double err = 0; From 944c15dd1b31d40fda03683294123ab6fb2e7751 Mon Sep 17 00:00:00 2001 From: Tim Davis Date: Wed, 19 Mar 2025 12:24:28 -0500 Subject: [PATCH 2/4] Mar 19 meeting --- .../LAGr_EdgeBetweennessCentrality.c | 54 ++++++++++------- .../edgeBetweennessCentrality_demo.c | 59 ++++++++++--------- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c b/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c index 9fea4ae129..425678abb9 100644 --- a/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c +++ b/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c @@ -19,7 +19,7 @@ // LAGr_EdgeBetweennessCentrality: Exact algorithm for computing // betweeness centrality. -// This is an Advanced algorithm (G->AT is required). +// This is an Advanced algorithm (no self edges allowed) //------------------------------------------------------------------------------ @@ -82,19 +82,19 @@ // (1+x)/y function for double: z = (1 + x) / y //------------------------------------------------------------------------------ -void add_one_divide_function (void *z, const void *x, const void *y) +void add_one_divide_function (double *z, const double *x, const double *y) { - double a = (*((double *) x)) ; - double b = (*((double *) y)) ; - (*((double *) z)) = (1 + a) / b ; + double a = (*(x)) ; + double b = (*(y)) ; + (*(z)) = (1 + a) / b ; } #define ADD_ONE_DIVIDE_FUNCTION_DEFN \ -"void add_one_divide_function (void *z, const void *x, const void *y) \n" \ +"void add_one_divide_function (double *z, const double *x, const double *y)\n" \ "{ \n" \ -" double a = (*((double *) x)) ; \n" \ -" double b = (*((double *) y)) ; \n" \ -" (*((double *) z)) = (1 + a) / b ; \n" \ +" double a = (*(x)) ; \n" \ +" double b = (*(y)) ; \n" \ +" (*(z)) = (1 + a) / b ; \n" \ "}" //------------------------------------------------------------------------------ @@ -154,6 +154,7 @@ int LAGr_EdgeBetweennessCentrality LG_TRY (LAGraph_CheckGraph (G, msg)) ; GrB_Matrix A = G->A ; + #if 0 GrB_Matrix AT ; if (G->kind == LAGraph_ADJACENCY_UNDIRECTED || G->is_symmetric_structure == LAGraph_TRUE) @@ -167,12 +168,14 @@ int LAGr_EdgeBetweennessCentrality AT = G->AT ; LG_ASSERT_MSG (AT != NULL, LAGRAPH_NOT_CACHED, "G->AT is required") ; } + #endif // ========================================================================= // === initialization ===================================================== // ========================================================================= - GRB_TRY (GxB_BinaryOp_new (&Add_One_Divide, add_one_divide_function, + GRB_TRY (GxB_BinaryOp_new (&Add_One_Divide, + (GxB_binary_function) add_one_divide_function, GrB_FP64, GrB_FP64, GrB_FP64, "add_one_divide_function", ADD_ONE_DIVIDE_FUNCTION_DEFN)) ; @@ -214,10 +217,12 @@ int LAGr_EdgeBetweennessCentrality GRB_TRY (GrB_Matrix_clear (Update)) ; - // Extract row root from A into frontier vector: frontier = AT(root,:) - GRB_TRY (GrB_Col_extract (frontier, NULL, NULL, AT, GrB_ALL, n, root, - NULL)) ; + // Extract row root from A into frontier vector: frontier = A(root,:) + GRB_TRY (GrB_Col_extract (frontier, NULL, NULL, A, GrB_ALL, n, root, + GrB_DESC_T0)) ; + GRB_TRY (GrB_Vector_nvals (&frontier_size, frontier)) ; + GRB_TRY (GrB_assign (frontier, frontier, NULL, 1.0, GrB_ALL, n, GrB_DESC_S)) ; while (frontier_size != 0) { @@ -242,7 +247,8 @@ int LAGr_EdgeBetweennessCentrality //---------------------------------------------------------------------- GRB_TRY (LG_SET_FORMAT_HINT (frontier, LG_SPARSE)) ; - GRB_TRY (GrB_vxm (frontier, paths, NULL, GxB_PLUS_FIRST_FP64, frontier, + GRB_TRY (GrB_vxm (frontier, paths, NULL, /* LAGraph_plus_first_fp64 */ + GxB_PLUS_FIRST_FP64, frontier, A, GrB_DESC_RSC )) ; //---------------------------------------------------------------------- @@ -269,8 +275,12 @@ int LAGr_EdgeBetweennessCentrality // Backtrack through the BFS and compute centrality updates for each vertex // GrB_Index fd1_size; + + printf ("\n----------------------------- backtrack:\n") ; + while (depth >= 1) { + printf ("\n----------------------------- backtrack depth : %" PRId64 "\n", depth) ; GrB_Vector f_d = Search [depth] ; GrB_Vector f_d1 = Search [depth - 1] ; @@ -291,20 +301,20 @@ int LAGr_EdgeBetweennessCentrality // combine // intermediate matrix for Fd1 * A - // GRB_TRY (GrB_eWiseMult(Fd1A, NULL, NULL, GrB_TIMES_FP64, I_matrix, AT, NULL)) ; - GRB_TRY(GrB_mxm(Fd1A, NULL, NULL, GrB_PLUS_TIMES_SEMIRING_FP64, + GRB_TRY(GrB_mxm(Fd1A, NULL, NULL, LAGraph_plus_first_fp64, I_matrix, A, NULL)) ; - // GRB_TRY (GrB_eWiseMult(U, NULL, NULL, GrB_TIMES_FP64, Fd1A, J_matrix, NULL)) ; GRB_TRY(GrB_mxm(Update, NULL, NULL, GrB_PLUS_TIMES_SEMIRING_FP64, Fd1A, J_matrix, NULL)) ; - - // 22 centrality = centrality + Update - // GRB_TRY (GrB_assign(centrality, centrality, GrB_PLUS_FP64, Update, GrB_ALL, n, GrB_ALL, n, - // GrB_DESC_S)) ; + #if 1 + // 22 centrality{A} += Update, using assign + GRB_TRY (GrB_assign(*centrality, A, GrB_PLUS_FP64, Update, GrB_ALL, n, GrB_ALL, n, + GrB_DESC_S)) ; + #else + // 22 centrality = centrality + Update using eWiseAdd GRB_TRY (GrB_eWiseAdd (*centrality, NULL, NULL, GrB_PLUS_FP64, *centrality, Update, NULL)) ; - + #endif // 23 v = Update +. diff --git a/experimental/benchmark/edgeBetweennessCentrality_demo.c b/experimental/benchmark/edgeBetweennessCentrality_demo.c index 2a185dc8f9..d942edebe5 100644 --- a/experimental/benchmark/edgeBetweennessCentrality_demo.c +++ b/experimental/benchmark/edgeBetweennessCentrality_demo.c @@ -1,43 +1,35 @@ -#include "LAGraphX.h" -#include "LG_internal.h" -#include -#define LAGRAPH_CATCH(info) \ -{ \ +#define LG_FREE_ALL \ + printf ("done here: %d\n", __LINE__) ; \ + printf ("msg: [%s]\n", msg) ; \ GrB_free (¢rality) ; \ GrB_free (&A) ; \ LAGraph_Delete (&G, msg) ; \ - return (info) ; \ -} + +#include "LAGraphX.h" +#include "LG_internal.h" +#include int main (int argc, char **argv) { - double difference(GrB_Matrix bc, double* gap_result, GrB_Index rows, GrB_Index cols) ; +// double difference(GrB_Matrix bc, double* gap_result, GrB_Index rows, GrB_Index cols) ; - double difference(GrB_Matrix bc, double* gap_result, GrB_Index rows, GrB_Index cols) + double difference(GrB_Matrix bc, GrB_Matrix reference_bc) { - // GrB_Matrix diff = NULL; - GrB_Matrix diff = NULL, gap_bc = NULL; - OK(GrB_Matrix_new(&gap_bc, GrB_FP64, rows, cols)); + GrB_Matrix diff = NULL ; - // Populate gap_bc with values from gap_result - for (GrB_Index i = 0; i < rows; i++) { - for (GrB_Index j = 0; j < cols; j++) { - // if (*(gap_result + i * cols + j) != 0) printf(" (%ld, %ld) %g\n", i, j, *(gap_result + i * cols + j)); - OK(GrB_Matrix_setElement_FP64(gap_bc, *(gap_result + i * cols + j), i, j)); - } - } + uint64_t n ; + GrB_Matrix_nrows (&n, bc) ; - // Compute diff = max(abs(gap_bc - bc)) - OK(GrB_Matrix_new(&diff, GrB_FP64, rows, cols)); - OK(GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, gap_bc, bc, NULL)); - OK(GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL)); + // Compute diff = max(abs(reference_bc - bc)) + GrB_Matrix_new(&diff, GrB_FP64, n, n); + GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, reference_bc, bc, NULL); + GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL); - double err = 0; - OK(GrB_reduce(&err, NULL, GrB_MAX_MONOID_FP64, diff, NULL)); + double err = 1; + GrB_reduce(&err, NULL, GrB_MAX_MONOID_FP64, diff, NULL); - OK(GrB_free(&diff)); - OK(GrB_free(&gap_bc)); + GrB_free(&diff); return err; } @@ -49,6 +41,7 @@ int main (int argc, char **argv) char msg [LAGRAPH_MSG_LEN] ; // for error messages from LAGraph LAGraph_Graph G = NULL ; GrB_Matrix centrality = NULL, A = NULL ; + GrB_Info info ; // start GraphBLAS and LAGraph LAGRAPH_TRY (LAGraph_Init (msg)) ; @@ -73,7 +66,13 @@ int main (int argc, char **argv) double t = LAGraph_WallClockTime ( ) ; LAGRAPH_TRY (LAGraph_MMRead (&A, f, msg)) ; fclose(f); + uint64_t n ; + GRB_TRY (GrB_Matrix_nrows (&n, A)) ; +// GRB_TRY (GrB_assign (A, A, NULL, 1.0, GrB_ALL, n, GrB_ALL, n, GrB_DESC_S)) ; + LAGRAPH_TRY (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ; + LAGRAPH_TRY (LAGraph_DeleteSelfEdges (G, msg)) ; + LAGRAPH_TRY (LAGraph_Cached_AT (G, msg)) ; t = LAGraph_WallClockTime ( ) - t ; printf ("Time to read the graph: %g sec\n", t) ; @@ -84,11 +83,15 @@ int main (int argc, char **argv) // compute edge betweenness centrality //-------------------------------------------------------------------------- + LG_SET_BURBLE (true) ; + t = LAGraph_WallClockTime ( ) ; LAGRAPH_TRY (LAGr_EdgeBetweennessCentrality (¢rality, G, msg)) ; t = LAGraph_WallClockTime ( ) - t ; printf ("Time for LAGr_EdgeBetweennessCentrality: %g sec\n", t) ; + LG_SET_BURBLE (false) ; + //-------------------------------------------------------------------------- // check the results using LG_check_edgeBetweennessCentrality //-------------------------------------------------------------------------- @@ -96,7 +99,7 @@ int main (int argc, char **argv) GrB_Matrix reference_centrality = NULL; LAGRAPH_TRY (LG_check_edgeBetweennessCentrality(&reference_centrality, G, msg)) ; - double err = difference(centrality, reference_centrality, G->n, G->n) ; + double err = difference(centrality, reference_centrality) ; printf ("Error between computed and reference centrality: %e\n", err) ; if (err < 1e-4) { From 48085a49378a7c31907b936ae71c6adef4c094aa Mon Sep 17 00:00:00 2001 From: peicasey Date: Wed, 19 Mar 2025 13:15:28 -0500 Subject: [PATCH 3/4] clean up tests and demo --- .../LAGr_EdgeBetweennessCentrality.c | 4 +- .../edgeBetweennessCentrality_demo.c | 16 ++- .../test/test_edgeBetweennessCentrality.c | 110 ++++++++++++++---- 3 files changed, 98 insertions(+), 32 deletions(-) diff --git a/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c b/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c index 425678abb9..551dc21401 100644 --- a/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c +++ b/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c @@ -276,11 +276,11 @@ int LAGr_EdgeBetweennessCentrality // Backtrack through the BFS and compute centrality updates for each vertex // GrB_Index fd1_size; - printf ("\n----------------------------- backtrack:\n") ; + // printf ("\n----------------------------- backtrack:\n") ; while (depth >= 1) { - printf ("\n----------------------------- backtrack depth : %" PRId64 "\n", depth) ; + // printf ("\n----------------------------- backtrack depth : %" PRId64 "\n", depth) ; GrB_Vector f_d = Search [depth] ; GrB_Vector f_d1 = Search [depth - 1] ; diff --git a/experimental/benchmark/edgeBetweennessCentrality_demo.c b/experimental/benchmark/edgeBetweennessCentrality_demo.c index d942edebe5..ffef93926e 100644 --- a/experimental/benchmark/edgeBetweennessCentrality_demo.c +++ b/experimental/benchmark/edgeBetweennessCentrality_demo.c @@ -12,7 +12,6 @@ int main (int argc, char **argv) { -// double difference(GrB_Matrix bc, double* gap_result, GrB_Index rows, GrB_Index cols) ; double difference(GrB_Matrix bc, GrB_Matrix reference_bc) { @@ -22,16 +21,16 @@ int main (int argc, char **argv) GrB_Matrix_nrows (&n, bc) ; // Compute diff = max(abs(reference_bc - bc)) - GrB_Matrix_new(&diff, GrB_FP64, n, n); - GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, reference_bc, bc, NULL); - GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL); + GrB_Matrix_new(&diff, GrB_FP64, n, n) ; + GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, reference_bc, bc, NULL) ; + GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL) ; - double err = 1; - GrB_reduce(&err, NULL, GrB_MAX_MONOID_FP64, diff, NULL); + double err = 1 ; + GrB_reduce(&err, NULL, GrB_MAX_MONOID_FP64, diff, NULL) ; - GrB_free(&diff); + GrB_free(&diff) ; - return err; + return err ; } //-------------------------------------------------------------------------- @@ -68,7 +67,6 @@ int main (int argc, char **argv) fclose(f); uint64_t n ; GRB_TRY (GrB_Matrix_nrows (&n, A)) ; -// GRB_TRY (GrB_assign (A, A, NULL, 1.0, GrB_ALL, n, GrB_ALL, n, GrB_DESC_S)) ; LAGRAPH_TRY (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ; LAGRAPH_TRY (LAGraph_DeleteSelfEdges (G, msg)) ; diff --git a/experimental/test/test_edgeBetweennessCentrality.c b/experimental/test/test_edgeBetweennessCentrality.c index f2c15018ed..cd4560e908 100644 --- a/experimental/test/test_edgeBetweennessCentrality.c +++ b/experimental/test/test_edgeBetweennessCentrality.c @@ -31,36 +31,56 @@ LAGraph_Graph G = NULL ; // difference: compare the LAGraph and GAP results //------------------------------------------------------------------------------ -double difference(GrB_Matrix bc, double* gap_result, GrB_Index rows, GrB_Index cols) ; +double difference(GrB_Matrix bc, double* reference_bc, GrB_Index rows, GrB_Index cols) ; -double difference(GrB_Matrix bc, double* gap_result, GrB_Index rows, GrB_Index cols) +double difference(GrB_Matrix bc, double* reference_bc, GrB_Index rows, GrB_Index cols) { // GrB_Matrix diff = NULL; - GrB_Matrix diff = NULL, gap_bc = NULL; - OK(GrB_Matrix_new(&gap_bc, GrB_FP64, rows, cols)); + GrB_Matrix diff = NULL, reference_bc_matrix = NULL ; + OK(GrB_Matrix_new(&reference_bc_matrix, GrB_FP64, rows, cols)) ; // Populate gap_bc with values from gap_result for (GrB_Index i = 0; i < rows; i++) { for (GrB_Index j = 0; j < cols; j++) { - // if (*(gap_result + i * cols + j) != 0) printf(" (%ld, %ld) %g\n", i, j, *(gap_result + i * cols + j)); - OK(GrB_Matrix_setElement_FP64(gap_bc, *(gap_result + i * cols + j), i, j)); + OK(GrB_Matrix_setElement_FP64(reference_bc_matrix, *(reference_bc + i * cols + j), i, j)) ; } } - // Compute diff = max(abs(gap_bc - bc)) - OK(GrB_Matrix_new(&diff, GrB_FP64, rows, cols)); - OK(GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, gap_bc, bc, NULL)); - OK(GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL)); + // Compute diff = max(abs(reference_bc_matrix - bc)) + OK(GrB_Matrix_new(&diff, GrB_FP64, rows, cols)) ; + OK(GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, reference_bc_matrix, bc, NULL)) ; + OK(GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL)) ; - double err = 0; - OK(GrB_reduce(&err, NULL, GrB_MAX_MONOID_FP64, diff, NULL)); + double err = 0 ; + OK(GrB_reduce(&err, NULL, GrB_MAX_MONOID_FP64, diff, NULL)) ; - OK(GrB_free(&diff)); - OK(GrB_free(&gap_bc)); + OK(GrB_free(&diff)) ; + OK(GrB_free(&reference_bc_matrix)) ; - return err; + return err ; } +double matrix_difference(GrB_Matrix bc, GrB_Matrix reference_bc) ; + +double matrix_difference(GrB_Matrix bc, GrB_Matrix reference_bc) +{ + GrB_Matrix diff = NULL ; + + uint64_t n ; + GrB_Matrix_nrows (&n, bc) ; + + // Compute diff = max(abs(reference_bc - bc)) + GrB_Matrix_new(&diff, GrB_FP64, n, n) ; + GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, reference_bc, bc, NULL) ; + GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL) ; + + double err = 1 ; + GrB_reduce(&err, NULL, GrB_MAX_MONOID_FP64, diff, NULL) ; + + GrB_free(&diff) ; + + return err ; +} //------------------------------------------------------------------------------ // results for book graph @@ -158,14 +178,14 @@ void test_diamonds_ebc (void) // compute its betweenness centrality with C version OK (LG_check_edgeBetweennessCentrality (¢rality, G, msg)) ; double err = difference(centrality, &diamonds_ebc[0][0], 8, 8) ; - printf ("diamonds: err: %e (C version)\n", err) ; + printf ("\n diamonds: err: %e (C version)", err) ; TEST_CHECK (err < 1e-4) ; OK (GrB_free (¢rality)) ; // compute its betweenness centrality with GraphBLAS version OK (LAGr_EdgeBetweennessCentrality (¢rality, G, msg)) ; err = difference(centrality, &diamonds_ebc[0][0], 8, 8) ; - printf ("diamonds: err: %e (pure GraphBLAS)\n", err) ; + printf ("\n diamonds: err: %e (pure GraphBLAS)\n", err) ; TEST_CHECK (err < 1e-4) ; OK (GrB_free (¢rality)) ; @@ -196,14 +216,14 @@ void test_karate_ebc (void) // compute its betweenness centrality (C version) OK (LG_check_edgeBetweennessCentrality (¢rality, G, msg)) ; double err = difference(centrality, &karate_ebc[0][0], 34, 34) ; - printf ("karate: err: %e (C version)\n", err) ; + printf ("\n karate: err: %e (C version)", err) ; TEST_CHECK (err < 1e-4) ; OK (GrB_free (¢rality)) ; // compute its betweenness centrality (GraphBLAS version) OK (LAGr_EdgeBetweennessCentrality (¢rality, G, msg)) ; err = difference(centrality, &karate_ebc[0][0], 34, 34) ; - printf ("karate: err: %e (GraphBLAS version)\n", err) ; + printf ("\n karate: err: %e (GraphBLAS version)\n", err) ; TEST_CHECK (err < 1e-4) ; OK (GrB_free (¢rality)) ; @@ -212,15 +232,63 @@ void test_karate_ebc (void) } +// Function to test multiple matrix market files +void test_many(void) +{ + LAGraph_Init(msg); + + const char *files[] = { + "random_unweighted_bipartite1.mtx", + "random_unweighted_bipartite2.mtx", + "random_unweighted_general1.mtx", + "random_unweighted_general2.mtx", + NULL + }; + + for (int i = 0; files[i] != NULL; i++) + { + GrB_Matrix A = NULL; + GrB_Matrix centrality = NULL; + GrB_Matrix reference_centrality = NULL; + + snprintf(filename, LEN, LG_DATA_DIR "%s", files[i]); + FILE *f = fopen(filename, "r"); + TEST_CHECK(f != NULL); + OK(LAGraph_MMRead(&A, f, msg)); + OK(fclose(f)); + OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)); + LAGRAPH_TRY (LAGraph_DeleteSelfEdges (G, msg)) ; + LAGRAPH_TRY (LAGraph_Cached_AT (G, msg)) ; + TEST_CHECK(A == NULL); // A has been moved into G->A + + // compute its betweenness centrality (GraphBLAS version) + OK(LAGr_EdgeBetweennessCentrality(¢rality, G, msg)); + + // compute its betweenness centrality (C version) + OK(LG_check_edgeBetweennessCentrality(&reference_centrality, G, msg)); + + // Compare the results + double err = matrix_difference(centrality, reference_centrality); + printf("\n %s: err: %e", files[i], err); + TEST_CHECK(err < 1e-4); + + OK(GrB_free(¢rality)); + OK(GrB_free(&reference_centrality)); + OK(LAGraph_Delete(&G, msg)); + } + printf("\n") ; + + LAGraph_Finalize(msg); +} + //------------------------------------------------------------------------------ // list of tests //------------------------------------------------------------------------------ -// FIXME: add more matrices TEST_LIST = { {"test_diamonds_ebc", test_diamonds_ebc}, {"test_karate_ebc", test_karate_ebc}, -// {"test_many", test_many}, FIXME ADD THIS + {"test_many", test_many}, {NULL, NULL} }; From 605ab39e71e6d5362c9445b69f1cc6ad27617e99 Mon Sep 17 00:00:00 2001 From: peicasey Date: Fri, 28 Mar 2025 23:40:41 -0500 Subject: [PATCH 4/4] make test and demo nicer --- .../edgeBetweennessCentrality_demo.c | 38 ++++++++++--------- .../test/test_edgeBetweennessCentrality.c | 5 ++- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/experimental/benchmark/edgeBetweennessCentrality_demo.c b/experimental/benchmark/edgeBetweennessCentrality_demo.c index ffef93926e..46dfae134c 100644 --- a/experimental/benchmark/edgeBetweennessCentrality_demo.c +++ b/experimental/benchmark/edgeBetweennessCentrality_demo.c @@ -10,28 +10,28 @@ #include "LG_internal.h" #include -int main (int argc, char **argv) +double difference(GrB_Matrix bc, GrB_Matrix reference_bc) { + GrB_Matrix diff = NULL ; - double difference(GrB_Matrix bc, GrB_Matrix reference_bc) - { - GrB_Matrix diff = NULL ; + uint64_t n ; + GrB_Matrix_nrows (&n, bc) ; - uint64_t n ; - GrB_Matrix_nrows (&n, bc) ; + // Compute diff = max(abs(reference_bc - bc)) + GrB_Matrix_new(&diff, GrB_FP64, n, n) ; + GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, reference_bc, bc, NULL) ; + GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL) ; - // Compute diff = max(abs(reference_bc - bc)) - GrB_Matrix_new(&diff, GrB_FP64, n, n) ; - GrB_eWiseAdd(diff, NULL, NULL, GrB_MINUS_FP64, reference_bc, bc, NULL) ; - GrB_apply(diff, NULL, NULL, GrB_ABS_FP64, diff, NULL) ; + double err = 1 ; + GrB_reduce(&err, NULL, GrB_MAX_MONOID_FP64, diff, NULL) ; - double err = 1 ; - GrB_reduce(&err, NULL, GrB_MAX_MONOID_FP64, diff, NULL) ; + GrB_free(&diff) ; - GrB_free(&diff) ; + return err ; +} ; - return err ; - } +int main (int argc, char **argv) +{ //-------------------------------------------------------------------------- // startup LAGraph and GraphBLAS @@ -81,21 +81,25 @@ int main (int argc, char **argv) // compute edge betweenness centrality //-------------------------------------------------------------------------- - LG_SET_BURBLE (true) ; + // LG_SET_BURBLE (true) ; t = LAGraph_WallClockTime ( ) ; LAGRAPH_TRY (LAGr_EdgeBetweennessCentrality (¢rality, G, msg)) ; t = LAGraph_WallClockTime ( ) - t ; printf ("Time for LAGr_EdgeBetweennessCentrality: %g sec\n", t) ; - LG_SET_BURBLE (false) ; + // LG_SET_BURBLE (false) ; //-------------------------------------------------------------------------- // check the results using LG_check_edgeBetweennessCentrality //-------------------------------------------------------------------------- GrB_Matrix reference_centrality = NULL; + t = LAGraph_WallClockTime ( ) ; LAGRAPH_TRY (LG_check_edgeBetweennessCentrality(&reference_centrality, G, msg)) ; + t = LAGraph_WallClockTime ( ) - t ; + printf ("Time for LG_check_edgeBetweennessCentrality: %g sec\n", t) ; + double err = difference(centrality, reference_centrality) ; printf ("Error between computed and reference centrality: %e\n", err) ; diff --git a/experimental/test/test_edgeBetweennessCentrality.c b/experimental/test/test_edgeBetweennessCentrality.c index cd4560e908..ee85206599 100644 --- a/experimental/test/test_edgeBetweennessCentrality.c +++ b/experimental/test/test_edgeBetweennessCentrality.c @@ -242,6 +242,7 @@ void test_many(void) "random_unweighted_bipartite2.mtx", "random_unweighted_general1.mtx", "random_unweighted_general2.mtx", + "dnn_data/n1024-l1.mtx", NULL }; @@ -257,8 +258,8 @@ void test_many(void) OK(LAGraph_MMRead(&A, f, msg)); OK(fclose(f)); OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)); - LAGRAPH_TRY (LAGraph_DeleteSelfEdges (G, msg)) ; - LAGRAPH_TRY (LAGraph_Cached_AT (G, msg)) ; + OK(LAGraph_DeleteSelfEdges (G, msg)) ; + OK(LAGraph_Cached_AT (G, msg)) ; TEST_CHECK(A == NULL); // A has been moved into G->A // compute its betweenness centrality (GraphBLAS version)