Line data Source code
1 : //------------------------------------------------------------------------------
2 : // LAGraph_MMWrite: write a matrix to a Matrix Market file
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 : // LAGraph_MMWrite: write a matrix to a Matrix Market file.
19 :
20 : // Writes a matrix to a file in the Matrix Market format. See LAGraph_MMRead
21 : // for a description of the format.
22 :
23 : // The Matrix Market format is described at:
24 : // https://math.nist.gov/MatrixMarket/formats.html
25 :
26 : // Parts of this code are from SuiteSparse/CHOLMOD/Check/cholmod_write.c, and
27 : // are used here by permission of the author of CHOLMOD/Check (T. A. Davis).
28 :
29 : #include "LG_internal.h"
30 :
31 : #undef LG_FREE_WORK
32 : #define LG_FREE_WORK \
33 : { \
34 : LAGraph_Free ((void **) &I, NULL) ; \
35 : LAGraph_Free ((void **) &J, NULL) ; \
36 : LAGraph_Free ((void **) &K, NULL) ; \
37 : LAGraph_Free ((void **) &X, NULL) ; \
38 : GrB_free (&AT) ; \
39 : GrB_free (&M) ; \
40 : GrB_free (&C) ; \
41 : }
42 :
43 : #undef LG_FREE_ALL
44 : #define LG_FREE_ALL LG_FREE_WORK
45 :
46 : //------------------------------------------------------------------------------
47 : // print_double
48 : //------------------------------------------------------------------------------
49 :
50 : // Print a double value to the file, using the shortest format that ensures the
51 : // value is written precisely. Returns true if successful, false if an I/O
52 : // error occurred.
53 :
54 120798 : static bool print_double
55 : (
56 : FILE *f, // file to print to
57 : double x // value to print
58 : )
59 : {
60 :
61 : char s [MAXLINE], *p ;
62 120798 : int64_t i, dest = 0, src = 0 ;
63 : int width, ok ;
64 :
65 : //--------------------------------------------------------------------------
66 : // handle Inf and NaN
67 : //--------------------------------------------------------------------------
68 :
69 120798 : if (isnan (x))
70 : {
71 1 : return (fprintf (f, "nan") > 0) ;
72 : }
73 120797 : if (isinf (x))
74 : {
75 12 : return (fprintf (f, (x < 0) ? "-inf" : "inf") > 0) ;
76 : }
77 :
78 : //--------------------------------------------------------------------------
79 : // find the smallest acceptable precision
80 : //--------------------------------------------------------------------------
81 :
82 869437 : for (width = 6 ; width < 20 ; width++)
83 : {
84 : double y ;
85 869437 : sprintf (s, "%.*g", width, x) ;
86 869437 : sscanf (s, "%lg", &y) ;
87 869437 : if (x == y) break ;
88 : }
89 :
90 : //--------------------------------------------------------------------------
91 : // shorten the string
92 : //--------------------------------------------------------------------------
93 :
94 : // change "e+0" to "e", change "e+" to "e", and change "e-0" to "e-"
95 1774378 : for (i = 0 ; i < MAXLINE && s [i] != '\0' ; i++)
96 : {
97 1671099 : if (s [i] == 'e')
98 : {
99 17506 : if (s [i+1] == '+')
100 : {
101 3532 : dest = i+1 ;
102 3532 : if (s [i+2] == '0')
103 : {
104 : // delete characters s[i+1] and s[i+2]
105 3324 : src = i+3 ;
106 : }
107 : else
108 : {
109 : // delete characters s[i+1]
110 208 : src = i+2 ;
111 : }
112 : }
113 13974 : else if (s [i+1] == '-')
114 : {
115 13974 : dest = i+2 ;
116 13974 : if (s [i+2] == '0')
117 : {
118 : // delete character s[i+2]
119 12258 : src = i+3 ;
120 : }
121 : else
122 : {
123 : // no change
124 1716 : break ;
125 : }
126 : }
127 31788 : while (s [src] != '\0')
128 : {
129 15998 : s [dest++] = s [src++] ;
130 : }
131 15790 : s [dest] = '\0' ;
132 15790 : break ;
133 : }
134 : }
135 :
136 : // delete the leading "0" if present and not necessary
137 120785 : p = s ;
138 120785 : s [MAXLINE-1] = '\0' ;
139 120785 : i = strlen (s) ;
140 120785 : if (i > 2 && s [0] == '0' && s [1] == '.')
141 : {
142 : // change "0.x" to ".x"
143 9359 : p = s + 1 ;
144 : }
145 111426 : else if (i > 3 && s [0] == '-' && s [1] == '0' && s [2] == '.')
146 : {
147 : // change "-0.x" to "-.x"
148 4528 : s [1] = '-' ;
149 4528 : p = s + 1 ;
150 : }
151 :
152 : #if 0
153 : // double-check
154 : i = sscanf (p, "%lg", &z) ;
155 : if (i != 1 || y != z)
156 : {
157 : // oops! something went wrong in the "e+0" edit, above.
158 : // this "cannot" happen
159 : sprintf (s, "%.*g", width, x) ;
160 : p = s ;
161 : }
162 : #endif
163 :
164 : //--------------------------------------------------------------------------
165 : // print the value to the file
166 : //--------------------------------------------------------------------------
167 :
168 120785 : return (fprintf (f, "%s", p) > 0) ;
169 : }
170 :
171 : //------------------------------------------------------------------------------
172 : // LAGraph_MMWrite: write a matrix to a MatrixMarket file
173 : //------------------------------------------------------------------------------
174 :
175 1329 : int LAGraph_MMWrite
176 : (
177 : // input:
178 : GrB_Matrix A, // matrix to write to the file
179 : FILE *f, // file to write it to, must be already open
180 : FILE *fcomments, // optional file with extra comments, may be NULL
181 : char *msg
182 : )
183 : {
184 :
185 : //--------------------------------------------------------------------------
186 : // check inputs
187 : //--------------------------------------------------------------------------
188 :
189 1329 : LG_CLEAR_MSG ;
190 1329 : void *X = NULL ;
191 1329 : GrB_Index *I = NULL, *J = NULL, *K = NULL ;
192 1329 : GrB_Matrix M = NULL, AT = NULL, C = NULL ;
193 1329 : LG_ASSERT (A != NULL, GrB_NULL_POINTER) ;
194 1328 : LG_ASSERT (f != NULL, GrB_NULL_POINTER) ;
195 :
196 : //--------------------------------------------------------------------------
197 : // determine the basic matrix properties
198 : //--------------------------------------------------------------------------
199 :
200 : GrB_Index nrows, ncols, nvals ;
201 1328 : GRB_TRY (GrB_Matrix_nrows (&nrows, A)) ;
202 1328 : GRB_TRY (GrB_Matrix_ncols (&ncols, A)) ;
203 1328 : GRB_TRY (GrB_Matrix_nvals (&nvals, A)) ;
204 1328 : GrB_Index n = nrows ;
205 :
206 : //--------------------------------------------------------------------------
207 : // determine if the matrix is dense
208 : //--------------------------------------------------------------------------
209 :
210 1328 : MM_fmt_enum MM_fmt = MM_coordinate ;
211 :
212 : // guard against integer overflow
213 1328 : if (((double) nrows * (double) ncols < (double) INT64_MAX) &&
214 1328 : (nvals == nrows * ncols))
215 : {
216 60 : MM_fmt = MM_array ;
217 : }
218 :
219 : //--------------------------------------------------------------------------
220 : // determine the entry type
221 : //--------------------------------------------------------------------------
222 :
223 : GrB_Type type ;
224 : char atype_name [LAGRAPH_MAX_NAME_LEN] ;
225 1328 : LG_TRY (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
226 1328 : LG_TRY (LAGraph_TypeFromName (&type, atype_name, msg)) ;
227 :
228 1328 : MM_type_enum MM_type = MM_integer ;
229 :
230 1328 : if (type == GrB_BOOL || type == GrB_INT8 || type == GrB_INT16 ||
231 889 : type == GrB_INT32 || type == GrB_INT64 || type == GrB_UINT8 ||
232 513 : type == GrB_UINT16 || type == GrB_UINT32 || type == GrB_UINT64)
233 : {
234 881 : MM_type = MM_integer ;
235 : }
236 447 : else if (type == GrB_FP32 || type == GrB_FP64)
237 : {
238 446 : MM_type = MM_real ;
239 : }
240 : #if 0
241 : #if LAGRAPH_SUITESPARSE
242 : else if (type == GxB_FC32 || type == GxB_FC64)
243 : {
244 : MM_type = MM_complex ;
245 : }
246 : #endif
247 : #endif
248 : else
249 : {
250 1 : LG_ASSERT_MSG (false, GrB_NOT_IMPLEMENTED, "type not supported") ;
251 : }
252 :
253 : //--------------------------------------------------------------------------
254 : // determine symmetry
255 : //--------------------------------------------------------------------------
256 :
257 1327 : MM_storage_enum MM_storage = MM_general ;
258 :
259 1327 : if (nrows == ncols)
260 : {
261 : // AT = A'
262 1803 : GRB_TRY (GrB_Matrix_new (&AT, type, n, n)) ;
263 1152 : GRB_TRY (GrB_transpose (AT, NULL, NULL, A, NULL)) ;
264 :
265 : //----------------------------------------------------------------------
266 : // check for symmetry
267 : //----------------------------------------------------------------------
268 :
269 1046 : bool isequal = false ;
270 1046 : LG_TRY (LAGraph_Matrix_IsEqual (&isequal, A, AT, msg)) ;
271 778 : if (isequal)
272 : {
273 237 : MM_storage = MM_symmetric ;
274 : }
275 :
276 : //----------------------------------------------------------------------
277 : // check for skew-symmetry
278 : //----------------------------------------------------------------------
279 :
280 : // for signed types only
281 778 : if (MM_storage == MM_general)
282 : {
283 : // select the operator
284 541 : GrB_UnaryOp op = NULL ;
285 541 : if (type == GrB_INT8 ) op = GrB_AINV_INT8 ;
286 502 : else if (type == GrB_INT16) op = GrB_AINV_INT16 ;
287 463 : else if (type == GrB_INT32) op = GrB_AINV_INT32 ;
288 388 : else if (type == GrB_INT64) op = GrB_AINV_INT64 ;
289 288 : else if (type == GrB_FP32 ) op = GrB_AINV_FP32 ;
290 249 : else if (type == GrB_FP64 ) op = GrB_AINV_FP64 ;
291 : #if 0
292 : else if (type == GxB_FC32 ) op = GxB_AINV_FC32 ;
293 : else if (type == GxB_FC64 ) op = GxB_AINV_FC64 ;
294 : #endif
295 541 : if (op != NULL)
296 : {
297 444 : GRB_TRY (GrB_apply (AT, NULL, NULL, op, AT, NULL)) ;
298 443 : LG_TRY (LAGraph_Matrix_IsEqual (&isequal, A, AT, msg)) ;
299 308 : if (isequal)
300 : {
301 102 : MM_storage = MM_skew_symmetric ;
302 : }
303 : }
304 : }
305 :
306 : //----------------------------------------------------------------------
307 : // check for Hermitian (not yet supported)
308 : //----------------------------------------------------------------------
309 :
310 : #if 0
311 : if (MM_type == MM_complex && MM_storage == MM_general)
312 : {
313 : LG_TRY (LAGraph_Matrix_IsEqualOp (&isequal, A, AT,
314 : LAGraph_HERMITIAN_ComplexFP64, msg)) ;
315 : if (isequal)
316 : {
317 : MM_storage = MM_hermitian ;
318 : }
319 : }
320 : #endif
321 :
322 642 : GrB_free (&AT) ;
323 : }
324 :
325 : //--------------------------------------------------------------------------
326 : // determine if the matrix is structural-only
327 : //--------------------------------------------------------------------------
328 :
329 676 : bool is_structural = false ;
330 676 : if (! (MM_storage == MM_skew_symmetric || MM_storage == MM_hermitian))
331 : {
332 574 : if (type == GrB_BOOL)
333 : {
334 165 : GRB_TRY (GrB_reduce (&is_structural, NULL, GrB_LAND_MONOID_BOOL,
335 : A, NULL)) ;
336 : }
337 : else
338 : {
339 409 : GRB_TRY (GrB_Matrix_new (&C, GrB_BOOL, nrows, ncols)) ;
340 320 : GrB_BinaryOp op = NULL ;
341 320 : if (type == GrB_INT8 ) op = GrB_EQ_INT8 ;
342 311 : else if (type == GrB_INT16 ) op = GrB_EQ_INT16 ;
343 302 : else if (type == GrB_INT32 ) op = GrB_EQ_INT32 ;
344 270 : else if (type == GrB_INT64 ) op = GrB_EQ_INT64 ;
345 190 : else if (type == GrB_UINT8 ) op = GrB_EQ_UINT8 ;
346 181 : else if (type == GrB_UINT16) op = GrB_EQ_UINT16 ;
347 172 : else if (type == GrB_UINT32) op = GrB_EQ_UINT32 ;
348 163 : else if (type == GrB_UINT64) op = GrB_EQ_UINT64 ;
349 154 : else if (type == GrB_FP32 ) op = GrB_EQ_FP32 ;
350 145 : else if (type == GrB_FP64 ) op = GrB_EQ_FP64 ;
351 : #if 0
352 : else if (type == GxB_FC32 ) op = GrB_EQ_FC32 ;
353 : else if (type == GxB_FC64 ) op = GrB_EQ_FC64 ;
354 : #endif
355 320 : GRB_TRY (GrB_apply (C, NULL, NULL, op, A, 1, NULL)) ;
356 257 : GRB_TRY (GrB_reduce (&is_structural, NULL, GrB_LAND_MONOID_BOOL,
357 : C, NULL)) ;
358 257 : GrB_free (&C) ;
359 : }
360 422 : if (is_structural)
361 : {
362 207 : MM_type = MM_pattern ;
363 207 : MM_fmt = MM_coordinate ;
364 : }
365 : }
366 :
367 : //--------------------------------------------------------------------------
368 : // write the Matrix Market header
369 : //--------------------------------------------------------------------------
370 :
371 524 : FPRINTF (f, "%%%%MatrixMarket matrix") ;
372 :
373 524 : switch (MM_fmt)
374 : {
375 496 : default :
376 496 : case MM_coordinate : FPRINTF (f, " coordinate") ; break ;
377 28 : case MM_array : FPRINTF (f, " array") ; break ;
378 : }
379 :
380 524 : switch (MM_type)
381 : {
382 158 : default :
383 158 : case MM_real : FPRINTF (f, " real") ; break ;
384 159 : case MM_integer : FPRINTF (f, " integer") ; break ;
385 : // case MM_complex : FPRINTF (f, " complex") ; break ;
386 207 : case MM_pattern : FPRINTF (f, " pattern") ; break ;
387 : }
388 :
389 524 : switch (MM_storage)
390 : {
391 215 : default :
392 215 : case MM_general : FPRINTF (f, " general\n") ; break ;
393 207 : case MM_symmetric : FPRINTF (f, " symmetric\n") ; break ;
394 102 : case MM_skew_symmetric : FPRINTF (f, " skew-symmetric\n") ; break ;
395 : // case MM_hermitian : FPRINTF (f, " Hermitian\n") ; break ;
396 : }
397 :
398 524 : FPRINTF (f, "%%%%GraphBLAS type ") ;
399 524 : if (type == GrB_BOOL ) { FPRINTF (f, "bool\n") ; }
400 359 : else if (type == GrB_INT8 ) { FPRINTF (f, "int8_t\n") ; }
401 335 : else if (type == GrB_INT16 ) { FPRINTF (f, "int16_t\n") ; }
402 311 : else if (type == GrB_INT32 ) { FPRINTF (f, "int32_t\n") ; }
403 270 : else if (type == GrB_INT64 ) { FPRINTF (f, "int64_t\n") ; }
404 186 : else if (type == GrB_UINT8 ) { FPRINTF (f, "uint8_t\n") ; }
405 179 : else if (type == GrB_UINT16) { FPRINTF (f, "uint16_t\n") ; }
406 172 : else if (type == GrB_UINT32) { FPRINTF (f, "uint32_t\n") ; }
407 165 : else if (type == GrB_UINT64) { FPRINTF (f, "uint64_t\n") ; }
408 158 : else if (type == GrB_FP32 ) { FPRINTF (f, "float\n") ; }
409 134 : else if (type == GrB_FP64 ) { FPRINTF (f, "double\n") ; }
410 : #if 0
411 : else if (type == GxB_FC32 ) { FPRINTF (f, "float complex\n") ; }
412 : else if (type == GxB_FC64 ) { FPRINTF (f, "double complex\n") ; }
413 : #endif
414 :
415 : #if 0
416 : if (type == GrB_BOOL ) { FPRINTF (f, "GrB_BOOL\n") ; }
417 : else if (type == GrB_INT8 ) { FPRINTF (f, "GrB_INT8\n") ; }
418 : else if (type == GrB_INT16 ) { FPRINTF (f, "GrB_INT16\n") ; }
419 : else if (type == GrB_INT32 ) { FPRINTF (f, "GrB_INT32\n") ; }
420 : else if (type == GrB_INT64 ) { FPRINTF (f, "GrB_INT64\n") ; }
421 : else if (type == GrB_UINT8 ) { FPRINTF (f, "GrB_UINT8\n") ; }
422 : else if (type == GrB_UINT16) { FPRINTF (f, "GrB_UINT16\n") ; }
423 : else if (type == GrB_UINT32) { FPRINTF (f, "GrB_UINT32\n") ; }
424 : else if (type == GrB_UINT64) { FPRINTF (f, "GrB_UINT64\n") ; }
425 : else if (type == GrB_FP32 ) { FPRINTF (f, "GrB_FP32\n") ; }
426 : else if (type == GrB_FP64 ) { FPRINTF (f, "GrB_FP64\n") ; }
427 : #if 0
428 : else if (type == GxB_FC32 ) { FPRINTF (f, "GxB_FC32\n") ; }
429 : else if (type == GxB_FC64 ) { FPRINTF (f, "GxB_FC64\n") ; }
430 : #endif
431 : #endif
432 :
433 : //--------------------------------------------------------------------------
434 : // include any additional comments
435 : //--------------------------------------------------------------------------
436 :
437 524 : if (fcomments != NULL)
438 : {
439 : char buffer [MAXLINE] ;
440 12 : while (fgets (buffer, MAXLINE-1, fcomments) != NULL)
441 : {
442 8 : FPRINTF (f, "%%%s", buffer) ;
443 : }
444 : }
445 :
446 : //--------------------------------------------------------------------------
447 : // print the first line
448 : //--------------------------------------------------------------------------
449 :
450 524 : bool is_general = (MM_storage == MM_general) ;
451 524 : GrB_Index nvals_to_print = nvals ;
452 :
453 524 : if (!is_general)
454 : {
455 : // count the entries on the diagonal
456 309 : int64_t nself_edges = 0 ;
457 309 : LG_TRY (LG_nself_edges (&nself_edges, A, msg)) ;
458 : // nvals_to_print = # of entries in tril(A), including diagonal
459 130 : nvals_to_print = nself_edges + (nvals - nself_edges) / 2 ;
460 : }
461 :
462 345 : if (MM_fmt == MM_array)
463 : {
464 : // write `nrows ncols` if the array format is used
465 19 : FPRINTF (f, "%" PRIu64 " %" PRIu64 "\n",
466 : nrows, ncols) ;
467 : }
468 : else
469 : {
470 : // otherwise write `nrows ncols nvals` for the coordinate format
471 326 : FPRINTF (f, "%" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
472 : nrows, ncols, nvals_to_print) ;
473 : }
474 :
475 345 : if (nvals_to_print == 0)
476 : {
477 : // quick return if nothing more to do
478 2 : LG_FREE_ALL ;
479 2 : return (GrB_SUCCESS) ;
480 : }
481 :
482 : //--------------------------------------------------------------------------
483 : // extract and print tuples
484 : //--------------------------------------------------------------------------
485 :
486 343 : LG_TRY (LAGraph_Malloc ((void **) &I, nvals, sizeof (GrB_Index), msg)) ;
487 293 : LG_TRY (LAGraph_Malloc ((void **) &J, nvals, sizeof (GrB_Index), msg)) ;
488 243 : LG_TRY (LAGraph_Malloc ((void **) &K, nvals, sizeof (GrB_Index), msg)) ;
489 329549 : for (int64_t k = 0 ; k < nvals ; k++)
490 : {
491 329356 : K [k] = k ;
492 : }
493 :
494 193 : GrB_Index nvals_printed = 0 ;
495 193 : bool coord = (MM_fmt == MM_coordinate) ;
496 :
497 : #define WRITE_TUPLES(ctype,is_unsigned,is_signed,is_real,is_complex) \
498 : { \
499 : ctype *X = NULL ; \
500 : LG_TRY (LAGraph_Malloc ((void **) &X, nvals, sizeof (ctype), msg)) ;\
501 : GRB_TRY (GrB_Matrix_extractTuples (I, J, X, &nvals, A)) ; \
502 : LG_TRY (LG_msort3 ((int64_t *) J, (int64_t *) I, \
503 : (int64_t *) K, nvals, msg)) ; \
504 : for (int64_t k = 0 ; k < nvals ; k++) \
505 : { \
506 : /* convert the row and column index to 1-based */ \
507 : GrB_Index i = I [k] + 1 ; \
508 : GrB_Index j = J [k] + 1 ; \
509 : ctype x = X [K [k]] ; \
510 : if (is_general || i >= j) \
511 : { \
512 : /* print the row and column index of the tuple */ \
513 : if (coord) FPRINTF (f, "%" PRIu64 " %" PRIu64 " ", i, j) ; \
514 : /* print the value of the tuple */ \
515 : if (is_structural) \
516 : { \
517 : /* print nothing */ ; \
518 : } \
519 : else if (is_unsigned) \
520 : { \
521 : FPRINTF (f, "%" PRIu64, (uint64_t) x) ; \
522 : } \
523 : else if (is_signed) \
524 : { \
525 : FPRINTF (f, "%" PRId64, (int64_t) x) ; \
526 : } \
527 : else if (is_real) \
528 : { \
529 : LG_ASSERT_MSG (print_double (f, (double) x), \
530 : LAGRAPH_IO_ERROR, "Unable to write to file") ; \
531 : } \
532 : /* else if (is_complex) */ \
533 : /* { */ \
534 : /* LG_ASSERT_MSG (print_double (f, creal (x)), */ \
535 : /* LAGRAPH_IO_ERROR, */ \
536 : /* "Unable to write to file") ; */ \
537 : /* FPRINTF (f, " ") ; */ \
538 : /* LG_ASSERT_MSG (print_double (f, cimag (x)), */ \
539 : /* LAGRAPH_IO_ERROR, */ \
540 : /* "Unable to write to file") ; */ \
541 : /* } */ \
542 : FPRINTF (f, "\n") ; \
543 : } \
544 : nvals_printed++ ; \
545 : } \
546 : LG_TRY (LAGraph_Free ((void **) &X, NULL)) ; \
547 : }
548 :
549 16069 : if (type == GrB_BOOL ) WRITE_TUPLES (bool , 1, 0, 0, 0)
550 200 : else if (type == GrB_INT8 ) WRITE_TUPLES (int8_t , 0, 1, 0, 0)
551 192 : else if (type == GrB_INT16 ) WRITE_TUPLES (int16_t , 0, 1, 0, 0)
552 244 : else if (type == GrB_INT32 ) WRITE_TUPLES (int32_t , 0, 1, 0, 0)
553 438 : else if (type == GrB_INT64 ) WRITE_TUPLES (int64_t , 0, 1, 0, 0)
554 95 : else if (type == GrB_UINT8 ) WRITE_TUPLES (uint8_t , 1, 0, 0, 0)
555 91 : else if (type == GrB_UINT16 ) WRITE_TUPLES (uint16_t, 1, 0, 0, 0)
556 87 : else if (type == GrB_UINT32 ) WRITE_TUPLES (uint32_t, 1, 0, 0, 0)
557 83 : else if (type == GrB_UINT64 ) WRITE_TUPLES (uint64_t, 1, 0, 0, 0)
558 119 : else if (type == GrB_FP32 ) WRITE_TUPLES (float , 0, 0, 1, 0)
559 202769 : else if (type == GrB_FP64 ) WRITE_TUPLES (double , 0, 0, 1, 0)
560 : #if 0
561 : else if (type == GxB_FC32 ) WRITE_TUPLES (GxB_FC32_t, 0, 0, 0, 1) ;
562 : else if (type == GxB_FC64 ) WRITE_TUPLES (GxB_FC64_t, 0, 0, 0, 1) ;
563 : #endif
564 :
565 : ASSERT (nvals_to_print == nvals_printed) ;
566 :
567 : //--------------------------------------------------------------------------
568 : // free workspace and return
569 : //--------------------------------------------------------------------------
570 :
571 105 : LG_FREE_ALL ;
572 105 : return (GrB_SUCCESS) ;
573 : }
|