1 //------------------------------------------------------------------------------
2 // GB_cast_array: typecast or copy an array
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 // Casts an input array Ax to an output array Cx with a different built-in
11 // type. Does not handle user-defined types.
12
13 #include "GB.h"
14 #ifndef GBCOMPACT
15 #include "GB_unop__include.h"
16 #endif
17
18 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
GB_cast_array(GB_void * Cx,const GB_Type_code code1,GB_void * Ax,const GB_Type_code code2,const int8_t * restrict Ab,const size_t user_size,const int64_t anz,const int nthreads)19 void GB_cast_array // typecast an array
20 (
21 GB_void *Cx, // output array
22 const GB_Type_code code1, // type code for Cx
23 GB_void *Ax, // input array
24 const GB_Type_code code2, // type code for Ax
25 const int8_t *restrict Ab, // bitmap for Ax
26 const size_t user_size, // size of Ax and Cx if user-defined
27 const int64_t anz, // number of entries in Cx and Ax
28 const int nthreads // number of threads to use
29 )
30 {
31
32 //--------------------------------------------------------------------------
33 // check inputs
34 //--------------------------------------------------------------------------
35
36 if (anz == 0 || Cx == Ax)
37 {
38 // if anz is zero: no work to do, and the Ax and Cx pointer may be NULL
39 // as well. If Cx and Ax are aliased, then no copy is needed.
40 return ;
41 }
42
43 ASSERT (Cx != NULL) ;
44 ASSERT (Ax != NULL) ;
45 ASSERT (anz > 0) ;
46 ASSERT (GB_code_compatible (code1, code2)) ;
47
48 //--------------------------------------------------------------------------
49 // typecast the array
50 //--------------------------------------------------------------------------
51
52 #ifndef GBCOMPACT
53
54 //----------------------------------------------------------------------
55 // define the worker for the switch factory
56 //----------------------------------------------------------------------
57
58 #define GB_unop_apply(zname,xname) \
59 GB (_unop_apply__identity ## zname ## xname)
60
61 #define GB_WORKER(ignore1,zname,ztype,xname,xtype) \
62 { \
63 GrB_Info info = GB_unop_apply (zname,xname) \
64 ((ztype *) Cx, (xtype *) Ax, Ab, anz, nthreads) ; \
65 if (info == GrB_SUCCESS) return ; \
66 } \
67 break ;
68
69 //----------------------------------------------------------------------
70 // launch the switch factory
71 //----------------------------------------------------------------------
72
73 #include "GB_2type_factory.c"
74
75 #endif
76
77 //--------------------------------------------------------------------------
78 // generic worker
79 //--------------------------------------------------------------------------
80
81 int64_t csize = GB_code_size (code1, user_size) ;
82 int64_t asize = GB_code_size (code2, user_size) ;
83 GB_cast_function cast_A_to_C = GB_cast_factory (code1, code2) ;
84
85 int64_t p ;
86 #pragma omp parallel for num_threads(nthreads) schedule(static)
87 for (p = 0 ; p < anz ; p++)
88 {
89 if (!GBB (Ab, p)) continue ;
90 // Cx [p] = Ax [p]
91 cast_A_to_C (Cx +(p*csize), Ax +(p*asize), asize) ;
92 }
93 }
94
95