1 //------------------------------------------------------------------------------
2 // GB_select_factory: switch factory for C=select(A,thunk)
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 switch (opcode)
11 {
12 
13     case GB_TRIL_opcode          : GB_SEL_WORKER (_tril    , _any, GB_void)
14     case GB_TRIU_opcode          : GB_SEL_WORKER (_triu    , _any, GB_void)
15     case GB_DIAG_opcode          : GB_SEL_WORKER (_diag    , _any, GB_void)
16     case GB_OFFDIAG_opcode       : GB_SEL_WORKER (_offdiag , _any, GB_void)
17     case GB_USER_SELECT_opcode   : GB_SEL_WORKER (_user    , _any, GB_void)
18 
19     // resize and nonzombie selectors are not used for the bitmap case
20     #ifndef GB_BITMAP_SELECTOR
21     case GB_RESIZE_opcode        : GB_SEL_WORKER (_resize  , _any, GB_void)
22     case GB_NONZOMBIE_opcode :  // A(i,j) not a zombie
23 
24         #ifdef GB_SELECT_PHASE1
25         // phase1: use a single worker for all types, since the test does not
26         // depend on the values, just Ai.
27         GB_SEL_WORKER (_nonzombie, _any, GB_void)
28         #else
29         // phase2:
30         switch (typecode)
31         {
32             case GB_BOOL_code   : GB_SEL_WORKER (_nonzombie, _bool  , bool    )
33             case GB_INT8_code   : GB_SEL_WORKER (_nonzombie, _int8  , int8_t  )
34             case GB_INT16_code  : GB_SEL_WORKER (_nonzombie, _int16 , int16_t )
35             case GB_INT32_code  : GB_SEL_WORKER (_nonzombie, _int32 , int32_t )
36             case GB_INT64_code  : GB_SEL_WORKER (_nonzombie, _int64 , int64_t )
37             case GB_UINT8_code  : GB_SEL_WORKER (_nonzombie, _uint8 , uint8_t )
38             case GB_UINT16_code : GB_SEL_WORKER (_nonzombie, _uint16, uint16_t)
39             case GB_UINT32_code : GB_SEL_WORKER (_nonzombie, _uint32, uint32_t)
40             case GB_UINT64_code : GB_SEL_WORKER (_nonzombie, _uint64, uint64_t)
41             case GB_FP32_code   : GB_SEL_WORKER (_nonzombie, _fp32  , float   )
42             case GB_FP64_code   : GB_SEL_WORKER (_nonzombie, _fp64  , double  )
43             case GB_FC32_code   : GB_SEL_WORKER (_nonzombie, _fc32, GxB_FC32_t)
44             case GB_FC64_code   : GB_SEL_WORKER (_nonzombie, _fc64, GxB_FC64_t)
45             default             : GB_SEL_WORKER (_nonzombie, _any   , GB_void )
46         }
47         break ;
48         #endif
49     #endif
50 
51     case GB_NONZERO_opcode   :  // A(i,j) != 0
52 
53         switch (typecode)
54         {
55             case GB_BOOL_code   : GB_SEL_WORKER (_nonzero, _bool  , bool    )
56             case GB_INT8_code   : GB_SEL_WORKER (_nonzero, _int8  , int8_t  )
57             case GB_INT16_code  : GB_SEL_WORKER (_nonzero, _int16 , int16_t )
58             case GB_INT32_code  : GB_SEL_WORKER (_nonzero, _int32 , int32_t )
59             case GB_INT64_code  : GB_SEL_WORKER (_nonzero, _int64 , int64_t )
60             case GB_UINT8_code  : GB_SEL_WORKER (_nonzero, _uint8 , uint8_t )
61             case GB_UINT16_code : GB_SEL_WORKER (_nonzero, _uint16, uint16_t)
62             case GB_UINT32_code : GB_SEL_WORKER (_nonzero, _uint32, uint32_t)
63             case GB_UINT64_code : GB_SEL_WORKER (_nonzero, _uint64, uint64_t)
64             case GB_FP32_code   : GB_SEL_WORKER (_nonzero, _fp32  , float   )
65             case GB_FP64_code   : GB_SEL_WORKER (_nonzero, _fp64  , double  )
66             case GB_FC32_code   : GB_SEL_WORKER (_nonzero, _fc32, GxB_FC32_t)
67             case GB_FC64_code   : GB_SEL_WORKER (_nonzero, _fc64, GxB_FC64_t)
68             default             : GB_SEL_WORKER (_nonzero, _any   , GB_void )
69         }
70         break ;
71 
72     case GB_EQ_ZERO_opcode   :  // A(i,j) == 0
73 
74         switch (typecode)
75         {
76             case GB_BOOL_code   : GB_SEL_WORKER (_eq_zero, _bool  , bool    )
77             case GB_INT8_code   : GB_SEL_WORKER (_eq_zero, _int8  , int8_t  )
78             case GB_INT16_code  : GB_SEL_WORKER (_eq_zero, _int16 , int16_t )
79             case GB_INT32_code  : GB_SEL_WORKER (_eq_zero, _int32 , int32_t )
80             case GB_INT64_code  : GB_SEL_WORKER (_eq_zero, _int64 , int64_t )
81             case GB_UINT8_code  : GB_SEL_WORKER (_eq_zero, _uint8 , uint8_t )
82             case GB_UINT16_code : GB_SEL_WORKER (_eq_zero, _uint16, uint16_t)
83             case GB_UINT32_code : GB_SEL_WORKER (_eq_zero, _uint32, uint32_t)
84             case GB_UINT64_code : GB_SEL_WORKER (_eq_zero, _uint64, uint64_t)
85             case GB_FP32_code   : GB_SEL_WORKER (_eq_zero, _fp32  , float   )
86             case GB_FP64_code   : GB_SEL_WORKER (_eq_zero, _fp64  , double  )
87             case GB_FC32_code   : GB_SEL_WORKER (_eq_zero, _fc32, GxB_FC32_t)
88             case GB_FC64_code   : GB_SEL_WORKER (_eq_zero, _fc64, GxB_FC64_t)
89             default             : GB_SEL_WORKER (_eq_zero, _any   , GB_void )
90         }
91         break ;
92 
93     case GB_GT_ZERO_opcode   :  // A(i,j) > 0
94 
95         // bool and uint: renamed GxB_GT_ZERO to GxB_NONZERO
96         // user type and complex: return error
97         switch (typecode)
98         {
99             case GB_INT8_code   : GB_SEL_WORKER (_gt_zero, _int8  , int8_t  )
100             case GB_INT16_code  : GB_SEL_WORKER (_gt_zero, _int16 , int16_t )
101             case GB_INT32_code  : GB_SEL_WORKER (_gt_zero, _int32 , int32_t )
102             case GB_INT64_code  : GB_SEL_WORKER (_gt_zero, _int64 , int64_t )
103             case GB_FP32_code   : GB_SEL_WORKER (_gt_zero, _fp32  , float   )
104             case GB_FP64_code   : GB_SEL_WORKER (_gt_zero, _fp64  , double  )
105             default: ;          // not for uint, bool, complex, or user-defined
106         }
107         break ;
108 
109     case GB_GE_ZERO_opcode   :  // A(i,j) >= 0
110 
111         // bool and uint: always true; use GB_dup
112         // user type and complex: return error
113         switch (typecode)
114         {
115             case GB_INT8_code   : GB_SEL_WORKER (_ge_zero, _int8  , int8_t  )
116             case GB_INT16_code  : GB_SEL_WORKER (_ge_zero, _int16 , int16_t )
117             case GB_INT32_code  : GB_SEL_WORKER (_ge_zero, _int32 , int32_t )
118             case GB_INT64_code  : GB_SEL_WORKER (_ge_zero, _int64 , int64_t )
119             case GB_FP32_code   : GB_SEL_WORKER (_ge_zero, _fp32  , float   )
120             case GB_FP64_code   : GB_SEL_WORKER (_ge_zero, _fp64  , double  )
121             default: ;          // not for uint, bool, complex, or user-defined
122         }
123         break ;
124 
125     case GB_LT_ZERO_opcode   :  // A(i,j) < 0
126 
127         // bool and uint: always false; return an empty matrix
128         // user type and complex: return error
129         switch (typecode)
130         {
131             case GB_INT8_code   : GB_SEL_WORKER (_lt_zero, _int8  , int8_t  )
132             case GB_INT16_code  : GB_SEL_WORKER (_lt_zero, _int16 , int16_t )
133             case GB_INT32_code  : GB_SEL_WORKER (_lt_zero, _int32 , int32_t )
134             case GB_INT64_code  : GB_SEL_WORKER (_lt_zero, _int64 , int64_t )
135             case GB_FP32_code   : GB_SEL_WORKER (_lt_zero, _fp32  , float   )
136             case GB_FP64_code   : GB_SEL_WORKER (_lt_zero, _fp64  , double  )
137             default: ;          // not for uint, bool, complex, or user-defined
138         }
139         break ;
140 
141     case GB_LE_ZERO_opcode   :  // A(i,j) <= 0
142 
143         // bool and uint: renamed GxB_LE_ZERO to GxB_EQ_ZERO
144         // user type and complex: return error
145         switch (typecode)
146         {
147             case GB_INT8_code   : GB_SEL_WORKER (_le_zero, _int8  , int8_t  )
148             case GB_INT16_code  : GB_SEL_WORKER (_le_zero, _int16 , int16_t )
149             case GB_INT32_code  : GB_SEL_WORKER (_le_zero, _int32 , int32_t )
150             case GB_INT64_code  : GB_SEL_WORKER (_le_zero, _int64 , int64_t )
151             case GB_FP32_code   : GB_SEL_WORKER (_le_zero, _fp32  , float   )
152             case GB_FP64_code   : GB_SEL_WORKER (_le_zero, _fp64  , double  )
153             default: ;          // not for uint, bool, complex, or user-defined
154         }
155         break ;
156 
157     case GB_NE_THUNK_opcode   : // A(i,j) != thunk
158 
159         // bool: if thunk is true,  renamed GxB_NE_THUNK to GxB_EQ_ZERO
160         //       if thunk is false, renamed GxB_NE_THUNK to GxB_NONZERO
161         switch (typecode)
162         {
163             case GB_INT8_code   : GB_SEL_WORKER (_ne_thunk, _int8  , int8_t  )
164             case GB_INT16_code  : GB_SEL_WORKER (_ne_thunk, _int16 , int16_t )
165             case GB_INT32_code  : GB_SEL_WORKER (_ne_thunk, _int32 , int32_t )
166             case GB_INT64_code  : GB_SEL_WORKER (_ne_thunk, _int64 , int64_t )
167             case GB_UINT8_code  : GB_SEL_WORKER (_ne_thunk, _uint8 , uint8_t )
168             case GB_UINT16_code : GB_SEL_WORKER (_ne_thunk, _uint16, uint16_t)
169             case GB_UINT32_code : GB_SEL_WORKER (_ne_thunk, _uint32, uint32_t)
170             case GB_UINT64_code : GB_SEL_WORKER (_ne_thunk, _uint64, uint64_t)
171             case GB_FP32_code   : GB_SEL_WORKER (_ne_thunk, _fp32  , float   )
172             case GB_FP64_code   : GB_SEL_WORKER (_ne_thunk, _fp64  , double  )
173             case GB_FC32_code   : GB_SEL_WORKER (_ne_thunk, _fc32, GxB_FC32_t)
174             case GB_FC64_code   : GB_SEL_WORKER (_ne_thunk, _fc64, GxB_FC64_t)
175             default             : GB_SEL_WORKER (_ne_thunk, _any   , GB_void )
176         }
177         break ;
178 
179     case GB_EQ_THUNK_opcode   : // A(i,j) == thunk
180 
181         // bool: if thunk is true,  renamed GxB_NE_THUNK to GxB_NONZERO
182         //       if thunk is false, renamed GxB_NE_THUNK to GxB_EQ_ZERO
183         switch (typecode)
184         {
185             case GB_INT8_code   : GB_SEL_WORKER (_eq_thunk, _int8  , int8_t  )
186             case GB_INT16_code  : GB_SEL_WORKER (_eq_thunk, _int16 , int16_t )
187             case GB_INT32_code  : GB_SEL_WORKER (_eq_thunk, _int32 , int32_t )
188             case GB_INT64_code  : GB_SEL_WORKER (_eq_thunk, _int64 , int64_t )
189             case GB_UINT8_code  : GB_SEL_WORKER (_eq_thunk, _uint8 , uint8_t )
190             case GB_UINT16_code : GB_SEL_WORKER (_eq_thunk, _uint16, uint16_t)
191             case GB_UINT32_code : GB_SEL_WORKER (_eq_thunk, _uint32, uint32_t)
192             case GB_UINT64_code : GB_SEL_WORKER (_eq_thunk, _uint64, uint64_t)
193             case GB_FP32_code   : GB_SEL_WORKER (_eq_thunk, _fp32  , float   )
194             case GB_FP64_code   : GB_SEL_WORKER (_eq_thunk, _fp64  , double  )
195             case GB_FC32_code   : GB_SEL_WORKER (_eq_thunk, _fc32, GxB_FC32_t)
196             case GB_FC64_code   : GB_SEL_WORKER (_eq_thunk, _fc64, GxB_FC64_t)
197             default             : GB_SEL_WORKER (_eq_thunk, _any   , GB_void )
198         }
199         break ;
200 
201     case GB_GT_THUNK_opcode   : // A(i,j) > thunk
202 
203         // bool: if thunk is false, renamed GxB_GT_THUNK to GxB_NONZERO
204         //       if thunk is true,  return an empty matrix
205         // user type and complex: return error
206         switch (typecode)
207         {
208             case GB_INT8_code   : GB_SEL_WORKER (_gt_thunk, _int8  , int8_t  )
209             case GB_INT16_code  : GB_SEL_WORKER (_gt_thunk, _int16 , int16_t )
210             case GB_INT32_code  : GB_SEL_WORKER (_gt_thunk, _int32 , int32_t )
211             case GB_INT64_code  : GB_SEL_WORKER (_gt_thunk, _int64 , int64_t )
212             case GB_UINT8_code  : GB_SEL_WORKER (_gt_thunk, _uint8 , uint8_t )
213             case GB_UINT16_code : GB_SEL_WORKER (_gt_thunk, _uint16, uint16_t)
214             case GB_UINT32_code : GB_SEL_WORKER (_gt_thunk, _uint32, uint32_t)
215             case GB_UINT64_code : GB_SEL_WORKER (_gt_thunk, _uint64, uint64_t)
216             case GB_FP32_code   : GB_SEL_WORKER (_gt_thunk, _fp32  , float   )
217             case GB_FP64_code   : GB_SEL_WORKER (_gt_thunk, _fp64  , double  )
218             default: ;          // not for bool, complex, or user-defined
219         }
220         break ;
221 
222     case GB_GE_THUNK_opcode   : // A(i,j) >= thunk
223 
224         // bool: if thunk is false, use GB_dup
225         //       if thunk is true,  renamed GxB_GE_THUNK to GxB_NONZERO
226         // user type and complex: return error
227         switch (typecode)
228         {
229             case GB_INT8_code   : GB_SEL_WORKER (_ge_thunk, _int8  , int8_t  )
230             case GB_INT16_code  : GB_SEL_WORKER (_ge_thunk, _int16 , int16_t )
231             case GB_INT32_code  : GB_SEL_WORKER (_ge_thunk, _int32 , int32_t )
232             case GB_INT64_code  : GB_SEL_WORKER (_ge_thunk, _int64 , int64_t )
233             case GB_UINT8_code  : GB_SEL_WORKER (_ge_thunk, _uint8 , uint8_t )
234             case GB_UINT16_code : GB_SEL_WORKER (_ge_thunk, _uint16, uint16_t)
235             case GB_UINT32_code : GB_SEL_WORKER (_ge_thunk, _uint32, uint32_t)
236             case GB_UINT64_code : GB_SEL_WORKER (_ge_thunk, _uint64, uint64_t)
237             case GB_FP32_code   : GB_SEL_WORKER (_ge_thunk, _fp32  , float   )
238             case GB_FP64_code   : GB_SEL_WORKER (_ge_thunk, _fp64  , double  )
239             default: ;          // not for bool, complex, or user-defined
240         }
241         break ;
242 
243     case GB_LT_THUNK_opcode   : // A(i,j) < thunk
244 
245         // bool: if thunk is true,  renamed GxB_LT_THUNK to GxB_EQ_ZERO
246         //       if thunk is false, return an empty matrix
247         // user type and complex: return error
248         switch (typecode)
249         {
250             case GB_INT8_code   : GB_SEL_WORKER (_lt_thunk, _int8  , int8_t  )
251             case GB_INT16_code  : GB_SEL_WORKER (_lt_thunk, _int16 , int16_t )
252             case GB_INT32_code  : GB_SEL_WORKER (_lt_thunk, _int32 , int32_t )
253             case GB_INT64_code  : GB_SEL_WORKER (_lt_thunk, _int64 , int64_t )
254             case GB_UINT8_code  : GB_SEL_WORKER (_lt_thunk, _uint8 , uint8_t )
255             case GB_UINT16_code : GB_SEL_WORKER (_lt_thunk, _uint16, uint16_t)
256             case GB_UINT32_code : GB_SEL_WORKER (_lt_thunk, _uint32, uint32_t)
257             case GB_UINT64_code : GB_SEL_WORKER (_lt_thunk, _uint64, uint64_t)
258             case GB_FP32_code   : GB_SEL_WORKER (_lt_thunk, _fp32  , float   )
259             case GB_FP64_code   : GB_SEL_WORKER (_lt_thunk, _fp64  , double  )
260             default: ;          // not for bool, complex, or user-defined
261         }
262         break ;
263 
264     case GB_LE_THUNK_opcode   : // A(i,j) <= thunk
265 
266         // bool: if thunk is true,  use GB_dup
267         //       if thunk is false, renamed GxB_LE_ZERO to GxB_EQ_ZERO
268         // user type and complex: return error
269         switch (typecode)
270         {
271             case GB_INT8_code   : GB_SEL_WORKER (_le_thunk, _int8  , int8_t  )
272             case GB_INT16_code  : GB_SEL_WORKER (_le_thunk, _int16 , int16_t )
273             case GB_INT32_code  : GB_SEL_WORKER (_le_thunk, _int32 , int32_t )
274             case GB_INT64_code  : GB_SEL_WORKER (_le_thunk, _int64 , int64_t )
275             case GB_UINT8_code  : GB_SEL_WORKER (_le_thunk, _uint8 , uint8_t )
276             case GB_UINT16_code : GB_SEL_WORKER (_le_thunk, _uint16, uint16_t)
277             case GB_UINT32_code : GB_SEL_WORKER (_le_thunk, _uint32, uint32_t)
278             case GB_UINT64_code : GB_SEL_WORKER (_le_thunk, _uint64, uint64_t)
279             case GB_FP32_code   : GB_SEL_WORKER (_le_thunk, _fp32  , float   )
280             case GB_FP64_code   : GB_SEL_WORKER (_le_thunk, _fp64  , double  )
281             default: ;          // not for bool, complex, or user-defined
282         }
283         break ;
284 
285     default:  ;
286 }
287 
288