Line data Source code
1 : //------------------------------------------------------------------------------
2 : // LAGraph/src/test/test_minmax.c: test LAGraph_Cached_EMin/EMax
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 ;
29 : LAGraph_Graph G = NULL ;
30 : const char *name ;
31 : #define LEN 512
32 : char filename [LEN+1] ;
33 : char atype_name [LAGRAPH_MAX_NAME_LEN] ;
34 :
35 : //------------------------------------------------------------------------------
36 : // test matrices
37 : //------------------------------------------------------------------------------
38 :
39 : typedef struct
40 : {
41 : double emin ;
42 : double emax ;
43 : const char *name ;
44 : }
45 : matrix_info ;
46 :
47 : const matrix_info files [ ] =
48 : {
49 : // amin amax name
50 : { 1, 1, "A2.mtx" } ,
51 : { 1, 1, "A.mtx" } ,
52 : { -583929119292, 1191785641270, "bcsstk13.mtx" } ,
53 : { 1, 9, "comments_cover.mtx" } ,
54 : { 0.118, 0.754, "comments_full.mtx" } ,
55 : { -1.863354, 1.863354, "comments_west0067.mtx" } ,
56 : { 1, 9, "cover.mtx" } ,
57 : { 1, 1, "cover_structure.mtx" } ,
58 : { -5679.837539484813, 4615.532487504805, "cryg2500.mtx" } ,
59 : { 0, 0, "empty.mtx" } ,
60 : { 0.118, 0.754, "full.mtx" } ,
61 : { 0.118, 0.754, "full_noheader.mtx" } ,
62 : { 3.9635860919952393, 28.239410400390625, "full_symmetric.mtx" } ,
63 : { 1, 1, "jagmesh7.mtx" } ,
64 : { 1, 1, "karate.mtx" } ,
65 : { 1, 1, "ldbc-cdlp-directed-example.mtx" } ,
66 : { 1, 1, "ldbc-cdlp-undirected-example.mtx" } ,
67 : { 1, 1, "ldbc-directed-example-bool.mtx" } ,
68 : { 0.1, 0.83, "ldbc-directed-example.mtx" } ,
69 : { 1, 1, "ldbc-directed-example-unweighted.mtx" } ,
70 : { 1, 1, "ldbc-undirected-example-bool.mtx" } ,
71 : { 0.12, 0.9, "ldbc-undirected-example.mtx" } ,
72 : { 1, 1, "ldbc-undirected-example-unweighted.mtx" } ,
73 : { 1, 1, "ldbc-wcc-example.mtx" } ,
74 : { -6283200, 12566400, "LFAT5.mtx" } ,
75 : { -6283200, 12566400, "LFAT5_two.mtx" } ,
76 : { -1.06, 2.429, "lp_afiro.mtx" } ,
77 : { 1, 1, "lp_afiro_structure.mtx" } ,
78 : { 0, 1, "matrix_bool.mtx" } ,
79 : { -INFINITY, INFINITY, "matrix_fp32.mtx" } ,
80 : { 1, 1, "matrix_fp32_structure.mtx" } ,
81 : { -INFINITY, INFINITY, "matrix_fp64.mtx" } ,
82 : { -32768, 32767, "matrix_int16.mtx" } ,
83 : { -2147483648.0, 2147483647, "matrix_int32.mtx" } ,
84 : { -128, 127, "matrix_int8.mtx" } ,
85 : { 0, 65535, "matrix_uint16.mtx" } ,
86 : { 0, 4294967295, "matrix_uint32.mtx" } ,
87 : { 0, 255, "matrix_uint8.mtx" } ,
88 : { 1, 1, "msf1.mtx" } ,
89 : { 1, 6, "msf2.mtx" } ,
90 : { 1, 2, "msf3.mtx" } ,
91 : { -45777.0931, 22888.5466, "olm1000.mtx" } ,
92 : { 1, 1, "pushpull.mtx" } ,
93 : { 1, 1, "sample2.mtx" } ,
94 : { 1, 1, "sample.mtx" } ,
95 : { -INFINITY, INFINITY, "skew_fp32.mtx" } ,
96 : { -INFINITY, INFINITY, "skew_fp64.mtx" } ,
97 : { -30000, 30000, "skew_int16.mtx" } ,
98 : { -30000000, 30000000, "skew_int32.mtx" } ,
99 : { -125, 125, "skew_int8.mtx" } ,
100 : { 1, 7, "sources_7.mtx" } ,
101 : { 1, 1, "structure.mtx" } ,
102 : { 1, 9, "test_BF.mtx" } ,
103 : { 0, 457, "test_FW_1000.mtx" } ,
104 : { 1, 214, "test_FW_2003.mtx" } ,
105 : { 1, 5679, "test_FW_2500.mtx" } ,
106 : { 1, 1, "tree-example.mtx" } ,
107 : { -1.863354, 1.863354, "west0067_jumbled.mtx" } ,
108 : { -1.863354, 1.863354, "west0067.mtx" } ,
109 : { -1.863354, 1.863354, "west0067_noheader.mtx" } ,
110 : { 0, 1.4055985944, "zenios.mtx" } ,
111 : { 0, 0, "" }
112 : } ;
113 :
114 : // additional files (cast to double is not accurate):
115 :
116 : typedef struct
117 : {
118 : int64_t emin ;
119 : int64_t emax ;
120 : const char *name ;
121 : }
122 : matrix_info_int64 ;
123 :
124 : const matrix_info_int64 files_int64 [ ] =
125 : {
126 : { -9223372036854775800L, 9223372036854775807L, "matrix_int64.mtx" } ,
127 : { -9223372036854775807L, 9223372036854775807L, "skew_int64.mtx" } ,
128 : { 0, 0, "" }
129 : } ;
130 :
131 : typedef struct
132 : {
133 : uint64_t emin ;
134 : uint64_t emax ;
135 : const char *name ;
136 : }
137 : matrix_info_uint64 ;
138 :
139 : const matrix_info_uint64 files_uint64 [ ] =
140 : {
141 : { 0, 18446744073709551615UL, "matrix_uint64.mtx" } ,
142 : { 0, 0, "" }
143 : } ;
144 :
145 : //------------------------------------------------------------------------------
146 : // setup: start a test
147 : //------------------------------------------------------------------------------
148 :
149 4 : void setup (void)
150 : {
151 4 : OK (LAGraph_Init (msg)) ;
152 4 : }
153 :
154 : //------------------------------------------------------------------------------
155 : // teardown: finalize a test
156 : //------------------------------------------------------------------------------
157 :
158 4 : void teardown (void)
159 : {
160 4 : OK (LAGraph_Finalize (msg)) ;
161 4 : }
162 :
163 : //------------------------------------------------------------------------------
164 : // test_minmax: read a set of matrices and compute min/max
165 : //------------------------------------------------------------------------------
166 :
167 1 : void test_minmax (void)
168 : {
169 :
170 : //--------------------------------------------------------------------------
171 : // start up the test
172 : //--------------------------------------------------------------------------
173 :
174 1 : setup ( ) ;
175 :
176 1 : for (int k = 0 ; ; k++)
177 61 : {
178 :
179 : //----------------------------------------------------------------------
180 : // load in the kth file and create the graph G
181 : //----------------------------------------------------------------------
182 :
183 62 : const char *aname = files [k].name ;
184 62 : if (strlen (aname) == 0) break;
185 61 : TEST_CASE (aname) ;
186 61 : printf ("\n============= %2d: %s\n", k, aname) ;
187 61 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
188 61 : FILE *f = fopen (filename, "rb") ;
189 61 : TEST_CHECK (f != NULL) ;
190 61 : OK (LAGraph_MMRead (&A, f, msg)) ;
191 61 : OK (fclose (f)) ;
192 61 : TEST_MSG ("Failed to load %s\n", aname) ;
193 : GrB_Index nvals ;
194 61 : OK (GrB_Matrix_nvals (&nvals, A)) ;
195 61 : OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ;
196 :
197 : //----------------------------------------------------------------------
198 : // compute emin and emax
199 : //----------------------------------------------------------------------
200 :
201 61 : OK (LAGraph_Cached_EMin (G, msg)) ;
202 61 : TEST_CHECK (G->emin_state == LAGraph_VALUE) ;
203 61 : OK (LAGraph_Cached_EMax (G, msg)) ;
204 61 : TEST_CHECK (G->emax_state == LAGraph_VALUE) ;
205 :
206 : //----------------------------------------------------------------------
207 : // check the result
208 : //----------------------------------------------------------------------
209 :
210 61 : double emin1 = files [k].emin ;
211 61 : double emax1 = files [k].emax ;
212 61 : double emin2 = 0 ;
213 61 : double emax2 = 0 ;
214 :
215 61 : printf ("min/max as GrB_Scalars:\n") ;
216 61 : GxB_print (G->emin, 3) ;
217 61 : GxB_print (G->emax, 3) ;
218 :
219 : int result ;
220 61 : result = GrB_Scalar_extractElement_FP64 (&emin2, G->emin) ;
221 61 : printf ("min: %g %g err %g\n", emin1, emin2, emin1 - emin2) ;
222 61 : if (nvals == 0)
223 : {
224 1 : TEST_CHECK (result == GrB_NO_VALUE) ;
225 : }
226 : else
227 : {
228 60 : TEST_CHECK (result == GrB_SUCCESS) ;
229 : }
230 :
231 : #if 0
232 : if (emin1 != emin2)
233 : {
234 : // failure on MSVC, OpenMP
235 : // https://github.com/DrTimothyAldenDavis/SuiteSparse/actions/runs/6763376325/job/18380420493?pr=503
236 : // now fixed.
237 : printf ("Test failure, k: %d name: %s\n", k, aname) ;
238 : printf ("emin1: %30.20g\n", emin1) ;
239 : printf ("emin2: %30.20g\n", emin2) ;
240 : OK (LAGraph_Matrix_Print (G->A, 5, stdout, msg)) ;
241 :
242 : // extract as int64:
243 : int64_t emin2_int64 = 0 ;
244 : int64_t emax2_int64 = 0 ;
245 : GrB_Scalar_extractElement_INT64 (&emin2_int64, G->emin) ;
246 : GrB_Scalar_extractElement_INT64 (&emax2_int64, G->emax) ;
247 : printf ("emin2 int64: %" PRId64 "\n", emin2_int64) ;
248 : printf ("emax2 int64: %" PRId64 "\n", emax2_int64) ;
249 :
250 : }
251 : #endif
252 :
253 61 : TEST_CHECK (emin1 == emin2) ;
254 :
255 61 : result = GrB_Scalar_extractElement_FP64 (&emax2, G->emax) ;
256 61 : printf ("max: %g %g err %g\n", emax1, emax2, emax1 - emax2) ;
257 61 : if (nvals == 0)
258 : {
259 1 : printf ("no entries\n") ;
260 1 : TEST_CHECK (result == GrB_NO_VALUE) ;
261 : }
262 : else
263 : {
264 60 : TEST_CHECK (result == GrB_SUCCESS) ;
265 : }
266 61 : TEST_CHECK (emax1 == emax2) ;
267 :
268 61 : OK (LAGraph_Delete (&G, msg)) ;
269 : }
270 :
271 : //--------------------------------------------------------------------------
272 : // finish the test
273 : //--------------------------------------------------------------------------
274 :
275 1 : teardown ( ) ;
276 1 : }
277 :
278 : //------------------------------------------------------------------------------
279 : // test_minmax_int64: read a set of matrices and compute min/max
280 : //------------------------------------------------------------------------------
281 :
282 1 : void test_minmax_int64 (void)
283 : {
284 :
285 : //--------------------------------------------------------------------------
286 : // start up the test
287 : //--------------------------------------------------------------------------
288 :
289 1 : setup ( ) ;
290 :
291 1 : for (int k = 0 ; ; k++)
292 2 : {
293 :
294 : //----------------------------------------------------------------------
295 : // load in the kth file and create the graph G
296 : //----------------------------------------------------------------------
297 :
298 3 : const char *aname = files_int64 [k].name ;
299 3 : if (strlen (aname) == 0) break;
300 2 : TEST_CASE (aname) ;
301 2 : printf ("\n============= %2d: %s\n", k, aname) ;
302 2 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
303 2 : FILE *f = fopen (filename, "rb") ;
304 2 : TEST_CHECK (f != NULL) ;
305 2 : OK (LAGraph_MMRead (&A, f, msg)) ;
306 2 : OK (fclose (f)) ;
307 2 : TEST_MSG ("Failed to load %s\n", aname) ;
308 : GrB_Index nvals ;
309 2 : OK (GrB_Matrix_nvals (&nvals, A)) ;
310 2 : OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ;
311 :
312 6 : for (int trial = 1 ; trial <= 2 ; trial++)
313 : {
314 :
315 : //------------------------------------------------------------------
316 : // compute emin and emax
317 : //------------------------------------------------------------------
318 :
319 4 : OK (LAGraph_Cached_EMin (G, msg)) ;
320 4 : TEST_CHECK (G->emin_state == LAGraph_VALUE) ;
321 4 : OK (LAGraph_Cached_EMax (G, msg)) ;
322 4 : TEST_CHECK (G->emax_state == LAGraph_VALUE) ;
323 :
324 : //------------------------------------------------------------------
325 : // check the result
326 : //------------------------------------------------------------------
327 :
328 4 : int64_t emin1 = files_int64 [k].emin ;
329 4 : int64_t emax1 = files_int64 [k].emax ;
330 4 : int64_t emin2 = 0 ;
331 4 : int64_t emax2 = 0 ;
332 :
333 : int result ;
334 4 : result = GrB_Scalar_extractElement_INT64 (&emin2, G->emin) ;
335 4 : printf ("min (int64): %" PRId64" %" PRId64 "\n", emin1, emin2) ;
336 4 : TEST_CHECK (result == GrB_SUCCESS) ;
337 4 : TEST_CHECK (emin1 == emin2) ;
338 :
339 4 : result = GrB_Scalar_extractElement_INT64 (&emax2, G->emax) ;
340 4 : printf ("max (int64): %" PRId64" %" PRId64 "\n", emax1, emax2) ;
341 4 : TEST_CHECK (result == GrB_SUCCESS) ;
342 4 : TEST_CHECK (emax1 == emax2) ;
343 : }
344 :
345 2 : OK (LAGraph_Delete (&G, msg)) ;
346 : }
347 :
348 : //--------------------------------------------------------------------------
349 : // finish the test
350 : //--------------------------------------------------------------------------
351 :
352 1 : teardown ( ) ;
353 1 : }
354 :
355 : //------------------------------------------------------------------------------
356 : // test_minmax_uint64: read a set of matrices and compute min/max
357 : //------------------------------------------------------------------------------
358 :
359 1 : void test_minmax_uint64 (void)
360 : {
361 :
362 : //--------------------------------------------------------------------------
363 : // start up the test
364 : //--------------------------------------------------------------------------
365 :
366 1 : setup ( ) ;
367 :
368 1 : for (int k = 0 ; ; k++)
369 1 : {
370 :
371 : //----------------------------------------------------------------------
372 : // load in the kth file and create the graph G
373 : //----------------------------------------------------------------------
374 :
375 2 : const char *aname = files_uint64 [k].name ;
376 2 : if (strlen (aname) == 0) break;
377 1 : TEST_CASE (aname) ;
378 1 : printf ("\n============= %2d: %s\n", k, aname) ;
379 1 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
380 1 : FILE *f = fopen (filename, "rb") ;
381 1 : TEST_CHECK (f != NULL) ;
382 1 : OK (LAGraph_MMRead (&A, f, msg)) ;
383 1 : OK (fclose (f)) ;
384 1 : TEST_MSG ("Failed to load %s\n", aname) ;
385 : GrB_Index nvals ;
386 1 : OK (GrB_Matrix_nvals (&nvals, A)) ;
387 1 : OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ;
388 :
389 : //----------------------------------------------------------------------
390 : // compute emin and emax
391 : //----------------------------------------------------------------------
392 :
393 1 : OK (LAGraph_Cached_EMin (G, msg)) ;
394 1 : TEST_CHECK (G->emin_state == LAGraph_VALUE) ;
395 1 : OK (LAGraph_Cached_EMax (G, msg)) ;
396 1 : TEST_CHECK (G->emax_state == LAGraph_VALUE) ;
397 :
398 : //----------------------------------------------------------------------
399 : // check the result
400 : //----------------------------------------------------------------------
401 :
402 1 : uint64_t emin1 = files_uint64 [k].emin ;
403 1 : uint64_t emax1 = files_uint64 [k].emax ;
404 1 : uint64_t emin2 = 0 ;
405 1 : uint64_t emax2 = 0 ;
406 :
407 : int result ;
408 1 : result = GrB_Scalar_extractElement_UINT64 (&emin2, G->emin) ;
409 1 : printf ("min (uint64): %" PRIu64" %" PRIu64 "\n", emin1, emin2) ;
410 1 : TEST_CHECK (result == GrB_SUCCESS) ;
411 1 : TEST_CHECK (emin1 == emin2) ;
412 :
413 1 : result = GrB_Scalar_extractElement_UINT64 (&emax2, G->emax) ;
414 1 : printf ("max (uint64): %" PRIu64" %" PRIu64 "\n", emax1, emax2) ;
415 1 : TEST_CHECK (result == GrB_SUCCESS) ;
416 1 : TEST_CHECK (emax1 == emax2) ;
417 :
418 1 : OK (LAGraph_Delete (&G, msg)) ;
419 : }
420 :
421 : //--------------------------------------------------------------------------
422 : // finish the test
423 : //--------------------------------------------------------------------------
424 :
425 1 : teardown ( ) ;
426 1 : }
427 :
428 : //-----------------------------------------------------------------------------
429 : // test_minmax_failures
430 : //-----------------------------------------------------------------------------
431 :
432 : typedef int myint ;
433 :
434 1 : void test_minmax_failures (void)
435 : {
436 1 : setup ( ) ;
437 : GrB_Type MyInt ;
438 1 : OK (GrB_Type_new (&MyInt, sizeof (myint))) ;
439 1 : OK (GrB_Matrix_new (&A, MyInt, 4, 4)) ;
440 1 : OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ;
441 1 : int result = LAGraph_Cached_EMax (G, msg) ;
442 1 : printf ("\nresult: %d msg: %s\n", result, msg) ;
443 1 : TEST_CHECK (result == GrB_NOT_IMPLEMENTED) ;
444 1 : result = LAGraph_Cached_EMin (G, msg) ;
445 1 : printf ("result: %d msg: %s\n", result, msg) ;
446 1 : TEST_CHECK (result == GrB_NOT_IMPLEMENTED) ;
447 1 : OK (GrB_free (&MyInt)) ;
448 1 : OK (LAGraph_Delete (&G, msg)) ;
449 1 : teardown ( ) ;
450 1 : }
451 :
452 : //-----------------------------------------------------------------------------
453 : // TEST_LIST: the list of tasks for this entire test
454 : //-----------------------------------------------------------------------------
455 :
456 : TEST_LIST =
457 : {
458 : { "test_minmax", test_minmax },
459 : { "test_minmax_int64", test_minmax_int64 },
460 : { "test_minmax_uint64", test_minmax_uint64 },
461 : { "test_minmax_failures", test_minmax_failures },
462 : { NULL, NULL }
463 : } ;
|