Skip to content

Commit f4201ca

Browse files
Merge pull request #357 from GraphBLAS/with_GraphBLAS_v10
testing maxflow
2 parents ab43da4 + a5dcbde commit f4201ca

File tree

2 files changed

+99
-26
lines changed

2 files changed

+99
-26
lines changed

experimental/algorithm/LAGr_MaxFlow.c

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515

1616
//------------------------------------------------------------------------------
1717

18+
// FIXME: the GrB_ and GRB_ prefixes should be reserved for GraphBLAS itself,
19+
// and not used for new matrices and operators here. Rename them.
20+
1821
#include <LAGraphX.h>
1922
#include "LG_internal.h"
2023
#include <LAGraph.h>
@@ -394,6 +397,7 @@ JIT_STR(void MF_MxeMult32(MF_resultTuple32 * z, const MF_compareTuple32 * x,
394397
}, GRB_MXEMULT_STR32)
395398

396399

400+
// FIXME: x will always be non-NULL in the test below:
397401
JIT_STR(void MF_MxeAdd64(MF_resultTuple64 * z,
398402
const MF_resultTuple64 * x, const MF_resultTuple64 * y){
399403
if(x != NULL){
@@ -404,6 +408,7 @@ JIT_STR(void MF_MxeAdd64(MF_resultTuple64 * z,
404408
}
405409
}, GRB_MXEADD_STR64)
406410

411+
// FIXME: x will always be non-NULL in the test below:
407412
JIT_STR(void MF_MxeAdd32(MF_resultTuple32 * z,
408413
const MF_resultTuple32 * x, const MF_resultTuple32 * y){
409414
if(x != NULL){
@@ -449,6 +454,7 @@ JIT_STR(void MF_MakeFlow(MF_flowEdge * flow_edge, const double * flow){
449454
flow_edge->flow = (*flow);
450455
}, GRB_MAKEF_STR)
451456

457+
#ifdef DBG
452458
JIT_STR(void MF_CheckInvariant64(bool *z, const int64_t *height,
453459
const MF_resultTuple64 *result) {
454460
(*z) = ((*height) == result->d+1);
@@ -458,7 +464,7 @@ JIT_STR(void MF_CheckInvariant32(bool *z, const int32_t *height,
458464
const MF_resultTuple32 *result) {
459465
(*z) = ((*height) == result->d+1);
460466
}, GRB_INV_STR32)
461-
467+
#endif
462468

463469
JIT_STR(void MF_getResidual(double * res, const MF_flowEdge * flow_edge){
464470
(*res) = flow_edge->capacity - flow_edge->flow; /* FLOP */
@@ -502,7 +508,7 @@ int LAGr_MaxFlow(double* f, GrB_Matrix* flow_mtx, LAGraph_Graph G, GrB_Index src
502508

503509
//src and sink mask vec and n_active
504510
GrB_Vector src_and_sink = NULL ;
505-
GrB_Index n_active = INT32_MAX ;
511+
GrB_Index n_active = INT64_MAX ;
506512

507513
//semiring and vectors for y<e, struct> = R x d
508514
GrB_Vector y = NULL ;
@@ -605,7 +611,7 @@ int LAGr_MaxFlow(double* f, GrB_Matrix* flow_mtx, LAGraph_Graph G, GrB_Index src
605611
"MF_CreateResidualBackward", GRB_CRB_STR));
606612
GRB_TRY(GrB_Matrix_new(&R, GrB_FlowEdge, n, n));
607613
GRB_TRY(GrB_apply(R, NULL, NULL, GrB_CreateResidualForward, A, NULL));
608-
GRB_TRY(GrB_apply(R, A, NULL, GrB_CreateResidualBackward, G->AT, GrB_DESC_SC));
614+
GRB_TRY(GrB_apply(R, A, NULL, GrB_CreateResidualBackward, AT, GrB_DESC_SC));
609615

610616
//init R with initial saturated flows
611617
GRB_TRY(GxB_BinaryOp_new(&GrB_InitForwardFlows,
@@ -644,25 +650,34 @@ int LAGr_MaxFlow(double* f, GrB_Matrix* flow_mtx, LAGraph_Graph G, GrB_Index src
644650
//create scalars
645651
GRB_TRY(GrB_Scalar_new(&zero, GrB_FP64));
646652
GRB_TRY(GrB_Scalar_setElement(zero, 0));
647-
GRB_TRY(GrB_Scalar_new (&empty, GrB_FP64)) ;\
653+
GRB_TRY(GrB_Scalar_new (&empty, GrB_FP64)) ;
648654

649655
GRB_TRY(GxB_UnaryOp_new(&GrB_extractMatrixFlows,
650656
F_UNARY(MF_extractMatrixFlow),
651657
GrB_FP64, GrB_FlowEdge, "MF_extractMatrixFlow", GRB_EMFLOW_STR));
652658

653-
if(n > INT32_MAX){
654-
655-
//create 64 bit types for computation
659+
#ifdef COVERAGE
660+
// Just for test coverage, use 64-bit ints for n > 100. Do not use this
661+
// rule in production!
662+
#define NBIG 100
663+
#else
664+
// For production use: 64-bit integers if n > 2^31
665+
#define NBIG INT32_MAX
666+
#endif
667+
if (n > NBIG){
668+
//create types for computation
656669
GRB_TRY(GxB_Type_new(&GrB_ResultTuple, sizeof(MF_resultTuple64),
657670
"MF_resultTuple64", GRB_RESULTTUPLE_STR64));
658671
GRB_TRY(GxB_Type_new(&GrB_CompareTuple, sizeof(MF_compareTuple64),
659672
"MF_compareTuple64", GRB_COMPARETUPLE_STR64));
660673

661674
//invariant check
675+
#ifdef DBG
662676
GRB_TRY(GrB_Vector_new(&invariant, GrB_BOOL, n));
663677
GRB_TRY(GxB_BinaryOp_new(&GrB_InvariantCheck, F_BINARY(MF_CheckInvariant64),
664678
GrB_BOOL, GrB_INT64,
665679
GrB_ResultTuple, "MF_CheckInvariant64", GRB_INV_STR64));
680+
#endif
666681

667682
//create and init d vector
668683
GRB_TRY(GrB_Vector_new(&d, GrB_INT64, n));
@@ -737,10 +752,12 @@ int LAGr_MaxFlow(double* f, GrB_Matrix* flow_mtx, LAGraph_Graph G, GrB_Index src
737752
"MF_compareTuple32", GRB_COMPARETUPLE_STR32));
738753

739754
//invariant check
755+
#ifdef DBG
740756
GRB_TRY(GrB_Vector_new(&invariant, GrB_BOOL, n));
741757
GRB_TRY(GxB_BinaryOp_new(&GrB_InvariantCheck, F_BINARY(MF_CheckInvariant32),
742758
GrB_BOOL, GrB_INT32,
743759
GrB_ResultTuple, "MF_CheckInvariant32", GRB_INV_STR32));
760+
#endif
744761

745762
GRB_TRY(GxB_UnaryOp_new(&GrB_extractFlows,
746763
F_UNARY(MF_extractFlow32),
@@ -948,6 +965,35 @@ int LAGr_MaxFlow(double* f, GrB_Matrix* flow_mtx, LAGraph_Graph G, GrB_Index src
948965
GRB_TRY(GrB_select(*flow_mtx, NULL, NULL, GrB_VALUEGE_FP64, *flow_mtx, 0, NULL));
949966
}
950967

968+
#ifdef COVERAGE
969+
// The GrB_MxeAdd operator is not tested via the call to GrB_mxv with the
970+
// GrB_MxeSemiring above, so test it via the GrB_MxeAddMonoid.
971+
GrB_free(&y);
972+
GRB_TRY(GrB_Vector_new(&y, GrB_ResultTuple, 3));
973+
if (n > NBIG)
974+
{
975+
MF_resultTuple64 a = {.d = 1, .j = 2, .residual = 3};
976+
MF_resultTuple64 b = {.d = 4, .j = 5, .residual = 6};
977+
GRB_TRY (GrB_Vector_setElement_UDT (y, (void *) &a, 0)) ;
978+
GRB_TRY (GrB_Vector_setElement_UDT (y, (void *) &b, 0)) ;
979+
MF_resultTuple64 c = {.d = 0, .j = 0, .residual = 0};
980+
GRB_TRY (GrB_Vector_reduce_UDT ((void *) &c, NULL, GrB_MxeAddMonoid, y, NULL)) ;
981+
// printf ("c: resid %g j %g d %g\n", c.residual, (double) c.j, (double) c.d) ;
982+
LG_ASSERT ((c.residual == 6 && c.j == 5 && c.d == 4), GrB_PANIC) ;
983+
}
984+
else
985+
{
986+
MF_resultTuple32 a = {.d = 1, .j = 2, .residual = 3};
987+
MF_resultTuple32 b = {.d = 4, .j = 5, .residual = 6};
988+
GRB_TRY (GrB_Vector_setElement_UDT (y, (void *) &a, 0)) ;
989+
GRB_TRY (GrB_Vector_setElement_UDT (y, (void *) &b, 0)) ;
990+
MF_resultTuple32 c = {.d = 0, .j = 0, .residual = 0};
991+
GRB_TRY (GrB_Vector_reduce_UDT ((void *) &c, NULL, GrB_MxeAddMonoid, y, NULL)) ;
992+
// printf ("c: resid %g j %g d %g\n", c.residual, (double) c.j, (double) c.d) ;
993+
LG_ASSERT ((c.residual == 6 && c.j == 5 && c.d == 4), GrB_PANIC) ;
994+
}
995+
#endif
996+
951997
LG_FREE_ALL;
952998
return GrB_SUCCESS;
953999
#else

experimental/test/test_MaxFlow.c

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,17 @@ typedef struct{
3535
GrB_Index S;
3636
GrB_Index T;
3737
double F;
38+
LAGraph_Kind kind ;
3839
}test_info;
3940

4041
test_info tests[] = {
41-
{"wiki.mtx", 0, 5, 4},
42-
{"matrix_random_flow.mtx", 0,9, 22},
43-
{"rand.mtx", 0, 19, 37},
44-
{"mcl.mtx", 0, 9, 0},
45-
{"cycle_flow.mtx", 0, 89, 1},
46-
{"random_weighted_general2.mtx", 0, 299, 11098623877},
47-
{"random_weighted_general1.mtx", 0, 499, 6264009335}
42+
{"wiki.mtx", 0, 5, 4, LAGraph_ADJACENCY_DIRECTED},
43+
{"matrix_random_flow.mtx", 0,9, 22, LAGraph_ADJACENCY_DIRECTED},
44+
{"rand.mtx", 0, 19, 37, LAGraph_ADJACENCY_DIRECTED},
45+
{"mcl.mtx", 0, 9, 0, LAGraph_ADJACENCY_DIRECTED},
46+
{"cycle_flow.mtx", 0, 89, 1, LAGraph_ADJACENCY_DIRECTED},
47+
{"random_weighted_general2.mtx", 0, 299, 11098623877, LAGraph_ADJACENCY_UNDIRECTED},
48+
{"random_weighted_general1.mtx", 0, 499, 6264009335, LAGraph_ADJACENCY_UNDIRECTED}
4849
};
4950

5051
//399 11098623877 alt sink and src for test 6
@@ -54,25 +55,37 @@ void test_MaxFlow(void) {
5455
LAGraph_Init(msg);
5556
//OK(LG_SET_BURBLE(1));
5657
OK(LG_SET_BURBLE(0));
57-
OK(GxB_Global_Option_set(GxB_JIT_C_CONTROL, 4));
5858
for(uint8_t test = 0; test < NTESTS; test++){
5959
GrB_Matrix A=NULL;
60+
printf ("\nMatrix: %s\n", tests[test].filename);
6061
TEST_CASE(tests[test].filename);
6162
snprintf(filename, LEN, LG_DATA_DIR "%s", tests[test].filename);
6263
FILE* f = fopen(filename, "r");
6364
TEST_CHECK(f != NULL);
6465
OK(LAGraph_MMRead(&A, f, msg));
6566
OK(fclose(f));
66-
OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_DIRECTED, msg));
67-
OK(LAGraph_Cached_AT(G, msg));
67+
LAGraph_Kind kind = tests [test].kind ;
68+
OK(LAGraph_New(&G, &A, kind, msg));
69+
if (kind == LAGraph_ADJACENCY_DIRECTED)
70+
{
71+
OK(LAGraph_Cached_AT(G, msg));
72+
}
73+
6874
OK(LAGraph_Cached_EMin(G, msg));
6975

70-
//begin test
76+
// test with JIT
77+
OK(GxB_Global_Option_set(GxB_JIT_C_CONTROL, GxB_JIT_ON));
7178
double flow = 0;
7279
OK(LAGr_MaxFlow(&flow, NULL, G, tests[test].S, tests[test].T, msg));
7380
printf("%s\n", msg);
74-
TEST_CHECK(flow == tests[test].F);
7581
printf("flow is: %lf\n", flow);
82+
TEST_CHECK(flow == tests[test].F);
83+
84+
// test without JIT
85+
OK(GxB_Global_Option_set(GxB_JIT_C_CONTROL, GxB_JIT_OFF));
86+
OK(LAGr_MaxFlow(&flow, NULL, G, tests[test].S, tests[test].T, msg));
87+
TEST_CHECK(flow == tests[test].F);
88+
OK(GxB_Global_Option_set(GxB_JIT_C_CONTROL, GxB_JIT_ON));
7689

7790
//free work
7891
OK(LAGraph_Delete(&G, msg));
@@ -86,9 +99,9 @@ void test_MaxFlowMtx(void) {
8699
#if LG_SUITESPARSE_GRAPHBLAS_V10
87100
//OK(LG_SET_BURBLE(1));
88101
OK(LG_SET_BURBLE(0));
89-
OK(GxB_Global_Option_set(GxB_JIT_C_CONTROL, 4));
90102
for(uint8_t test = 0; test < NTESTS; test++){
91103
GrB_Matrix A=NULL;
104+
printf ("\nMatrix: %s\n", tests[test].filename);
92105
TEST_CASE(tests[test].filename);
93106
snprintf(filename, LEN, LG_DATA_DIR "%s", tests[test].filename);
94107
FILE* f = fopen(filename, "r");
@@ -100,20 +113,34 @@ void test_MaxFlowMtx(void) {
100113
GrB_Index n;
101114
OK(GrB_Matrix_nrows(&n, A));
102115
OK(GrB_Matrix_new(&flow_mtx, GrB_FP64, n, n));
103-
116+
104117
OK(fclose(f));
105-
OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_DIRECTED, msg));
106-
OK(LAGraph_Cached_AT(G, msg));
118+
// treat all matrices as directed graphs
119+
LAGraph_Kind kind = LAGraph_ADJACENCY_DIRECTED ;
120+
// LAGraph_Kind kind = tests [test].kind ;
121+
OK(LAGraph_New(&G, &A, kind, msg));
122+
if (kind == LAGraph_ADJACENCY_DIRECTED)
123+
{
124+
OK(LAGraph_Cached_AT(G, msg));
125+
}
107126
OK(LAGraph_Cached_EMin(G, msg));
108127

109-
//begin test
128+
// test with JIT
129+
OK(GxB_Global_Option_set(GxB_JIT_C_CONTROL, GxB_JIT_ON));
110130
double flow = 0;
111131
OK(LAGr_MaxFlow(&flow, &flow_mtx, G, tests[test].S, tests[test].T, msg));
112132
int status = LG_check_flow(&flow_mtx, msg);
113-
printf("%d", status);
133+
printf("status: %d ", status);
114134
printf("%s\n", msg);
115-
TEST_CHECK(flow == tests[test].F);
116135
printf("flow is: %lf\n", flow);
136+
TEST_CHECK(flow == tests[test].F);
137+
138+
// test without JIT
139+
OK(GxB_Global_Option_set(GxB_JIT_C_CONTROL, GxB_JIT_OFF));
140+
OK(LAGr_MaxFlow(&flow, &flow_mtx, G, tests[test].S, tests[test].T, msg));
141+
status = LG_check_flow(&flow_mtx, msg);
142+
TEST_CHECK(flow == tests[test].F);
143+
OK(GxB_Global_Option_set(GxB_JIT_C_CONTROL, GxB_JIT_ON));
117144

118145
//free work
119146
GrB_free(&flow_mtx);

0 commit comments

Comments
 (0)