#include "LAGraph_test.h"
#include "LG_internal.h"
int status ;
GrB_Info info ;
char msg [LAGRAPH_MSG_LEN] ;
GrB_Matrix A = NULL, B = NULL ;
char library [256], date [256] ;
int32_t ver [3] ;
GrB_Index nrows, ncols, nvals ;
#define LEN 512
char filename [LEN+1] ;
char atype_name [LAGRAPH_MAX_NAME_LEN] ;
char btype_name [LAGRAPH_MAX_NAME_LEN] ;
typedef struct
{
GrB_Index nrows ;
GrB_Index ncols ;
GrB_Index nvals ;
const char *type ;
const char *name ;
}
matrix_info ;
const matrix_info files [ ] =
{
{ 7, 7, 30, "bool", "A.mtx" },
{ 7, 7, 12, "int32_t", "cover.mtx" },
{ 7, 7, 12, "bool", "cover_structure.mtx" },
{ 1138, 1138, 7450, "bool", "jagmesh7.mtx" },
{ 8, 8, 18, "bool", "ldbc-cdlp-directed-example.mtx" },
{ 8, 8, 24, "bool", "ldbc-cdlp-undirected-example.mtx" },
{ 10, 10, 17, "bool", "ldbc-directed-example-bool.mtx" },
{ 10, 10, 17, "double", "ldbc-directed-example.mtx" },
{ 10, 10, 17, "bool", "ldbc-directed-example-unweighted.mtx" },
{ 9, 9, 24, "bool", "ldbc-undirected-example-bool.mtx" },
{ 9, 9, 24, "double", "ldbc-undirected-example.mtx" },
{ 9, 9, 24, "bool", "ldbc-undirected-example-unweighted.mtx"},
{ 10, 10, 30, "int64_t", "ldbc-wcc-example.mtx" },
{ 14, 14, 46, "double", "LFAT5.mtx" },
{ 6, 6, 8, "int64_t", "msf1.mtx" },
{ 8, 8, 12, "int64_t", "msf2.mtx" },
{ 5, 5, 7, "int64_t", "msf3.mtx" },
{ 8, 8, 28, "bool", "sample2.mtx" },
{ 8, 8, 12, "bool", "sample.mtx" },
{ 64, 1, 64, "int64_t", "sources_7.mtx" },
{ 1000, 1000, 3996, "double", "olm1000.mtx" },
{ 2003, 2003, 83883, "double", "bcsstk13.mtx" },
{ 2500, 2500, 12349, "double", "cryg2500.mtx" },
{ 6, 6, 10, "int64_t", "tree-example.mtx" },
{ 67, 67, 294, "double", "west0067.mtx" },
{ 27, 51, 102, "double", "lp_afiro.mtx" },
{ 27, 51, 102, "bool", "lp_afiro_structure.mtx" },
{ 34, 34, 156, "bool", "karate.mtx" },
{ 7, 7, 12, "bool", "matrix_bool.mtx" },
{ 7, 7, 12, "int8_t", "matrix_int8.mtx" },
{ 7, 7, 12, "int16_t", "matrix_int16.mtx" },
{ 7, 7, 12, "int32_t", "matrix_int32.mtx" },
{ 7, 7, 12, "int64_t", "matrix_int64.mtx" },
{ 7, 7, 12, "uint8_t", "matrix_uint8.mtx" },
{ 7, 7, 12, "uint16_t","matrix_uint16.mtx" },
{ 7, 7, 12, "uint32_t","matrix_uint32.mtx" },
{ 7, 7, 12, "uint64_t","matrix_uint64.mtx" },
{ 7, 7, 12, "float", "matrix_fp32.mtx" },
{ 7, 7, 12, "bool", "matrix_fp32_structure.mtx" },
{ 7, 7, 12, "double", "matrix_fp64.mtx" },
{ 67, 67, 294, "double", "west0067_jumbled.mtx" },
{ 6, 6, 20, "float", "skew_fp32.mtx" },
{ 6, 6, 20, "double", "skew_fp64.mtx" },
{ 6, 6, 20, "int8_t", "skew_int8.mtx" },
{ 6, 6, 20, "int16_t", "skew_int16.mtx" },
{ 6, 6, 20, "int32_t", "skew_int32.mtx" },
{ 6, 6, 20, "int64_t", "skew_int64.mtx" },
{ 7, 7, 12, "int32_t", "structure.mtx" },
{ 3, 3, 9, "double", "full.mtx" },
{ 4, 4, 16, "double", "full_symmetric.mtx" },
{ 3, 4, 0, "int32_t", "empty.mtx" },
{ 0, 0, 0, "", "" },
} ;
void setup (void)
{
printf ("\nsetup: %s\n", __FILE__) ;
printf ("data is in [%s]\n", LG_DATA_DIR) ;
OK (LAGraph_Init (msg)) ;
OK (GrB_get (GrB_GLOBAL, library, GrB_NAME)) ;
OK (GrB_get (GrB_GLOBAL, &(ver [0]), GrB_LIBRARY_VER_MAJOR)) ;
OK (GrB_get (GrB_GLOBAL, &(ver [1]), GrB_LIBRARY_VER_MINOR)) ;
OK (GrB_get (GrB_GLOBAL, &(ver [2]), GrB_LIBRARY_VER_PATCH)) ;
date [0] = '\0' ;
OK (LG_GET_LIBRARY_DATE (date)) ;
}
void teardown (void)
{
printf ("\n%s %d.%d.%d (%s)\n", library, ver [0], ver [1], ver [2], date) ;
OK (GrB_free (&A)) ;
OK (GrB_free (&B)) ;
TEST_CHECK (A == NULL) ;
TEST_CHECK (B == NULL) ;
OK (LAGraph_Finalize (msg)) ;
}
void test_MMRead (void)
{
setup ( ) ;
for (int k = 0 ; ; k++)
{
const char *aname = files [k].name ;
if (strlen (aname) == 0) break;
TEST_CASE (aname) ;
printf ("\n============= %2d: %s\n", k, 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 ("Failed to load %s\n", aname) ;
OK (GrB_Matrix_nrows (&nrows, A)) ;
OK (GrB_Matrix_ncols (&ncols, A)) ;
OK (GrB_Matrix_nvals (&nvals, A)) ;
TEST_CHECK (nrows == files [k].nrows) ;
TEST_CHECK (ncols == files [k].ncols) ;
TEST_CHECK (nvals == files [k].nvals) ;
OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
printf ("types: [%s] [%s]\n", atype_name, files [k].type) ;
TEST_CHECK (MATCHNAME (atype_name, files [k].type)) ;
TEST_MSG ("Stats are wrong for %s\n", aname) ;
for (int pr = 0 ; pr <= 2 ; pr++)
{
printf ("\nPretty-print %s: pr=%d:\n", aname, pr) ;
LAGraph_PrintLevel prl = pr ;
OK (LAGraph_Matrix_Print (A, prl, stdout, msg)) ;
}
f = tmpfile ( ) ;
OK (LAGraph_MMWrite (A, f, NULL, msg)) ;
TEST_MSG ("Failed to write %s to a temp file\n", aname) ;
rewind (f) ;
OK (LAGraph_MMRead (&B, f, msg)) ;
TEST_MSG ("Failed to load %s from a temp file\n", aname) ;
OK (fclose (f)) ;
OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
TEST_CHECK (MATCHNAME (atype_name, btype_name)) ;
bool ok ;
OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
TEST_CHECK (ok) ;
TEST_MSG ("Failed test for equality, file: %s\n", aname) ;
OK (GrB_free (&A)) ;
OK (GrB_free (&B)) ;
}
teardown ( ) ;
}
void test_karate (void)
{
setup ( ) ;
FILE *f = fopen (LG_DATA_DIR "karate.mtx", "r") ;
TEST_CHECK (f != NULL) ;
OK (LAGraph_MMRead (&A, f, msg)) ;
OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
TEST_CHECK (MATCHNAME (atype_name, "bool")) ;
OK (fclose (f)) ;
OK (LAGraph_Matrix_Print (A, LAGraph_SHORT, stdout, msg)) ;
TEST_MSG ("Loading of A matrix failed: karate matrix") ;
OK (GrB_Matrix_new (&B, GrB_BOOL, ZACHARY_NUM_NODES, ZACHARY_NUM_NODES)) ;
OK (GrB_Matrix_build (B, ZACHARY_I, ZACHARY_J, ZACHARY_V,
ZACHARY_NUM_EDGES, GrB_LOR)) ;
OK (LAGraph_Matrix_Print (B, LAGraph_SHORT, stdout, msg)) ;
TEST_MSG ("Loading of B matrix failed: karate matrix") ;
bool ok ;
OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
TEST_CHECK (ok) ;
TEST_MSG ("Test for A and B equal failed: karate matrix") ;
OK (GrB_free (&A)) ;
OK (GrB_free (&B)) ;
teardown ( ) ;
}
typedef struct
{
int error ;
const char *name ;
}
mangled_matrix_info ;
const mangled_matrix_info mangled_files [ ] =
{
LAGRAPH_IO_ERROR, "mangled1.mtx", LAGRAPH_IO_ERROR, "mangled2.mtx", LAGRAPH_IO_ERROR, "mangled3.mtx", GrB_NOT_IMPLEMENTED, "complex.mtx", LAGRAPH_IO_ERROR, "mangled4.mtx", LAGRAPH_IO_ERROR, "mangled5.mtx", LAGRAPH_IO_ERROR, "mangled6.mtx", LAGRAPH_IO_ERROR, "mangled7.mtx", LAGRAPH_IO_ERROR, "mangled8.mtx", LAGRAPH_IO_ERROR, "mangled9.mtx", LAGRAPH_IO_ERROR, "mangled10.mtx", LAGRAPH_IO_ERROR, "mangled11.mtx", LAGRAPH_IO_ERROR, "mangled12.mtx", GrB_INDEX_OUT_OF_BOUNDS, "mangled13.mtx", GrB_INVALID_VALUE, "mangled14.mtx", LAGRAPH_IO_ERROR, "mangled_bool.mtx", LAGRAPH_IO_ERROR, "mangled_int8.mtx", LAGRAPH_IO_ERROR, "mangled_int16.mtx", LAGRAPH_IO_ERROR, "mangled_int32.mtx", LAGRAPH_IO_ERROR, "mangled_uint8.mtx", LAGRAPH_IO_ERROR, "mangled_uint16.mtx", LAGRAPH_IO_ERROR, "mangled_uint32.mtx", LAGRAPH_IO_ERROR, "mangled_skew.mtx", GrB_NOT_IMPLEMENTED, "mangled15.mtx", GrB_NOT_IMPLEMENTED, "mangled16.mtx", LAGRAPH_IO_ERROR, "mangled_format.mtx", 0, "",
} ;
void test_MMRead_failures (void)
{
setup ( ) ;
printf ("\nTesting error handling of LAGraph_MMRead when giving it "
"mangled matrices:\n") ;
TEST_CHECK (LAGraph_MMRead (NULL, NULL, msg) == GrB_NULL_POINTER) ;
printf ("msg: [%s]\n", msg) ;
TEST_CHECK (LAGraph_MMRead (&A, NULL, msg) == GrB_NULL_POINTER) ;
printf ("msg: [%s]\n", msg) ;
for (int k = 0 ; ; k++)
{
const char *aname = mangled_files [k].name ;
if (strlen (aname) == 0) break;
TEST_CASE (aname) ;
int error = mangled_files [k].error ;
snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
printf ("file: [%s]\n", filename) ;
FILE *f = fopen (filename, "r") ;
TEST_CHECK (f != NULL) ;
int status = LAGraph_MMRead (&A, f, msg) ;
printf ("error expected: %d %d [%s]\n", error, status, msg) ;
TEST_CHECK (status == error) ;
OK (fclose (f)) ;
TEST_CHECK (A == NULL) ;
}
teardown ( ) ;
}
void test_jumbled (void)
{
setup ( ) ;
FILE *f = fopen (LG_DATA_DIR "west0067.mtx", "r") ;
TEST_CHECK (f != NULL) ;
OK (LAGraph_MMRead (&A, f, msg)) ;
OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
TEST_CHECK (MATCHNAME (atype_name, "double")) ;
OK (fclose (f)) ;
TEST_MSG ("Loading of west0067.mtx failed") ;
f = fopen (LG_DATA_DIR "west0067_jumbled.mtx", "r") ;
TEST_CHECK (f != NULL) ;
OK (LAGraph_MMRead (&B, f, msg)) ;
OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
TEST_CHECK (MATCHNAME (btype_name, "double")) ;
OK (fclose (f)) ;
TEST_MSG ("Loading of west0067_jumbled.mtx failed") ;
bool ok ;
OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
TEST_CHECK (ok) ;
TEST_MSG ("Test for A and B equal failed: west0067_jumbled.mtx matrix") ;
OK (GrB_free (&A)) ;
OK (GrB_free (&B)) ;
teardown ( ) ;
}
const char* files_for_MMWrite [ ] =
{
"west0067.mtx",
"full.mtx",
"cover.mtx",
""
} ;
void test_MMWrite (void)
{
setup ( ) ;
for (int k = 0 ; ; k++)
{
const char *aname = files_for_MMWrite [k] ;
if (strlen (aname) == 0) break;
TEST_CASE (aname) ;
printf ("\n============= %2d: %s\n", k, 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 ("Failed to load %s\n", aname) ;
OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
FILE *fcomments = fopen (LG_DATA_DIR "comments.txt", "wb") ;
TEST_CHECK (fcomments != NULL) ;
fprintf (fcomments, " comments for %s\n", aname) ;
fprintf (fcomments, " this file was created by test_MMRead.c\n") ;
fclose (fcomments) ;
TEST_MSG ("Failed to create comments.txt") ;
snprintf (filename, LEN, LG_DATA_DIR "comments_%s", aname) ;
fcomments = fopen (LG_DATA_DIR "comments.txt", "r") ;
FILE *foutput = fopen (filename, "wb") ;
TEST_CHECK (foutput != NULL) ;
TEST_CHECK (fcomments != NULL) ;
OK (LAGraph_MMWrite (A, foutput, fcomments, msg)) ;
fclose (fcomments) ;
fclose (foutput) ;
TEST_MSG ("Failed to create %s", filename) ;
f = fopen (filename, "r") ;
TEST_CHECK (f != NULL) ;
OK (LAGraph_MMRead (&B, f, msg)) ;
OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
TEST_CHECK (MATCHNAME (atype_name, btype_name)) ;
OK (fclose (f)) ;
TEST_MSG ("Loading of %s failed", filename) ;
bool ok ;
OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
TEST_CHECK (ok) ;
TEST_MSG ("Test for A and B equal failed: %s", filename) ;
if (k == 0)
{
OK (GrB_Matrix_setElement (A, NAN, 0, 0)) ;
double a ;
OK (GrB_Matrix_extractElement (&a, A, 0, 0)) ;
TEST_CHECK (isnan (a)) ;
foutput = fopen (filename, "wb") ;
fcomments = fopen (LG_DATA_DIR "comments.txt", "r") ;
TEST_CHECK (foutput != NULL) ;
OK (LAGraph_MMWrite (A, foutput, fcomments, msg)) ;
fclose (fcomments) ;
fclose (foutput) ;
OK (GrB_free (&A)) ;
f = fopen (filename, "r") ;
TEST_CHECK (f != NULL) ;
OK (LAGraph_MMRead (&A, f, msg)) ;
fclose (f) ;
a = 0 ;
OK (GrB_Matrix_extractElement (&a, A, 0, 0)) ;
TEST_CHECK (isnan (a)) ;
}
OK (GrB_free (&A)) ;
OK (GrB_free (&B)) ;
}
teardown ( ) ;
}
typedef int mytype ;
void test_MMWrite_failures (void)
{
setup ( ) ;
GrB_Type atype = NULL ;
printf ("\nTesting error handling of LAGraph_MMWrite\n") ;
TEST_CHECK (LAGraph_MMWrite (NULL, NULL, NULL, msg) == GrB_NULL_POINTER) ;
printf ("msg: [%s]\n", msg) ;
FILE *f = tmpfile ( ) ;
TEST_CHECK (f != NULL) ;
OK (GrB_Type_new (&atype, sizeof (mytype))) ;
OK (GrB_Matrix_new (&A, atype, 4, 4)) ;
int status = LAGraph_Matrix_Print (A, LAGraph_COMPLETE, stdout, msg) ;
printf ("msg: [%s]\n", msg) ;
TEST_CHECK (status == GrB_NOT_IMPLEMENTED) ;
status = LAGraph_MMWrite (A, f, NULL, msg) ;
printf ("msg: %d [%s]\n", status, msg) ;
TEST_CHECK (status == GrB_NOT_IMPLEMENTED) ;
OK (GrB_free (&atype)) ;
OK (GrB_free (&A)) ;
OK (fclose (f)) ;
teardown ( ) ;
}
#if LG_BRUTAL_TESTS
void test_MMReadWrite_brutal (void)
{
OK (LG_brutal_setup (msg)) ;
for (int k = 0 ; ; k++)
{
const char *aname = files [k].name ;
if (strlen (aname) == 0) break;
TEST_CASE (aname) ;
printf ("\n============= %2d: %s\n", k, 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 ("Failed to load %s\n", aname) ;
printf ("\n") ;
for (int nbrutal = 0 ; ; nbrutal++)
{
printf (".") ;
LG_brutal = nbrutal ;
f = tmpfile ( ) ; int brutal_result = LAGraph_MMWrite (A, f, NULL, msg) ;
if (brutal_result >= 0)
{
printf (" MMWrite ok: %d mallocs\n", nbrutal) ;
break ;
}
OK (fclose (f)) ; if (nbrutal > 10000) { printf ("Infinite!\n") ; abort ( ) ; }
}
LG_brutal = -1 ;
for (int nbrutal = 0 ; ; nbrutal++)
{
printf (".") ;
LG_brutal = nbrutal ;
rewind (f) ; int brutal_result = LAGraph_MMRead (&B, f, msg) ;
if (brutal_result >= 0)
{
printf (" MMRead ok: %d mallocs\n", nbrutal) ;
OK (fclose (f)) ; break ;
}
if (nbrutal > 10000) { printf ("Infinite!\n") ; abort ( ) ; }
}
LG_brutal = -1 ;
OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
TEST_CHECK (MATCHNAME (atype_name, btype_name)) ;
bool ok ;
OK (GrB_Matrix_wait (A, GrB_MATERIALIZE)) ;
OK (GrB_Matrix_wait (B, GrB_MATERIALIZE)) ;
LG_BRUTAL (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
TEST_CHECK (ok) ;
TEST_MSG ("Failed test for equality, file: %s\n", aname) ;
OK (GrB_free (&A)) ;
OK (GrB_free (&B)) ;
}
OK (LG_brutal_teardown (msg)) ;
}
#endif
void test_array_pattern (void)
{
OK (LG_brutal_setup (msg)) ;
OK (GrB_Matrix_new (&A, GrB_INT64, 3, 3)) ;
OK (GrB_Matrix_assign_INT64 (A, NULL, NULL, 1, GrB_ALL, 3, GrB_ALL, 3,
NULL)) ;
OK (GrB_Matrix_wait (A, GrB_MATERIALIZE)) ;
printf ("\nA matrix:\n") ;
OK (LAGraph_Matrix_Print (A, LAGraph_COMPLETE, stdout, msg)) ;
FILE *f = tmpfile ( ) ; OK (LAGraph_MMWrite (A, f, NULL, msg)) ;
TEST_MSG ("Failed to write matrix to a temp file\n") ;
rewind (f) ;
OK (LAGraph_MMRead (&B, f, msg)) ;
TEST_MSG ("Failed to load matrix from a temp file\n") ;
OK (fclose (f)) ;
printf ("\nB matrix:\n") ;
OK (LAGraph_Matrix_Print (B, LAGraph_COMPLETE, stdout, msg)) ;
OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
TEST_CHECK (MATCHNAME ("int64_t", btype_name)) ;
bool ok ;
OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
TEST_CHECK (ok) ;
TEST_MSG ("Failed test for equality, dense 3-by-3\n") ;
OK (GrB_free (&A)) ;
OK (GrB_free (&B)) ;
OK (LG_brutal_teardown (msg)) ;
}
TEST_LIST =
{
{ "MMRead", test_MMRead },
{ "karate", test_karate },
{ "MMRead_failures", test_MMRead_failures },
{ "jumbled", test_jumbled },
{ "MMWrite", test_MMWrite },
{ "MMWrite_failures", test_MMWrite_failures },
#if LG_BRUTAL_TESTS
{ "MMReadWrite_brutal", test_MMReadWrite_brutal },
#endif
{ "array_pattern", test_array_pattern },
{ NULL, NULL }
} ;