Line data Source code
1 : //------------------------------------------------------------------------------
2 : // LAGraph/src/test/test_MMRead.c: test LAGraph_MMRead and LAGraph_MMWrite
3 : //------------------------------------------------------------------------------
4 :
5 : // LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved.
6 : // SPDX-License-Identifier: BSD-2-Clause
7 : //
8 : // For additional details (including references to third party source code and
9 : // other files) see the LICENSE file or contact permission@sei.cmu.edu. See
10 : // Contributors.txt for a full list of contributors. Created, in part, with
11 : // funding and support from the U.S. Government (see Acknowledgments.txt file).
12 : // DM22-0790
13 :
14 : // Contributed by Timothy A. Davis, Texas A&M University
15 :
16 : //------------------------------------------------------------------------------
17 :
18 : #include "LAGraph_test.h"
19 : #include "LG_internal.h"
20 :
21 : //------------------------------------------------------------------------------
22 : // global variables
23 : //------------------------------------------------------------------------------
24 :
25 : int status ;
26 : GrB_Info info ;
27 : char msg [LAGRAPH_MSG_LEN] ;
28 : GrB_Matrix A = NULL, B = NULL ;
29 : char library [256], date [256] ;
30 : int32_t ver [3] ;
31 : GrB_Index nrows, ncols, nvals ;
32 : #define LEN 512
33 : char filename [LEN+1] ;
34 : char atype_name [LAGRAPH_MAX_NAME_LEN] ;
35 : char btype_name [LAGRAPH_MAX_NAME_LEN] ;
36 :
37 : //------------------------------------------------------------------------------
38 : // test matrices
39 : //------------------------------------------------------------------------------
40 :
41 : typedef struct
42 : {
43 : GrB_Index nrows ;
44 : GrB_Index ncols ;
45 : GrB_Index nvals ;
46 : const char *type ;
47 : const char *name ;
48 : }
49 : matrix_info ;
50 :
51 : const matrix_info files [ ] =
52 : {
53 : // nrows ncols nvals type name
54 : { 7, 7, 30, "bool", "A.mtx" },
55 : { 7, 7, 12, "int32_t", "cover.mtx" },
56 : { 7, 7, 12, "bool", "cover_structure.mtx" },
57 : { 1138, 1138, 7450, "bool", "jagmesh7.mtx" },
58 : { 8, 8, 18, "bool", "ldbc-cdlp-directed-example.mtx" },
59 : { 8, 8, 24, "bool", "ldbc-cdlp-undirected-example.mtx" },
60 : { 10, 10, 17, "bool", "ldbc-directed-example-bool.mtx" },
61 : { 10, 10, 17, "double", "ldbc-directed-example.mtx" },
62 : { 10, 10, 17, "bool", "ldbc-directed-example-unweighted.mtx" },
63 : { 9, 9, 24, "bool", "ldbc-undirected-example-bool.mtx" },
64 : { 9, 9, 24, "double", "ldbc-undirected-example.mtx" },
65 : { 9, 9, 24, "bool", "ldbc-undirected-example-unweighted.mtx"},
66 : { 10, 10, 30, "int64_t", "ldbc-wcc-example.mtx" },
67 : { 14, 14, 46, "double", "LFAT5.mtx" },
68 : { 6, 6, 8, "int64_t", "msf1.mtx" },
69 : { 8, 8, 12, "int64_t", "msf2.mtx" },
70 : { 5, 5, 7, "int64_t", "msf3.mtx" },
71 : { 8, 8, 28, "bool", "sample2.mtx" },
72 : { 8, 8, 12, "bool", "sample.mtx" },
73 : { 64, 1, 64, "int64_t", "sources_7.mtx" },
74 : { 1000, 1000, 3996, "double", "olm1000.mtx" },
75 : { 2003, 2003, 83883, "double", "bcsstk13.mtx" },
76 : { 2500, 2500, 12349, "double", "cryg2500.mtx" },
77 : { 6, 6, 10, "int64_t", "tree-example.mtx" },
78 : { 67, 67, 294, "double", "west0067.mtx" },
79 : { 27, 51, 102, "double", "lp_afiro.mtx" },
80 : { 27, 51, 102, "bool", "lp_afiro_structure.mtx" },
81 : { 34, 34, 156, "bool", "karate.mtx" },
82 : { 7, 7, 12, "bool", "matrix_bool.mtx" },
83 : { 7, 7, 12, "int8_t", "matrix_int8.mtx" },
84 : { 7, 7, 12, "int16_t", "matrix_int16.mtx" },
85 : { 7, 7, 12, "int32_t", "matrix_int32.mtx" },
86 : { 7, 7, 12, "int64_t", "matrix_int64.mtx" },
87 : { 7, 7, 12, "uint8_t", "matrix_uint8.mtx" },
88 : { 7, 7, 12, "uint16_t","matrix_uint16.mtx" },
89 : { 7, 7, 12, "uint32_t","matrix_uint32.mtx" },
90 : { 7, 7, 12, "uint64_t","matrix_uint64.mtx" },
91 : { 7, 7, 12, "float", "matrix_fp32.mtx" },
92 : { 7, 7, 12, "bool", "matrix_fp32_structure.mtx" },
93 : { 7, 7, 12, "double", "matrix_fp64.mtx" },
94 : { 67, 67, 294, "double", "west0067_jumbled.mtx" },
95 : { 6, 6, 20, "float", "skew_fp32.mtx" },
96 : { 6, 6, 20, "double", "skew_fp64.mtx" },
97 : { 6, 6, 20, "int8_t", "skew_int8.mtx" },
98 : { 6, 6, 20, "int16_t", "skew_int16.mtx" },
99 : { 6, 6, 20, "int32_t", "skew_int32.mtx" },
100 : { 6, 6, 20, "int64_t", "skew_int64.mtx" },
101 : { 7, 7, 12, "int32_t", "structure.mtx" },
102 : { 3, 3, 9, "double", "full.mtx" },
103 : { 4, 4, 16, "double", "full_symmetric.mtx" },
104 : { 3, 4, 0, "int32_t", "empty.mtx" },
105 : { 0, 0, 0, "", "" },
106 : } ;
107 :
108 : //------------------------------------------------------------------------------
109 : // setup: start a test
110 : //------------------------------------------------------------------------------
111 :
112 6 : void setup (void)
113 : {
114 6 : printf ("\nsetup: %s\n", __FILE__) ;
115 6 : printf ("data is in [%s]\n", LG_DATA_DIR) ;
116 6 : OK (LAGraph_Init (msg)) ;
117 6 : OK (GrB_get (GrB_GLOBAL, library, GrB_NAME)) ;
118 6 : OK (GrB_get (GrB_GLOBAL, &(ver [0]), GrB_LIBRARY_VER_MAJOR)) ;
119 6 : OK (GrB_get (GrB_GLOBAL, &(ver [1]), GrB_LIBRARY_VER_MINOR)) ;
120 6 : OK (GrB_get (GrB_GLOBAL, &(ver [2]), GrB_LIBRARY_VER_PATCH)) ;
121 6 : date [0] = '\0' ;
122 6 : OK (LG_GET_LIBRARY_DATE (date)) ;
123 6 : }
124 :
125 : //------------------------------------------------------------------------------
126 : // teardown: finalize a test
127 : //------------------------------------------------------------------------------
128 :
129 6 : void teardown (void)
130 : {
131 6 : printf ("\n%s %d.%d.%d (%s)\n", library, ver [0], ver [1], ver [2], date) ;
132 6 : OK (GrB_free (&A)) ;
133 6 : OK (GrB_free (&B)) ;
134 6 : TEST_CHECK (A == NULL) ;
135 6 : TEST_CHECK (B == NULL) ;
136 6 : OK (LAGraph_Finalize (msg)) ;
137 6 : }
138 :
139 : //------------------------------------------------------------------------------
140 : // test_MMRead: read a set of matrices, check their stats, and write them out
141 : //------------------------------------------------------------------------------
142 :
143 1 : void test_MMRead (void)
144 : {
145 :
146 : //--------------------------------------------------------------------------
147 : // start up the test
148 : //--------------------------------------------------------------------------
149 :
150 1 : setup ( ) ;
151 :
152 1 : for (int k = 0 ; ; k++)
153 51 : {
154 :
155 : //----------------------------------------------------------------------
156 : // load in the kth file
157 : //----------------------------------------------------------------------
158 :
159 52 : const char *aname = files [k].name ;
160 52 : if (strlen (aname) == 0) break;
161 51 : TEST_CASE (aname) ;
162 51 : printf ("\n============= %2d: %s\n", k, aname) ;
163 51 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
164 51 : FILE *f = fopen (filename, "r") ;
165 51 : TEST_CHECK (f != NULL) ;
166 51 : OK (LAGraph_MMRead (&A, f, msg)) ;
167 51 : OK (fclose (f)) ;
168 51 : TEST_MSG ("Failed to load %s\n", aname) ;
169 :
170 : //----------------------------------------------------------------------
171 : // check its stats
172 : //----------------------------------------------------------------------
173 :
174 51 : OK (GrB_Matrix_nrows (&nrows, A)) ;
175 51 : OK (GrB_Matrix_ncols (&ncols, A)) ;
176 51 : OK (GrB_Matrix_nvals (&nvals, A)) ;
177 51 : TEST_CHECK (nrows == files [k].nrows) ;
178 51 : TEST_CHECK (ncols == files [k].ncols) ;
179 51 : TEST_CHECK (nvals == files [k].nvals) ;
180 :
181 51 : OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
182 51 : printf ("types: [%s] [%s]\n", atype_name, files [k].type) ;
183 51 : TEST_CHECK (MATCHNAME (atype_name, files [k].type)) ;
184 51 : TEST_MSG ("Stats are wrong for %s\n", aname) ;
185 :
186 : //----------------------------------------------------------------------
187 : // pretty-print the matrix
188 : //----------------------------------------------------------------------
189 :
190 204 : for (int pr = 0 ; pr <= 2 ; pr++)
191 : {
192 153 : printf ("\nPretty-print %s: pr=%d:\n", aname, pr) ;
193 153 : LAGraph_PrintLevel prl = pr ;
194 153 : OK (LAGraph_Matrix_Print (A, prl, stdout, msg)) ;
195 : }
196 :
197 : //----------------------------------------------------------------------
198 : // write it to a temporary file
199 : //----------------------------------------------------------------------
200 :
201 51 : f = tmpfile ( ) ;
202 51 : OK (LAGraph_MMWrite (A, f, NULL, msg)) ;
203 51 : TEST_MSG ("Failed to write %s to a temp file\n", aname) ;
204 :
205 : //----------------------------------------------------------------------
206 : // load it back in again
207 : //----------------------------------------------------------------------
208 :
209 51 : rewind (f) ;
210 51 : OK (LAGraph_MMRead (&B, f, msg)) ;
211 51 : TEST_MSG ("Failed to load %s from a temp file\n", aname) ;
212 51 : OK (fclose (f)) ; // close and delete the temporary file
213 :
214 : //----------------------------------------------------------------------
215 : // ensure A and B are the same
216 : //----------------------------------------------------------------------
217 :
218 51 : OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
219 51 : TEST_CHECK (MATCHNAME (atype_name, btype_name)) ;
220 : bool ok ;
221 51 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
222 51 : TEST_CHECK (ok) ;
223 51 : TEST_MSG ("Failed test for equality, file: %s\n", aname) ;
224 :
225 : //----------------------------------------------------------------------
226 : // free workspace
227 : //----------------------------------------------------------------------
228 :
229 51 : OK (GrB_free (&A)) ;
230 51 : OK (GrB_free (&B)) ;
231 : }
232 :
233 : //--------------------------------------------------------------------------
234 : // finish the test
235 : //--------------------------------------------------------------------------
236 :
237 1 : teardown ( ) ;
238 1 : }
239 :
240 : //-----------------------------------------------------------------------------
241 : // test_karate: read in karate graph from a file and compare it known graph
242 : //-----------------------------------------------------------------------------
243 :
244 1 : void test_karate (void)
245 : {
246 :
247 : //--------------------------------------------------------------------------
248 : // start up the test
249 : //--------------------------------------------------------------------------
250 :
251 1 : setup ( ) ;
252 :
253 : //--------------------------------------------------------------------------
254 : // load in the data/karate.mtx file as the matrix A
255 : //--------------------------------------------------------------------------
256 :
257 1 : FILE *f = fopen (LG_DATA_DIR "karate.mtx", "r") ;
258 1 : TEST_CHECK (f != NULL) ;
259 1 : OK (LAGraph_MMRead (&A, f, msg)) ;
260 1 : OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
261 1 : TEST_CHECK (MATCHNAME (atype_name, "bool")) ;
262 1 : OK (fclose (f)) ;
263 1 : OK (LAGraph_Matrix_Print (A, LAGraph_SHORT, stdout, msg)) ;
264 1 : TEST_MSG ("Loading of A matrix failed: karate matrix") ;
265 :
266 : //--------------------------------------------------------------------------
267 : // load in the matrix defined by graph_zachary_karate.h as the matrix B
268 : //--------------------------------------------------------------------------
269 :
270 1 : OK (GrB_Matrix_new (&B, GrB_BOOL, ZACHARY_NUM_NODES, ZACHARY_NUM_NODES)) ;
271 1 : OK (GrB_Matrix_build (B, ZACHARY_I, ZACHARY_J, ZACHARY_V,
272 : ZACHARY_NUM_EDGES, GrB_LOR)) ;
273 1 : OK (LAGraph_Matrix_Print (B, LAGraph_SHORT, stdout, msg)) ;
274 1 : TEST_MSG ("Loading of B matrix failed: karate matrix") ;
275 :
276 : //--------------------------------------------------------------------------
277 : // ensure A and B are the same
278 : //--------------------------------------------------------------------------
279 :
280 : bool ok ;
281 1 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
282 1 : TEST_CHECK (ok) ;
283 1 : TEST_MSG ("Test for A and B equal failed: karate matrix") ;
284 :
285 : //--------------------------------------------------------------------------
286 : // free workspace and finish the test
287 : //--------------------------------------------------------------------------
288 :
289 1 : OK (GrB_free (&A)) ;
290 1 : OK (GrB_free (&B)) ;
291 1 : teardown ( ) ;
292 1 : }
293 :
294 : //-----------------------------------------------------------------------------
295 : // test_failures: test for failure modes of LAGraph_MMRead and MMWrite
296 : //-----------------------------------------------------------------------------
297 :
298 : typedef struct
299 : {
300 : int error ;
301 : const char *name ;
302 : }
303 : mangled_matrix_info ;
304 :
305 : const mangled_matrix_info mangled_files [ ] =
306 : {
307 : // error filename how the matrix is mangled
308 : LAGRAPH_IO_ERROR, "mangled1.mtx", // bad header
309 : LAGRAPH_IO_ERROR, "mangled2.mtx", // bad header
310 : LAGRAPH_IO_ERROR, "mangled3.mtx", // bad type
311 : GrB_NOT_IMPLEMENTED, "complex.mtx", // valid complex, but not supported
312 : LAGRAPH_IO_ERROR, "mangled4.mtx", // bad format
313 : LAGRAPH_IO_ERROR, "mangled5.mtx", // invalid format options
314 : LAGRAPH_IO_ERROR, "mangled6.mtx", // invalid format options
315 : LAGRAPH_IO_ERROR, "mangled7.mtx", // invalid GraphBLAS type
316 : LAGRAPH_IO_ERROR, "mangled8.mtx", // invalid first line
317 : LAGRAPH_IO_ERROR, "mangled9.mtx", // symmetric and rectangular
318 : LAGRAPH_IO_ERROR, "mangled10.mtx", // truncated
319 : LAGRAPH_IO_ERROR, "mangled11.mtx", // entries mangled
320 : LAGRAPH_IO_ERROR, "mangled12.mtx", // entries mangled
321 : GrB_INDEX_OUT_OF_BOUNDS, "mangled13.mtx",// indices out of range
322 : GrB_INVALID_VALUE, "mangled14.mtx", // duplicate entries
323 : LAGRAPH_IO_ERROR, "mangled_bool.mtx", // entry value out of range
324 : LAGRAPH_IO_ERROR, "mangled_int8.mtx", // entry value out of range
325 : LAGRAPH_IO_ERROR, "mangled_int16.mtx", // entry value out of range
326 : LAGRAPH_IO_ERROR, "mangled_int32.mtx", // entry value out of range
327 : LAGRAPH_IO_ERROR, "mangled_uint8.mtx", // entry value out of range
328 : LAGRAPH_IO_ERROR, "mangled_uint16.mtx", // entry value out of range
329 : LAGRAPH_IO_ERROR, "mangled_uint32.mtx", // entry value out of range
330 : LAGRAPH_IO_ERROR, "mangled_skew.mtx", // unsigned skew invalid
331 : GrB_NOT_IMPLEMENTED, "mangled15.mtx", // complex not supported
332 : GrB_NOT_IMPLEMENTED, "mangled16.mtx", // complex not supported
333 : LAGRAPH_IO_ERROR, "mangled_format.mtx", // "array pattern" invalid
334 : 0, "",
335 : } ;
336 :
337 1 : void test_MMRead_failures (void)
338 : {
339 1 : setup ( ) ;
340 1 : printf ("\nTesting error handling of LAGraph_MMRead when giving it "
341 : "mangled matrices:\n") ;
342 :
343 : // input arguments are NULL
344 1 : TEST_CHECK (LAGraph_MMRead (NULL, NULL, msg) == GrB_NULL_POINTER) ;
345 1 : printf ("msg: [%s]\n", msg) ;
346 1 : TEST_CHECK (LAGraph_MMRead (&A, NULL, msg) == GrB_NULL_POINTER) ;
347 1 : printf ("msg: [%s]\n", msg) ;
348 :
349 : // matrix files are mangled in some way, or unsupported
350 1 : for (int k = 0 ; ; k++)
351 26 : {
352 27 : const char *aname = mangled_files [k].name ;
353 27 : if (strlen (aname) == 0) break;
354 26 : TEST_CASE (aname) ;
355 26 : int error = mangled_files [k].error ;
356 26 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
357 26 : printf ("file: [%s]\n", filename) ;
358 26 : FILE *f = fopen (filename, "r") ;
359 26 : TEST_CHECK (f != NULL) ;
360 26 : int status = LAGraph_MMRead (&A, f, msg) ;
361 26 : printf ("error expected: %d %d [%s]\n", error, status, msg) ;
362 26 : TEST_CHECK (status == error) ;
363 26 : OK (fclose (f)) ;
364 26 : TEST_CHECK (A == NULL) ;
365 : }
366 :
367 1 : teardown ( ) ;
368 1 : }
369 :
370 : //-----------------------------------------------------------------------------
371 : // test_jumbled: test reading a jumbled matrix
372 : //-----------------------------------------------------------------------------
373 :
374 1 : void test_jumbled (void)
375 : {
376 :
377 : //--------------------------------------------------------------------------
378 : // start up the test
379 : //--------------------------------------------------------------------------
380 :
381 1 : setup ( ) ;
382 :
383 : //--------------------------------------------------------------------------
384 : // load in the data/west0067.mtx file as the matrix A
385 : //--------------------------------------------------------------------------
386 :
387 1 : FILE *f = fopen (LG_DATA_DIR "west0067.mtx", "r") ;
388 1 : TEST_CHECK (f != NULL) ;
389 1 : OK (LAGraph_MMRead (&A, f, msg)) ;
390 1 : OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
391 1 : TEST_CHECK (MATCHNAME (atype_name, "double")) ;
392 1 : OK (fclose (f)) ;
393 1 : TEST_MSG ("Loading of west0067.mtx failed") ;
394 :
395 : //--------------------------------------------------------------------------
396 : // load in the data/west0067_jumbled.mtx file as the matrix B
397 : //--------------------------------------------------------------------------
398 :
399 1 : f = fopen (LG_DATA_DIR "west0067_jumbled.mtx", "r") ;
400 1 : TEST_CHECK (f != NULL) ;
401 1 : OK (LAGraph_MMRead (&B, f, msg)) ;
402 1 : OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
403 1 : TEST_CHECK (MATCHNAME (btype_name, "double")) ;
404 1 : OK (fclose (f)) ;
405 1 : TEST_MSG ("Loading of west0067_jumbled.mtx failed") ;
406 :
407 : //--------------------------------------------------------------------------
408 : // ensure A and B are the same
409 : //--------------------------------------------------------------------------
410 :
411 : bool ok ;
412 1 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
413 1 : TEST_CHECK (ok) ;
414 1 : TEST_MSG ("Test for A and B equal failed: west0067_jumbled.mtx matrix") ;
415 :
416 : //--------------------------------------------------------------------------
417 : // free workspace and finish the test
418 : //--------------------------------------------------------------------------
419 :
420 1 : OK (GrB_free (&A)) ;
421 1 : OK (GrB_free (&B)) ;
422 1 : teardown ( ) ;
423 1 : }
424 :
425 : //-----------------------------------------------------------------------------
426 : // test_MMWrite: test LAGraph_MMWrite
427 : //-----------------------------------------------------------------------------
428 :
429 : const char* files_for_MMWrite [ ] =
430 : {
431 : "west0067.mtx",
432 : "full.mtx",
433 : "cover.mtx",
434 : ""
435 : } ;
436 :
437 1 : void test_MMWrite (void)
438 : {
439 :
440 : //--------------------------------------------------------------------------
441 : // start up the test
442 : //--------------------------------------------------------------------------
443 :
444 1 : setup ( ) ;
445 :
446 1 : for (int k = 0 ; ; k++)
447 3 : {
448 :
449 : //----------------------------------------------------------------------
450 : // load in the kth file
451 : //----------------------------------------------------------------------
452 :
453 4 : const char *aname = files_for_MMWrite [k] ;
454 4 : if (strlen (aname) == 0) break;
455 3 : TEST_CASE (aname) ;
456 3 : printf ("\n============= %2d: %s\n", k, aname) ;
457 3 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
458 3 : FILE *f = fopen (filename, "r") ;
459 3 : TEST_CHECK (f != NULL) ;
460 3 : OK (LAGraph_MMRead (&A, f, msg)) ;
461 3 : OK (fclose (f)) ;
462 3 : TEST_MSG ("Failed to load %s\n", aname) ;
463 3 : OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
464 :
465 : //----------------------------------------------------------------------
466 : // create a file for comments
467 : //----------------------------------------------------------------------
468 :
469 3 : FILE *fcomments = fopen (LG_DATA_DIR "comments.txt", "wb") ;
470 3 : TEST_CHECK (fcomments != NULL) ;
471 3 : fprintf (fcomments, " comments for %s\n", aname) ;
472 3 : fprintf (fcomments, " this file was created by test_MMRead.c\n") ;
473 3 : fclose (fcomments) ;
474 3 : TEST_MSG ("Failed to create comments.txt") ;
475 :
476 : //----------------------------------------------------------------------
477 : // write the matrix to the data/comments_*.mtx file
478 : //----------------------------------------------------------------------
479 :
480 3 : snprintf (filename, LEN, LG_DATA_DIR "comments_%s", aname) ;
481 3 : fcomments = fopen (LG_DATA_DIR "comments.txt", "r") ;
482 3 : FILE *foutput = fopen (filename, "wb") ;
483 3 : TEST_CHECK (foutput != NULL) ;
484 3 : TEST_CHECK (fcomments != NULL) ;
485 3 : OK (LAGraph_MMWrite (A, foutput, fcomments, msg)) ;
486 3 : fclose (fcomments) ;
487 3 : fclose (foutput) ;
488 3 : TEST_MSG ("Failed to create %s", filename) ;
489 :
490 : //----------------------------------------------------------------------
491 : // load in the data/comments_.mtx file as the matrix B
492 : //----------------------------------------------------------------------
493 :
494 3 : f = fopen (filename, "r") ;
495 3 : TEST_CHECK (f != NULL) ;
496 3 : OK (LAGraph_MMRead (&B, f, msg)) ;
497 :
498 3 : OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
499 3 : TEST_CHECK (MATCHNAME (atype_name, btype_name)) ;
500 3 : OK (fclose (f)) ;
501 3 : TEST_MSG ("Loading of %s failed", filename) ;
502 :
503 : //----------------------------------------------------------------------
504 : // ensure A and B are the same
505 : //----------------------------------------------------------------------
506 :
507 : bool ok ;
508 3 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
509 3 : TEST_CHECK (ok) ;
510 3 : TEST_MSG ("Test for A and B equal failed: %s", filename) ;
511 :
512 : //----------------------------------------------------------------------
513 : // write a nan
514 : //----------------------------------------------------------------------
515 :
516 3 : if (k == 0)
517 : {
518 1 : OK (GrB_Matrix_setElement (A, NAN, 0, 0)) ;
519 : double a ;
520 1 : OK (GrB_Matrix_extractElement (&a, A, 0, 0)) ;
521 1 : TEST_CHECK (isnan (a)) ;
522 1 : foutput = fopen (filename, "wb") ;
523 1 : fcomments = fopen (LG_DATA_DIR "comments.txt", "r") ;
524 1 : TEST_CHECK (foutput != NULL) ;
525 1 : OK (LAGraph_MMWrite (A, foutput, fcomments, msg)) ;
526 1 : fclose (fcomments) ;
527 1 : fclose (foutput) ;
528 1 : OK (GrB_free (&A)) ;
529 1 : f = fopen (filename, "r") ;
530 1 : TEST_CHECK (f != NULL) ;
531 1 : OK (LAGraph_MMRead (&A, f, msg)) ;
532 1 : fclose (f) ;
533 1 : a = 0 ;
534 1 : OK (GrB_Matrix_extractElement (&a, A, 0, 0)) ;
535 1 : TEST_CHECK (isnan (a)) ;
536 : }
537 :
538 : //----------------------------------------------------------------------
539 : // free workspace
540 : //----------------------------------------------------------------------
541 :
542 3 : OK (GrB_free (&A)) ;
543 3 : OK (GrB_free (&B)) ;
544 : }
545 :
546 : //--------------------------------------------------------------------------
547 : // finish the test
548 : //--------------------------------------------------------------------------
549 :
550 1 : teardown ( ) ;
551 1 : }
552 :
553 : //-----------------------------------------------------------------------------
554 : // test_MMWrite_failures: test error handling of LAGraph_MMWrite
555 : //-----------------------------------------------------------------------------
556 :
557 : typedef int mytype ;
558 :
559 1 : void test_MMWrite_failures (void)
560 : {
561 1 : setup ( ) ;
562 1 : GrB_Type atype = NULL ;
563 1 : printf ("\nTesting error handling of LAGraph_MMWrite\n") ;
564 :
565 : // input arguments are NULL
566 1 : TEST_CHECK (LAGraph_MMWrite (NULL, NULL, NULL, msg) == GrB_NULL_POINTER) ;
567 1 : printf ("msg: [%s]\n", msg) ;
568 :
569 : // attempt to print a matrix with a user-defined type, which should fail
570 1 : FILE *f = tmpfile ( ) ;
571 1 : TEST_CHECK (f != NULL) ;
572 1 : OK (GrB_Type_new (&atype, sizeof (mytype))) ;
573 1 : OK (GrB_Matrix_new (&A, atype, 4, 4)) ;
574 1 : int status = LAGraph_Matrix_Print (A, LAGraph_COMPLETE, stdout, msg) ;
575 1 : printf ("msg: [%s]\n", msg) ;
576 1 : TEST_CHECK (status == GrB_NOT_IMPLEMENTED) ;
577 1 : status = LAGraph_MMWrite (A, f, NULL, msg) ;
578 1 : printf ("msg: %d [%s]\n", status, msg) ;
579 1 : TEST_CHECK (status == GrB_NOT_IMPLEMENTED) ;
580 1 : OK (GrB_free (&atype)) ;
581 1 : OK (GrB_free (&A)) ;
582 1 : OK (fclose (f)) ; // close and delete the temporary file
583 :
584 1 : teardown ( ) ;
585 1 : }
586 :
587 : //------------------------------------------------------------------------------
588 : // test_MMReadWrite_brutal
589 : //------------------------------------------------------------------------------
590 :
591 : #if LG_BRUTAL_TESTS
592 1 : void test_MMReadWrite_brutal (void)
593 : {
594 :
595 : //--------------------------------------------------------------------------
596 : // start up the test
597 : //--------------------------------------------------------------------------
598 :
599 1 : OK (LG_brutal_setup (msg)) ;
600 :
601 1 : for (int k = 0 ; ; k++)
602 51 : {
603 :
604 : //----------------------------------------------------------------------
605 : // load in the kth file
606 : //----------------------------------------------------------------------
607 :
608 52 : const char *aname = files [k].name ;
609 52 : if (strlen (aname) == 0) break;
610 51 : TEST_CASE (aname) ;
611 51 : printf ("\n============= %2d: %s\n", k, aname) ;
612 51 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
613 51 : FILE *f = fopen (filename, "r") ;
614 51 : TEST_CHECK (f != NULL) ;
615 51 : OK (LAGraph_MMRead (&A, f, msg)) ;
616 51 : OK (fclose (f)) ;
617 51 : TEST_MSG ("Failed to load %s\n", aname) ;
618 51 : printf ("\n") ;
619 :
620 : //----------------------------------------------------------------------
621 : // write it to a temporary file
622 : //----------------------------------------------------------------------
623 :
624 51 : for (int nbrutal = 0 ; ; nbrutal++)
625 1258 : {
626 : /* allow for only nbrutal mallocs before 'failing' */
627 1309 : printf (".") ;
628 1309 : LG_brutal = nbrutal ;
629 : /* try the method with brutal malloc */
630 1309 : f = tmpfile ( ) ; // create a new temp file for each trial
631 1309 : int brutal_result = LAGraph_MMWrite (A, f, NULL, msg) ;
632 1309 : if (brutal_result >= 0)
633 : {
634 : /* the method finally succeeded */
635 : // leave the file open for the next phase
636 51 : printf (" MMWrite ok: %d mallocs\n", nbrutal) ;
637 51 : break ;
638 : }
639 1258 : OK (fclose (f)) ; // close and delete the file and try again
640 1258 : if (nbrutal > 10000) { printf ("Infinite!\n") ; abort ( ) ; }
641 : }
642 51 : LG_brutal = -1 ; /* turn off brutal mallocs */
643 :
644 : //----------------------------------------------------------------------
645 : // load it back in again
646 : //----------------------------------------------------------------------
647 :
648 51 : for (int nbrutal = 0 ; ; nbrutal++)
649 679 : {
650 : /* allow for only nbrutal mallocs before 'failing' */
651 730 : printf (".") ;
652 730 : LG_brutal = nbrutal ;
653 : /* try the method with brutal malloc */
654 730 : rewind (f) ; // rewind the temp file for each trial
655 730 : int brutal_result = LAGraph_MMRead (&B, f, msg) ;
656 730 : if (brutal_result >= 0)
657 : {
658 : /* the method finally succeeded */
659 51 : printf (" MMRead ok: %d mallocs\n", nbrutal) ;
660 51 : OK (fclose (f)) ; // finally close and delete the temp file
661 51 : break ;
662 : }
663 679 : if (nbrutal > 10000) { printf ("Infinite!\n") ; abort ( ) ; }
664 : }
665 51 : LG_brutal = -1 ; /* turn off brutal mallocs */
666 :
667 : //----------------------------------------------------------------------
668 : // ensure A and B are the same
669 : //----------------------------------------------------------------------
670 :
671 51 : OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
672 51 : OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
673 51 : TEST_CHECK (MATCHNAME (atype_name, btype_name)) ;
674 :
675 : bool ok ;
676 51 : OK (GrB_Matrix_wait (A, GrB_MATERIALIZE)) ;
677 51 : OK (GrB_Matrix_wait (B, GrB_MATERIALIZE)) ;
678 325 : LG_BRUTAL (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
679 51 : TEST_CHECK (ok) ;
680 51 : TEST_MSG ("Failed test for equality, file: %s\n", aname) ;
681 :
682 : //----------------------------------------------------------------------
683 : // free workspace
684 : //----------------------------------------------------------------------
685 :
686 51 : OK (GrB_free (&A)) ;
687 51 : OK (GrB_free (&B)) ;
688 : }
689 :
690 : //--------------------------------------------------------------------------
691 : // finish the test
692 : //--------------------------------------------------------------------------
693 :
694 1 : OK (LG_brutal_teardown (msg)) ;
695 1 : }
696 : #endif
697 :
698 : //------------------------------------------------------------------------------
699 : // test_array_pattern
700 : //------------------------------------------------------------------------------
701 :
702 1 : void test_array_pattern (void)
703 : {
704 :
705 : //--------------------------------------------------------------------------
706 : // start up the test
707 : //--------------------------------------------------------------------------
708 :
709 1 : OK (LG_brutal_setup (msg)) ;
710 :
711 : //--------------------------------------------------------------------------
712 : // construct a dense 3-by-3 matrix of all 1's (iso-valued)
713 : //--------------------------------------------------------------------------
714 :
715 1 : OK (GrB_Matrix_new (&A, GrB_INT64, 3, 3)) ;
716 1 : OK (GrB_Matrix_assign_INT64 (A, NULL, NULL, 1, GrB_ALL, 3, GrB_ALL, 3,
717 : NULL)) ;
718 1 : OK (GrB_Matrix_wait (A, GrB_MATERIALIZE)) ;
719 1 : printf ("\nA matrix:\n") ;
720 1 : OK (LAGraph_Matrix_Print (A, LAGraph_COMPLETE, stdout, msg)) ;
721 :
722 : //--------------------------------------------------------------------------
723 : // write it to a temporary file
724 : //--------------------------------------------------------------------------
725 :
726 1 : FILE *f = tmpfile ( ) ; // fopen ("/tmp/mine.mtx", "wb") ;
727 1 : OK (LAGraph_MMWrite (A, f, NULL, msg)) ;
728 1 : TEST_MSG ("Failed to write matrix to a temp file\n") ;
729 : // OK (fclose (f)) ;
730 :
731 : //--------------------------------------------------------------------------
732 : // load it back in again
733 : //--------------------------------------------------------------------------
734 :
735 1 : rewind (f) ;
736 : // f = fopen ("/tmp/mine.mtx", "r") ;
737 1 : OK (LAGraph_MMRead (&B, f, msg)) ;
738 1 : TEST_MSG ("Failed to load matrix from a temp file\n") ;
739 1 : OK (fclose (f)) ; // close and delete the temporary file
740 :
741 1 : printf ("\nB matrix:\n") ;
742 1 : OK (LAGraph_Matrix_Print (B, LAGraph_COMPLETE, stdout, msg)) ;
743 :
744 : //--------------------------------------------------------------------------
745 : // ensure A and B are the same
746 : //--------------------------------------------------------------------------
747 :
748 1 : OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
749 1 : TEST_CHECK (MATCHNAME ("int64_t", btype_name)) ;
750 : bool ok ;
751 1 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
752 1 : TEST_CHECK (ok) ;
753 1 : TEST_MSG ("Failed test for equality, dense 3-by-3\n") ;
754 :
755 : //--------------------------------------------------------------------------
756 : // finish the test
757 : //--------------------------------------------------------------------------
758 :
759 1 : OK (GrB_free (&A)) ;
760 1 : OK (GrB_free (&B)) ;
761 :
762 1 : OK (LG_brutal_teardown (msg)) ;
763 1 : }
764 :
765 : //-----------------------------------------------------------------------------
766 : // TEST_LIST: the list of tasks for this entire test
767 : //-----------------------------------------------------------------------------
768 :
769 : TEST_LIST =
770 : {
771 : { "MMRead", test_MMRead },
772 : { "karate", test_karate },
773 : { "MMRead_failures", test_MMRead_failures },
774 : { "jumbled", test_jumbled },
775 : { "MMWrite", test_MMWrite },
776 : { "MMWrite_failures", test_MMWrite_failures },
777 : #if LG_BRUTAL_TESTS
778 : { "MMReadWrite_brutal", test_MMReadWrite_brutal },
779 : #endif
780 : { "array_pattern", test_array_pattern },
781 : { NULL, NULL }
782 : } ;
|