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