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