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 : const char *name, *date ;
30 : int 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 : #if LAGRAPH_SUITESPARSE
118 6 : OK (GxB_get (GxB_LIBRARY_NAME, &name)) ;
119 6 : OK (GxB_get (GxB_LIBRARY_DATE, &date)) ;
120 6 : OK (GxB_get (GxB_LIBRARY_VERSION, ver)) ;
121 : #endif
122 6 : }
123 :
124 : //------------------------------------------------------------------------------
125 : // teardown: finalize a test
126 : //------------------------------------------------------------------------------
127 :
128 6 : void teardown (void)
129 : {
130 : #if LAGRAPH_SUITESPARSE
131 6 : printf ("\n%s %d.%d.%d (%s)\n", name, ver [0], ver [1], ver [2], date) ;
132 : #endif
133 6 : OK (GrB_free (&A)) ;
134 6 : OK (GrB_free (&B)) ;
135 6 : TEST_CHECK (A == NULL) ;
136 6 : TEST_CHECK (B == NULL) ;
137 6 : OK (LAGraph_Finalize (msg)) ;
138 6 : }
139 :
140 : //------------------------------------------------------------------------------
141 : // test_MMRead: read a set of matrices, check their stats, and write them out
142 : //------------------------------------------------------------------------------
143 :
144 1 : void test_MMRead (void)
145 : {
146 :
147 : //--------------------------------------------------------------------------
148 : // start up the test
149 : //--------------------------------------------------------------------------
150 :
151 1 : setup ( ) ;
152 :
153 1 : for (int k = 0 ; ; k++)
154 51 : {
155 :
156 : //----------------------------------------------------------------------
157 : // load in the kth file
158 : //----------------------------------------------------------------------
159 :
160 52 : const char *aname = files [k].name ;
161 52 : if (strlen (aname) == 0) break;
162 51 : TEST_CASE (aname) ;
163 51 : printf ("\n============= %2d: %s\n", k, aname) ;
164 51 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
165 51 : FILE *f = fopen (filename, "r") ;
166 51 : TEST_CHECK (f != NULL) ;
167 51 : OK (LAGraph_MMRead (&A, f, msg)) ;
168 51 : OK (fclose (f)) ;
169 51 : TEST_MSG ("Failed to load %s\n", aname) ;
170 :
171 : //----------------------------------------------------------------------
172 : // check its stats
173 : //----------------------------------------------------------------------
174 :
175 51 : OK (GrB_Matrix_nrows (&nrows, A)) ;
176 51 : OK (GrB_Matrix_ncols (&ncols, A)) ;
177 51 : OK (GrB_Matrix_nvals (&nvals, A)) ;
178 51 : TEST_CHECK (nrows == files [k].nrows) ;
179 51 : TEST_CHECK (ncols == files [k].ncols) ;
180 51 : TEST_CHECK (nvals == files [k].nvals) ;
181 :
182 51 : OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
183 51 : printf ("types: [%s] [%s]\n", atype_name, files [k].type) ;
184 51 : TEST_CHECK (MATCHNAME (atype_name, files [k].type)) ;
185 51 : TEST_MSG ("Stats are wrong for %s\n", aname) ;
186 :
187 : //----------------------------------------------------------------------
188 : // pretty-print the matrix
189 : //----------------------------------------------------------------------
190 :
191 204 : for (int pr = 0 ; pr <= 2 ; pr++)
192 : {
193 153 : printf ("\nPretty-print %s: pr=%d:\n", aname, pr) ;
194 153 : LAGraph_PrintLevel prl = pr ;
195 153 : OK (LAGraph_Matrix_Print (A, prl, stdout, msg)) ;
196 : }
197 :
198 : //----------------------------------------------------------------------
199 : // write it to a temporary file
200 : //----------------------------------------------------------------------
201 :
202 51 : f = tmpfile ( ) ;
203 51 : OK (LAGraph_MMWrite (A, f, NULL, msg)) ;
204 51 : TEST_MSG ("Failed to write %s to a temp file\n", aname) ;
205 :
206 : //----------------------------------------------------------------------
207 : // load it back in again
208 : //----------------------------------------------------------------------
209 :
210 51 : rewind (f) ;
211 51 : OK (LAGraph_MMRead (&B, f, msg)) ;
212 51 : TEST_MSG ("Failed to load %s from a temp file\n", aname) ;
213 51 : OK (fclose (f)) ; // close and delete the temporary file
214 :
215 : //----------------------------------------------------------------------
216 : // ensure A and B are the same
217 : //----------------------------------------------------------------------
218 :
219 51 : OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
220 51 : TEST_CHECK (MATCHNAME (atype_name, btype_name)) ;
221 : bool ok ;
222 51 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
223 51 : TEST_CHECK (ok) ;
224 51 : TEST_MSG ("Failed test for equality, file: %s\n", aname) ;
225 :
226 : //----------------------------------------------------------------------
227 : // free workspace
228 : //----------------------------------------------------------------------
229 :
230 51 : OK (GrB_free (&A)) ;
231 51 : OK (GrB_free (&B)) ;
232 : }
233 :
234 : //--------------------------------------------------------------------------
235 : // finish the test
236 : //--------------------------------------------------------------------------
237 :
238 1 : teardown ( ) ;
239 1 : }
240 :
241 : //-----------------------------------------------------------------------------
242 : // test_karate: read in karate graph from a file and compare it known graph
243 : //-----------------------------------------------------------------------------
244 :
245 1 : void test_karate (void)
246 : {
247 :
248 : //--------------------------------------------------------------------------
249 : // start up the test
250 : //--------------------------------------------------------------------------
251 :
252 1 : setup ( ) ;
253 :
254 : //--------------------------------------------------------------------------
255 : // load in the data/karate.mtx file as the matrix A
256 : //--------------------------------------------------------------------------
257 :
258 1 : FILE *f = fopen (LG_DATA_DIR "karate.mtx", "r") ;
259 1 : TEST_CHECK (f != NULL) ;
260 1 : OK (LAGraph_MMRead (&A, f, msg)) ;
261 1 : OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
262 1 : TEST_CHECK (MATCHNAME (atype_name, "bool")) ;
263 1 : OK (fclose (f)) ;
264 1 : OK (LAGraph_Matrix_Print (A, LAGraph_SHORT, stdout, msg)) ;
265 1 : TEST_MSG ("Loading of A matrix failed: karate matrix") ;
266 :
267 : //--------------------------------------------------------------------------
268 : // load in the matrix defined by graph_zachary_karate.h as the matrix B
269 : //--------------------------------------------------------------------------
270 :
271 1 : OK (GrB_Matrix_new (&B, GrB_BOOL, ZACHARY_NUM_NODES, ZACHARY_NUM_NODES)) ;
272 1 : OK (GrB_Matrix_build (B, ZACHARY_I, ZACHARY_J, ZACHARY_V,
273 : ZACHARY_NUM_EDGES, GrB_LOR)) ;
274 1 : OK (LAGraph_Matrix_Print (B, LAGraph_SHORT, stdout, msg)) ;
275 1 : TEST_MSG ("Loading of B matrix failed: karate matrix") ;
276 :
277 : //--------------------------------------------------------------------------
278 : // ensure A and B are the same
279 : //--------------------------------------------------------------------------
280 :
281 : bool ok ;
282 1 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
283 1 : TEST_CHECK (ok) ;
284 1 : TEST_MSG ("Test for A and B equal failed: karate matrix") ;
285 :
286 : //--------------------------------------------------------------------------
287 : // free workspace and finish the test
288 : //--------------------------------------------------------------------------
289 :
290 1 : OK (GrB_free (&A)) ;
291 1 : OK (GrB_free (&B)) ;
292 1 : teardown ( ) ;
293 1 : }
294 :
295 : //-----------------------------------------------------------------------------
296 : // test_failures: test for failure modes of LAGraph_MMRead and MMWrite
297 : //-----------------------------------------------------------------------------
298 :
299 : typedef struct
300 : {
301 : int error ;
302 : const char *name ;
303 : }
304 : mangled_matrix_info ;
305 :
306 : const mangled_matrix_info mangled_files [ ] =
307 : {
308 : // error filename how the matrix is mangled
309 : LAGRAPH_IO_ERROR, "mangled1.mtx", // bad header
310 : LAGRAPH_IO_ERROR, "mangled2.mtx", // bad header
311 : LAGRAPH_IO_ERROR, "mangled3.mtx", // bad type
312 : GrB_NOT_IMPLEMENTED, "complex.mtx", // valid complex, but not supported
313 : LAGRAPH_IO_ERROR, "mangled4.mtx", // bad format
314 : LAGRAPH_IO_ERROR, "mangled5.mtx", // invalid format options
315 : LAGRAPH_IO_ERROR, "mangled6.mtx", // invalid format options
316 : LAGRAPH_IO_ERROR, "mangled7.mtx", // invalid GraphBLAS type
317 : LAGRAPH_IO_ERROR, "mangled8.mtx", // invalid first line
318 : LAGRAPH_IO_ERROR, "mangled9.mtx", // symmetric and rectangular
319 : LAGRAPH_IO_ERROR, "mangled10.mtx", // truncated
320 : LAGRAPH_IO_ERROR, "mangled11.mtx", // entries mangled
321 : LAGRAPH_IO_ERROR, "mangled12.mtx", // entries mangled
322 : GrB_INDEX_OUT_OF_BOUNDS, "mangled13.mtx",// indices out of range
323 : GrB_INVALID_VALUE, "mangled14.mtx", // duplicate entries
324 : LAGRAPH_IO_ERROR, "mangled_bool.mtx", // entry value out of range
325 : LAGRAPH_IO_ERROR, "mangled_int8.mtx", // entry value out of range
326 : LAGRAPH_IO_ERROR, "mangled_int16.mtx", // entry value out of range
327 : LAGRAPH_IO_ERROR, "mangled_int32.mtx", // entry value out of range
328 : LAGRAPH_IO_ERROR, "mangled_uint8.mtx", // entry value out of range
329 : LAGRAPH_IO_ERROR, "mangled_uint16.mtx", // entry value out of range
330 : LAGRAPH_IO_ERROR, "mangled_uint32.mtx", // entry value out of range
331 : LAGRAPH_IO_ERROR, "mangled_skew.mtx", // unsigned skew invalid
332 : GrB_NOT_IMPLEMENTED, "mangled15.mtx", // complex not supported
333 : GrB_NOT_IMPLEMENTED, "mangled16.mtx", // complex not supported
334 : LAGRAPH_IO_ERROR, "mangled_format.mtx", // "array pattern" invalid
335 : 0, "",
336 : } ;
337 :
338 1 : void test_MMRead_failures (void)
339 : {
340 1 : setup ( ) ;
341 1 : printf ("\nTesting error handling of LAGraph_MMRead when giving it "
342 : "mangled matrices:\n") ;
343 :
344 : // input arguments are NULL
345 1 : TEST_CHECK (LAGraph_MMRead (NULL, NULL, msg) == GrB_NULL_POINTER) ;
346 1 : printf ("msg: [%s]\n", msg) ;
347 1 : TEST_CHECK (LAGraph_MMRead (&A, NULL, msg) == GrB_NULL_POINTER) ;
348 1 : printf ("msg: [%s]\n", msg) ;
349 :
350 : // matrix files are mangled in some way, or unsupported
351 1 : for (int k = 0 ; ; k++)
352 26 : {
353 27 : const char *aname = mangled_files [k].name ;
354 27 : if (strlen (aname) == 0) break;
355 26 : TEST_CASE (aname) ;
356 26 : int error = mangled_files [k].error ;
357 26 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
358 26 : printf ("file: [%s]\n", filename) ;
359 26 : FILE *f = fopen (filename, "r") ;
360 26 : TEST_CHECK (f != NULL) ;
361 26 : int status = LAGraph_MMRead (&A, f, msg) ;
362 26 : printf ("error expected: %d %d [%s]\n", error, status, msg) ;
363 26 : TEST_CHECK (status == error) ;
364 26 : OK (fclose (f)) ;
365 26 : TEST_CHECK (A == NULL) ;
366 : }
367 :
368 1 : teardown ( ) ;
369 1 : }
370 :
371 : //-----------------------------------------------------------------------------
372 : // test_jumbled: test reading a jumbled matrix
373 : //-----------------------------------------------------------------------------
374 :
375 1 : void test_jumbled (void)
376 : {
377 :
378 : //--------------------------------------------------------------------------
379 : // start up the test
380 : //--------------------------------------------------------------------------
381 :
382 1 : setup ( ) ;
383 :
384 : //--------------------------------------------------------------------------
385 : // load in the data/west0067.mtx file as the matrix A
386 : //--------------------------------------------------------------------------
387 :
388 1 : FILE *f = fopen (LG_DATA_DIR "west0067.mtx", "r") ;
389 1 : TEST_CHECK (f != NULL) ;
390 1 : OK (LAGraph_MMRead (&A, f, msg)) ;
391 1 : OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
392 1 : TEST_CHECK (MATCHNAME (atype_name, "double")) ;
393 1 : OK (fclose (f)) ;
394 1 : TEST_MSG ("Loading of west0067.mtx failed") ;
395 :
396 : //--------------------------------------------------------------------------
397 : // load in the data/west0067_jumbled.mtx file as the matrix B
398 : //--------------------------------------------------------------------------
399 :
400 1 : f = fopen (LG_DATA_DIR "west0067_jumbled.mtx", "r") ;
401 1 : TEST_CHECK (f != NULL) ;
402 1 : OK (LAGraph_MMRead (&B, f, msg)) ;
403 1 : OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
404 1 : TEST_CHECK (MATCHNAME (btype_name, "double")) ;
405 1 : OK (fclose (f)) ;
406 1 : TEST_MSG ("Loading of west0067_jumbled.mtx failed") ;
407 :
408 : //--------------------------------------------------------------------------
409 : // ensure A and B are the same
410 : //--------------------------------------------------------------------------
411 :
412 : bool ok ;
413 1 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
414 1 : TEST_CHECK (ok) ;
415 1 : TEST_MSG ("Test for A and B equal failed: west0067_jumbled.mtx matrix") ;
416 :
417 : //--------------------------------------------------------------------------
418 : // free workspace and finish the test
419 : //--------------------------------------------------------------------------
420 :
421 1 : OK (GrB_free (&A)) ;
422 1 : OK (GrB_free (&B)) ;
423 1 : teardown ( ) ;
424 1 : }
425 :
426 : //-----------------------------------------------------------------------------
427 : // test_MMWrite: test LAGraph_MMWrite
428 : //-----------------------------------------------------------------------------
429 :
430 : const char* files_for_MMWrite [ ] =
431 : {
432 : "west0067.mtx",
433 : "full.mtx",
434 : "cover.mtx",
435 : ""
436 : } ;
437 :
438 1 : void test_MMWrite (void)
439 : {
440 :
441 : //--------------------------------------------------------------------------
442 : // start up the test
443 : //--------------------------------------------------------------------------
444 :
445 1 : setup ( ) ;
446 :
447 1 : for (int k = 0 ; ; k++)
448 3 : {
449 :
450 : //----------------------------------------------------------------------
451 : // load in the kth file
452 : //----------------------------------------------------------------------
453 :
454 4 : const char *aname = files_for_MMWrite [k] ;
455 4 : if (strlen (aname) == 0) break;
456 3 : TEST_CASE (aname) ;
457 3 : printf ("\n============= %2d: %s\n", k, aname) ;
458 3 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
459 3 : FILE *f = fopen (filename, "r") ;
460 3 : TEST_CHECK (f != NULL) ;
461 3 : OK (LAGraph_MMRead (&A, f, msg)) ;
462 3 : OK (fclose (f)) ;
463 3 : TEST_MSG ("Failed to load %s\n", aname) ;
464 3 : OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
465 :
466 : //----------------------------------------------------------------------
467 : // create a file for comments
468 : //----------------------------------------------------------------------
469 :
470 3 : FILE *fcomments = fopen (LG_DATA_DIR "comments.txt", "wb") ;
471 3 : TEST_CHECK (fcomments != NULL) ;
472 3 : fprintf (fcomments, " comments for %s\n", aname) ;
473 3 : fprintf (fcomments, " this file was created by test_MMRead.c\n") ;
474 3 : fclose (fcomments) ;
475 3 : TEST_MSG ("Failed to create comments.txt") ;
476 :
477 : //----------------------------------------------------------------------
478 : // write the matrix to the data/comments_*.mtx file
479 : //----------------------------------------------------------------------
480 :
481 3 : snprintf (filename, LEN, LG_DATA_DIR "comments_%s", aname) ;
482 3 : fcomments = fopen (LG_DATA_DIR "comments.txt", "r") ;
483 3 : FILE *foutput = fopen (filename, "wb") ;
484 3 : TEST_CHECK (foutput != NULL) ;
485 3 : TEST_CHECK (fcomments != NULL) ;
486 3 : OK (LAGraph_MMWrite (A, foutput, fcomments, msg)) ;
487 3 : fclose (fcomments) ;
488 3 : fclose (foutput) ;
489 3 : TEST_MSG ("Failed to create %s", filename) ;
490 :
491 : //----------------------------------------------------------------------
492 : // load in the data/comments_.mtx file as the matrix B
493 : //----------------------------------------------------------------------
494 :
495 3 : f = fopen (filename, "r") ;
496 3 : TEST_CHECK (f != NULL) ;
497 3 : OK (LAGraph_MMRead (&B, f, msg)) ;
498 :
499 3 : OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
500 3 : TEST_CHECK (MATCHNAME (atype_name, btype_name)) ;
501 3 : OK (fclose (f)) ;
502 3 : TEST_MSG ("Loading of %s failed", filename) ;
503 :
504 : //----------------------------------------------------------------------
505 : // ensure A and B are the same
506 : //----------------------------------------------------------------------
507 :
508 : bool ok ;
509 3 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
510 3 : TEST_CHECK (ok) ;
511 3 : TEST_MSG ("Test for A and B equal failed: %s", filename) ;
512 :
513 : //----------------------------------------------------------------------
514 : // write a nan
515 : //----------------------------------------------------------------------
516 :
517 3 : if (k == 0)
518 : {
519 1 : OK (GrB_Matrix_setElement (A, NAN, 0, 0)) ;
520 : double a ;
521 1 : OK (GrB_Matrix_extractElement (&a, A, 0, 0)) ;
522 1 : TEST_CHECK (isnan (a)) ;
523 1 : foutput = fopen (filename, "wb") ;
524 1 : fcomments = fopen (LG_DATA_DIR "comments.txt", "r") ;
525 1 : TEST_CHECK (foutput != NULL) ;
526 1 : OK (LAGraph_MMWrite (A, foutput, fcomments, msg)) ;
527 1 : fclose (fcomments) ;
528 1 : fclose (foutput) ;
529 1 : OK (GrB_free (&A)) ;
530 1 : f = fopen (filename, "r") ;
531 1 : TEST_CHECK (f != NULL) ;
532 1 : OK (LAGraph_MMRead (&A, f, msg)) ;
533 1 : fclose (f) ;
534 1 : a = 0 ;
535 1 : OK (GrB_Matrix_extractElement (&a, A, 0, 0)) ;
536 1 : TEST_CHECK (isnan (a)) ;
537 : }
538 :
539 : //----------------------------------------------------------------------
540 : // free workspace
541 : //----------------------------------------------------------------------
542 :
543 3 : OK (GrB_free (&A)) ;
544 3 : OK (GrB_free (&B)) ;
545 : }
546 :
547 : //--------------------------------------------------------------------------
548 : // finish the test
549 : //--------------------------------------------------------------------------
550 :
551 1 : teardown ( ) ;
552 1 : }
553 :
554 : //-----------------------------------------------------------------------------
555 : // test_MMWrite_failures: test error handling of LAGraph_MMWrite
556 : //-----------------------------------------------------------------------------
557 :
558 : typedef int mytype ;
559 :
560 1 : void test_MMWrite_failures (void)
561 : {
562 1 : setup ( ) ;
563 1 : GrB_Type atype = NULL ;
564 1 : printf ("\nTesting error handling of LAGraph_MMWrite\n") ;
565 :
566 : // input arguments are NULL
567 1 : TEST_CHECK (LAGraph_MMWrite (NULL, NULL, NULL, msg) == GrB_NULL_POINTER) ;
568 1 : printf ("msg: [%s]\n", msg) ;
569 :
570 : // attempt to print a matrix with a user-defined type, which should fail
571 1 : FILE *f = tmpfile ( ) ;
572 1 : TEST_CHECK (f != NULL) ;
573 1 : OK (GrB_Type_new (&atype, sizeof (mytype))) ;
574 1 : OK (GrB_Matrix_new (&A, atype, 4, 4)) ;
575 1 : int status = LAGraph_Matrix_Print (A, LAGraph_COMPLETE, stdout, msg) ;
576 1 : printf ("msg: [%s]\n", msg) ;
577 1 : TEST_CHECK (status == GrB_NOT_IMPLEMENTED) ;
578 1 : status = LAGraph_MMWrite (A, f, NULL, msg) ;
579 1 : printf ("msg: %d [%s]\n", status, msg) ;
580 1 : TEST_CHECK (status == GrB_NOT_IMPLEMENTED) ;
581 1 : OK (GrB_free (&atype)) ;
582 1 : OK (GrB_free (&A)) ;
583 1 : OK (fclose (f)) ; // close and delete the temporary file
584 :
585 1 : teardown ( ) ;
586 1 : }
587 :
588 : //------------------------------------------------------------------------------
589 : // test_MMReadWrite_brutal
590 : //------------------------------------------------------------------------------
591 :
592 : #if LAGRAPH_SUITESPARSE
593 1 : void test_MMReadWrite_brutal (void)
594 : {
595 :
596 : //--------------------------------------------------------------------------
597 : // start up the test
598 : //--------------------------------------------------------------------------
599 :
600 1 : OK (LG_brutal_setup (msg)) ;
601 :
602 1 : for (int k = 0 ; ; k++)
603 51 : {
604 :
605 : //----------------------------------------------------------------------
606 : // load in the kth file
607 : //----------------------------------------------------------------------
608 :
609 52 : const char *aname = files [k].name ;
610 52 : if (strlen (aname) == 0) break;
611 51 : TEST_CASE (aname) ;
612 51 : printf ("\n============= %2d: %s\n", k, aname) ;
613 51 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
614 51 : FILE *f = fopen (filename, "r") ;
615 51 : TEST_CHECK (f != NULL) ;
616 51 : OK (LAGraph_MMRead (&A, f, msg)) ;
617 51 : OK (fclose (f)) ;
618 51 : TEST_MSG ("Failed to load %s\n", aname) ;
619 51 : printf ("\n") ;
620 :
621 : //----------------------------------------------------------------------
622 : // write it to a temporary file
623 : //----------------------------------------------------------------------
624 :
625 51 : for (int nbrutal = 0 ; ; nbrutal++)
626 1220 : {
627 : /* allow for only nbrutal mallocs before 'failing' */
628 1271 : printf (".") ;
629 1271 : LG_brutal = nbrutal ;
630 : /* try the method with brutal malloc */
631 1271 : f = tmpfile ( ) ; // create a new temp file for each trial
632 1271 : int brutal_result = LAGraph_MMWrite (A, f, NULL, msg) ;
633 1271 : if (brutal_result >= 0)
634 : {
635 : /* the method finally succeeded */
636 : // leave the file open for the next phase
637 51 : printf (" MMWrite ok: %d mallocs\n", nbrutal) ;
638 51 : break ;
639 : }
640 1220 : OK (fclose (f)) ; // close and delete the file and try again
641 1220 : if (nbrutal > 10000) { printf ("Infinite!\n") ; abort ( ) ; }
642 : }
643 51 : LG_brutal = -1 ; /* turn off brutal mallocs */
644 :
645 : //----------------------------------------------------------------------
646 : // load it back in again
647 : //----------------------------------------------------------------------
648 :
649 51 : for (int nbrutal = 0 ; ; nbrutal++)
650 688 : {
651 : /* allow for only nbrutal mallocs before 'failing' */
652 739 : printf (".") ;
653 739 : LG_brutal = nbrutal ;
654 : /* try the method with brutal malloc */
655 739 : rewind (f) ; // rewind the temp file for each trial
656 739 : int brutal_result = LAGraph_MMRead (&B, f, msg) ;
657 739 : if (brutal_result >= 0)
658 : {
659 : /* the method finally succeeded */
660 51 : printf (" MMRead ok: %d mallocs\n", nbrutal) ;
661 51 : OK (fclose (f)) ; // finally close and delete the temp file
662 51 : break ;
663 : }
664 688 : if (nbrutal > 10000) { printf ("Infinite!\n") ; abort ( ) ; }
665 : }
666 51 : LG_brutal = -1 ; /* turn off brutal mallocs */
667 :
668 : //----------------------------------------------------------------------
669 : // ensure A and B are the same
670 : //----------------------------------------------------------------------
671 :
672 51 : OK (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
673 51 : OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
674 51 : TEST_CHECK (MATCHNAME (atype_name, btype_name)) ;
675 :
676 : bool ok ;
677 51 : OK (GrB_Matrix_wait (A, GrB_MATERIALIZE)) ;
678 51 : OK (GrB_Matrix_wait (B, GrB_MATERIALIZE)) ;
679 325 : LG_BRUTAL (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
680 51 : TEST_CHECK (ok) ;
681 51 : TEST_MSG ("Failed test for equality, file: %s\n", aname) ;
682 :
683 : //----------------------------------------------------------------------
684 : // free workspace
685 : //----------------------------------------------------------------------
686 :
687 51 : OK (GrB_free (&A)) ;
688 51 : OK (GrB_free (&B)) ;
689 : }
690 :
691 : //--------------------------------------------------------------------------
692 : // finish the test
693 : //--------------------------------------------------------------------------
694 :
695 1 : OK (LG_brutal_teardown (msg)) ;
696 1 : }
697 : #endif
698 :
699 : //------------------------------------------------------------------------------
700 : // test_array_pattern
701 : //------------------------------------------------------------------------------
702 :
703 1 : void test_array_pattern ( )
704 : {
705 :
706 : //--------------------------------------------------------------------------
707 : // start up the test
708 : //--------------------------------------------------------------------------
709 :
710 1 : OK (LG_brutal_setup (msg)) ;
711 :
712 : //--------------------------------------------------------------------------
713 : // construct a dense 3-by-3 matrix of all 1's (iso-valued)
714 : //--------------------------------------------------------------------------
715 :
716 1 : OK (GrB_Matrix_new (&A, GrB_INT64, 3, 3)) ;
717 1 : OK (GrB_Matrix_assign_INT64 (A, NULL, NULL, 1, GrB_ALL, 3, GrB_ALL, 3,
718 : NULL)) ;
719 1 : OK (GrB_Matrix_wait (A, GrB_MATERIALIZE)) ;
720 1 : printf ("\nA matrix:\n") ;
721 1 : OK (LAGraph_Matrix_Print (A, LAGraph_COMPLETE, stdout, msg)) ;
722 :
723 : //--------------------------------------------------------------------------
724 : // write it to a temporary file
725 : //--------------------------------------------------------------------------
726 :
727 1 : FILE *f = tmpfile ( ) ; // fopen ("/tmp/mine.mtx", "wb") ;
728 1 : OK (LAGraph_MMWrite (A, f, NULL, msg)) ;
729 1 : TEST_MSG ("Failed to write matrix to a temp file\n") ;
730 : // OK (fclose (f)) ;
731 :
732 : //--------------------------------------------------------------------------
733 : // load it back in again
734 : //--------------------------------------------------------------------------
735 :
736 1 : rewind (f) ;
737 : // f = fopen ("/tmp/mine.mtx", "r") ;
738 1 : OK (LAGraph_MMRead (&B, f, msg)) ;
739 1 : TEST_MSG ("Failed to load matrix from a temp file\n") ;
740 1 : OK (fclose (f)) ; // close and delete the temporary file
741 :
742 1 : printf ("\nB matrix:\n") ;
743 1 : OK (LAGraph_Matrix_Print (B, LAGraph_COMPLETE, stdout, msg)) ;
744 :
745 : //--------------------------------------------------------------------------
746 : // ensure A and B are the same
747 : //--------------------------------------------------------------------------
748 :
749 1 : OK (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
750 1 : TEST_CHECK (MATCHNAME ("int64_t", btype_name)) ;
751 : bool ok ;
752 1 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
753 1 : TEST_CHECK (ok) ;
754 1 : TEST_MSG ("Failed test for equality, dense 3-by-3\n") ;
755 :
756 : //--------------------------------------------------------------------------
757 : // finish the test
758 : //--------------------------------------------------------------------------
759 :
760 1 : OK (GrB_free (&A)) ;
761 1 : OK (GrB_free (&B)) ;
762 :
763 1 : OK (LG_brutal_teardown (msg)) ;
764 1 : }
765 :
766 : //-----------------------------------------------------------------------------
767 : // TEST_LIST: the list of tasks for this entire test
768 : //-----------------------------------------------------------------------------
769 :
770 : TEST_LIST =
771 : {
772 : { "MMRead", test_MMRead },
773 : { "karate", test_karate },
774 : { "MMRead_failures", test_MMRead_failures },
775 : { "jumbled", test_jumbled },
776 : { "MMWrite", test_MMWrite },
777 : { "MMWrite_failures", test_MMWrite_failures },
778 : #if LAGRAPH_SUITESPARSE
779 : { "MMReadWrite_brutal", test_MMReadWrite_brutal },
780 : #endif
781 : { "array_pattern", test_array_pattern },
782 : { NULL, NULL }
783 : } ;
|