LCOV - code coverage report
Current view: top level - src/utility - LAGraph_MMWrite.c (source / functions) Hit Total Coverage
Test: LAGraph code coverage report. Commit id: cc56ed4. Current time (UTC): 2024-08-30T17:14:30Z Lines: 166 166 100.0 %
Date: 2024-08-30 17:16:41 Functions: 2 2 100.0 %

          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             : }

Generated by: LCOV version 1.14