diff --git a/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c b/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c index 8ec8f7384e..e7b42820b9 100755 --- a/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c +++ b/experimental/algorithm/LAGr_EdgeBetweennessCentrality.c @@ -69,20 +69,13 @@ // (1+x)/y function for double: z = (1 + x) / y //------------------------------------------------------------------------------ +LG_JIT_STRING( void LG_EBC_add_one_divide_function (double *z, const double *x, const double *y) { double a = (*(x)) ; double b = (*(y)) ; (*(z)) = (1 + a) / b ; -} - -#define ADD_ONE_DIVIDE_FUNCTION_DEFN \ -"void LG_EBC_add_one_divide_function (double *z, const double *x, const double *y)\n" \ -"{ \n" \ -" double a = (*(x)) ; \n" \ -" double b = (*(y)) ; \n" \ -" (*(z)) = (1 + a) / b ; \n" \ -"}" +}, ADD_ONE_DIVIDE_FUNCTION_DEFN) //------------------------------------------------------------------------------ // LAGr_EdgeBetweennessCentrality: edge betweenness-centrality diff --git a/experimental/algorithm/LAGr_SwapEdges.c b/experimental/algorithm/LAGr_SwapEdges.c index e18b428b73..a72ffc636e 100755 --- a/experimental/algorithm/LAGr_SwapEdges.c +++ b/experimental/algorithm/LAGr_SwapEdges.c @@ -77,133 +77,87 @@ #include "LG_internal.h" #include "LAGraphX.h" -void LG_SE_shift_and - (uint16_t *z, const uint16_t *x) - { - (*z) = (*x) & ((*x) << 8); - (*z) |= (*z) >> 8; - } -#define SHIFT_AND \ -"void LG_SE_shift_and \n"\ -" (uint16_t *z, const uint16_t *x) \n"\ -" { \n"\ -" (*z) = (*x) & ((*x) << 8); \n"\ -" (*z) |= (*z) >> 8; \n"\ -" }" +LG_JIT_STRING( +void LG_SE_shift_and (uint16_t *z, const uint16_t *x) +{ + (*z) = (*x) & ((*x) << 8); + (*z) |= (*z) >> 8; +}, LG_SE_SHIFT_AND) + +LG_JIT_STRING( typedef struct { - uint64_t a; + uint64_t a; uint64_t b; -} LG_SE_edge_type64; -#define EDGE_TYPE64 \ -"typedef struct { uint64_t a; uint64_t b; } LG_SE_edge_type64;" +} LG_SE_edge_type64;, LG_SE_EDGE_TYPE64) +LG_JIT_STRING( typedef struct { - uint64_t a; + uint64_t a; uint64_t b; - uint64_t c; + uint64_t c; uint64_t d; -} LG_SE_swap_type64; -#define SWAP_TYPE64 \ -"typedef struct { \n"\ -" uint64_t a; uint64_t b; uint64_t c; uint64_t d; \n"\ -"} LG_SE_swap_type64;" +} LG_SE_swap_type64;, LG_SE_SWAP_TYPE64) +LG_JIT_STRING( typedef struct { - uint32_t a; + uint32_t a; uint32_t b; -} LG_SE_edge_type32; -#define EDGE_TYPE32 \ -"typedef struct { uint32_t a; uint32_t b; } LG_SE_edge_type32;" +} LG_SE_edge_type32;, LG_SE_EDGE_TYPE32) +LG_JIT_STRING( typedef struct { - uint32_t a; + uint32_t a; uint32_t b; - uint32_t c; + uint32_t c; uint32_t d; -} LG_SE_swap_type32; -#define SWAP_TYPE32 \ -"typedef struct { \n"\ -" uint32_t a; uint32_t b; uint32_t c; uint32_t d; \n"\ -"}LG_SE_swap_type32;" - -void LG_SE_swap_bc64 -(LG_SE_swap_type64 *z, const LG_SE_swap_type64 *x, GrB_Index I, GrB_Index J, const bool *y) -{ +} LG_SE_swap_type32;, LG_SE_SWAP_TYPE32) + +LG_JIT_STRING( +void LG_SE_swap_bc64 ( + LG_SE_swap_type64 *z, const LG_SE_swap_type64 *x, + GrB_Index I, GrB_Index J, const bool *y +) { memcpy(z, x, sizeof(*z)) ; //unnessesary when aliassed but done for safety. if(z->a == z->c || z->b == z->c || z->a == z->d || z->b == z->d ) return; if(I & 1) { uint64_t temp = z->d; z->d = z->b; - z->b = temp; + z->b = temp; } else { uint64_t temp = z->c; z->c = z->b; - z->b = temp; - } -} -void LG_SE_swap_bc32 -(LG_SE_swap_type32 *z, const LG_SE_swap_type32 *x, GrB_Index I, GrB_Index J, const bool *y) -{ + z->b = temp; + } +}, LG_SE_SWAP_BC64) + +LG_JIT_STRING( +void LG_SE_swap_bc32( + LG_SE_swap_type32 *z, const LG_SE_swap_type32 *x, + GrB_Index I, GrB_Index J, const bool *y +) { memcpy(z, x, sizeof(*z)) ; //unnessesary when aliassed but done for safety. if(z->a == z->c || z->b == z->c || z->a == z->d || z->b == z->d ) return; if(I & 1) { uint32_t temp = z->d; z->d = z->b; - z->b = temp; + z->b = temp; } else { uint32_t temp = z->c; z->c = z->b; - z->b = temp; - } -} -#define SWAP_BC64 \ -"void LG_SE_swap_bc64 \n"\ -"(LG_SE_swap_type64 *z, const LG_SE_swap_type64 *x, GrB_Index I, GrB_Index J, const bool *y)\n"\ -"{ \n"\ -" memcpy(z, x, sizeof(*z)) ; //unnessesary when aliassed but done for safety.\n"\ -" if(z->a == z->c || z->b == z->c || z->a == z->d || z->b == z->d ) return; \n"\ -" if(I & 1) \n"\ -" { \n"\ -" uint64_t temp = z->d; \n"\ -" z->d = z->b; \n"\ -" z->b = temp; \n"\ -" } \n"\ -" else \n"\ -" { \n"\ -" uint64_t temp = z->c; \n"\ -" z->c = z->b; \n"\ -" z->b = temp; \n"\ -" } \n"\ -"}" -#define SWAP_BC32 \ -"void LG_SE_swap_bc32 \n"\ -"(LG_SE_swap_type32 *z, const LG_SE_swap_type32 *x, GrB_Index I, GrB_Index J, const bool *y)\n"\ -"{ \n"\ -" memcpy(z, x, sizeof(*z)) ; //unnessesary when aliassed but done for safety.\n"\ -" if(z->a == z->c || z->b == z->c || z->a == z->d || z->b == z->d ) return; \n"\ -" if(I & 1) \n"\ -" { \n"\ -" uint32_t temp = z->d; \n"\ -" z->d = z->b; \n"\ -" z->b = temp; \n"\ -" } \n"\ -" else \n"\ -" { \n"\ -" uint32_t temp = z->c; \n"\ -" z->c = z->b; \n"\ -" z->b = temp; \n"\ -" } \n"\ -"}" + z->b = temp; + } +}, LG_SE_SWAP_BC32) // using xorshift, from https://en.wikipedia.org/wiki/Xorshift // with a state of uint64_t, or xorshift64star. +LG_JIT_STRING( void LG_SE_hash_edge64 (uint64_t *z, const LG_SE_edge_type64 *x, const uint64_t *mask) { @@ -213,108 +167,58 @@ void LG_SE_hash_edge64 (*z) ^= (x->a < x->b)? x->a: x->b; (*z) ^= (*z) << 17; (*z) &= (*mask); -} +}, LG_SE_HASH_EDGE64) + +LG_JIT_STRING( void LG_SE_hash_edge32 (uint64_t *z, const LG_SE_edge_type32 *x, const uint64_t *mask) { (*z) = x->a ^ x->b; - (*z) ^= (*z) << 13; - (*z) ^= (*z) >> 7; + (*z) ^= (*z) << 13; + (*z) ^= (*z) >> 7; (*z) ^= (uint64_t)((x->a < x->b)? x->a: x->b); - (*z) ^= (*z) << 17; + (*z) ^= (*z) << 17; (*z) &= (*mask); -} -#define HASH_EDGE64 \ -"void LG_SE_hash_edge64 \n"\ -"(uint64_t *z, const LG_SE_edge_type64 *x, const uint64_t *mask) \n"\ -"{ \n"\ -" (*z) = x->a ^ x->b; \n"\ -" (*z) ^= (*z) << 13; \n"\ -" (*z) ^= (*z) >> 7; \n"\ -" (*z) ^= (uint64_t)((x->a < x->b)? x->a: x->b); \n"\ -" (*z) ^= (*z) << 17; \n"\ -" (*z) &= (*mask); \n"\ -"}" -#define HASH_EDGE32 \ -"void LG_SE_hash_edge32 \n"\ -"(uint64_t *z, const LG_SE_edge_type32 *x, const uint64_t *mask) \n"\ -"{ \n"\ -" (*z) = x->a ^ x->b; \n"\ -" (*z) ^= (*z) << 13; \n"\ -" (*z) ^= (*z) >> 7; \n"\ -" (*z) ^= (uint64_t)((x->a < x->b)? x->a: x->b); \n"\ -" (*z) ^= (*z) << 17; \n"\ -" (*z) &= (*mask); \n"\ -"}" +}, LG_SE_HASH_EDGE32) +LG_JIT_STRING( void LG_SE_add_term (int8_t *z, const int8_t *x, const int8_t *y) { (*z) = (*x) | (*y) + ((int8_t)1 & (*x) & (*y)) ; -} -#define ADD_TERM \ -"void LG_SE_add_term \n"\ -"(int8_t *z, const int8_t *x, const int8_t *y) \n"\ -"{ \n"\ -" (*z) = (*x) | (*y) + ((int8_t)1 & (*x) & (*y)) ; \n"\ -"}" +}, LG_SE_ADD_TERM) +LG_JIT_STRING( void LG_SE_edge2nd64_bool (LG_SE_edge_type64 *z, const bool *x, const LG_SE_edge_type64 *y) { z->a = y->a; z->b = y->b; -} +}, LG_SE_EDGE2ND64_BOOL) + +LG_JIT_STRING( void LG_SE_edge2nd32_bool (LG_SE_edge_type32 *z, const bool *x, const LG_SE_edge_type32 *y) { z->a = y->a; z->b = y->b; -} +}, LG_SE_EDGE2ND32_BOOL) + +LG_JIT_STRING( void LG_SE_edge2nd64_edge (LG_SE_edge_type64 *z, const LG_SE_edge_type64 *x, const LG_SE_edge_type64 *y) { z->a = y->a; z->b = y->b; -} +}, LG_SE_EDGE2ND64_EDGE) + +LG_JIT_STRING( void LG_SE_edge2nd32_edge (LG_SE_edge_type32 *z, const LG_SE_edge_type32 *x, const LG_SE_edge_type32 *y) { z->a = y->a; z->b = y->b; -} -#define EDGE2ND32_BOOL \ -"void LG_SE_edge2nd32_bool \n"\ -"(LG_SE_edge_type32 *z, const bool *x, const LG_SE_edge_type32 *y) \n"\ -"{ \n"\ -" //if(y->a == 0 && y->b == 0) return; \n"\ -" z->a = y->a; \n"\ -" z->b = y->b; \n"\ -"}" -#define EDGE2ND64_BOOL \ -"void LG_SE_edge2nd64_bool \n"\ -"(LG_SE_edge_type64 *z, const bool *x, const LG_SE_edge_type64 *y) \n"\ -"{ \n"\ -" //if(y->a == 0 && y->b == 0) return; \n"\ -" z->a = y->a; \n"\ -" z->b = y->b; \n"\ -"}" -#define EDGE2ND32_EDGE \ -"void LG_SE_edge2nd32_edge \n"\ -"(LG_SE_edge_type32 *z, const LG_SE_edge_type32 *x, const LG_SE_edge_type32 *y)\n"\ -"{ \n"\ -" //if(y->a == 0 && y->b == 0) return; \n"\ -" z->a = y->a; \n"\ -" z->b = y->b; \n"\ -"}" -#define EDGE2ND64_EDGE \ -"void LG_SE_edge2nd64_edge \n"\ -"(LG_SE_edge_type64 *z, const LG_SE_edge_type64 *x, const LG_SE_edge_type64 *y)\n"\ -"{ \n"\ -" //if(y->a == 0 && y->b == 0) return; \n"\ -" z->a = y->a; \n"\ -" z->b = y->b; \n"\ -"}" +}, LG_SE_EDGE2ND32_EDGE) // FIXME: make loopTry, loopMin, totSwaps, seed inputs GrB_Scalar // FIXME: make pSwaps GrB_Scalar @@ -378,12 +282,12 @@ int LAGr_SwapEdges // 2^60 holds the buckets in which hashes collided. GrB_Vector exists = NULL; - + GrB_UnaryOp lg_shiftland = NULL; // b1 <---> a2 or b1 <---> b2 GrB_IndexUnaryOp swap_pair = NULL; - + // z = h_y(x) GrB_BinaryOp hash_seed_e = NULL; @@ -424,7 +328,7 @@ int LAGr_SwapEdges GrB_Scalar one8 = NULL; GrB_Index ind_size = 0; - + //-------------------------------------------------------------------------- // Check inputs //-------------------------------------------------------------------------- @@ -435,7 +339,7 @@ int LAGr_SwapEdges ) ; // char type[LAGRAPH_MAX_NAME_LEN]; LG_ASSERT_MSG (G->nself_edges == 0, LAGRAPH_NO_SELF_EDGES_ALLOWED, - "G->nself_edges must be zero") ; + "G->nself_edges must be zero") ; LG_ASSERT (G_new != NULL, GrB_NULL_POINTER) ; LG_ASSERT (pSwaps != NULL, GrB_NULL_POINTER) ; *G_new = NULL ; @@ -453,12 +357,12 @@ int LAGr_SwapEdges GRB_TRY (GrB_Matrix_new (&A_tril, GrB_BOOL, n, n)) ; GRB_TRY (GrB_Vector_new(&Ai, GrB_BOOL, 0)) ; GRB_TRY (GrB_Vector_new(&Aj, GrB_BOOL, 0)) ; - + // Extract lower triangular edges GRB_TRY (GrB_select (A_tril, NULL, NULL, GrB_TRIL, A, 0, NULL)) ; GRB_TRY (GrB_Matrix_nvals(&e, A_tril)) ; GRB_TRY (GxB_Matrix_extractTuples_Vector(Ai, Aj, NULL, A_tril, NULL)) ; - #ifdef COVERAGE +#ifdef COVERAGE if(n > 100) { // Make Ai and Aj 64 bit @@ -473,7 +377,7 @@ int LAGr_SwapEdges Aj = temp_i; temp_i = NULL; } - #endif +#endif int codei = 0, codej = 0; GRB_TRY (GxB_Vector_type(&Ai_type, Ai)) ; GrB_get(Ai, &codei, GrB_EL_TYPE_CODE); @@ -489,68 +393,85 @@ int LAGr_SwapEdges if(codei == GrB_UINT32_CODE) // Use uint32 if possible { GRB_TRY (GxB_Type_new( - &lg_edge, sizeof(LG_SE_edge_type32), "LG_SE_edge_type32", EDGE_TYPE32)) ; + &lg_edge, sizeof(LG_SE_edge_type32), + "LG_SE_edge_type32", LG_SE_EDGE_TYPE32)) ; GRB_TRY (GxB_Type_new( - &lg_swap, sizeof(LG_SE_swap_type32), "LG_SE_swap_type32", SWAP_TYPE32)) ; + &lg_swap, sizeof(LG_SE_swap_type32), + "LG_SE_swap_type32", LG_SE_SWAP_TYPE32)) ; GRB_TRY(GxB_BinaryOp_new( &hash_seed_e, (GxB_binary_function) (&LG_SE_hash_edge32), - GrB_UINT64, lg_edge, GrB_UINT64, "LG_SE_hash_edge32", HASH_EDGE32 + GrB_UINT64, lg_edge, GrB_UINT64, + "LG_SE_hash_edge32", LG_SE_HASH_EDGE32 )) ; GRB_TRY (GxB_IndexUnaryOp_new ( &swap_pair, (GxB_index_unary_function) (&LG_SE_swap_bc32), - lg_swap, lg_swap, GrB_BOOL, "LG_SE_swap_bc32", SWAP_BC32 + lg_swap, lg_swap, GrB_BOOL, "LG_SE_swap_bc32", + LG_SE_SWAP_BC32 )) ; GRB_TRY(GxB_BinaryOp_new( - &second_edge, (GxB_binary_function) (&LG_SE_edge2nd32_edge), - lg_edge, lg_edge, lg_edge, "LG_SE_edge2nd32_edge", EDGE2ND32_EDGE + &second_edge, (GxB_binary_function) (&LG_SE_edge2nd32_edge), + lg_edge, lg_edge, lg_edge, "LG_SE_edge2nd32_edge", + LG_SE_EDGE2ND32_EDGE )) ; GRB_TRY(GxB_BinaryOp_new( - &second_bool_edge, (GxB_binary_function) (&LG_SE_edge2nd32_bool), - lg_edge, GrB_BOOL, lg_edge, "LG_SE_edge2nd32_bool", EDGE2ND32_BOOL + &second_bool_edge, (GxB_binary_function) (&LG_SE_edge2nd32_bool), + lg_edge, GrB_BOOL, lg_edge, "LG_SE_edge2nd32_bool", + LG_SE_EDGE2ND32_BOOL + )) ; + + LG_SE_edge_type32 iden_second = {0,0}; + GRB_TRY (GrB_Monoid_new_UDT( + &second_edge_monoid, second_edge, (void *) &iden_second )) ; } else //uint64 types - { +{ GRB_TRY (GxB_Type_new( - &lg_edge, sizeof(LG_SE_edge_type64), "LG_SE_edge_type64", EDGE_TYPE64)) ; + &lg_edge, sizeof(LG_SE_edge_type64), "LG_SE_edge_type64", + LG_SE_EDGE_TYPE64)) ; GRB_TRY (GxB_Type_new( - &lg_swap, sizeof(LG_SE_swap_type64), "LG_SE_swap_type64", SWAP_TYPE64)) ; + &lg_swap, sizeof(LG_SE_swap_type64), "LG_SE_swap_type64", + LG_SE_SWAP_TYPE64)) ; GRB_TRY(GxB_BinaryOp_new( &hash_seed_e, (GxB_binary_function) (&LG_SE_hash_edge64), - GrB_UINT64, lg_edge, GrB_UINT64, "LG_SE_hash_edge64", HASH_EDGE64 + GrB_UINT64, lg_edge, GrB_UINT64, "LG_SE_hash_edge64", + LG_SE_HASH_EDGE64 )) ; GRB_TRY (GxB_IndexUnaryOp_new ( &swap_pair, (GxB_index_unary_function) (&LG_SE_swap_bc64), - lg_swap, lg_swap, GrB_BOOL, "LG_SE_swap_bc64", SWAP_BC64 + lg_swap, lg_swap, GrB_BOOL, "LG_SE_swap_bc64", + LG_SE_SWAP_BC64 )) ; GRB_TRY(GxB_BinaryOp_new( - &second_edge, (GxB_binary_function) (&LG_SE_edge2nd64_edge), - lg_edge, lg_edge, lg_edge, "LG_SE_edge2nd64_edge", EDGE2ND64_EDGE + &second_edge, (GxB_binary_function) (&LG_SE_edge2nd64_edge), + lg_edge, lg_edge, lg_edge, "LG_SE_edge2nd64_edge", + LG_SE_EDGE2ND64_EDGE )) ; GRB_TRY(GxB_BinaryOp_new( - &second_bool_edge, (GxB_binary_function) (&LG_SE_edge2nd64_bool), - lg_edge, GrB_BOOL, lg_edge, "LG_SE_edge2nd64_bool", EDGE2ND64_BOOL + &second_bool_edge, (GxB_binary_function) (&LG_SE_edge2nd64_bool), + lg_edge, GrB_BOOL, lg_edge, "LG_SE_edge2nd64_bool", + LG_SE_EDGE2ND64_BOOL + )) ; + + LG_SE_edge_type64 iden_second = {0,0}; + GRB_TRY (GrB_Monoid_new_UDT( + &second_edge_monoid, second_edge, (void *) &iden_second )) ; } - + GRB_TRY (GxB_UnaryOp_new ( &lg_shiftland, (GxB_unary_function) (&LG_SE_shift_and), - GrB_UINT16, GrB_UINT16, "LG_SE_shift_and", SHIFT_AND + GrB_UINT16, GrB_UINT16, "LG_SE_shift_and", LG_SE_SHIFT_AND )) ; GRB_TRY(GxB_BinaryOp_new( - &add_term_biop, (GxB_binary_function) (&LG_SE_add_term), - GrB_INT8, GrB_INT8, GrB_INT8, "LG_SE_add_term", ADD_TERM + &add_term_biop, (GxB_binary_function) (&LG_SE_add_term), + GrB_INT8, GrB_INT8, GrB_INT8, "LG_SE_add_term", LG_SE_ADD_TERM )) ; GRB_TRY (GxB_Monoid_terminal_new_INT8( &add_term_monoid, add_term_biop, (int8_t) 0, (int8_t) 2 )) ; - LG_SE_edge_type64 iden_second = {0,0}; - GRB_TRY (GrB_Monoid_new_UDT( - &second_edge_monoid, second_edge, (void *) &iden_second - )) ; - GRB_TRY(GrB_Semiring_new( &plus_term_one, add_term_monoid, GrB_ONEB_INT8 )) ; @@ -563,7 +484,7 @@ int LAGr_SwapEdges //-------------------------------------------------------------------------- GRB_TRY (GrB_Vector_new(&E_vec, Ai_type, 2 * e)) ; - + // Filling out E_vec helps assign be much quicker. GRB_TRY (GrB_assign( E_vec, NULL, NULL, 0, GrB_ALL, 0, NULL)); @@ -582,7 +503,7 @@ int LAGr_SwapEdges e /= 2; GRB_TRY (GxB_Vector_load( E_vec, &indices, lg_edge, e, ind_size, E_hand, NULL)); - + // Find Hash Size int shift_e = 63 - (int) floor (log2 ((double) e)) ; uint64_t ehash_size = (1ull << (67-shift_e)) ; @@ -599,9 +520,10 @@ int LAGr_SwapEdges // Ramp GRB_TRY (GrB_Vector_new(&ramp_v, GrB_UINT64, e + 1)) ; - GRB_TRY (GrB_Vector_assign_UINT64 (ramp_v, NULL, NULL, 0, GrB_ALL, 0, NULL)) ; - GRB_TRY (GrB_Vector_apply_IndexOp_UINT64 (ramp_v, NULL, NULL, - GrB_ROWINDEX_INT64, ramp_v, 0, NULL)) ; + GRB_TRY (GrB_Vector_assign_UINT64 ( + ramp_v, NULL, NULL, 0, GrB_ALL, 0, NULL)) ; + GRB_TRY (GrB_Vector_apply_IndexOp_UINT64 ( + ramp_v, NULL, NULL, GrB_ROWINDEX_INT64, ramp_v, 0, NULL)) ; GrB_Index ramp_size; // Constants @@ -618,7 +540,7 @@ int LAGr_SwapEdges random_v, NULL, NULL, 0, GrB_ALL, e, NULL)) ; LG_TRY( LAGraph_Random_Seed(random_v, seed, msg)) ; - + // printf("Entering loop, Good Luck:\n") ; while(num_swaps < totSwaps) { @@ -634,7 +556,7 @@ int LAGr_SwapEdges LG_TRY (LAGraph_FastAssign_Semiring( r_permute, NULL, NULL, r_60, x, ramp_v, GxB_ANY_FIRSTJ_INT64, NULL, msg)) ; - + GrB_Index edges_permed = 0; GRB_TRY (GrB_Vector_nvals(&edges_permed, r_permute)) ; GRB_TRY (GrB_Vector_new(&edge_perm, GrB_BOOL, edges_permed)) ; @@ -643,7 +565,7 @@ int LAGr_SwapEdges // Chose only the edges we need from edge_perm GRB_TRY (GrB_Vector_resize(edge_perm, n_keep * 2)) ; - + // Get the desired edges from the E_vec array. GRB_TRY (GrB_Vector_new(&M, lg_edge, n_keep * 2)) ; GRB_TRY (GxB_Vector_extract_Vector( @@ -688,7 +610,7 @@ int LAGr_SwapEdges GRB_TRY (GrB_Vector_new(&dup_swaps_v, GrB_INT8, n_keep * 2)) ; GRB_TRY (GrB_set(dup_swaps_v, GxB_BITMAP, GxB_SPARSITY_CONTROL)) ; - + GRB_TRY (GrB_Vector_clear(x)) ; GRB_TRY (GrB_Vector_resize(x, e)) ; GRB_TRY (GrB_Vector_assign_BOOL( @@ -698,7 +620,7 @@ int LAGr_SwapEdges exists, NULL, NULL, hashed_edges, x, ramp_v, GxB_ANY_PAIR_UINT8, NULL, msg )) ; - + GRB_TRY (GrB_Vector_clear(x)) ; GRB_TRY (GrB_Vector_resize(x, n_keep * 2)) ; GRB_TRY (GrB_Vector_assign_BOOL( @@ -715,7 +637,7 @@ int LAGr_SwapEdges con->b = NULL; GRB_TRY (GrB_free(&con)) ; // exist has to be full at this point - + // "Count" all of the edges that fit into each bucket. Stop counting at // 2 since we will have to throw that whole bucket away anyway. @@ -760,7 +682,7 @@ int LAGr_SwapEdges GRB_TRY (GxB_Vector_load( dup_swaps_v, (void **) &dup_swaps, GrB_INT8, M_nvals * 2, dup_arr_size, M_hand, NULL)) ; - + GRB_TRY (GrB_Vector_clear(exists)) ; // --------------------------------------------------------------------- // Place Good Swaps back into E_vec @@ -774,7 +696,7 @@ int LAGr_SwapEdges // dup_swaps_v, which will become nvals(M) after loading M from the // container con. GRB_TRY (GrB_reduce (&n_keep, NULL, GrB_PLUS_MONOID_UINT64, - dup_swaps_v, NULL)) ; + dup_swaps_v, NULL)) ; con->nvals = n_keep; con->format = GxB_BITMAP; dup_swaps_v = NULL; @@ -822,8 +744,8 @@ int LAGr_SwapEdges LG_FREE_WORK ; (*pSwaps) = num_swaps ; return (num_swaps >= totSwaps)? GrB_SUCCESS : LAGRAPH_INSUFFICIENT_SWAPS ; - #else +#else // printf("LAGr_SwapEdges Needs GB v10\n") ; return (GrB_NOT_IMPLEMENTED) ; - #endif +#endif } diff --git a/experimental/algorithm/LAGraph_Coarsen_Matching.c b/experimental/algorithm/LAGraph_Coarsen_Matching.c index b3275d03f6..bd144aa348 100644 --- a/experimental/algorithm/LAGraph_Coarsen_Matching.c +++ b/experimental/algorithm/LAGraph_Coarsen_Matching.c @@ -89,12 +89,19 @@ This method requires O(n + e) space for an undirected graph with e edges and n n #if LAGRAPH_SUITESPARSE -void LG_CM_valueeq_index_func (bool *z, const uint64_t *x, GrB_Index i, GrB_Index j, const void *y) { +LG_JIT_STRING( +void LG_CM_valueeq_index_func ( + bool *z, + const uint64_t *x, + GrB_Index i, + GrB_Index j, + const void *y +) { (*z) = ((*x) == i) ; -} +}, LG_CM_VALUEEQ_INDEX_FUNC_DEFN) static int LAGraph_Parent_to_S -( +( // input/outputs: GrB_Matrix *result, // resulting S matrix GrB_Vector *newlabels, // The contents of some newlabels_result[i], where newlabels_result is as described at the top of the file. @@ -162,28 +169,31 @@ static int LAGraph_Parent_to_S - GrB_extract into parent_cpy from parent_cpy with row indices as values from original parent - This fills in the new parents for discarded nodes */ - - GRB_TRY (GrB_IndexUnaryOp_new (&VALUEEQ_ROWINDEX_UINT64, F_INDEX_UNARY(LG_CM_valueeq_index_func), GrB_BOOL, GrB_UINT64, GrB_UINT64)) ; + + GRB_TRY (GxB_IndexUnaryOp_new ( + &VALUEEQ_ROWINDEX_UINT64, F_INDEX_UNARY(LG_CM_valueeq_index_func), + GrB_BOOL, GrB_UINT64, GrB_UINT64, "LG_CM_valueeq_index_func", + LG_CM_VALUEEQ_INDEX_FUNC_DEFN)) ; // identify preserved nodes GRB_TRY (GrB_select (parent_cpy, NULL, NULL, VALUEEQ_ROWINDEX_UINT64, parent, 0, NULL)) ; GRB_TRY (GrB_free (&VALUEEQ_ROWINDEX_UINT64)) ; - + // get indices of preserved nodes GRB_TRY (GxB_Vector_unpack_CSC ( - parent_cpy, - &preserved_indices, - (void**) &preserved_values, - &preserved_indices_size, - &preserved_values_size, - NULL, + parent_cpy, + &preserved_indices, + (void**) &preserved_values, + &preserved_indices_size, + &preserved_values_size, + NULL, &num_preserved, &is_jumbled, NULL )) ; LG_TRY (LAGraph_Free ((void**)(&preserved_values), msg)) ; - + // build ramp vector LG_TRY (LAGraph_Malloc ((void**) &ramp, num_preserved, sizeof(uint64_t), msg)) ; @@ -272,9 +282,9 @@ static int LAGraph_Parent_to_S LG_FREE_WORK ; \ } -#ifdef burble - #define CHKPT(msg){ printf("*** [CHKPT] *** %s\n", msg) ; } -#else +#ifdef burble + #define CHKPT(msg){ printf("*** [CHKPT] *** %s\n", msg) ; } +#else #define CHKPT(msg){} #endif diff --git a/experimental/algorithm/LAGraph_EstimateDiameter.c b/experimental/algorithm/LAGraph_EstimateDiameter.c index ba19fa94bb..4606367385 100755 --- a/experimental/algorithm/LAGraph_EstimateDiameter.c +++ b/experimental/algorithm/LAGraph_EstimateDiameter.c @@ -47,6 +47,7 @@ #include "LG_internal.h" #include "LAGraphX.h" +// FIXME: this mod function definition is wrong. void LG_ED_mod32 (int32_t *z, const int32_t *x, const int32_t *y) ; void LG_ED_mod32 (int32_t *z, const int32_t *x, const int32_t *y) { @@ -63,6 +64,7 @@ void LG_ED_mod32 (int32_t *z, const int32_t *x, const int32_t *y) " (*z) = t % (*y) ; \n" \ "}" +// FIXME: this mod function definition is wrong. void LG_ED_mod64 (int64_t *z, const int64_t *x, const int64_t *y) ; void LG_ED_mod64 (int64_t *z, const int64_t *x, const int64_t *y) { diff --git a/experimental/algorithm/LAGraph_FastGraphletTransform.c b/experimental/algorithm/LAGraph_FastGraphletTransform.c index 0628cf0c35..5b61ad0077 100644 --- a/experimental/algorithm/LAGraph_FastGraphletTransform.c +++ b/experimental/algorithm/LAGraph_FastGraphletTransform.c @@ -95,7 +95,10 @@ #include "LG_internal.h" #include "LAGraphX.h" -void LG_FGT_sub_one_mult (int64_t *z, const int64_t *x) { (*z) = (*x) * ((*x)-1) ; } +LG_JIT_STRING( +void LG_FGT_sub_one_mult (int64_t *z, const int64_t *x) { +(*z) = (*x) * ((*x)-1) ; +}, LG_FGT_SUB_ONE_MULT_DEFN) int LAGraph_FastGraphletTransform ( @@ -208,7 +211,9 @@ int LAGraph_FastGraphletTransform GRB_TRY (GrB_Vector_new (&d_3, GrB_INT64, n)) ; - GRB_TRY (GrB_UnaryOp_new (&Sub_one_mult, F_UNARY (LG_FGT_sub_one_mult), GrB_INT64, GrB_INT64)) ; + GRB_TRY (GxB_UnaryOp_new ( + &Sub_one_mult, F_UNARY (LG_FGT_sub_one_mult), GrB_INT64, GrB_INT64, + "LG_FGT_sub_one_mult", LG_FGT_SUB_ONE_MULT_DEFN)) ; GRB_TRY (GrB_apply (d_3, NULL, NULL, Sub_one_mult, d_1, NULL)) ; GRB_TRY (GrB_apply (d_3, NULL, NULL, GrB_DIV_INT64, d_3, (int64_t) 2, NULL)) ; diff --git a/experimental/algorithm/LAGraph_RichClubCoefficient.c b/experimental/algorithm/LAGraph_RichClubCoefficient.c index 0a66f15dc4..d20ed9dac1 100755 --- a/experimental/algorithm/LAGraph_RichClubCoefficient.c +++ b/experimental/algorithm/LAGraph_RichClubCoefficient.c @@ -65,34 +65,25 @@ #include "LG_internal.h" #include "LAGraphX.h" -typedef void (*LAGraph_binary_function) (void *, const void *, const void *) ; - -#define ISEQ_2ISLT \ - "void LG_RCC_iseq_2islt(int64_t *z, const int64_t *x, const int64_t *y) \n"\ - "{ \n"\ - "(*z) = (int64_t)((*x < *y) + (*x <= *y)) ; \n"\ - "}" +LG_JIT_STRING( void LG_RCC_iseq_2islt(int64_t *z, const int64_t *x, const int64_t *y) { (*z) = (int64_t)((*x < *y) + (*x <= *y)) ; -} +}, LG_RCC_ISEQ_2ISLT) -#define RICH_CLUB_FORMULA \ - "void LG_RCC_rich_club_formula(double *z, const int64_t *x, const int64_t *y) \n"\ - "{ \n"\ - " (*z) = ((double)(*x)) / (((double)(*y)) * (((double)(*y)) - 1.0)) ; \n"\ - "}" +LG_JIT_STRING( void LG_RCC_rich_club_formula(double *z, const int64_t *x, const int64_t *y) { (*z) = ((double)(*x)) / (((double)(*y)) * (((double)(*y)) - 1.0)); -} +}, LG_RCC_RICH_CLUB_FORMULA) + int LAGraph_RichClubCoefficient ( // output: //rccs(i): rich club coefficent of i - GrB_Vector *rccs, + GrB_Vector *rccs, - // input: + // input: LAGraph_Graph G, //input graph char *msg ) @@ -149,16 +140,16 @@ int LAGraph_RichClubCoefficient GrB_Matrix P = NULL; GrB_Index n ; - + GrB_Index edge_vec_nvals; int64_t max_deg; bool iso = false; void *a_space = NULL; - + int64_t *node_edges_arr = NULL, *deg_arr = NULL, - *epd_arr = NULL, *ones = NULL, - *vpd_arr = NULL; + *epd_arr = NULL, *ones = NULL, + *vpd_arr = NULL; GrB_Type epd_type = NULL, vpd_type = NULL; uint64_t epd_n = 0, vpd_n = 0, epd_size = 0, vpd_size = 0; int epd_h = 0, vpd_h = 0; @@ -174,9 +165,9 @@ int LAGraph_RichClubCoefficient G->kind == LAGraph_ADJACENCY_UNDIRECTED, GrB_INVALID_VALUE, "G->A must be symmetric") ; LG_ASSERT_MSG (G->out_degree != NULL, GrB_EMPTY_OBJECT, - "G->out_degree must be defined") ; + "G->out_degree must be defined") ; LG_ASSERT_MSG (G->nself_edges == 0, GrB_INVALID_VALUE, - "G->nself_edges must be zero") ; + "G->nself_edges must be zero") ; //-------------------------------------------------------------------------- // Initializations @@ -187,25 +178,26 @@ int LAGraph_RichClubCoefficient GRB_TRY (GrB_Vector_new(°rees, GrB_INT64, n)) ; GRB_TRY (GrB_Vector_new(&node_edges, GrB_INT64, n)) ; - #if LAGRAPH_SUITESPARSE +#if LAGRAPH_SUITESPARSE GRB_TRY (GxB_BinaryOp_new( - &iseq_2lt, (LAGraph_binary_function) (&LG_RCC_iseq_2islt), - GrB_INT64, GrB_INT64, GrB_INT64, "LG_RCC_iseq_2islt", ISEQ_2ISLT)) ; + &iseq_2lt, (GxB_binary_function) (&LG_RCC_iseq_2islt), + GrB_INT64, GrB_INT64, GrB_INT64, "LG_RCC_iseq_2islt", +LG_RCC_ISEQ_2ISLT)) ; GRB_TRY (GxB_BinaryOp_new( - &rcCalculation, (LAGraph_binary_function) (&LG_RCC_rich_club_formula), - GrB_FP64, GrB_INT64, GrB_INT64, - "LG_RCC_rich_club_formula", RICH_CLUB_FORMULA)) ; - #else + &rcCalculation, (GxB_binary_function) (&LG_RCC_rich_club_formula), + GrB_FP64, GrB_INT64, GrB_INT64, + "LG_RCC_rich_club_formula", LG_RCC_RICH_CLUB_FORMULA)) ; +#else GRB_TRY (GrB_BinaryOp_new( - &iseq_2lt, (LAGraph_binary_function) (&LG_RCC_iseq_2islt), + &iseq_2lt, (GxB_binary_function) (&LG_RCC_iseq_2islt), GrB_INT64, GrB_INT64, GrB_INT64)) ; GRB_TRY (GrB_BinaryOp_new( - &rcCalculation, (LAGraph_binary_function) (&LG_RCC_rich_club_formula), + &rcCalculation, (GxB_binary_function) (&LG_RCC_rich_club_formula), GrB_FP64, GrB_INT64, GrB_INT64 )) ; - #endif +#endif GRB_TRY (GrB_Semiring_new(&plus_2le, GrB_PLUS_MONOID_INT64, iseq_2lt)) ; - + GRB_TRY (GrB_Vector_reduce_INT64( &max_deg, NULL, GrB_MAX_MONOID_INT64, G->out_degree, NULL)) ; GRB_TRY (GrB_Vector_new(&edges_per_deg, GrB_INT64, max_deg)) ; @@ -226,13 +218,13 @@ int LAGraph_RichClubCoefficient GRB_TRY (GrB_Matrix_diag(&D, degrees, 0)) ; // Each edge in the graph gets the value of the degree of its row node - #if LAGRAPH_SUITESPARSE +#if LAGRAPH_SUITESPARSE GRB_TRY (GrB_mxm( A_deg, NULL, NULL, GxB_ANY_FIRST_INT64, D, A, NULL)) ; - #else +#else GRB_TRY (GrB_mxm( A_deg, NULL, NULL, GrB_PLUS_TIMES_SEMIRING_INT64, D, A, NULL)) ; - #endif +#endif // Sum the number of edges each node is "responsible" for. GRB_TRY (GrB_mxv( node_edges, NULL, GrB_PLUS_INT64, plus_2le, A_deg, degrees, NULL)) ; @@ -241,141 +233,141 @@ int LAGraph_RichClubCoefficient // each degree and then doing a cummulative sum to know the amount of edges // and nodes at degree geq k. GRB_TRY (GrB_Vector_nvals (&edge_vec_nvals, node_edges)) ; - #if LG_SUITESPARSE_GRAPHBLAS_V10 - if(n == edge_vec_nvals) - { - deg_x = degrees; - degrees = NULL; - node_edges_x = node_edges; - node_edges = NULL; - } - else - { - GRB_TRY (GrB_Vector_assign( - degrees, G->out_degree, NULL, degrees, GrB_ALL, 0, GrB_DESC_RS - )) ; - GRB_TRY (GrB_Vector_new(°_x, GrB_BOOL, 0)) ; - GRB_TRY (GrB_Vector_new(&node_edges_x, GrB_BOOL, 0)) ; - GRB_TRY (GxB_Vector_extractTuples_Vector( - NULL, deg_x, degrees, NULL - )) ; - GRB_TRY (GxB_Vector_extractTuples_Vector( - NULL, node_edges_x, node_edges, NULL - )) ; - } - GRB_TRY (GrB_Vector_nvals(&edge_vec_nvals, node_edges_x)) - GRB_TRY (GrB_Vector_new(&ones_v, GrB_INT64, edge_vec_nvals)) ; - - - GRB_TRY (GrB_Vector_assign_INT64( - edges_per_deg, NULL, NULL, (int64_t) 0, GrB_ALL, 0, NULL)) ; - GRB_TRY (GrB_Vector_assign_INT64( - verts_per_deg, NULL, NULL, (int64_t) 0, GrB_ALL, 0, NULL)) ; - GRB_TRY (GrB_Vector_assign_INT64( - ones_v, NULL, NULL, (int64_t) 0, GrB_ALL, 0, NULL)) ; - - #ifndef COVERAGE - GRB_TRY (GrB_Vector_new(&ramp_v, GrB_INT64, edge_vec_nvals + 1)) ; - GRB_TRY (GrB_Vector_assign_INT64( - ramp_v, NULL, NULL, (int64_t) 0, GrB_ALL, 0, NULL)) ; - GRB_TRY (GrB_apply ( - ramp_v, NULL, NULL, GrB_ROWINDEX_INT64, ramp_v, 0, NULL)) ; - #endif - - LG_TRY (LAGraph_FastAssign_Semiring ( - edges_per_deg, NULL, GrB_PLUS_INT64, deg_x, node_edges_x, ramp_v, - LAGraph_plus_second_int64, NULL, msg - )) ; - LG_TRY (LAGraph_FastAssign_Semiring ( - verts_per_deg, NULL, GrB_PLUS_INT64, deg_x, ones_v, ramp_v, - LAGraph_plus_one_int64, NULL, msg - )) ; - - GRB_TRY (GxB_Vector_unload( - edges_per_deg, (void **) &epd_arr, &epd_type, - &epd_n, &epd_size, &epd_h, NULL)) ; - GRB_TRY (GxB_Vector_unload( - verts_per_deg, (void **) &vpd_arr, &vpd_type, - &vpd_n, &vpd_size, &vpd_h, NULL)) ; - - LG_ASSERT (max_deg == vpd_n && max_deg == epd_n, GrB_INVALID_VALUE) ; - //run a cummulative sum (backwards) on vpd_arr - for(int64_t i = max_deg - 1; i > 0; --i) - { - vpd_arr[i-1] += vpd_arr[i] ; - epd_arr[i-1] += epd_arr[i] ; - } - GRB_TRY(GxB_Vector_load( - edges_per_deg, (void **) &epd_arr, epd_type, - epd_n, epd_size, epd_h, NULL)) ; - GRB_TRY(GxB_Vector_load( - verts_per_deg, (void **) &vpd_arr, vpd_type, - vpd_n, vpd_size, vpd_h, NULL)) ; - #else - LG_TRY (LAGraph_Malloc( - &a_space, edge_vec_nvals * 3 + max_deg * 4, sizeof(int64_t), NULL +#if LG_SUITESPARSE_GRAPHBLAS_V10 + if(n == edge_vec_nvals) + { + deg_x = degrees; + degrees = NULL; + node_edges_x = node_edges; + node_edges = NULL; + } + else +{ + GRB_TRY (GrB_Vector_assign( + degrees, G->out_degree, NULL, degrees, GrB_ALL, 0, GrB_DESC_RS )) ; - int64_t *T = a_space; - deg_arr = T; T += edge_vec_nvals; - node_edges_arr = T; T += edge_vec_nvals; - ones = T; T += edge_vec_nvals; - epd_arr = T; T += max_deg; - vpd_arr = T; T += max_deg; - epd_index = T; T += max_deg; - vpd_index = T; T += max_deg; - - #pragma omp parallel for schedule(static) - for(uint64_t i = 0; i < edge_vec_nvals; ++i) - { - ones[i] = 1ll; - } - GRB_TRY (GrB_Vector_apply_BinaryOp2nd_INT64( - degrees, NULL, NULL, GrB_MINUS_INT64, G->out_degree, 1, NULL)) ; - //TODO: remove NULL for Vanilla GB - GRB_TRY (GrB_Vector_extractTuples_INT64( - NULL, deg_arr, &edge_vec_nvals, degrees + GRB_TRY (GrB_Vector_new(°_x, GrB_BOOL, 0)) ; + GRB_TRY (GrB_Vector_new(&node_edges_x, GrB_BOOL, 0)) ; + GRB_TRY (GxB_Vector_extractTuples_Vector( + NULL, deg_x, degrees, NULL )) ; - GRB_TRY (GrB_Vector_extractTuples_INT64( - NULL, node_edges_arr, &edge_vec_nvals, node_edges + GRB_TRY (GxB_Vector_extractTuples_Vector( + NULL, node_edges_x, node_edges, NULL )) ; + } + GRB_TRY (GrB_Vector_nvals(&edge_vec_nvals, node_edges_x)) + GRB_TRY (GrB_Vector_new(&ones_v, GrB_INT64, edge_vec_nvals)) ; - // Build with degrees as indecies and handle duplicates via adition - GRB_TRY (GrB_Vector_build_INT64 ( - edges_per_deg, deg_arr, node_edges_arr, edge_vec_nvals, - GrB_PLUS_INT64)) ; - GRB_TRY (GrB_Vector_build_INT64 ( - verts_per_deg, deg_arr, ones, edge_vec_nvals, GrB_PLUS_INT64)) ; - GRB_TRY (GrB_Vector_assign_INT64( - edges_per_deg, edges_per_deg, NULL, (int64_t) 0, - GrB_ALL, 0, GrB_DESC_SC)) ; - GRB_TRY (GrB_Vector_assign_INT64( - verts_per_deg, verts_per_deg, NULL, (int64_t) 0, - GrB_ALL, 0, GrB_DESC_SC)) ; - - // Extract into arrays - GRB_TRY (GrB_Vector_extractTuples_INT64( - epd_index, epd_arr, &max_deg, edges_per_deg - )) ; - GRB_TRY (GrB_Vector_extractTuples_INT64( - vpd_index, vpd_arr, &max_deg, verts_per_deg - )) ; - //run a cummulative sum (backwards) on vpd_arr - for(int64_t i = max_deg - 1; i > 0; --i) - { - vpd_arr[i-1] += vpd_arr[i] ; - epd_arr[i-1] += epd_arr[i] ; - } - GRB_TRY (GrB_Vector_clear(edges_per_deg)) ; - GRB_TRY (GrB_Vector_clear(verts_per_deg)) ; - GRB_TRY (GrB_Vector_build_INT64( - edges_per_deg, epd_index, epd_arr, max_deg, NULL - )) ; - GRB_TRY (GrB_Vector_build_INT64( - verts_per_deg, vpd_index, vpd_arr, max_deg, NULL - )) ; - T = deg_arr = node_edges_arr = ones = NULL ; - epd_index = vpd_index = epd_arr = vpd_arr = NULL ; - #endif + + GRB_TRY (GrB_Vector_assign_INT64( + edges_per_deg, NULL, NULL, (int64_t) 0, GrB_ALL, 0, NULL)) ; + GRB_TRY (GrB_Vector_assign_INT64( + verts_per_deg, NULL, NULL, (int64_t) 0, GrB_ALL, 0, NULL)) ; + GRB_TRY (GrB_Vector_assign_INT64( + ones_v, NULL, NULL, (int64_t) 0, GrB_ALL, 0, NULL)) ; + +#ifndef COVERAGE + GRB_TRY (GrB_Vector_new(&ramp_v, GrB_INT64, edge_vec_nvals + 1)) ; + GRB_TRY (GrB_Vector_assign_INT64( + ramp_v, NULL, NULL, (int64_t) 0, GrB_ALL, 0, NULL)) ; + GRB_TRY (GrB_apply ( + ramp_v, NULL, NULL, GrB_ROWINDEX_INT64, ramp_v, 0, NULL)) ; +#endif + + LG_TRY (LAGraph_FastAssign_Semiring ( + edges_per_deg, NULL, GrB_PLUS_INT64, deg_x, node_edges_x, ramp_v, + LAGraph_plus_second_int64, NULL, msg + )) ; + LG_TRY (LAGraph_FastAssign_Semiring ( + verts_per_deg, NULL, GrB_PLUS_INT64, deg_x, ones_v, ramp_v, + LAGraph_plus_one_int64, NULL, msg + )) ; + + GRB_TRY (GxB_Vector_unload( + edges_per_deg, (void **) &epd_arr, &epd_type, + &epd_n, &epd_size, &epd_h, NULL)) ; + GRB_TRY (GxB_Vector_unload( + verts_per_deg, (void **) &vpd_arr, &vpd_type, + &vpd_n, &vpd_size, &vpd_h, NULL)) ; + + LG_ASSERT (max_deg == vpd_n && max_deg == epd_n, GrB_INVALID_VALUE) ; + //run a cummulative sum (backwards) on vpd_arr + for(int64_t i = max_deg - 1; i > 0; --i) + { + vpd_arr[i-1] += vpd_arr[i] ; + epd_arr[i-1] += epd_arr[i] ; + } + GRB_TRY(GxB_Vector_load( + edges_per_deg, (void **) &epd_arr, epd_type, + epd_n, epd_size, epd_h, NULL)) ; + GRB_TRY(GxB_Vector_load( + verts_per_deg, (void **) &vpd_arr, vpd_type, + vpd_n, vpd_size, vpd_h, NULL)) ; +#else + LG_TRY (LAGraph_Malloc( + &a_space, edge_vec_nvals * 3 + max_deg * 4, sizeof(int64_t), NULL + )) ; + int64_t *T = a_space; + deg_arr = T; T += edge_vec_nvals; + node_edges_arr = T; T += edge_vec_nvals; + ones = T; T += edge_vec_nvals; + epd_arr = T; T += max_deg; + vpd_arr = T; T += max_deg; + epd_index = T; T += max_deg; + vpd_index = T; T += max_deg; + + #pragma omp parallel for schedule(static) + for(uint64_t i = 0; i < edge_vec_nvals; ++i) + { + ones[i] = 1ll; + } + GRB_TRY (GrB_Vector_apply_BinaryOp2nd_INT64( + degrees, NULL, NULL, GrB_MINUS_INT64, G->out_degree, 1, NULL)) ; + //TODO: remove NULL for Vanilla GB + GRB_TRY (GrB_Vector_extractTuples_INT64( + NULL, deg_arr, &edge_vec_nvals, degrees + )) ; + GRB_TRY (GrB_Vector_extractTuples_INT64( + NULL, node_edges_arr, &edge_vec_nvals, node_edges + )) ; + + // Build with degrees as indecies and handle duplicates via adition + GRB_TRY (GrB_Vector_build_INT64 ( + edges_per_deg, deg_arr, node_edges_arr, edge_vec_nvals, + GrB_PLUS_INT64)) ; + GRB_TRY (GrB_Vector_build_INT64 ( + verts_per_deg, deg_arr, ones, edge_vec_nvals, GrB_PLUS_INT64)) ; + GRB_TRY (GrB_Vector_assign_INT64( + edges_per_deg, edges_per_deg, NULL, (int64_t) 0, + GrB_ALL, 0, GrB_DESC_SC)) ; + GRB_TRY (GrB_Vector_assign_INT64( + verts_per_deg, verts_per_deg, NULL, (int64_t) 0, + GrB_ALL, 0, GrB_DESC_SC)) ; + + // Extract into arrays + GRB_TRY (GrB_Vector_extractTuples_INT64( + epd_index, epd_arr, &max_deg, edges_per_deg + )) ; + GRB_TRY (GrB_Vector_extractTuples_INT64( + vpd_index, vpd_arr, &max_deg, verts_per_deg + )) ; + //run a cummulative sum (backwards) on vpd_arr + for(int64_t i = max_deg - 1; i > 0; --i) + { + vpd_arr[i-1] += vpd_arr[i] ; + epd_arr[i-1] += epd_arr[i] ; + } + GRB_TRY (GrB_Vector_clear(edges_per_deg)) ; + GRB_TRY (GrB_Vector_clear(verts_per_deg)) ; + GRB_TRY (GrB_Vector_build_INT64( + edges_per_deg, epd_index, epd_arr, max_deg, NULL + )) ; + GRB_TRY (GrB_Vector_build_INT64( + verts_per_deg, vpd_index, vpd_arr, max_deg, NULL + )) ; + T = deg_arr = node_edges_arr = ones = NULL ; + epd_index = vpd_index = epd_arr = vpd_arr = NULL ; +#endif /** * Cumulative sum (TODO: should be a GBLAS method!) @@ -393,7 +385,7 @@ int LAGraph_RichClubCoefficient * * If plus biop is not a monoid, this method should still work? */ - + //Computes the RCC of a matrix GRB_TRY(GrB_eWiseMult( *rccs, NULL, NULL, rcCalculation, diff --git a/experimental/algorithm/LAGraph_lcc.c b/experimental/algorithm/LAGraph_lcc.c index f418fee343..e40bf0e354 100755 --- a/experimental/algorithm/LAGraph_lcc.c +++ b/experimental/algorithm/LAGraph_lcc.c @@ -88,6 +88,7 @@ // z = x * (x - 1), used by LAGraph_lcc. // This operator calculates the 2-permutation of d(v). +LG_JIT_STRING( void LG_lcc_comb_dir_fp64 ( void *z, @@ -97,22 +98,11 @@ void LG_lcc_comb_dir_fp64 double xd = *(double *) x ; double *zd = (double *) z ; (*zd) = ((xd) * (xd - 1)) ; -} - -#define LAGRAPH_COMB_DIR_FP64 \ -"void LG_lcc_comb_dir_fp64 \n" \ -"( \n" \ -" void *z, \n" \ -" const void *x \n" \ -") \n" \ -"{ \n" \ -" double xd = *(double *) x ; \n" \ -" double *zd = (double *) z ; \n" \ -" (*zd) = ((xd) * (xd - 1)); \n" \ -"}" +}, LAGRAPH_COMB_DIR_FP64) // z = x * (x - 1) / 2, used by LAGraph_lcc. // This operator calculates the 2-combination of d(v). +LG_JIT_STRING( void LG_lcc_comb_undir_fp64 ( void *z, @@ -122,19 +112,7 @@ void LG_lcc_comb_undir_fp64 double xd = *(double *) x ; double *zd = (double *) z ; (*zd) = ((xd) * (xd - 1)) / 2; -} - -#define LAGRAPH_COMB_UNDIR_FP64 \ -"void LG_lcc_comb_undir_fp64 \n" \ -"( \n" \ -" void *z, \n" \ -" const void *x \n" \ -") \n" \ -"{ \n" \ -" double xd = *(double *) x ; \n" \ -" double *zd = (double *) z ; \n" \ -" (*zd) = ((xd) * (xd - 1)) / 2; \n" \ -"}" +}, LAGRAPH_COMB_UNDIR_FP64) //------------------------------------------------------------------------------ diff --git a/experimental/algorithm/LAGraph_msf.c b/experimental/algorithm/LAGraph_msf.c index 3d5e8b8098..193c6fe322 100755 --- a/experimental/algorithm/LAGraph_msf.c +++ b/experimental/algorithm/LAGraph_msf.c @@ -47,77 +47,34 @@ // LG_MSF_tuple_fp is used if the input graph is FP32 or FP64. Likewise for the // other *_int and *_fp types and operators. -typedef struct -{ - int64_t wInt; - uint64_t idx; -} LG_MSF_tuple_int; - -#define TUPLE_INT \ -"typedef struct \n" \ -"{ \n" \ -" int64_t wInt; \n" \ -" uint64_t idx; \n" \ -"} LG_MSF_tuple_int;" - -typedef struct -{ - double wFp; - uint64_t idx; -} LG_MSF_tuple_fp; +#define LG_MSF_TUPLE(ctype) \ +typedef struct \ +{ \ + ctype wInt; \ + uint64_t idx; \ +} LG_MSF_tuple_##ctype; + +LG_JIT_STRING(LG_MSF_TUPLE(double), LG_MSF_TUPLE_DOUBLE) -#define TUPLE_FP \ -"typedef struct \n" \ -"{ \n" \ -" double wFp; \n" \ -" uint64_t idx; \n" \ -"} LG_MSF_tuple_fp;" +LG_JIT_STRING(LG_MSF_TUPLE(int64_t), LG_MSF_TUPLE_INT64_T) //------------------------------------------------------------------------------ // context_type: context for IndexUnaryOps (using the theta input) //------------------------------------------------------------------------------ -typedef struct -{ - uint64_t *parent; // parent of each vertex in the spanning forest - struct - { - int64_t wInt; - uint64_t idx; - } *w_partner; // partner vertex in the spanning forest -} LG_MSF_context_int; - -#define LG_MSF_CONTEXT_INT \ -"typedef struct \n" \ -"{ \n" \ -" uint64_t *parent; \n" \ -" struct \n" \ -" { \n" \ -" int64_t wInt; \n" \ -" uint64_t idx; \n" \ -" } *w_partner; \n" \ -"} LG_MSF_context_int;" - -typedef struct -{ - uint64_t *parent; // parent of each vertex in the spanning forest - struct - { - double wFp; - uint64_t idx; - } *w_partner; // partner vertex in the spanning forest -} LG_MSF_context_fp; - -#define LG_MSF_CONTEXT_FP \ -"typedef struct \n" \ -"{ \n" \ -" uint64_t *parent; \n" \ -" struct \n" \ -" { \n" \ -" double wFp; \n" \ -" uint64_t idx; \n" \ -" } *w_partner; \n" \ -"} LG_MSF_context_fp;" +#define LG_MSF_CONTEXT(ctype) \ +typedef struct \ +{ \ + uint64_t *parent; /* parent of each vertex in the spanning forest */ \ + struct \ + { \ + ctype wInt; \ + uint64_t idx; \ + } *w_partner; /* partner vertex in the spanning forest */ \ +} LG_MSF_context_##ctype; + +LG_JIT_STRING(LG_MSF_CONTEXT(double), LG_MSF_CONTEXT_DOUBLE) +LG_JIT_STRING(LG_MSF_CONTEXT(int64_t), LG_MSF_CONTEXT_INT64_T) //------------------------------------------------------------------------------ // selectEdge: index-unary operator to select edges of min weight @@ -128,59 +85,22 @@ typedef struct // 1. weight[i] == A(i, j) -- where weight[i] stores i's minimum edge weight // 2. parent[j] == partner[i] -- j belongs to the specified connected component -void LG_MSF_selectEdge_int -( - bool *z, - const int64_t *x, - GrB_Index i, - GrB_Index j, - const LG_MSF_context_int *theta -) -{ - (*z) = (theta->w_partner[i].wInt == *x) && - (theta->parent[j] == theta->w_partner[i].idx); -} - -#define SELECTEDGE_INT \ -"void LG_MSF_selectEdge_int \n"\ -"( \n"\ -" bool *z, \n"\ -" const int64_t *x, \n"\ -" GrB_Index i, \n"\ -" GrB_Index j, \n"\ -" const LG_MSF_context_int *theta \n"\ -") \n"\ -"{ \n"\ -" (*z) = (theta->w_partner[i].wInt == *x) && \n"\ -" (theta->parent[j] == theta->w_partner[i].idx);\n"\ -"}" - -void LG_MSF_selectEdge_fp -( - bool *z, - const double *x, - GrB_Index i, - GrB_Index j, - const LG_MSF_context_fp *theta -) -{ - (*z) = (theta->w_partner[i].wFp == *x) && - (theta->parent[j] == theta->w_partner[i].idx); +#define LG_MSF_SELECTEDGE(ctype) \ +void LG_MSF_selectEdge_##ctype \ +( \ + bool *z, \ + const ctype *x, \ + GrB_Index i, \ + GrB_Index j, \ + const LG_MSF_context_##ctype *theta \ +) \ +{ \ + (*z) = (theta->w_partner[i].wInt == *x) && \ + (theta->parent[j] == theta->w_partner[i].idx); \ } -#define SELECTEDGE_FP \ -"void LG_MSF_selectEdge_fp \n"\ -"( \n"\ -" bool *z, \n"\ -" const double *x, \n"\ -" GrB_Index i, \n"\ -" GrB_Index j, \n"\ -" const LG_MSF_context_fp *theta \n"\ -") \n"\ -"{ \n"\ -" (*z) = (theta->w_partner[i].wFp == *x) && \n"\ -" (theta->parent[j] == theta->w_partner[i].idx);\n"\ -"}" +LG_JIT_STRING(LG_MSF_SELECTEDGE(double), LG_MSF_SELECTEDGE_DOUBLE) +LG_JIT_STRING(LG_MSF_SELECTEDGE(int64_t), LG_MSF_SELECTEDGE_INT64_T) //------------------------------------------------------------------------------ // removeEdge: remove edge (i,j) when i and j have the same parent @@ -189,309 +109,122 @@ void LG_MSF_selectEdge_fp // edge removal: // A(i, j) is removed when parent[i] == parent[j] -void LG_MSF_removeEdge_int -( - bool *z, - const int64_t *x, - GrB_Index i, - GrB_Index j, - const LG_MSF_context_int *theta -) -{ - (*z) = (theta->parent[i] != theta->parent[j]); -} - -#define REMOVEEDGE_INT \ -"void LG_MSF_removeEdge_int \n"\ -"( \n"\ -" bool *z, \n"\ -" const int64_t *x, \n"\ -" GrB_Index i, \n"\ -" GrB_Index j, \n"\ -" const LG_MSF_context_int *theta \n"\ -") \n"\ -"{ \n"\ -" (*z) = (theta->parent[i] != theta->parent[j]);\n"\ -"}" - -void LG_MSF_removeEdge_fp -( - bool *z, - const double *x, - GrB_Index i, - GrB_Index j, - const LG_MSF_context_fp *theta -) -{ - (*z) = (theta->parent[i] != theta->parent[j]); +#define LG_MSF_REMOVEEDGE(ctype) \ +void LG_MSF_removeEdge_##ctype \ +( \ + bool *z, \ + const ctype *x, \ + GrB_Index i, \ + GrB_Index j, \ + const LG_MSF_context_##ctype *theta \ +) \ +{ \ + (*z) = (theta->parent[i] != theta->parent[j]); \ } -#define REMOVEEDGE_FP \ -"void LG_MSF_removeEdge_fp \n"\ -"( \n"\ -" bool *z, \n"\ -" const double *x, \n"\ -" GrB_Index i, \n"\ -" GrB_Index j, \n"\ -" const LG_MSF_context_fp *theta \n"\ -") \n"\ -"{ \n"\ -" (*z) = (theta->parent[i] != theta->parent[j]);\n"\ -"}" +LG_JIT_STRING(LG_MSF_REMOVEEDGE(double), LG_MSF_REMOVEEDGE_DOUBLE) +LG_JIT_STRING(LG_MSF_REMOVEEDGE(int64_t), LG_MSF_REMOVEEDGE_INT64_T) //------------------------------------------------------------------------------ // combine: create a tuple from a weight and an index //------------------------------------------------------------------------------ -void LG_MSF_combine_int -( - LG_MSF_tuple_int *z, - const int64_t *x, - const uint64_t *y -) -{ - z->wInt = *x; - z->idx = *y; -} - -#define COMBINE_INT \ -"void LG_MSF_combine_int \n"\ -"( \n"\ -" LG_MSF_tuple_int *z, \n"\ -" const int64_t *x, \n"\ -" const uint64_t *y \n"\ -") \n"\ -"{ \n"\ -" z->wInt = *x; \n"\ -" z->idx = *y; \n"\ -"}" - -void LG_MSF_combine_fp -( - LG_MSF_tuple_fp *z, - const double *x, - const uint64_t *y -) -{ - z->wFp = *x; - z->idx = *y; +#define LG_MSF_COMBINE(ctype) \ +void LG_MSF_combine_##ctype \ +( \ + LG_MSF_tuple_##ctype *z, \ + const ctype *x, \ + const uint64_t *y \ +) \ +{ \ + z->wInt = *x; \ + z->idx = *y; \ } -#define COMBINE_FP \ -"void LG_MSF_combine_fp \n"\ -"( \n"\ -" LG_MSF_tuple_fp *z, \n"\ -" const double *x, \n"\ -" const uint64_t *y \n"\ -") \n"\ -"{ \n"\ -" z->wFp = *x; \n"\ -" z->idx = *y; \n"\ -"}" +LG_JIT_STRING(LG_MSF_COMBINE(double), LG_MSF_COMBINE_DOUBLE) +LG_JIT_STRING(LG_MSF_COMBINE(int64_t), LG_MSF_COMBINE_INT64_T) //------------------------------------------------------------------------------ // get_first: get first item in a tuple (the weight) //------------------------------------------------------------------------------ -void LG_MSF_get_first_int (int64_t *y, const LG_MSF_tuple_int *x) -{ - *y = x->wInt; +#define LG_MSF_GET_FIRST(ctype) \ +void LG_MSF_get_first_##ctype (ctype *y, const LG_MSF_tuple_##ctype *x) \ +{ \ + *y = x->wInt; \ } - -#define GET_FIRST_INT \ -"void LG_MSF_get_first_int (int64_t *y, const LG_MSF_tuple_int *x) \n" \ -"{ \n" \ -" *y = x->wInt; \n" \ -"}" - -void LG_MSF_get_first_fp (double *y, const LG_MSF_tuple_fp *x) -{ - *y = x->wFp; -} - -#define GET_FIRST_FP \ -"void LG_MSF_get_first_fp (double *y, const LG_MSF_tuple_fp *x) \n" \ -"{ \n" \ -" *y = x->wFp; \n" \ -"}" +LG_JIT_STRING(LG_MSF_GET_FIRST(double), LG_MSF_GET_FIRST_DOUBLE) +LG_JIT_STRING(LG_MSF_GET_FIRST(int64_t), LG_MSF_GET_FIRST_INT64_T) //------------------------------------------------------------------------------ // get_second: get second item in a tuple (the index) //------------------------------------------------------------------------------ -void LG_MSF_get_second_int (uint64_t *y, const LG_MSF_tuple_int *x) -{ - *y = x->idx; +#define LG_MSF_GET_SECOND(ctype) \ +void LG_MSF_get_second_##ctype (uint64_t *y, const LG_MSF_tuple_##ctype *x)\ +{ \ + *y = x->idx; \ } - -#define GET_SECOND_INT \ -"void LG_MSF_get_second_int (uint64_t *y, const LG_MSF_tuple_int *x) \n" \ -"{ \n" \ -" *y = x->idx; \n" \ -"}" - -void LG_MSF_get_second_fp (uint64_t *y, const LG_MSF_tuple_fp *x) -{ - *y = x->idx; -} - -#define GET_SECOND_FP \ -"void LG_MSF_get_second_fp (uint64_t *y, const LG_MSF_tuple_fp *x) \n" \ -"{ \n" \ -" *y = x->idx; \n" \ -"}" +LG_JIT_STRING(LG_MSF_GET_SECOND(double), LG_MSF_GET_SECOND_DOUBLE) +LG_JIT_STRING(LG_MSF_GET_SECOND(int64_t), LG_MSF_GET_SECOND_INT64_T) //------------------------------------------------------------------------------ // tupleMin: z = the min tuple of x and y //------------------------------------------------------------------------------ -void LG_MSF_tupleMin_int -( - LG_MSF_tuple_int *z, - const LG_MSF_tuple_int *x, - const LG_MSF_tuple_int *y -) -{ - bool xSmaller = x->wInt < y->wInt || - (x->wInt == y->wInt && x->idx < y->idx); - z->wInt = (xSmaller)? x->wInt: y->wInt; - z->idx = (xSmaller)? x->idx: y->idx; -} - -#define TUPLEMIN_INT \ -"void LG_MSF_tupleMin_int \n"\ -"( \n"\ -" LG_MSF_tuple_int *z, \n"\ -" const LG_MSF_tuple_int *x, \n"\ -" const LG_MSF_tuple_int *y \n"\ -") \n"\ -"{ \n"\ -" bool xSmaller = x->wInt < y->wInt || \n"\ -" (x->wInt == y->wInt && x->idx < y->idx);\n"\ -" z->wInt = (xSmaller)? x->wInt: y->wInt; \n"\ -" z->idx = (xSmaller)? x->idx: y->idx; \n"\ -"}" - -void LG_MSF_tupleMin_fp -( - LG_MSF_tuple_fp *z, - const LG_MSF_tuple_fp *x, - const LG_MSF_tuple_fp *y -) -{ - bool xSmaller = x->wFp < y->wFp || (x->wFp == y->wFp && x->idx < y->idx); - z->wFp = (xSmaller)? x->wFp: y->wFp; - z->idx = (xSmaller)? x->idx: y->idx; +#define LG_MSF_TUPLEMIN(ctype) \ +void LG_MSF_tupleMin_##ctype \ +( \ + LG_MSF_tuple_##ctype *z, \ + const LG_MSF_tuple_##ctype *x, \ + const LG_MSF_tuple_##ctype *y \ +) \ +{ \ + bool xSmaller = x->wInt < y->wInt || \ + (x->wInt == y->wInt && x->idx < y->idx); \ + z->wInt = (xSmaller)? x->wInt: y->wInt; \ + z->idx = (xSmaller)? x->idx: y->idx; \ } -#define TUPLEMIN_FP \ -"void LG_MSF_tupleMin_fp \n"\ -"( \n"\ -" LG_MSF_tuple_fp *z, \n"\ -" const LG_MSF_tuple_fp *x, \n"\ -" const LG_MSF_tuple_fp *y \n"\ -") \n"\ -"{ \n"\ -" bool xSmaller = x->wFp < y->wFp || (x->wFp == y->wFp && x->idx < y->idx);\n"\ -" z->wFp = (xSmaller)? x->wFp: y->wFp; \n"\ -" z->idx = (xSmaller)? x->idx: y->idx; \n"\ -"}" +LG_JIT_STRING(LG_MSF_TUPLEMIN(double), LG_MSF_TUPLEMIN_DOUBLE) +LG_JIT_STRING(LG_MSF_TUPLEMIN(int64_t), LG_MSF_TUPLEMIN_INT64_T) //------------------------------------------------------------------------------ // tuple2nd: z = y //------------------------------------------------------------------------------ -void LG_MSF_tuple2nd_int -( - LG_MSF_tuple_int *z, - const void *x, - const LG_MSF_tuple_int *y -) -{ - z->wInt = y->wInt; - z->idx = y->idx; +#define LG_MSF_TUPLE2ND(ctype) \ +void LG_MSF_tuple2nd_##ctype \ +( \ + LG_MSF_tuple_##ctype *z, \ + const void *x, \ + const LG_MSF_tuple_##ctype *y \ +) \ +{ \ + z->wInt = y->wInt; \ + z->idx = y->idx; \ } -#define TUPLE2ND_INT \ -"void LG_MSF_tuple2nd_int \n"\ -"( \n"\ -" LG_MSF_tuple_int *z, \n"\ -" const void *x, \n"\ -" const LG_MSF_tuple_int *y\n"\ -") \n"\ -"{ \n"\ -" z->wInt = y->wInt; \n"\ -" z->idx = y->idx; \n"\ -"}" - -void LG_MSF_tuple2nd_fp -( - LG_MSF_tuple_fp *z, - const void *x, - const LG_MSF_tuple_fp *y -) -{ - z->wFp = y->wFp; - z->idx = y->idx; -} - -#define TUPLE2ND_FP \ -"void LG_MSF_tuple2nd_fp \n"\ -"( \n"\ -" LG_MSF_tuple_fp *z, \n"\ -" const void *x, \n"\ -" const LG_MSF_tuple_fp *y\n"\ -") \n"\ -"{ \n"\ -" z->wFp = y->wFp; \n"\ -" z->idx = y->idx; \n"\ -"}" +LG_JIT_STRING(LG_MSF_TUPLE2ND(double), LG_MSF_TUPLE2ND_DOUBLE) +LG_JIT_STRING(LG_MSF_TUPLE2ND(int64_t), LG_MSF_TUPLE2ND_INT64_T) //------------------------------------------------------------------------------ // tupleEq: true if two tuples are equal //------------------------------------------------------------------------------ -void LG_MSF_tupleEq_int -( - bool *z, - const LG_MSF_tuple_int *x, - const LG_MSF_tuple_int *y -) -{ - *z = (x->wInt == y->wInt) && (x->idx == y->idx); +#define LG_MSF_TUPLEEQ(ctype) \ +void LG_MSF_tupleEq_##ctype \ +( \ + bool *z, \ + const LG_MSF_tuple_##ctype *x, \ + const LG_MSF_tuple_##ctype *y \ +) \ +{ \ + *z = (x->wInt == y->wInt) && (x->idx == y->idx); \ } -#define TUPLEEQ_INT \ -"void LG_MSF_tupleEq_int \n"\ -"( \n"\ -" bool *z, \n"\ -" const LG_MSF_tuple_int *x, \n"\ -" const LG_MSF_tuple_int *y \n"\ -") \n"\ -"{ \n"\ -" *z = (x->wInt == y->wInt) && (x->idx == y->idx);\n"\ -"}" - -void LG_MSF_tupleEq_fp -( - bool *z, - const LG_MSF_tuple_fp *x, - const LG_MSF_tuple_fp *y -) -{ - *z = (x->wFp == y->wFp) && (x->idx == y->idx); -} - -#define TUPLEEQ_FP \ -"void LG_MSF_tupleEq_fp \n"\ -"( \n"\ -" bool *z, \n"\ -" const LG_MSF_tuple_fp *x, \n"\ -" const LG_MSF_tuple_fp *y \n"\ -") \n"\ -"{ \n"\ -" *z = (x->wFp == y->wFp) && (x->idx == y->idx);\n"\ -"}" +LG_JIT_STRING(LG_MSF_TUPLEEQ(double), LG_MSF_TUPLEEQ_DOUBLE) +LG_JIT_STRING(LG_MSF_TUPLEEQ(int64_t), LG_MSF_TUPLEEQ_INT64_T) //------------------------------------------------------------------------------ @@ -613,10 +346,10 @@ int LAGraph_msf #if LG_SUITESPARSE_GRAPHBLAS_V10 LG_CLEAR_MSG ; - LG_MSF_context_int context_int = {.parent = NULL, .w_partner = NULL } ; - LG_MSF_context_fp context_fp = {.parent = NULL, .w_partner = NULL } ; - LG_MSF_tuple_int inf_int = {.wInt = INT64_MAX, .idx = UINT64_MAX}; - LG_MSF_tuple_fp inf_fp = {.wFp = INFINITY , .idx = UINT64_MAX}; + LG_MSF_context_int64_t context_int = {.parent = NULL, .w_partner = NULL } ; + LG_MSF_context_double context_fp = {.parent = NULL, .w_partner = NULL } ; + LG_MSF_tuple_int64_t inf_int = {.wInt = INT64_MAX, .idx = UINT64_MAX}; + LG_MSF_tuple_double inf_fp = {.wInt = INFINITY , .idx = UINT64_MAX}; GrB_Info info; GrB_Index n; @@ -698,56 +431,59 @@ int LAGraph_msf //---------------------------------------------------------------------- // types and ops for INT64 weights //---------------------------------------------------------------------- - - GRB_TRY (GxB_Type_new (&tuple, sizeof (LG_MSF_tuple_int), - "LG_MSF_tuple_int", TUPLE_INT)) ; + GRB_TRY (GxB_Type_new (&tuple, sizeof (LG_MSF_tuple_int64_t), + "LG_MSF_tuple_int64_t", LG_MSF_TUPLE_INT64_T)) ; GRB_TRY (GxB_BinaryOp_new ( - &combine, (GxB_binary_function) LG_MSF_combine_int, + &combine, (GxB_binary_function) LG_MSF_combine_int64_t, tuple, weight_type, GrB_UINT64, - "LG_MSF_combine_int", COMBINE_INT)) ; + "LG_MSF_combine_int64_t", LG_MSF_COMBINE_INT64_T)) ; GRB_TRY (GrB_Scalar_setElement_INT64(max_weight, INT64_MAX)) ; GRB_TRY (GxB_BinaryOp_new ( - &tupleMin, (GxB_binary_function) LG_MSF_tupleMin_int, + &tupleMin, (GxB_binary_function) LG_MSF_tupleMin_int64_t, tuple, tuple, tuple, - "LG_MSF_tupleMin_int", TUPLEMIN_INT)) ; + "LG_MSF_tupleMin_int64_t", LG_MSF_TUPLEMIN_INT64_T)) ; GRB_TRY (GxB_BinaryOp_new ( - &tuple2nd, (GxB_binary_function) LG_MSF_tuple2nd_int, + &tuple2nd, (GxB_binary_function) LG_MSF_tuple2nd_int64_t, tuple, GrB_BOOL, tuple, - "LG_MSF_tuple2nd_int", TUPLE2ND_INT)) ; + "LG_MSF_tuple2nd_int64_t", LG_MSF_TUPLE2ND_INT64_T)) ; GRB_TRY (GxB_BinaryOp_new ( - &tupleEq, (GxB_binary_function) LG_MSF_tupleEq_int, + &tupleEq, (GxB_binary_function) LG_MSF_tupleEq_int64_t, GrB_BOOL, tuple, tuple, - "LG_MSF_tupleEq_int", TUPLEEQ_INT)) ; + "LG_MSF_tupleEq_int64_t", LG_MSF_TUPLEEQ_INT64_T)) ; inf = (void *) (&inf_int) ; GRB_TRY (GxB_UnaryOp_new ( - &get_first, (GxB_unary_function) LG_MSF_get_first_int, weight_type, - tuple, "LG_MSF_get_first_int", GET_FIRST_INT)) ; + &get_first, (GxB_unary_function) LG_MSF_get_first_int64_t, + weight_type, tuple, + "LG_MSF_get_first_int64_t", LG_MSF_GET_FIRST_INT64_T)) ; GRB_TRY (GxB_UnaryOp_new ( - &get_second, (GxB_unary_function) LG_MSF_get_second_int, GrB_UINT64, - tuple, "LG_MSF_get_second_int", GET_SECOND_INT)) ; + &get_second, (GxB_unary_function) LG_MSF_get_second_int64_t, + GrB_UINT64, tuple, + "LG_MSF_get_second_int64_t", LG_MSF_GET_SECOND_INT64_T)) ; // context type GRB_TRY (GxB_Type_new ( - &context_type, sizeof (LG_MSF_context_int), - "LG_MSF_context_int", LG_MSF_CONTEXT_INT)) ; + &context_type, sizeof (LG_MSF_context_int64_t), + "LG_MSF_context_int64_t", LG_MSF_CONTEXT_INT64_T)) ; // ops for GrB_select GRB_TRY(GxB_IndexUnaryOp_new ( - &selectEdge, (GxB_index_unary_function) LG_MSF_selectEdge_int, + &selectEdge, (GxB_index_unary_function) LG_MSF_selectEdge_int64_t, GrB_BOOL, weight_type, context_type, - "LG_MSF_selectEdge_int", SELECTEDGE_INT)) ; + "LG_MSF_selectEdge_int64_t", LG_MSF_SELECTEDGE_INT64_T)) ; GRB_TRY(GxB_IndexUnaryOp_new ( - &removeEdge, (void *) LG_MSF_removeEdge_int, GrB_BOOL, weight_type, - context_type, "LG_MSF_removeEdge_int", REMOVEEDGE_INT)) ; + &removeEdge, (void *) LG_MSF_removeEdge_int64_t, GrB_BOOL, + weight_type, context_type, + "LG_MSF_removeEdge_int64_t", LG_MSF_REMOVEEDGE_INT64_T + )) ; } else @@ -757,54 +493,57 @@ int LAGraph_msf // types and ops for FP64 weights //---------------------------------------------------------------------- - GRB_TRY (GxB_Type_new (&tuple, sizeof (LG_MSF_tuple_fp), - "LG_MSF_tuple_fp", TUPLE_FP)) ; + GRB_TRY (GxB_Type_new (&tuple, sizeof (LG_MSF_tuple_double), + "LG_MSF_tuple_double", LG_MSF_TUPLE_DOUBLE)) ; GRB_TRY (GxB_BinaryOp_new ( - &combine, (GxB_binary_function) LG_MSF_combine_fp, + &combine, (GxB_binary_function) LG_MSF_combine_double, tuple, weight_type, GrB_UINT64, - "LG_MSF_combine_fp", COMBINE_FP)) ; + "LG_MSF_combine_double", LG_MSF_COMBINE_DOUBLE)) ; GRB_TRY (GrB_Scalar_setElement_FP64(max_weight, INFINITY)) ; GRB_TRY (GxB_BinaryOp_new ( - &tupleMin, (GxB_binary_function) LG_MSF_tupleMin_fp, + &tupleMin, (GxB_binary_function) LG_MSF_tupleMin_double, tuple, tuple, tuple, - "LG_MSF_tupleMin_fp", TUPLEMIN_FP)) ; + "LG_MSF_tupleMin_double", LG_MSF_TUPLEMIN_DOUBLE)) ; GRB_TRY (GxB_BinaryOp_new ( - &tuple2nd, (GxB_binary_function) LG_MSF_tuple2nd_fp, + &tuple2nd, (GxB_binary_function) LG_MSF_tuple2nd_double, tuple, GrB_BOOL, tuple, - "LG_MSF_tuple2nd_fp", TUPLE2ND_FP)) ; + "LG_MSF_tuple2nd_double", LG_MSF_TUPLE2ND_DOUBLE)) ; GRB_TRY (GxB_BinaryOp_new ( - &tupleEq, (GxB_binary_function) LG_MSF_tupleEq_fp, + &tupleEq, (GxB_binary_function) LG_MSF_tupleEq_double, GrB_BOOL, tuple, tuple, - "LG_MSF_tupleEq_fp", TUPLEEQ_FP)) ; + "LG_MSF_tupleEq_double", LG_MSF_TUPLEEQ_DOUBLE)) ; inf = (void *) (&inf_fp) ; GRB_TRY (GxB_UnaryOp_new ( - &get_first, (GxB_unary_function) LG_MSF_get_first_fp, weight_type, - tuple, "LG_MSF_get_first_fp", GET_FIRST_FP)) ; + &get_first, (GxB_unary_function) LG_MSF_get_first_double, + weight_type, tuple, + "LG_MSF_get_first_double", LG_MSF_GET_FIRST_DOUBLE)) ; GRB_TRY (GxB_UnaryOp_new ( - &get_second, (GxB_unary_function) LG_MSF_get_second_fp, GrB_UINT64, - tuple, "LG_MSF_get_second_fp", GET_SECOND_FP)) ; + &get_second, (GxB_unary_function) LG_MSF_get_second_double, + GrB_UINT64, tuple, + "LG_MSF_get_second_double", LG_MSF_GET_SECOND_DOUBLE)) ; GRB_TRY (GxB_Type_new ( - &context_type, sizeof (LG_MSF_context_fp), - "LG_MSF_context_fp", LG_MSF_CONTEXT_FP)) ; + &context_type, sizeof (LG_MSF_context_double), + "LG_MSF_context_double", LG_MSF_CONTEXT_DOUBLE)) ; // ops for GrB_select GRB_TRY(GxB_IndexUnaryOp_new ( - &selectEdge, (GxB_index_unary_function) LG_MSF_selectEdge_fp, + &selectEdge, (GxB_index_unary_function) LG_MSF_selectEdge_double, GrB_BOOL, weight_type, context_type, - "LG_MSF_selectEdge_fp", SELECTEDGE_FP)) ; + "LG_MSF_selectEdge_double", LG_MSF_SELECTEDGE_DOUBLE)) ; GRB_TRY(GxB_IndexUnaryOp_new ( - &removeEdge, (void *) LG_MSF_removeEdge_fp, GrB_BOOL, weight_type, - context_type, "LG_MSF_removeEdge_fp", REMOVEEDGE_FP)) ; + &removeEdge, (void *) LG_MSF_removeEdge_double, + GrB_BOOL, weight_type, context_type, + "LG_MSF_removeEdge_double", LG_MSF_REMOVEEDGE_DOUBLE)) ; } GRB_TRY (GrB_Monoid_new_UDT (&tupleMin_monoid, tupleMin, inf)) ; diff --git a/experimental/algorithm/LAGraph_scc.c b/experimental/algorithm/LAGraph_scc.c index f5a4e8c639..e26628ae78 100755 --- a/experimental/algorithm/LAGraph_scc.c +++ b/experimental/algorithm/LAGraph_scc.c @@ -35,18 +35,12 @@ //**************************************************************************** //arrays used in SelectOp -typedef struct -{ - uint64_t *F, *B; +LG_JIT_STRING( +typedef struct { + uint64_t *F; + uint64_t *B; bool *M; -} LG_SCC_Context; -#define SCCCONTEXT \ -"typedef struct \n" \ -"{\n" \ -" uint64_t *F, *B;\n" \ -" bool *M;\n" \ -"} LG_SCC_Context;\n" - +} LG_SCC_Context;, SCCCONTEXT) // LG_SCC_edge_removal: // - remove the edges connected to newly identified SCCs (vertices u with M[u]==1) @@ -61,21 +55,18 @@ typedef struct // an edge (u, v) if either F[u]!=F[v] or B[u]!=B[v] holds, which can accelerate // the SCC computation in the future rounds. -void LG_SCC_edge_removal (bool *z, const void *x, GrB_Index i, GrB_Index j, const LG_SCC_Context *thunk) ; -void LG_SCC_edge_removal (bool *z, const void *x, GrB_Index i, GrB_Index j, const LG_SCC_Context *thunk) -{ - (*z) = (!thunk->M[i] && !thunk->M[j] - && thunk->F[i] == thunk->F[j] +LG_JIT_STRING( +void LG_SCC_edge_removal ( + bool *z, + const void *x, + GrB_Index i, + GrB_Index j, + const LG_SCC_Context *thunk +) { + (*z) = (!thunk->M[i] && !thunk->M[j] + && thunk->F[i] == thunk->F[j] && thunk->B[i] == thunk->B[j]) ; -} -#define EDGE_REMOVAL \ -"void LG_SCC_edge_removal \n" \ -"(bool *z, const void *x, GrB_Index i, GrB_Index j, const LG_SCC_Context *thunk)\n" \ -"{\n" \ -" (*z) = (!thunk->M[i] && !thunk->M[j] \n" \ -" && thunk->F[i] == thunk->F[j] \n" \ -" && thunk->B[i] == thunk->B[j]) ;\n" \ -"}\n" +}, EDGE_REMOVAL) //**************************************************************************** // LG_SCC_trim_one: remove the edges connected to trivial SCCs @@ -83,17 +74,16 @@ void LG_SCC_edge_removal (bool *z, const void *x, GrB_Index i, GrB_Index j, cons // - M[i] = i | if vertex i is a trivial SCC // M[i] = n | otherwise -void LG_SCC_trim_one (bool *z, const void *x, GrB_Index i, GrB_Index j, const LG_SCC_Context *thunk) ; -void LG_SCC_trim_one (bool *z, const void *x, GrB_Index i, GrB_Index j, const LG_SCC_Context *thunk) -{ +LG_JIT_STRING( +void LG_SCC_trim_one ( + bool *z, + const void *x, + GrB_Index i, + GrB_Index j, + const LG_SCC_Context *thunk +) { (*z) = (thunk->F[i] == thunk->F[j]) ; -} -#define TRIM_ONE \ -"void LG_SCC_trim_one\n" \ -"(bool *z, const void *x, GrB_Index i, GrB_Index j, const LG_SCC_Context *thunk)\n" \ -"{\n" \ -" (*z) = (thunk->F[i] == thunk->F[j]) ;\n" \ -"}\n" +}, TRIM_ONE) //**************************************************************************** // label propagation @@ -197,7 +187,7 @@ int LAGraph_scc GRB_TRY (GrB_Matrix_nrows (&n, A)); GRB_TRY (GrB_Matrix_ncols (&ncols, A)); LG_ASSERT(n == ncols, GrB_DIMENSION_MISMATCH); - + #if !LG_SUITESPARSE_GRAPHBLAS_V10 LG_TRY (LAGraph_Malloc ((void **) &contx.F, n, sizeof (uint64_t), msg)) ; LG_TRY (LAGraph_Malloc ((void **) &contx.B, n, sizeof (uint64_t), msg)) ; diff --git a/src/utility/LAGraph_Random.c b/src/utility/LAGraph_Random.c index ca4cf43b1f..9c7bfd5ebe 100644 --- a/src/utility/LAGraph_Random.c +++ b/src/utility/LAGraph_Random.c @@ -86,6 +86,7 @@ uint64_t LG_Random64 (uint64_t *state) } // return a random uint64_t; as a unary operator +LG_JIT_STRING( void LG_rand_next_f2 (uint64_t *z, const uint64_t *x) { uint64_t state = (*x) ; @@ -93,17 +94,7 @@ void LG_rand_next_f2 (uint64_t *z, const uint64_t *x) state ^= state >> 7 ; state ^= state << 17 ; (*z) = state ; -} - -#define LG_RAND_NEXT_F2_DEFN \ -"void LG_rand_next_f2 (uint64_t *z, const uint64_t *x) \n" \ -"{ \n" \ -" uint64_t state = (*x) ; \n" \ -" state ^= state << 13 ; \n" \ -" state ^= state >> 7 ; \n" \ -" state ^= state << 17 ; \n" \ -" (*z) = state ; \n" \ -"}" +}, LG_RAND_NEXT_F2_DEFN) // From these references, the recommendation is to create the initial state of // a random number generator with an entirely different random number @@ -146,6 +137,7 @@ void LG_rand_next_f2 (uint64_t *z, const uint64_t *x) // The init function computes z = splitmix64 (i + seed), but it does not // advance the seed value on return. +LG_JIT_STRING( void LG_rand_init_func (uint64_t *z, const void *x, GrB_Index i, GrB_Index j, const uint64_t *seed) { @@ -155,19 +147,7 @@ void LG_rand_init_func (uint64_t *z, const void *x, result = (result ^ (result >> 27)) * 0x94D049BB133111EBLL ; result = (result ^ (result >> 31)) ; (*z) = result ; -} - -#define LG_RAND_INIT_F_DEFN \ -"void LG_rand_init_func (uint64_t *z, const void *x, \n" \ -" GrB_Index i, GrB_Index j, const uint64_t *seed) \n" \ -"{ \n" \ -" uint64_t state = i + (*seed) ; \n" \ -" uint64_t result = (state += 0x9E3779B97F4A7C15LL) ; \n" \ -" result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9LL ; \n" \ -" result = (result ^ (result >> 27)) * 0x94D049BB133111EBLL ; \n" \ -" result = (result ^ (result >> 31)) ; \n" \ -" (*z) = result ; \n" \ -"}" +}, LG_RAND_INIT_F_DEFN) //------------------------------------------------------------------------------ // LG_Random_Init: create the random state operator diff --git a/src/utility/LG_internal.h b/src/utility/LG_internal.h index 6d72dfc8cc..fe319451e8 100644 --- a/src/utility/LG_internal.h +++ b/src/utility/LG_internal.h @@ -49,6 +49,11 @@ #define MATCH(s1,s2,n) (strncmp (s1, s2, n) == 0) #define MATCHNAME(s1,s2) MATCH (s1, s2, LAGRAPH_MAX_NAME_LEN) +//------------------------------------------------------------------------------ +// JIT string generation +//------------------------------------------------------------------------------ +#define LG_JIT_STRING(f, name) static const char* name = LG_XSTR(f); f + //------------------------------------------------------------------------------ // typedefs //------------------------------------------------------------------------------