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