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