#include <stdio.h>
#include <acutest.h>
#include <LAGraph_test.h>
#include <graph_zachary_karate.h>
char msg[LAGRAPH_MSG_LEN];
LAGraph_Graph G = NULL;
#define LEN 512
char filename [LEN+1] ;
typedef struct
{
uint64_t ntriangles ; const char *name ; }
matrix_info ;
const matrix_info files [ ] =
{
{ 45, "karate.mtx" },
{ 11, "A.mtx" },
{ 2016, "jagmesh7.mtx" },
{ 6, "ldbc-cdlp-undirected-example.mtx" },
{ 4, "ldbc-undirected-example.mtx" },
{ 5, "ldbc-wcc-example.mtx" },
{ 0, "LFAT5.mtx" },
{ 342300, "bcsstk13.mtx" },
{ 0, "tree-example.mtx" },
{ 111958, "arrow.mtx"},
{ 0, "" },
} ;
void setup(void)
{
LAGraph_Init(msg);
int retval;
GrB_Matrix A = NULL;
GrB_Matrix_new(&A, GrB_UINT32, ZACHARY_NUM_NODES, ZACHARY_NUM_NODES);
GrB_Matrix_build(A, ZACHARY_I, ZACHARY_J, ZACHARY_V, ZACHARY_NUM_EDGES,
GrB_LOR);
retval = LAGraph_New(&G, &A, LAGraph_ADJACENCY_UNDIRECTED, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
retval = LAGraph_Cached_NSelfEdges(G, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
TEST_CHECK(G->nself_edges == 0);
}
void teardown(void)
{
int retval = LAGraph_Delete(&G, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
G = NULL;
LAGraph_Finalize(msg);
}
void test_TriangleCount_Methods1(void)
{
setup();
int retval;
uint64_t ntriangles = 0UL;
LAGr_TriangleCount_Presort presort = LAGr_TriangleCount_AutoSort ;
LAGr_TriangleCount_Method method = LAGr_TriangleCount_Burkhardt ;
ntriangles = 0UL;
retval = LAGr_TriangleCount(&ntriangles, G, &method, &presort, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
TEST_CHECK( ntriangles == 45 );
TEST_MSG("numtri = %g", (double) ntriangles);
teardown();
}
void test_TriangleCount_Methods2(void)
{
setup();
int retval;
uint64_t ntriangles = 0UL;
LAGr_TriangleCount_Presort presort = LAGr_TriangleCount_AutoSort ;
LAGr_TriangleCount_Method method = LAGr_TriangleCount_Cohen ;
ntriangles = 0UL;
retval = LAGr_TriangleCount(&ntriangles, G, &method, &presort, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
TEST_CHECK( ntriangles == 45 );
TEST_MSG("numtri = %g", (double) ntriangles);
teardown();
}
void test_TriangleCount_Methods3(void)
{
setup();
int retval;
uint64_t ntriangles = 0UL;
LAGr_TriangleCount_Presort presort = LAGr_TriangleCount_AutoSort ;
LAGr_TriangleCount_Method method = LAGr_TriangleCount_Sandia_LL ;
ntriangles = 0UL;
retval = LAGr_TriangleCount (&ntriangles, G, &method, &presort, msg) ;
TEST_CHECK(retval == LAGRAPH_NOT_CACHED);
TEST_MSG("retval = %d (%s)", retval, msg);
retval = LAGraph_Cached_OutDegree(G, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
presort = LAGr_TriangleCount_AutoSort ;
method = LAGr_TriangleCount_Sandia_LL ;
retval = LAGr_TriangleCount(&ntriangles, G, &method, &presort, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
TEST_CHECK( ntriangles == 45 );
TEST_MSG("numtri = %g", (double) ntriangles);
teardown();
}
void test_TriangleCount_Methods4(void)
{
setup();
int retval;
uint64_t ntriangles = 0UL;
LAGr_TriangleCount_Presort presort = LAGr_TriangleCount_AutoSort ;
LAGr_TriangleCount_Method method = LAGr_TriangleCount_Sandia_UU ;
ntriangles = 0UL;
retval = LAGr_TriangleCount(&ntriangles, G, &method, &presort, msg);
TEST_CHECK(retval == LAGRAPH_NOT_CACHED);
TEST_MSG("retval = %d (%s)", retval, msg);
retval = LAGraph_Cached_OutDegree(G, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
presort = LAGr_TriangleCount_AutoSort ;
method = LAGr_TriangleCount_Sandia_UU ;
retval = LAGr_TriangleCount(&ntriangles, G, &method, &presort, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
TEST_CHECK( ntriangles == 45 );
TEST_MSG("numtri = %g", (double) ntriangles) ;
teardown();
}
void test_TriangleCount_Methods5(void)
{
setup();
int retval;
uint64_t ntriangles = 0UL;
LAGr_TriangleCount_Presort presort = LAGr_TriangleCount_AutoSort ;
LAGr_TriangleCount_Method method = LAGr_TriangleCount_Sandia_LUT ;
ntriangles = 0UL;
retval = LAGr_TriangleCount(&ntriangles, G, &method, &presort, msg);
TEST_CHECK(retval == LAGRAPH_NOT_CACHED);
TEST_MSG("retval = %d (%s)", retval, msg);
retval = LAGraph_Cached_OutDegree(G, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
presort = LAGr_TriangleCount_AutoSort ;
method = LAGr_TriangleCount_Sandia_LUT ;
retval = LAGr_TriangleCount(&ntriangles, G, &method, &presort, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
TEST_CHECK( ntriangles == 45 );
TEST_MSG("numtri = %g", (double) ntriangles) ;
teardown();
}
void test_TriangleCount_Methods6(void)
{
setup();
int retval;
uint64_t ntriangles = 0UL;
LAGr_TriangleCount_Presort presort = LAGr_TriangleCount_AutoSort ;
LAGr_TriangleCount_Method method = LAGr_TriangleCount_Sandia_ULT ;
ntriangles = 0UL;
retval = LAGr_TriangleCount(&ntriangles, G, &method, &presort, msg);
TEST_CHECK(retval == LAGRAPH_NOT_CACHED) ;
TEST_MSG("retval = %d (%s)", retval, msg);
retval = LAGraph_Cached_OutDegree(G, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
presort = LAGr_TriangleCount_AutoSort ;
method = LAGr_TriangleCount_Sandia_ULT ;
retval = LAGr_TriangleCount(&ntriangles, G, &method, &presort, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
TEST_CHECK( ntriangles == 45 );
TEST_MSG("numtri = %g", (double) ntriangles) ;
teardown();
}
void test_TriangleCount(void)
{
setup();
uint64_t ntriangles = 0UL;
int retval = LAGraph_TriangleCount(&ntriangles, G, msg);
TEST_CHECK(retval == 0);
TEST_MSG("retval = %d (%s)", retval, msg);
TEST_CHECK( ntriangles == 45 );
TEST_MSG("numtri = %g", (double) ntriangles) ;
OK (LG_check_tri (&ntriangles, G, msg)) ;
TEST_CHECK( ntriangles == 45 );
teardown();
}
void test_TriangleCount_many (void)
{
LAGraph_Init(msg);
GrB_Matrix A = NULL ;
printf ("\n") ;
for (int k = 0 ; ; k++)
{
const char *aname = files [k].name ;
uint64_t ntriangles = files [k].ntriangles ;
if (strlen (aname) == 0) break;
TEST_CASE (aname) ;
snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
FILE *f = fopen (filename, "r") ;
TEST_CHECK (f != NULL) ;
OK (LAGraph_MMRead (&A, f, msg)) ;
OK (fclose (f)) ;
TEST_MSG ("Loading of adjacency matrix failed") ;
OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_UNDIRECTED, msg)) ;
TEST_CHECK (A == NULL) ;
OK (LAGraph_DeleteSelfEdges (G, msg)) ;
TEST_CHECK (G->nself_edges == 0) ;
OK (LAGraph_DeleteSelfEdges (G, msg)) ;
TEST_CHECK (G->nself_edges == 0) ;
uint64_t nt0, nt1 ;
OK (LAGraph_TriangleCount (&nt1, G, msg)) ;
printf ("# triangles: %g Matrix: %s\n", (double) nt1, aname) ;
TEST_CHECK (nt1 == ntriangles) ;
OK (LG_check_tri (&nt0, G, msg)) ;
TEST_CHECK (nt0 == nt1) ;
G->kind = LAGraph_ADJACENCY_DIRECTED ;
G->is_symmetric_structure = LAGraph_TRUE ;
OK (LAGraph_TriangleCount (&nt1, G, msg)) ;
TEST_CHECK (nt1 == ntriangles) ;
OK (LG_check_tri (&nt0, G, msg)) ;
TEST_CHECK (nt0 == nt1) ;
for (int method = 0 ; method <= 6 ; method++)
{
for (int presort = 0 ; presort <= 2 ; presort++)
{
LAGr_TriangleCount_Presort s = presort ;
LAGr_TriangleCount_Method m = method ;
OK (LAGr_TriangleCount (&nt1, G, &m, &s, msg)) ;
TEST_CHECK (nt1 == ntriangles) ;
}
}
LAGr_TriangleCount_Method method = 99 ;
int result = LAGr_TriangleCount (&nt1, G, &method, NULL, msg) ;
TEST_CHECK (result == GrB_INVALID_VALUE) ;
LAGr_TriangleCount_Presort presort = 99 ;
result = LAGr_TriangleCount (&nt1, G, NULL, &presort, msg) ;
TEST_CHECK (result == GrB_INVALID_VALUE) ;
OK (LAGraph_Delete (&G, msg)) ;
}
LAGraph_Finalize(msg);
}
void test_TriangleCount_autosort (void)
{
OK (LAGraph_Init(msg)) ;
GrB_Index n = 50000 ;
GrB_Matrix A = NULL ;
OK (GrB_Matrix_new (&A, GrB_BOOL, n, n)) ;
for (int k = 0 ; k <= 50 ; k++)
{
for (int i = 0 ; i < n ; i++)
{
OK (GrB_Matrix_setElement_BOOL (A, true, i, k)) ;
OK (GrB_Matrix_setElement_BOOL (A, true, k, i)) ;
}
}
for (int i = 0 ; i < n ; i++)
{
for (int j = i ; j < LAGRAPH_MIN (n, i + 5) ; j++)
{
OK (GrB_Matrix_setElement_BOOL (A, true, j, i)) ;
OK (GrB_Matrix_setElement_BOOL (A, true, i, j)) ;
}
}
OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_UNDIRECTED, msg)) ;
TEST_CHECK (A == NULL) ;
OK (LAGraph_DeleteSelfEdges (G, msg)) ;
TEST_CHECK (G->nself_edges == 0) ;
OK (LAGraph_Cached_OutDegree (G, msg)) ;
GrB_Index nt1 = 0, nt0 = 0 ;
for (int method = 3 ; method <= 6 ; method++)
{
LAGr_TriangleCount_Presort presort = LAGr_TriangleCount_AutoSort ;
LAGr_TriangleCount_Method m = method ;
nt1 = 0 ;
OK (LAGr_TriangleCount (&nt1, G, &m, &presort, msg)) ;
if (method == 3)
{
nt0 = nt1 ;
}
TEST_CHECK (nt1 == nt0) ;
}
nt1 = 0 ;
OK (LAGraph_TriangleCount (&nt1, G, msg)) ;
TEST_CHECK (nt1 == nt0) ;
OK (LAGraph_Delete (&G, msg)) ;
OK (LAGraph_Finalize(msg)) ;
}
#if LG_BRUTAL_TESTS
void test_TriangleCount_brutal (void)
{
OK (LG_brutal_setup (msg)) ;
GrB_Matrix A = NULL ;
printf ("\n") ;
for (int k = 0 ; ; k++)
{
const char *aname = files [k].name ;
uint64_t ntriangles = files [k].ntriangles ;
if (strlen (aname) == 0) break;
printf ("\n================== Matrix: %s\n", aname) ;
TEST_CASE (aname) ;
snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
FILE *f = fopen (filename, "r") ;
TEST_CHECK (f != NULL) ;
OK (LAGraph_MMRead (&A, f, msg)) ;
OK (fclose (f)) ;
TEST_MSG ("Loading of adjacency matrix failed") ;
OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_UNDIRECTED, msg)) ;
OK (LAGraph_DeleteSelfEdges (G, msg)) ;
uint64_t nt0, nt1 ;
LG_BRUTAL_BURBLE (LAGraph_TriangleCount (&nt1, G, msg)) ;
printf ("# triangles: %g Matrix: %s\n", (double) nt1, aname) ;
TEST_CHECK (nt1 == ntriangles) ;
LG_BRUTAL_BURBLE (LG_check_tri (&nt0, G, msg)) ;
TEST_CHECK (nt0 == nt1) ;
G->kind = LAGraph_ADJACENCY_DIRECTED ;
G->is_symmetric_structure = LAGraph_TRUE ;
LG_BRUTAL (LAGraph_TriangleCount (&nt1, G, msg)) ;
TEST_CHECK (nt1 == ntriangles) ;
LG_BRUTAL_BURBLE (LG_check_tri (&nt0, G, msg)) ;
TEST_CHECK (nt0 == nt1) ;
for (int method = 0 ; method <= 6 ; method++)
{
for (int presort = 0 ; presort <= 2 ; presort++)
{
LAGr_TriangleCount_Presort s = presort ;
LAGr_TriangleCount_Method m = method ;
LG_BRUTAL_BURBLE (LAGr_TriangleCount (&nt1, G, &m, &s, msg)) ;
TEST_CHECK (nt1 == ntriangles) ;
}
}
OK (LAGraph_Delete (&G, msg)) ;
}
OK (LG_brutal_teardown (msg)) ;
}
#endif
TEST_LIST = {
{"TriangleCount_Methods1", test_TriangleCount_Methods1},
{"TriangleCount_Methods2", test_TriangleCount_Methods2},
{"TriangleCount_Methods3", test_TriangleCount_Methods3},
{"TriangleCount_Methods4", test_TriangleCount_Methods4},
{"TriangleCount_Methods5", test_TriangleCount_Methods5},
{"TriangleCount_Methods6", test_TriangleCount_Methods6},
{"TriangleCount" , test_TriangleCount},
{"TriangleCount_many" , test_TriangleCount_many},
{"TriangleCount_autosort", test_TriangleCount_autosort},
#if LG_BRUTAL_TESTS
{"TriangleCount_brutal" , test_TriangleCount_brutal},
#endif
{NULL, NULL}
};