Line data Source code
1 : //----------------------------------------------------------------------------
2 : // LAGraph/src/test/test_SWrite.c: test cases for LAGraph_SWrite and SRead
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 <stdio.h>
19 : #include <acutest.h>
20 : #include <LAGraphX.h>
21 : #include <LAGraph_test.h>
22 :
23 : char msg [LAGRAPH_MSG_LEN] ;
24 : LAGraph_Graph G = NULL ;
25 : GrB_Matrix A = NULL ;
26 : GrB_Matrix B = NULL ;
27 : GrB_Matrix *S = NULL ;
28 :
29 : #define LEN 512
30 : char filename [LEN+1] ;
31 :
32 : GrB_Type atype = NULL ;
33 : char atypename [LAGRAPH_MAX_NAME_LEN] ;
34 :
35 : #define NFILES 51
36 : const char *files [ ] =
37 : {
38 : "A.mtx",
39 : "cover.mtx",
40 : "cover_structure.mtx",
41 : "jagmesh7.mtx",
42 : "ldbc-cdlp-directed-example.mtx",
43 : "ldbc-cdlp-undirected-example.mtx",
44 : "ldbc-directed-example-bool.mtx",
45 : "ldbc-directed-example.mtx",
46 : "ldbc-directed-example-unweighted.mtx",
47 : "ldbc-undirected-example-bool.mtx",
48 : "ldbc-undirected-example.mtx",
49 : "ldbc-undirected-example-unweighted.mtx",
50 : "ldbc-wcc-example.mtx",
51 : "LFAT5.mtx",
52 : "msf1.mtx",
53 : "msf2.mtx",
54 : "msf3.mtx",
55 : "sample2.mtx",
56 : "sample.mtx",
57 : "sources_7.mtx",
58 : "olm1000.mtx",
59 : "bcsstk13.mtx",
60 : "cryg2500.mtx",
61 : "tree-example.mtx",
62 : "west0067.mtx",
63 : "lp_afiro.mtx",
64 : "lp_afiro_structure.mtx",
65 : "karate.mtx",
66 : "matrix_bool.mtx",
67 : "matrix_int8.mtx",
68 : "matrix_int16.mtx",
69 : "matrix_int32.mtx",
70 : "matrix_int64.mtx",
71 : "matrix_uint8.mtx",
72 : "matrix_uint16.mtx",
73 : "matrix_uint32.mtx",
74 : "matrix_uint64.mtx",
75 : "matrix_fp32.mtx",
76 : "matrix_fp32_structure.mtx",
77 : "matrix_fp64.mtx",
78 : "west0067_jumbled.mtx",
79 : "skew_fp32.mtx",
80 : "skew_fp64.mtx",
81 : "skew_int8.mtx",
82 : "skew_int16.mtx",
83 : "skew_int32.mtx",
84 : "skew_int64.mtx",
85 : "structure.mtx",
86 : "full.mtx",
87 : "full_symmetric.mtx",
88 : "empty.mtx",
89 : "",
90 : } ;
91 :
92 : //****************************************************************************
93 :
94 1 : void test_SWrite (void)
95 : {
96 1 : LAGraph_Init (msg) ;
97 1 : GrB_Descriptor desc = NULL ;
98 : #if LAGRAPH_SUITESPARSE
99 1 : OK (GrB_Descriptor_new (&desc)) ;
100 1 : OK (GxB_set (desc, GxB_COMPRESSION, GxB_COMPRESSION_LZ4HC + 9)) ;
101 : #endif
102 :
103 52 : for (int k = 0 ; k < NFILES ; k++)
104 : {
105 :
106 : // load the matrix as A
107 51 : const char *aname = files [k] ;
108 51 : if (strlen (aname) == 0) break;
109 51 : printf ("\n================================== %d %s:\n", k, aname) ;
110 51 : TEST_CASE (aname) ;
111 51 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
112 51 : FILE *f = fopen (filename, "r") ;
113 51 : TEST_CHECK (f != NULL) ;
114 51 : OK (LAGraph_MMRead (&A, f, msg)) ;
115 51 : fclose (f) ;
116 : // GxB_print (A, 3) ;
117 :
118 : // get the name of the C typedef for the matrix
119 51 : OK (LAGraph_Matrix_TypeName (atypename, A, msg)) ;
120 51 : OK (LAGraph_TypeFromName (&atype, atypename, msg)) ;
121 :
122 : #if LAGRAPH_SUITESPARSE
123 255 : for (int scon = 1 ; scon <= 8 ; scon = 2*scon)
124 : #endif
125 : {
126 : #if LAGRAPH_SUITESPARSE
127 : // for SuiteSparse only: test all sparsity formats
128 204 : OK (GxB_set (A, GxB_SPARSITY_CONTROL, scon)) ;
129 : #endif
130 :
131 : // workaround for bug in v6.0.0 to v6.0.2:
132 : // ensure the matrix is not iso
133 : #if LAGRAPH_SUITESPARSE
134 : #if GxB_IMPLEMENTATION < GxB_VERSION (6,0,3)
135 : printf ("workaround for bug in SS:GrB v6.0.2 (fixed in v6.0.3)\n") ;
136 : OK (GrB_Matrix_setElement (A, 0, 0, 0)) ;
137 : OK (GrB_wait (A, GrB_MATERIALIZE)) ;
138 : #endif
139 : #endif
140 :
141 : // open a temporary *.lagraph file to hold the matrix
142 204 : f = tmpfile ( ) ;
143 : // snprintf (filename, LEN, "%s.lagraph", aname) ;
144 : // f = fopen (filename, "w") ;
145 204 : TEST_CHECK (f != NULL) ;
146 :
147 : // serialize the matrix
148 : // GxB_set (GxB_BURBLE, true) ;
149 204 : void *blob = NULL ;
150 204 : GrB_Index blob_size = 0 ;
151 : #if LAGRAPH_SUITESPARSE
152 204 : if (k % 2 == 0)
153 : {
154 : // for SuiteSparse: try GxB for every other matrix
155 104 : OK (GxB_Matrix_serialize (&blob, &blob_size, A, desc)) ;
156 : }
157 : else
158 : #endif
159 : {
160 : // try GrB version
161 100 : OK (GrB_Matrix_serializeSize (&blob_size, A)) ;
162 100 : GrB_Index blob_size_old = blob_size ;
163 100 : OK (LAGraph_Malloc ((void **) &blob, blob_size,
164 : sizeof (uint8_t), msg)) ;
165 100 : TEST_CHECK (blob != NULL) ;
166 100 : OK (GrB_Matrix_serialize (blob, &blob_size, A)) ;
167 100 : OK (LAGraph_Realloc ((void **) &blob, blob_size,
168 : blob_size_old, sizeof (uint8_t), msg)) ;
169 : }
170 :
171 : // deserialize the matrix
172 204 : int rr = (GrB_Matrix_deserialize (&B, atype, blob, blob_size)) ;
173 : // printf ("A:\n") ; GxB_print (A, 2) ;
174 : // printf ("B:\n") ; GxB_print (B, 2) ;
175 : // printf ("rr: %d\n", rr) ;
176 204 : OK (rr) ;
177 : // GxB_set (GxB_BURBLE, false) ;
178 :
179 : // ensure the matrices A and B are the same
180 : // GxB_print (A,3) ;
181 : // GxB_print (B,3) ;
182 204 : bool ok = false ;
183 204 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
184 204 : TEST_CHECK (ok) ;
185 204 : OK (GrB_free (&B)) ;
186 :
187 : // write the header for a single matrix
188 204 : OK (LAGraph_SWrite_HeaderStart (f, "lagraph_test", msg)) ;
189 204 : OK (LAGraph_SWrite_HeaderItem (f, LAGraph_matrix_kind, "A",
190 : atypename, 0, blob_size, msg)) ;
191 204 : OK (LAGraph_SWrite_HeaderEnd (f, msg)) ;
192 :
193 : // write the binary blob to the file then free the blob
194 204 : OK (LAGraph_SWrite_Item (f, blob, blob_size, msg)) ;
195 204 : LAGraph_Free (&blob, NULL) ;
196 :
197 : // open the file and load back the contents
198 204 : rewind (f) ;
199 : // fclose (f) ;
200 : // f = fopen (filename, "r") ;
201 :
202 204 : char *collection = NULL ;
203 204 : LAGraph_Contents *Contents = NULL ;
204 : GrB_Index ncontents ;
205 204 : OK (LAGraph_SRead (f, &collection, &Contents, &ncontents, msg)) ;
206 204 : TEST_CHECK (collection != NULL) ;
207 204 : if (collection == NULL) abort ( ) ;
208 : // printf ("collection %s\n", collection) ;
209 204 : TEST_CHECK (strcmp (collection, "lagraph_test") == 0) ;
210 204 : TEST_CHECK (ncontents == 1) ;
211 204 : fclose (f) ;
212 :
213 : // convert the contents to a matrix B
214 204 : void *blob2 = Contents [0].blob ;
215 204 : size_t blob_size2 = Contents [0].blob_size ;
216 : // printf ("blob_size2 %lu\n", blob_size2) ;
217 204 : TEST_CHECK (blob_size == blob_size2) ;
218 :
219 204 : OK (GrB_Matrix_deserialize (&B, atype, blob2, blob_size2)) ;
220 : // GxB_set (GxB_BURBLE, false) ;
221 :
222 : // ensure the matrices A and B are the same
223 : // GxB_print (A,3) ;
224 : // GxB_print (B,3) ;
225 204 : OK (LAGraph_Matrix_IsEqual (&ok, A, B, msg)) ;
226 204 : TEST_CHECK (ok) ;
227 204 : OK (GrB_free (&B)) ;
228 :
229 : // free the contents: todo make this a utility function
230 204 : LAGraph_Free ((void **) &collection, NULL) ;
231 408 : for (int i = 0 ; i < ncontents ; i++)
232 : {
233 204 : LAGraph_Contents *Item = &(Contents [i]) ;
234 204 : LAGraph_Free ((void **) &(Item->blob), NULL) ;
235 : }
236 204 : LAGraph_Free ((void **) &Contents, NULL) ;
237 : }
238 :
239 51 : OK (GrB_free (&A)) ;
240 : }
241 :
242 1 : OK (GrB_free (&desc)) ;
243 1 : LAGraph_Finalize (msg) ;
244 1 : }
245 :
246 : //------------------------------------------------------------------------------
247 :
248 1 : void test_SWrite_errors (void)
249 : {
250 1 : LAGraph_Init (msg) ;
251 :
252 : // create a simple test matrix
253 1 : GrB_Index n = 5 ;
254 1 : OK (GrB_Matrix_new (&A, GrB_FP32, n, n)) ;
255 1 : OK (GrB_assign (A, NULL, NULL, 0, GrB_ALL, n, GrB_ALL, n, NULL)) ;
256 1 : OK (GrB_apply (A, NULL, NULL, GrB_ROWINDEX_INT64, A, 0, NULL)) ;
257 1 : printf ("\nTest matrix:\n") ;
258 1 : OK (LAGraph_Matrix_Print (A, LAGraph_COMPLETE, stdout, msg)) ;
259 :
260 : // serialize the matrix
261 : bool ok ;
262 1 : void *blob = NULL ;
263 1 : GrB_Index blob_size = 0 ;
264 : #if LAGRAPH_SUITESPARSE
265 : {
266 : // for SuiteSparse
267 1 : OK (GxB_Matrix_serialize (&blob, &blob_size, A, NULL)) ;
268 : }
269 : #else
270 : {
271 : // use GrB version
272 : OK (GrB_Matrix_serializeSize (&blob_size, A)) ;
273 : GrB_Index blob_size_old = blob_size ;
274 : OK (LAGraph_Malloc ((void **) &blob, blob_size, sizeof (uint8_t), msg));
275 : TEST_CHECK (blob != NULL) ;
276 : OK (GrB_Matrix_serialize (blob, &blob_size, A)) ;
277 : OK (LAGraph_Realloc ((void **) &blob, blob_size,
278 : blob_size_old, sizeof (uint8_t), msg)) ;
279 : }
280 : #endif
281 :
282 1 : FILE *f = tmpfile ( ) ;
283 1 : TEST_CHECK (f != NULL) ;
284 :
285 1 : int result = LAGraph_SWrite_HeaderItem (f, -2, "A",
286 : "float", 0, blob_size, msg) ;
287 1 : printf ("result: %d [%s]\n", result, msg) ;
288 1 : TEST_CHECK (result == GrB_INVALID_VALUE) ;
289 1 : fclose (f) ;
290 :
291 1 : f = fopen ("error.lagraph", "wb") ;
292 1 : TEST_CHECK (f != NULL) ;
293 :
294 1 : result = LAGraph_SWrite_HeaderStart (f, NULL, msg) ;
295 1 : TEST_CHECK (result == GrB_NULL_POINTER) ;
296 :
297 1 : result = LAGraph_SWrite_HeaderStart (NULL, "stuff", msg) ;
298 1 : TEST_CHECK (result == GrB_NULL_POINTER) ;
299 :
300 1 : OK (LAGraph_SWrite_HeaderStart (f, "lagraph_test", msg)) ;
301 :
302 1 : result = LAGraph_SWrite_HeaderItem (NULL, LAGraph_matrix_kind, "A",
303 : "float", 0, blob_size, msg) ;
304 1 : TEST_CHECK (result == GrB_NULL_POINTER) ;
305 :
306 1 : result = LAGraph_SWrite_HeaderItem (NULL, -2, "A",
307 : "float", 0, blob_size, msg) ;
308 1 : TEST_CHECK (result == GrB_NULL_POINTER) ;
309 :
310 1 : OK (LAGraph_SWrite_HeaderItem (f, LAGraph_matrix_kind, "A",
311 : "float", 0, blob_size, msg)) ;
312 :
313 1 : result = LAGraph_SWrite_HeaderEnd (NULL, msg) ;
314 1 : TEST_CHECK (result == GrB_NULL_POINTER) ;
315 :
316 1 : OK (LAGraph_SWrite_HeaderEnd (f, msg)) ;
317 :
318 : // write the binary blob to the file then free the blob
319 1 : OK (LAGraph_SWrite_Item (f, blob, blob_size, msg)) ;
320 1 : LAGraph_Free (&blob, NULL) ;
321 :
322 1 : result = LAGraph_SWrite_Item (NULL, blob, blob_size, msg) ;
323 1 : TEST_CHECK (result == GrB_NULL_POINTER) ;
324 :
325 1 : result = LAGraph_SWrite_Item (f, NULL, blob_size, msg) ;
326 1 : TEST_CHECK (result == GrB_NULL_POINTER) ;
327 :
328 : // close the file and reopen it
329 1 : fclose (f) ;
330 1 : f = fopen ("error.lagraph", "r") ;
331 1 : TEST_CHECK (f != NULL) ;
332 :
333 : // load in the matrix
334 1 : GrB_Matrix *Set = NULL ;
335 1 : GrB_Index nmatrices = 0 ;
336 1 : char *collection = NULL ;
337 :
338 1 : result = LAGraph_SLoadSet ("error.lagraph", NULL, &nmatrices,
339 : &collection, msg) ;
340 1 : TEST_CHECK (result == GrB_NULL_POINTER) ;
341 :
342 1 : result = LAGraph_SLoadSet ("unknown.lagraph", &Set, &nmatrices,
343 : &collection, msg) ;
344 1 : printf ("\nresult %d, [%s]\n", result, msg) ;
345 1 : TEST_CHECK (result == -1002) ;
346 :
347 : // mangled file
348 1 : result = LAGraph_SLoadSet (LG_DATA_DIR "garbage.lagraph",
349 : &Set, &nmatrices, &collection, msg) ;
350 1 : printf ("\nresult %d, [%s]\n", result, msg) ;
351 1 : TEST_CHECK (result == LAGRAPH_IO_ERROR) ;
352 :
353 : // finally works
354 1 : OK (LAGraph_SLoadSet ("error.lagraph", &Set, &nmatrices, &collection,
355 : msg)) ;
356 1 : TEST_CHECK (Set != NULL) ;
357 1 : TEST_CHECK (collection != NULL) ;
358 1 : TEST_CHECK (nmatrices == 1) ;
359 :
360 1 : ok = false ;
361 1 : OK (LAGraph_Matrix_IsEqual (&ok, A, Set [0], msg)) ;
362 1 : TEST_CHECK (ok) ;
363 :
364 : // free everything
365 1 : LAGraph_SFreeSet (&Set, nmatrices) ;
366 1 : LAGraph_Free ((void **) &collection, NULL) ;
367 1 : fclose (f) ;
368 :
369 : // read garbage with LAGraph_SRead
370 1 : f = fopen (LG_DATA_DIR "garbage.lagraph", "r") ;
371 1 : TEST_CHECK (f != NULL) ;
372 1 : LAGraph_Contents *Contents = NULL ;
373 1 : GrB_Index ncontents = 0 ;
374 1 : result = LAGraph_SRead (f, &collection, &Contents, &ncontents, msg) ;
375 1 : TEST_CHECK (result = -1001) ;
376 1 : TEST_CHECK (collection == NULL) ;
377 1 : TEST_CHECK (Contents == NULL) ;
378 1 : TEST_CHECK (ncontents == 0) ;
379 1 : fclose (f) ;
380 :
381 1 : OK (GrB_free (&A)) ;
382 1 : LAGraph_Finalize (msg) ;
383 1 : }
384 :
385 : //****************************************************************************
386 :
387 : TEST_LIST = {
388 : {"SWrite", test_SWrite},
389 : {"SWrite_errors", test_SWrite_errors},
390 : {NULL, NULL}
391 : };
|