1 //------------------------------------------------------------------------------
2 // GB_casting.h: define the unary typecasting functions
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 // TODO: complex code is #ifdef'd out when using CUDA.
11 
12 #ifndef GB_CASTING_H
13 #define GB_CASTING_H
14 
15 //------------------------------------------------------------------------------
16 // pointer casting function, returned by GB_cast_factory.
17 //------------------------------------------------------------------------------
18 
19 typedef void (*GB_cast_function) (void *, const void *, size_t) ;
20 
21 GB_PUBLIC   // accessed by the MATLAB tests in GraphBLAS/Test only
22 GB_cast_function GB_cast_factory   // returns pointer to function to cast x to z
23 (
24     const GB_Type_code code1,      // the type of z, the output value
25     const GB_Type_code code2       // the type of x, the input value
26 ) ;
27 
28 //------------------------------------------------------------------------------
29 // typecasting from double to integer
30 //------------------------------------------------------------------------------
31 
32 // The GraphBLAS C API states that typecasting follows the rules of the C
33 // language.  However, the ANSI C11 language specification states that results
34 // are undefined when typecasting a float or double to an integer value that is
35 // outside the range of the integer type.  MATLAB handles this case by
36 // typecasting a float or double that is larger than the maximum integer to the
37 // max integer, and a value less than the minimum integer to the min integer.
38 // NaN's are typecasted to the integer value zero.  GraphBLAS follows the same
39 // rules as MATLAB.
40 
GB_cast_to_int8_t(double x)41 inline int8_t GB_cast_to_int8_t (double x)
42 {
43     if (isnan (x)) return (0) ;
44     if (x <= (double) INT8_MIN) return (INT8_MIN) ;
45     if (x >= (double) INT8_MAX) return (INT8_MAX) ;
46     return ((int8_t) x) ;
47 }
48 
GB_cast_to_int16_t(double x)49 inline int16_t GB_cast_to_int16_t (double x)
50 {
51     if (isnan (x)) return (0) ;
52     if (x <= (double) INT16_MIN) return (INT16_MIN) ;
53     if (x >= (double) INT16_MAX) return (INT16_MAX) ;
54     return ((int16_t) x) ;
55 }
56 
GB_cast_to_int32_t(double x)57 inline int32_t GB_cast_to_int32_t (double x)
58 {
59     if (isnan (x)) return (0) ;
60     if (x <= (double) INT32_MIN) return (INT32_MIN) ;
61     if (x >= (double) INT32_MAX) return (INT32_MAX) ;
62     return ((int32_t) x) ;
63 }
64 
GB_cast_to_int64_t(double x)65 inline int64_t GB_cast_to_int64_t (double x)
66 {
67     if (isnan (x)) return (0) ;
68     if (x <= (double) INT64_MIN) return (INT64_MIN) ;
69     if (x >= (double) INT64_MAX) return (INT64_MAX) ;
70     return ((int64_t) x) ;
71 }
72 
GB_cast_to_uint8_t(double x)73 inline uint8_t GB_cast_to_uint8_t (double x)
74 {
75     if (isnan (x) || x <= 0) return (0) ;
76     if (x >= (double) UINT8_MAX) return (UINT8_MAX) ;
77     return ((uint8_t) x) ;
78 }
79 
GB_cast_to_uint16_t(double x)80 inline uint16_t GB_cast_to_uint16_t (double x)
81 {
82     if (isnan (x) || x <= 0) return (0) ;
83     if (x >= (double) UINT16_MAX) return (UINT16_MAX) ;
84     return ((uint16_t) x) ;
85 }
86 
GB_cast_to_uint32_t(double x)87 inline uint32_t GB_cast_to_uint32_t (double x)
88 {
89     if (isnan (x) || x <= 0) return (0) ;
90     if (x >= (double) UINT32_MAX) return (UINT32_MAX) ;
91     return ((uint32_t) x) ;
92 }
93 
GB_cast_to_uint64_t(double x)94 inline uint64_t GB_cast_to_uint64_t (double x)
95 {
96     if (isnan (x) || x <= 0) return (0) ;
97     if (x >= (double) UINT64_MAX) return (UINT64_MAX) ;
98     return ((uint64_t) x) ;
99 }
100 
101 //------------------------------------------------------------------------------
102 // unary typecast operators, used in GB_cast_factory.c.
103 //------------------------------------------------------------------------------
104 
105 // construct the typecast functions: z = (ztype) x, where x has type xtype.
106 
107 // GB_cast_ztype_xtype casts a single value ((xtype) x) into the result
108 // ((ztype) z).  Functions with the xtype and ztype the same, such as
109 // GB_cast_double_double, simply copy their input to their output.
110 
111 // The s parameter is not used in these functions.  It is present because one
112 // function returned by GB_cast_factory requires it (GB_copy_user_user).
113 
114 void GB_copy_user_user (void *z, const void *x, size_t s) ;
115 
116 #define GB_CAST_FUNCTION(ztype,xtype)                                   \
117 inline void GB (_cast_ ## ztype ## _ ## xtype)                          \
118 (                                                                       \
119     void *z,            /* typecasted output, of type ztype */          \
120     const void *x,      /* input value to typecast, of type xtype */    \
121     size_t s            /* size of type, for GB_copy_user_user only */  \
122 )                                                                       \
123 {                                                                       \
124     xtype xx = (*((xtype *) x)) ;                                       \
125     ztype zz = GB_CAST (ztype, xx) ;                                    \
126     (*((ztype *) z)) = zz ;                                             \
127 }
128 
129 //------------------------------------------------------------------------------
130 // typecast to boolean
131 //------------------------------------------------------------------------------
132 
133 // Typecasting a NaN to a bool results in 'true', as defined by the ANSI C11
134 // standard (NaN converts to true, since Nan != 0 is true).  MATLAB throws an
135 // error when trying to convert NaN's to logical.  GraphBLAS follows the ANSI
136 // C11 standard in this case.
137 
138 #undef  GB_CAST
139 #define GB_CAST(ztype,x) (ztype) x
GB_CAST_FUNCTION(bool,bool)140 GB_CAST_FUNCTION (bool      , bool      )
141 #undef  GB_CAST
142 #define GB_CAST(ztype,x) (x != 0)
143 GB_CAST_FUNCTION (bool      , int8_t    )
144 GB_CAST_FUNCTION (bool      , int16_t   )
145 GB_CAST_FUNCTION (bool      , int32_t   )
146 GB_CAST_FUNCTION (bool      , int64_t   )
147 GB_CAST_FUNCTION (bool      , uint8_t   )
148 GB_CAST_FUNCTION (bool      , uint16_t  )
149 GB_CAST_FUNCTION (bool      , uint32_t  )
150 GB_CAST_FUNCTION (bool      , uint64_t  )
151 GB_CAST_FUNCTION (bool      , float     )
152 GB_CAST_FUNCTION (bool      , double    )
153 #ifndef GBCUDA
154 // TODO: this does not work on CUDA yet
155 #undef  GB_CAST
156 #define GB_CAST(ztype,x) (crealf (x) != 0 || cimagf (x) != 0)
157 GB_CAST_FUNCTION (bool      , GxB_FC32_t)
158 #undef  GB_CAST
159 #define GB_CAST(ztype,x) (creal (x) != 0 || cimag (x) != 0)
160 GB_CAST_FUNCTION (bool      , GxB_FC64_t)
161 #endif
162 
163 //------------------------------------------------------------------------------
164 // typecast to int8_t
165 //------------------------------------------------------------------------------
166 
167 #undef  GB_CAST
168 #define GB_CAST(ztype,x) (ztype) x
169 GB_CAST_FUNCTION (int8_t    , bool      )
170 GB_CAST_FUNCTION (int8_t    , int8_t    )
171 GB_CAST_FUNCTION (int8_t    , int16_t   )
172 GB_CAST_FUNCTION (int8_t    , int32_t   )
173 GB_CAST_FUNCTION (int8_t    , int64_t   )
174 GB_CAST_FUNCTION (int8_t    , uint8_t   )
175 GB_CAST_FUNCTION (int8_t    , uint16_t  )
176 GB_CAST_FUNCTION (int8_t    , uint32_t  )
177 GB_CAST_FUNCTION (int8_t    , uint64_t  )
178 #undef  GB_CAST
179 #define GB_CAST(ztype,x) GB_cast_to_int8_t ((double) x)
180 GB_CAST_FUNCTION (int8_t    , float     )
181 GB_CAST_FUNCTION (int8_t    , double    )
182 #ifndef GBCUDA
183 // TODO: this does not work on CUDA yet
184 #undef  GB_CAST
185 #define GB_CAST(ztype,x) GB_cast_to_int8_t ((double) crealf (x))
186 GB_CAST_FUNCTION (int8_t    , GxB_FC32_t)
187 #undef  GB_CAST
188 #define GB_CAST(ztype,x) GB_cast_to_int8_t (creal (x))
189 GB_CAST_FUNCTION (int8_t    , GxB_FC64_t)
190 #endif
191 
192 //------------------------------------------------------------------------------
193 // typecast to int16_t
194 //------------------------------------------------------------------------------
195 
196 #undef  GB_CAST
197 #define GB_CAST(ztype,x) (ztype) x
198 GB_CAST_FUNCTION (int16_t   , bool      )
199 GB_CAST_FUNCTION (int16_t   , int8_t    )
200 GB_CAST_FUNCTION (int16_t   , int16_t   )
201 GB_CAST_FUNCTION (int16_t   , int32_t   )
202 GB_CAST_FUNCTION (int16_t   , int64_t   )
203 GB_CAST_FUNCTION (int16_t   , uint8_t   )
204 GB_CAST_FUNCTION (int16_t   , uint16_t  )
205 GB_CAST_FUNCTION (int16_t   , uint32_t  )
206 GB_CAST_FUNCTION (int16_t   , uint64_t  )
207 #undef  GB_CAST
208 #define GB_CAST(ztype,x) GB_cast_to_int16_t ((double) x)
209 GB_CAST_FUNCTION (int16_t   , float     )
210 GB_CAST_FUNCTION (int16_t   , double    )
211 #ifndef GBCUDA
212 // TODO: this does not work on CUDA yet
213 #undef  GB_CAST
214 #define GB_CAST(ztype,x) GB_cast_to_int16_t ((double) crealf (x))
215 GB_CAST_FUNCTION (int16_t   , GxB_FC32_t)
216 #undef  GB_CAST
217 #define GB_CAST(ztype,x) GB_cast_to_int16_t (creal (x))
218 GB_CAST_FUNCTION (int16_t   , GxB_FC64_t)
219 #endif
220 
221 //------------------------------------------------------------------------------
222 // typecast to int32_t
223 //------------------------------------------------------------------------------
224 
225 #undef  GB_CAST
226 #define GB_CAST(ztype,x) (ztype) x
227 GB_CAST_FUNCTION (int32_t   , bool      )
228 GB_CAST_FUNCTION (int32_t   , int8_t    )
229 GB_CAST_FUNCTION (int32_t   , int16_t   )
230 GB_CAST_FUNCTION (int32_t   , int32_t   )
231 GB_CAST_FUNCTION (int32_t   , int64_t   )
232 GB_CAST_FUNCTION (int32_t   , uint8_t   )
233 GB_CAST_FUNCTION (int32_t   , uint16_t  )
234 GB_CAST_FUNCTION (int32_t   , uint32_t  )
235 GB_CAST_FUNCTION (int32_t   , uint64_t  )
236 #undef  GB_CAST
237 #define GB_CAST(ztype,x) GB_cast_to_int32_t ((double) x)
238 GB_CAST_FUNCTION (int32_t   , float     )
239 GB_CAST_FUNCTION (int32_t   , double    )
240 #ifndef GBCUDA
241 // TODO: this does not work on CUDA yet
242 #undef  GB_CAST
243 #define GB_CAST(ztype,x) GB_cast_to_int32_t ((double) crealf (x))
244 GB_CAST_FUNCTION (int32_t   , GxB_FC32_t)
245 #undef  GB_CAST
246 #define GB_CAST(ztype,x) GB_cast_to_int32_t (creal (x))
247 GB_CAST_FUNCTION (int32_t   , GxB_FC64_t)
248 #endif
249 
250 //------------------------------------------------------------------------------
251 // typecast to int64_t
252 //------------------------------------------------------------------------------
253 
254 #undef  GB_CAST
255 #define GB_CAST(ztype,x) (ztype) x
256 GB_CAST_FUNCTION (int64_t   , bool      )
257 GB_CAST_FUNCTION (int64_t   , int8_t    )
258 GB_CAST_FUNCTION (int64_t   , int16_t   )
259 GB_CAST_FUNCTION (int64_t   , int32_t   )
260 GB_CAST_FUNCTION (int64_t   , int64_t   )
261 GB_CAST_FUNCTION (int64_t   , uint8_t   )
262 GB_CAST_FUNCTION (int64_t   , uint16_t  )
263 GB_CAST_FUNCTION (int64_t   , uint32_t  )
264 GB_CAST_FUNCTION (int64_t   , uint64_t  )
265 #undef  GB_CAST
266 #define GB_CAST(ztype,x) GB_cast_to_int64_t ((double) x)
267 GB_CAST_FUNCTION (int64_t   , float     )
268 GB_CAST_FUNCTION (int64_t   , double    )
269 #ifndef GBCUDA
270 // TODO: this does not work on CUDA yet
271 #undef  GB_CAST
272 #define GB_CAST(ztype,x) GB_cast_to_int64_t ((double) crealf (x))
273 GB_CAST_FUNCTION (int64_t   , GxB_FC32_t)
274 #undef  GB_CAST
275 #define GB_CAST(ztype,x) GB_cast_to_int64_t (creal (x))
276 GB_CAST_FUNCTION (int64_t   , GxB_FC64_t)
277 #endif
278 
279 //------------------------------------------------------------------------------
280 // typecast to uint8_t
281 //------------------------------------------------------------------------------
282 
283 #undef  GB_CAST
284 #define GB_CAST(ztype,x) (ztype) x
285 GB_CAST_FUNCTION (uint8_t   , bool      )
286 GB_CAST_FUNCTION (uint8_t   , int8_t    )
287 GB_CAST_FUNCTION (uint8_t   , int16_t   )
288 GB_CAST_FUNCTION (uint8_t   , int32_t   )
289 GB_CAST_FUNCTION (uint8_t   , int64_t   )
290 GB_CAST_FUNCTION (uint8_t   , uint8_t   )
291 GB_CAST_FUNCTION (uint8_t   , uint16_t  )
292 GB_CAST_FUNCTION (uint8_t   , uint32_t  )
293 GB_CAST_FUNCTION (uint8_t   , uint64_t  )
294 #undef  GB_CAST
295 #define GB_CAST(ztype,x) GB_cast_to_uint8_t ((double) x)
296 GB_CAST_FUNCTION (uint8_t   , float     )
297 GB_CAST_FUNCTION (uint8_t   , double    )
298 #ifndef GBCUDA
299 // TODO: this does not work on CUDA yet
300 #undef  GB_CAST
301 #define GB_CAST(ztype,x) GB_cast_to_uint8_t ((double) crealf (x))
302 GB_CAST_FUNCTION (uint8_t   , GxB_FC32_t)
303 #undef  GB_CAST
304 #define GB_CAST(ztype,x) GB_cast_to_uint8_t (creal (x))
305 GB_CAST_FUNCTION (uint8_t   , GxB_FC64_t)
306 #endif
307 
308 //------------------------------------------------------------------------------
309 // typecast to uint16_t
310 //------------------------------------------------------------------------------
311 
312 #undef  GB_CAST
313 #define GB_CAST(ztype,x) (ztype) x
314 GB_CAST_FUNCTION (uint16_t  , bool      )
315 GB_CAST_FUNCTION (uint16_t  , int8_t    )
316 GB_CAST_FUNCTION (uint16_t  , int16_t   )
317 GB_CAST_FUNCTION (uint16_t  , int32_t   )
318 GB_CAST_FUNCTION (uint16_t  , int64_t   )
319 GB_CAST_FUNCTION (uint16_t  , uint8_t   )
320 GB_CAST_FUNCTION (uint16_t  , uint16_t  )
321 GB_CAST_FUNCTION (uint16_t  , uint32_t  )
322 GB_CAST_FUNCTION (uint16_t  , uint64_t  )
323 #undef  GB_CAST
324 #define GB_CAST(ztype,x) GB_cast_to_uint16_t ((double) x)
325 GB_CAST_FUNCTION (uint16_t  , float     )
326 GB_CAST_FUNCTION (uint16_t  , double    )
327 #ifndef GBCUDA
328 // TODO: this does not work on CUDA yet
329 #undef  GB_CAST
330 #define GB_CAST(ztype,x) GB_cast_to_uint16_t ((double) crealf (x))
331 GB_CAST_FUNCTION (uint16_t  , GxB_FC32_t)
332 #undef  GB_CAST
333 #define GB_CAST(ztype,x) GB_cast_to_uint16_t (creal (x))
334 GB_CAST_FUNCTION (uint16_t  , GxB_FC64_t)
335 #endif
336 
337 //------------------------------------------------------------------------------
338 // typecast to uint32_t
339 //------------------------------------------------------------------------------
340 
341 #undef  GB_CAST
342 #define GB_CAST(ztype,x) (ztype) x
343 GB_CAST_FUNCTION (uint32_t  , bool      )
344 GB_CAST_FUNCTION (uint32_t  , int8_t    )
345 GB_CAST_FUNCTION (uint32_t  , int16_t   )
346 GB_CAST_FUNCTION (uint32_t  , int32_t   )
347 GB_CAST_FUNCTION (uint32_t  , int64_t   )
348 GB_CAST_FUNCTION (uint32_t  , uint8_t   )
349 GB_CAST_FUNCTION (uint32_t  , uint16_t  )
350 GB_CAST_FUNCTION (uint32_t  , uint32_t  )
351 GB_CAST_FUNCTION (uint32_t  , uint64_t  )
352 #undef  GB_CAST
353 #define GB_CAST(ztype,x) GB_cast_to_uint32_t ((double) x)
354 GB_CAST_FUNCTION (uint32_t  , float     )
355 GB_CAST_FUNCTION (uint32_t  , double    )
356 #ifndef GBCUDA
357 // TODO: this does not work on CUDA yet
358 #undef  GB_CAST
359 #define GB_CAST(ztype,x) GB_cast_to_uint32_t ((double) crealf (x))
360 GB_CAST_FUNCTION (uint32_t  , GxB_FC32_t)
361 #undef  GB_CAST
362 #define GB_CAST(ztype,x) GB_cast_to_uint32_t (creal (x))
363 GB_CAST_FUNCTION (uint32_t  , GxB_FC64_t)
364 #endif
365 
366 //------------------------------------------------------------------------------
367 // typecast to uint64_t
368 //------------------------------------------------------------------------------
369 
370 #undef  GB_CAST
371 #define GB_CAST(ztype,x) (ztype) x
372 GB_CAST_FUNCTION (uint64_t  , bool      )
373 GB_CAST_FUNCTION (uint64_t  , int8_t    )
374 GB_CAST_FUNCTION (uint64_t  , int16_t   )
375 GB_CAST_FUNCTION (uint64_t  , int32_t   )
376 GB_CAST_FUNCTION (uint64_t  , int64_t   )
377 GB_CAST_FUNCTION (uint64_t  , uint8_t   )
378 GB_CAST_FUNCTION (uint64_t  , uint16_t  )
379 GB_CAST_FUNCTION (uint64_t  , uint32_t  )
380 GB_CAST_FUNCTION (uint64_t  , uint64_t  )
381 #undef  GB_CAST
382 #define GB_CAST(ztype,x) GB_cast_to_uint64_t ((double) x)
383 GB_CAST_FUNCTION (uint64_t  , float     )
384 GB_CAST_FUNCTION (uint64_t  , double    )
385 #ifndef GBCUDA
386 // TODO: this does not work on CUDA yet
387 #undef  GB_CAST
388 #define GB_CAST(ztype,x) GB_cast_to_uint64_t ((double) crealf (x))
389 GB_CAST_FUNCTION (uint64_t  , GxB_FC32_t)
390 #undef  GB_CAST
391 #define GB_CAST(ztype,x) GB_cast_to_uint64_t (creal (x))
392 GB_CAST_FUNCTION (uint64_t  , GxB_FC64_t)
393 #endif
394 
395 //------------------------------------------------------------------------------
396 // typecast to float
397 //------------------------------------------------------------------------------
398 
399 #undef  GB_CAST
400 #define GB_CAST(ztype,x) (ztype) x
401 GB_CAST_FUNCTION (float     , bool      )
402 GB_CAST_FUNCTION (float     , int8_t    )
403 GB_CAST_FUNCTION (float     , int16_t   )
404 GB_CAST_FUNCTION (float     , int32_t   )
405 GB_CAST_FUNCTION (float     , int64_t   )
406 GB_CAST_FUNCTION (float     , uint8_t   )
407 GB_CAST_FUNCTION (float     , uint16_t  )
408 GB_CAST_FUNCTION (float     , uint32_t  )
409 GB_CAST_FUNCTION (float     , uint64_t  )
410 GB_CAST_FUNCTION (float     , float     )
411 GB_CAST_FUNCTION (float     , double    )
412 #ifndef GBCUDA
413 // TODO: this does not work on CUDA yet
414 #undef  GB_CAST
415 #define GB_CAST(ztype,x) crealf (x)
416 GB_CAST_FUNCTION (float     , GxB_FC32_t)
417 #undef  GB_CAST
418 #define GB_CAST(ztype,x) ((float) creal (x))
419 GB_CAST_FUNCTION (float     , GxB_FC64_t)
420 #endif
421 
422 //------------------------------------------------------------------------------
423 // typecast to double
424 //------------------------------------------------------------------------------
425 
426 #undef  GB_CAST
427 #define GB_CAST(ztype,x) (ztype) x
428 GB_CAST_FUNCTION (double    , bool      )
429 GB_CAST_FUNCTION (double    , int8_t    )
430 GB_CAST_FUNCTION (double    , int16_t   )
431 GB_CAST_FUNCTION (double    , int32_t   )
432 GB_CAST_FUNCTION (double    , int64_t   )
433 GB_CAST_FUNCTION (double    , uint8_t   )
434 GB_CAST_FUNCTION (double    , uint16_t  )
435 GB_CAST_FUNCTION (double    , uint32_t  )
436 GB_CAST_FUNCTION (double    , uint64_t  )
437 GB_CAST_FUNCTION (double    , float     )
438 GB_CAST_FUNCTION (double    , double    )
439 #ifndef GBCUDA
440 // TODO: this does not work on CUDA yet
441 #undef  GB_CAST
442 #define GB_CAST(ztype,x) ((double) crealf (x))
443 GB_CAST_FUNCTION (double    , GxB_FC32_t)
444 #undef  GB_CAST
445 #define GB_CAST(ztype,x) creal (x)
446 GB_CAST_FUNCTION (double    , GxB_FC64_t)
447 #endif
448 
449 //------------------------------------------------------------------------------
450 // typecast to float complex
451 //------------------------------------------------------------------------------
452 
453 #undef  GB_CAST
454 #define GB_CAST(ztype,x) GxB_CMPLXF ((float) x, (float) 0)
455 GB_CAST_FUNCTION (GxB_FC32_t, bool      )
456 GB_CAST_FUNCTION (GxB_FC32_t, int8_t    )
457 GB_CAST_FUNCTION (GxB_FC32_t, int16_t   )
458 GB_CAST_FUNCTION (GxB_FC32_t, int32_t   )
459 GB_CAST_FUNCTION (GxB_FC32_t, int64_t   )
460 GB_CAST_FUNCTION (GxB_FC32_t, uint8_t   )
461 GB_CAST_FUNCTION (GxB_FC32_t, uint16_t  )
462 GB_CAST_FUNCTION (GxB_FC32_t, uint32_t  )
463 GB_CAST_FUNCTION (GxB_FC32_t, uint64_t  )
464 GB_CAST_FUNCTION (GxB_FC32_t, float     )
465 GB_CAST_FUNCTION (GxB_FC32_t, double    )
466 #ifndef GBCUDA
467 // TODO: this does not work on CUDA yet
468 #undef  GB_CAST
469 #define GB_CAST(ztype,x) x
470 GB_CAST_FUNCTION (GxB_FC32_t, GxB_FC32_t)
471 #undef  GB_CAST
472 #define GB_CAST(ztype,x) GxB_CMPLXF ((float) creal (x), (float) cimag (x))
473 GB_CAST_FUNCTION (GxB_FC32_t, GxB_FC64_t)
474 #endif
475 
476 //------------------------------------------------------------------------------
477 // typecast to double complex
478 //------------------------------------------------------------------------------
479 
480 #undef  GB_CAST
481 #define GB_CAST(ztype,x) GxB_CMPLX ((double) x, (double) 0)
482 GB_CAST_FUNCTION (GxB_FC64_t, bool      )
483 GB_CAST_FUNCTION (GxB_FC64_t, int8_t    )
484 GB_CAST_FUNCTION (GxB_FC64_t, int16_t   )
485 GB_CAST_FUNCTION (GxB_FC64_t, int32_t   )
486 GB_CAST_FUNCTION (GxB_FC64_t, int64_t   )
487 GB_CAST_FUNCTION (GxB_FC64_t, uint8_t   )
488 GB_CAST_FUNCTION (GxB_FC64_t, uint16_t  )
489 GB_CAST_FUNCTION (GxB_FC64_t, uint32_t  )
490 GB_CAST_FUNCTION (GxB_FC64_t, uint64_t  )
491 GB_CAST_FUNCTION (GxB_FC64_t, float     )
492 GB_CAST_FUNCTION (GxB_FC64_t, double    )
493 #ifndef GBCUDA
494 // TODO: this does not work on CUDA yet
495 #undef  GB_CAST
496 #define GB_CAST(ztype,x) GxB_CMPLX ((double) crealf (x), (double) cimagf (x))
497 GB_CAST_FUNCTION (GxB_FC64_t, GxB_FC32_t)
498 #undef  GB_CAST
499 #define GB_CAST(ztype,x) x
500 GB_CAST_FUNCTION (GxB_FC64_t, GxB_FC64_t)
501 
502 #undef  GB_CAST
503 #undef  GB_CAST_FUNCTION
504 #endif
505 
506 //------------------------------------------------------------------------------
507 // GB_mcast: cast a mask entry from any native type to boolean
508 //------------------------------------------------------------------------------
509 
510 // The mask matrix M must be one of the native data types, which have sizes of
511 // 1, 2, 4, 8, or 16 bytes.  The value could be properly typecasted to bool,
512 // but this requires a function pointer to the proper GB_cast_function.
513 // Instead, it is faster to simply use type punning, based on the size of the
514 // data type, and use the inline GB_mcast function instead.
515 
516 static inline bool GB_mcast         // return the value of M(i,j)
517 (
518     const GB_void *restrict Mx,  // mask values
519     const int64_t pM,               // extract boolean value of Mx [pM]
520     const size_t msize              // size of each data type
521 )
522 {
523     if (Mx == NULL)
524     {
525         // If Mx is NULL, then values in the mask matrix M are ignored, and
526         // only the structural pattern is used.  This function is only called
527         // for entries M(i,j) in the structure of M, so the result is always
528         // true if Mx is NULL.
529         return (true) ;
530     }
531     else
532     {
533         // check the value of M(i,j)
534         switch (msize)
535         {
536             default:
537             case 1: return ((*(uint8_t  *) (Mx +((pM)*1))) != 0) ;
538             case 2: return ((*(uint16_t *) (Mx +((pM)*2))) != 0) ;
539             case 4: return ((*(uint32_t *) (Mx +((pM)*4))) != 0) ;
540             case 8: return ((*(uint64_t *) (Mx +((pM)*8))) != 0) ;
541             case 16:
542             {
543                 const uint64_t *restrict Zx = (uint64_t *) Mx ;
544                 return (Zx [2*pM] != 0 || Zx [2*pM+1] != 0) ;
545             }
546         }
547     }
548 }
549 
550 #endif
551