1 //------------------------------------------------------------------------------
2 // GB_red_factory.c: switch factory for reduction operators
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 // This is a generic body of code for creating hard-coded versions of code for
11 // 61 or 87 combinations of associative operators and built-in types:
12 
13 //  20:  min, max: 10 non-boolean real types
14 //  24:  plus, times:  12 non-boolean types
15 //  4:   lor, land, eq (same as lxnor), lxor for boolean
16 //  13:  any: for all 13 types
17 //  26:  first, second: for all 13 types, if GB_INCLUDE_SECOND_OPERATOR
18 //          is defined, for GB_builder.
19 
20 if (typecode != GB_BOOL_code)
21 {
22 
23     //--------------------------------------------------------------------------
24     // non-boolean case
25     //--------------------------------------------------------------------------
26 
27     switch (opcode)
28     {
29 
30         case GB_MIN_opcode   :
31 
32             switch (typecode)
33             {
34                 case GB_INT8_code   : GB_RED_WORKER (_min, _int8,   int8_t  )
35                 case GB_INT16_code  : GB_RED_WORKER (_min, _int16,  int16_t )
36                 case GB_INT32_code  : GB_RED_WORKER (_min, _int32,  int32_t )
37                 case GB_INT64_code  : GB_RED_WORKER (_min, _int64,  int64_t )
38                 case GB_UINT8_code  : GB_RED_WORKER (_min, _uint8,  uint8_t )
39                 case GB_UINT16_code : GB_RED_WORKER (_min, _uint16, uint16_t)
40                 case GB_UINT32_code : GB_RED_WORKER (_min, _uint32, uint32_t)
41                 case GB_UINT64_code : GB_RED_WORKER (_min, _uint64, uint64_t)
42                 case GB_FP32_code   : GB_RED_WORKER (_min, _fp32,   float   )
43                 case GB_FP64_code   : GB_RED_WORKER (_min, _fp64,   double  )
44                 default: ;
45             }
46             break ;
47 
48         case GB_MAX_opcode   :
49 
50             switch (typecode)
51             {
52                 case GB_INT8_code   : GB_RED_WORKER (_max, _int8,   int8_t  )
53                 case GB_INT16_code  : GB_RED_WORKER (_max, _int16,  int16_t )
54                 case GB_INT32_code  : GB_RED_WORKER (_max, _int32,  int32_t )
55                 case GB_INT64_code  : GB_RED_WORKER (_max, _int64,  int64_t )
56                 case GB_UINT8_code  : GB_RED_WORKER (_max, _uint8,  uint8_t )
57                 case GB_UINT16_code : GB_RED_WORKER (_max, _uint16, uint16_t)
58                 case GB_UINT32_code : GB_RED_WORKER (_max, _uint32, uint32_t)
59                 case GB_UINT64_code : GB_RED_WORKER (_max, _uint64, uint64_t)
60                 case GB_FP32_code   : GB_RED_WORKER (_max, _fp32,   float   )
61                 case GB_FP64_code   : GB_RED_WORKER (_max, _fp64,   double  )
62                 default: ;
63             }
64             break ;
65 
66         case GB_PLUS_opcode  :
67 
68             switch (typecode)
69             {
70                 case GB_INT8_code   : GB_RED_WORKER (_plus, _int8,   int8_t  )
71                 case GB_INT16_code  : GB_RED_WORKER (_plus, _int16,  int16_t )
72                 case GB_INT32_code  : GB_RED_WORKER (_plus, _int32,  int32_t )
73                 case GB_INT64_code  : GB_RED_WORKER (_plus, _int64,  int64_t )
74                 case GB_UINT8_code  : GB_RED_WORKER (_plus, _uint8,  uint8_t )
75                 case GB_UINT16_code : GB_RED_WORKER (_plus, _uint16, uint16_t)
76                 case GB_UINT32_code : GB_RED_WORKER (_plus, _uint32, uint32_t)
77                 case GB_UINT64_code : GB_RED_WORKER (_plus, _uint64, uint64_t)
78                 case GB_FP32_code   : GB_RED_WORKER (_plus, _fp32,   float   )
79                 case GB_FP64_code   : GB_RED_WORKER (_plus, _fp64,   double  )
80                 case GB_FC32_code   : GB_RED_WORKER (_plus, _fc32,   GxB_FC32_t)
81                 case GB_FC64_code   : GB_RED_WORKER (_plus, _fc64,   GxB_FC64_t)
82                 default: ;
83             }
84             break ;
85 
86         case GB_TIMES_opcode :
87 
88             switch (typecode)
89             {
90                 case GB_INT8_code   : GB_RED_WORKER (_times, _int8,   int8_t  )
91                 case GB_INT16_code  : GB_RED_WORKER (_times, _int16,  int16_t )
92                 case GB_INT32_code  : GB_RED_WORKER (_times, _int32,  int32_t )
93                 case GB_INT64_code  : GB_RED_WORKER (_times, _int64,  int64_t )
94                 case GB_UINT8_code  : GB_RED_WORKER (_times, _uint8,  uint8_t )
95                 case GB_UINT16_code : GB_RED_WORKER (_times, _uint16, uint16_t)
96                 case GB_UINT32_code : GB_RED_WORKER (_times, _uint32, uint32_t)
97                 case GB_UINT64_code : GB_RED_WORKER (_times, _uint64, uint64_t)
98                 case GB_FP32_code   : GB_RED_WORKER (_times, _fp32,   float   )
99                 case GB_FP64_code   : GB_RED_WORKER (_times, _fp64,   double  )
100                 case GB_FC32_code   : GB_RED_WORKER (_times, _fc32, GxB_FC32_t)
101                 case GB_FC64_code   : GB_RED_WORKER (_times, _fc64, GxB_FC64_t)
102                 default: ;
103             }
104             break ;
105 
106         case GB_ANY_opcode :
107 
108             switch (typecode)
109             {
110                 case GB_INT8_code   : GB_RED_WORKER (_any, _int8,   int8_t  )
111                 case GB_INT16_code  : GB_RED_WORKER (_any, _int16,  int16_t )
112                 case GB_INT32_code  : GB_RED_WORKER (_any, _int32,  int32_t )
113                 case GB_INT64_code  : GB_RED_WORKER (_any, _int64,  int64_t )
114                 case GB_UINT8_code  : GB_RED_WORKER (_any, _uint8,  uint8_t )
115                 case GB_UINT16_code : GB_RED_WORKER (_any, _uint16, uint16_t)
116                 case GB_UINT32_code : GB_RED_WORKER (_any, _uint32, uint32_t)
117                 case GB_UINT64_code : GB_RED_WORKER (_any, _uint64, uint64_t)
118                 case GB_FP32_code   : GB_RED_WORKER (_any, _fp32,   float   )
119                 case GB_FP64_code   : GB_RED_WORKER (_any, _fp64,   double  )
120                 case GB_FC32_code   : GB_RED_WORKER (_any, _fc32, GxB_FC32_t)
121                 case GB_FC64_code   : GB_RED_WORKER (_any, _fc64, GxB_FC64_t)
122                 default: ;
123             }
124             break ;
125 
126         //----------------------------------------------------------------------
127         // FIRST and SECOND for GB_builder
128         //----------------------------------------------------------------------
129 
130         #ifdef GB_INCLUDE_SECOND_OPERATOR
131 
132         case GB_FIRST_opcode :
133 
134             switch (typecode)
135             {
136                 case GB_INT8_code   : GB_RED_WORKER (_first, _int8,   int8_t  )
137                 case GB_INT16_code  : GB_RED_WORKER (_first, _int16,  int16_t )
138                 case GB_INT32_code  : GB_RED_WORKER (_first, _int32,  int32_t )
139                 case GB_INT64_code  : GB_RED_WORKER (_first, _int64,  int64_t )
140                 case GB_UINT8_code  : GB_RED_WORKER (_first, _uint8,  uint8_t )
141                 case GB_UINT16_code : GB_RED_WORKER (_first, _uint16, uint16_t)
142                 case GB_UINT32_code : GB_RED_WORKER (_first, _uint32, uint32_t)
143                 case GB_UINT64_code : GB_RED_WORKER (_first, _uint64, uint64_t)
144                 case GB_FP32_code   : GB_RED_WORKER (_first, _fp32,   float   )
145                 case GB_FP64_code   : GB_RED_WORKER (_first, _fp64,   double  )
146                 case GB_FC32_code   : GB_RED_WORKER (_first, _fc32, GxB_FC32_t)
147                 case GB_FC64_code   : GB_RED_WORKER (_first, _fc64, GxB_FC64_t)
148                 default: ;
149             }
150             break ;
151 
152         case GB_SECOND_opcode :
153 
154             switch (typecode)
155             {
156                 case GB_INT8_code   : GB_RED_WORKER (_second, _int8,   int8_t  )
157                 case GB_INT16_code  : GB_RED_WORKER (_second, _int16,  int16_t )
158                 case GB_INT32_code  : GB_RED_WORKER (_second, _int32,  int32_t )
159                 case GB_INT64_code  : GB_RED_WORKER (_second, _int64,  int64_t )
160                 case GB_UINT8_code  : GB_RED_WORKER (_second, _uint8,  uint8_t )
161                 case GB_UINT16_code : GB_RED_WORKER (_second, _uint16, uint16_t)
162                 case GB_UINT32_code : GB_RED_WORKER (_second, _uint32, uint32_t)
163                 case GB_UINT64_code : GB_RED_WORKER (_second, _uint64, uint64_t)
164                 case GB_FP32_code   : GB_RED_WORKER (_second, _fp32,   float   )
165                 case GB_FP64_code   : GB_RED_WORKER (_second, _fp64,   double  )
166                 case GB_FC32_code   : GB_RED_WORKER (_second, _fc32, GxB_FC32_t)
167                 case GB_FC64_code   : GB_RED_WORKER (_second, _fc64, GxB_FC64_t)
168                 default: ;
169             }
170             break ;
171 
172         #endif
173 
174         default: ;
175     }
176 
177 }
178 else
179 {
180 
181     //--------------------------------------------------------------------------
182     // boolean case: rename the opcode as needed
183     //--------------------------------------------------------------------------
184 
185     // The FIRST and SECOND operators are not associative, but are added for
186     // GB_builder.
187 
188     switch (GB_boolean_rename (opcode))
189     {
190         case GB_LOR_opcode    : GB_RED_WORKER (_lor,    _bool, bool)
191         case GB_LAND_opcode   : GB_RED_WORKER (_land,   _bool, bool)
192         case GB_LXOR_opcode   : GB_RED_WORKER (_lxor,   _bool, bool)
193         case GB_EQ_opcode     : GB_RED_WORKER (_eq,     _bool, bool)
194         case GB_ANY_opcode    : GB_RED_WORKER (_any,    _bool, bool)
195         #ifdef GB_INCLUDE_SECOND_OPERATOR
196         case GB_FIRST_opcode  : GB_RED_WORKER (_first,  _bool, bool)
197         case GB_SECOND_opcode : GB_RED_WORKER (_second, _bool, bool)
198         #endif
199         default: ;
200     }
201 }
202 
203