1 //------------------------------------------------------------------------------ 2 // GB_printf.h: definitions for printing from GraphBLAS 3 //------------------------------------------------------------------------------ 4 5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved. 6 // SPDX-License-Identifier: Apache-2.0 7 8 //------------------------------------------------------------------------------ 9 10 #ifndef GB_PRINTF_H 11 #define GB_PRINTF_H 12 13 #define GB_STRING_MATCH(s,t) (strcmp (s,t) == 0) 14 15 //------------------------------------------------------------------------------ 16 // printing control 17 //------------------------------------------------------------------------------ 18 19 // format strings, normally %llu and %lld, for GrB_Index values 20 #define GBu "%" PRIu64 21 #define GBd "%" PRId64 22 23 // print to the standard output, and flush the result. This function can 24 // print to the MATLAB command window. No error check is done. This function 25 // is used for the BURBLE, and for debugging output. 26 #define GBDUMP(...) \ 27 { \ 28 GB_printf_function_t printf_func = GB_Global_printf_get ( ) ; \ 29 if (printf_func != NULL) \ 30 { \ 31 printf_func (__VA_ARGS__) ; \ 32 } \ 33 else \ 34 { \ 35 printf (__VA_ARGS__) ; \ 36 } \ 37 GB_flush_function_t flush_func = GB_Global_flush_get ( ) ; \ 38 if (flush_func != NULL) \ 39 { \ 40 flush_func ( ) ; \ 41 } \ 42 else \ 43 { \ 44 fflush (stdout) ; \ 45 } \ 46 } 47 48 // print to a file f, or to stdout if f is NULL, and check the result. This 49 // macro is used by all user-callable GxB_*print and GB_*check functions. 50 #define GBPR(...) \ 51 { \ 52 int printf_result = 0 ; \ 53 if (f == NULL) \ 54 { \ 55 GB_printf_function_t printf_func = GB_Global_printf_get ( ) ; \ 56 if (printf_func != NULL) \ 57 { \ 58 printf_result = printf_func (__VA_ARGS__) ; \ 59 } \ 60 else \ 61 { \ 62 printf_result = printf (__VA_ARGS__) ; \ 63 } \ 64 GB_flush_function_t flush_func = GB_Global_flush_get ( ) ; \ 65 if (flush_func != NULL) \ 66 { \ 67 flush_func ( ) ; \ 68 } \ 69 else \ 70 { \ 71 fflush (stdout) ; \ 72 } \ 73 } \ 74 else \ 75 { \ 76 printf_result = fprintf (f, __VA_ARGS__) ; \ 77 fflush (f) ; \ 78 } \ 79 if (printf_result < 0) \ 80 { \ 81 int err = errno ; \ 82 return (GrB_INVALID_VALUE) ; \ 83 } \ 84 } 85 86 // print if the print level is greater than zero 87 #define GBPR0(...) \ 88 { \ 89 if (pr != GxB_SILENT) \ 90 { \ 91 GBPR (__VA_ARGS__) ; \ 92 } \ 93 } 94 95 // check object->magic and print an error if invalid 96 #define GB_CHECK_MAGIC(object,kind) \ 97 { \ 98 switch (object->magic) \ 99 { \ 100 case GB_MAGIC : \ 101 /* the object is valid */ \ 102 break ; \ 103 \ 104 case GB_FREED : \ 105 /* dangling pointer! */ \ 106 GBPR0 (" object already freed!\n") ; \ 107 return (GrB_UNINITIALIZED_OBJECT) ; \ 108 \ 109 case GB_MAGIC2 : \ 110 /* invalid */ \ 111 GBPR0 (" invalid object\n") ; \ 112 return (GrB_INVALID_OBJECT) ; \ 113 \ 114 default : \ 115 /* uninitialized */ \ 116 GBPR0 (" uninititialized object\n") ; \ 117 return (GrB_UNINITIALIZED_OBJECT) ; \ 118 } \ 119 } 120 121 //------------------------------------------------------------------------------ 122 // burble 123 //------------------------------------------------------------------------------ 124 125 // GB_BURBLE provides diagnostic output. 126 // Use GxB_set (GxB_BURBLE, true) to turn it on 127 // and GxB_set (GxB_BURBLE, false) to turn it off. 128 129 #if GB_BURBLE 130 131 void GB_burble_assign 132 ( 133 const bool C_replace, // descriptor for C 134 const int Ikind, 135 const int Jkind, 136 const GrB_Matrix M, // mask matrix, which is not NULL here 137 const bool Mask_comp, // true for !M, false for M 138 const bool Mask_struct, // true if M is structural, false if valued 139 const GrB_BinaryOp accum, // present here 140 const GrB_Matrix A, // input matrix, not transposed 141 const int assign_kind // row assign, col assign, assign, or subassign 142 ) ; 143 144 // define the function to use to burble 145 #define GBURBLE(...) \ 146 { \ 147 if (GB_Global_burble_get ( )) \ 148 { \ 149 GBDUMP (__VA_ARGS__) ; \ 150 } \ 151 } 152 153 // burble if a matrix is dense or full 154 #define GB_BURBLE_DENSE(A,format) \ 155 { \ 156 if (GB_IS_FULL (A)) \ 157 { \ 158 GBURBLE (format, "full") ; \ 159 } \ 160 else if (GB_IS_BITMAP (A)) \ 161 { \ 162 GBURBLE (format, "bitmap") ; \ 163 } \ 164 else if (GB_is_dense (A) && !GB_PENDING_OR_ZOMBIES (A)) \ 165 { \ 166 GBURBLE (format, "dense") ; \ 167 } \ 168 } 169 170 #if defined ( _OPENMP ) 171 172 // burble with timing 173 #define GB_BURBLE_START(func) \ 174 double t_burble = 0 ; \ 175 { \ 176 if (GB_Global_burble_get ( )) \ 177 { \ 178 GBURBLE (" [ " func " ") ; \ 179 t_burble = GB_OPENMP_GET_WTIME ; \ 180 } \ 181 } 182 183 #define GB_BURBLE_END \ 184 { \ 185 if (GB_Global_burble_get ( )) \ 186 { \ 187 t_burble = GB_OPENMP_GET_WTIME - t_burble ; \ 188 GBURBLE ("\n %.3g sec ]\n", t_burble) ; \ 189 } \ 190 } 191 192 #else 193 194 // burble with no timing 195 196 #define GB_BURBLE_START(func) \ 197 GBURBLE (" [ " func " ") 198 199 #define GB_BURBLE_END \ 200 GBURBLE ("]\n") 201 202 #endif 203 204 #define GB_BURBLE_N(n,...) \ 205 { \ 206 if (n > 1) GBURBLE (__VA_ARGS__) \ 207 } 208 209 #define GB_BURBLE_MATRIX(A, ...) \ 210 { \ 211 if (!(A->vlen <= 1 && A->vdim <= 1)) GBURBLE (__VA_ARGS__) \ 212 } 213 214 #else 215 216 // no burble 217 #define GBURBLE(...) 218 #define GB_BURBLE_START(func) 219 #define GB_BURBLE_END 220 #define GB_BURBLE_N(n,...) 221 #define GB_BURBLE_MATRIX(A,...) 222 #define GB_BURBLE_DENSE(A,format) 223 224 #endif 225 #endif 226 227