Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 32 additions & 22 deletions experimental/algorithm/LAGr_EdgeBetweennessCentrality.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)


//------------------------------------------------------------------------------
Expand Down Expand Up @@ -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" \
"}"

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -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)
Expand All @@ -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)) ;

Expand Down Expand Up @@ -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)
{
Expand All @@ -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 )) ;

//----------------------------------------------------------------------
Expand All @@ -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] ;

Expand All @@ -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 +.

Expand Down
124 changes: 124 additions & 0 deletions experimental/benchmark/edgeBetweennessCentrality_demo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@

#define LG_FREE_ALL \
printf ("done here: %d\n", __LINE__) ; \
printf ("msg: [%s]\n", msg) ; \
GrB_free (&centrality) ; \
GrB_free (&A) ; \
LAGraph_Delete (&G, msg) ; \

#include "LAGraphX.h"
#include "LG_internal.h"
#include <stdio.h>

double 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 ;
} ;

int main (int argc, char **argv)
{

//--------------------------------------------------------------------------
// startup LAGraph and GraphBLAS
//--------------------------------------------------------------------------

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)) ;

//--------------------------------------------------------------------------
// read in the graph via a Matrix Market file from stdin
//--------------------------------------------------------------------------

if (argc < 2)
{
printf("Usage: %s <matrix-market-file>\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);
uint64_t n ;
GRB_TRY (GrB_Matrix_nrows (&n, A)) ;

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) ;

printf ("\n==========================The input graph matrix G:\n") ;
LAGRAPH_TRY (LAGraph_Graph_Print (G, LAGraph_SHORT, stdout, msg)) ;

//--------------------------------------------------------------------------
// compute edge betweenness centrality
//--------------------------------------------------------------------------

// LG_SET_BURBLE (true) ;

t = LAGraph_WallClockTime ( ) ;
LAGRAPH_TRY (LAGr_EdgeBetweennessCentrality (&centrality, 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
//--------------------------------------------------------------------------

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) ;
if (err < 1e-4)
{
printf ("Test passed.\n") ;
}
else
{
printf ("Test failure!\n") ;
}

//--------------------------------------------------------------------------
// free everything and finish
//--------------------------------------------------------------------------

GrB_free (&centrality) ;
GrB_free (&reference_centrality) ;
LAGraph_Delete (&G, msg) ;
LAGRAPH_TRY (LAGraph_Finalize (msg)) ;
return (GrB_SUCCESS) ;
}
Loading
Loading