1 //------------------------------------------------------------------------------
2 // GB_AxB_type_factory.c: switch factory for C=A*B
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 // A template file #include'd in GB_AxB_factory.c, which calls up to 61
11 // semirings.  Not all multiplicative operators and types are used with every
12 // monoid.  The 2 complex types appear only in the times, plus, and any
13 // monoids, for a subset of the multiply operators.
14 
15 //  min monoid:     10 real, non-boolean types
16 //  max monoid:     10 real, non-boolean types
17 //  times monoid:   10 real, non-boolean types (+2 if complex)
18 //  plus monoid:    10 real, non-boolean types (+2 if complex)
19 //  any monoid:     10 real, non-boolean types (+2 if complex)
20 //  boolean:        5 monoids: lor, land, eq, lxor, any
21 
22 // GB_NO_BOOLEAN is defined for multiply operators in the #include'ing file
23 // (min, max, plus, minus, rminus, times, div, rdiv, is*) since those multiply
24 // operators are redundant and have been renamed.  For these, the boolean
25 // monoids are not needed.
26 
27 // GB_NO_MIN_MAX_ANY_TIMES_MONOIDS is defined for the LOR, LAND, and LXOR
28 // multiply operators; these are valid semirings, but not useful.  The
29 // corresponding semirings (such as GxB_TIMES_LOR_FP32) still exist, but are
30 // done using the generic methods, not via fast methods controlled by this case
31 // statement.
32 
33 // For the PAIR multiply operator, the monoids MIN, MAX, TIMES, EQ, LAND,
34 // and LOR have been renamed to ANY_PAIR.  See GB_AxB_semiring_builtin.c.
35 
36 // the additive operator is a monoid, where all types of x,y,z are the same
37 ASSERT (zcode == xcode) ;
38 ASSERT (zcode == ycode) ;
39 ASSERT (mult_opcode != GB_ANY_opcode) ;
40 
41 if (xcode != GB_BOOL_code)
42 {
43     switch (add_opcode)
44     {
45 
46         // disable the MIN, MAX, ANY, and TIMES monoids for some multops
47         #ifndef GB_NO_MIN_MAX_ANY_TIMES_MONOIDS
48 
49         // MIN_PAIR, MAX_PAIR, and TIMES_PAIR have been renamed to ANY_PAIR
50         #ifndef GB_MULT_IS_PAIR_OPERATOR
51 
52         case GB_MIN_opcode:
53 
54             switch (xcode)
55             {
56                 // 10 real, non-boolean types
57                 case GB_INT8_code   : GB_AxB_WORKER (_min, GB_MNAME, _int8  )
58                 case GB_INT16_code  : GB_AxB_WORKER (_min, GB_MNAME, _int16 )
59                 case GB_INT32_code  : GB_AxB_WORKER (_min, GB_MNAME, _int32 )
60                 case GB_INT64_code  : GB_AxB_WORKER (_min, GB_MNAME, _int64 )
61                 case GB_UINT8_code  : GB_AxB_WORKER (_min, GB_MNAME, _uint8 )
62                 case GB_UINT16_code : GB_AxB_WORKER (_min, GB_MNAME, _uint16)
63                 case GB_UINT32_code : GB_AxB_WORKER (_min, GB_MNAME, _uint32)
64                 case GB_UINT64_code : GB_AxB_WORKER (_min, GB_MNAME, _uint64)
65                 case GB_FP32_code   : GB_AxB_WORKER (_min, GB_MNAME, _fp32  )
66                 case GB_FP64_code   : GB_AxB_WORKER (_min, GB_MNAME, _fp64  )
67                 default: ;
68             }
69             break ;
70 
71         case GB_MAX_opcode:
72 
73             switch (xcode)
74             {
75                 // 10 real, non-boolean types
76                 case GB_INT8_code   : GB_AxB_WORKER (_max, GB_MNAME, _int8  )
77                 case GB_INT16_code  : GB_AxB_WORKER (_max, GB_MNAME, _int16 )
78                 case GB_INT32_code  : GB_AxB_WORKER (_max, GB_MNAME, _int32 )
79                 case GB_INT64_code  : GB_AxB_WORKER (_max, GB_MNAME, _int64 )
80                 case GB_UINT8_code  : GB_AxB_WORKER (_max, GB_MNAME, _uint8 )
81                 case GB_UINT16_code : GB_AxB_WORKER (_max, GB_MNAME, _uint16)
82                 case GB_UINT32_code : GB_AxB_WORKER (_max, GB_MNAME, _uint32)
83                 case GB_UINT64_code : GB_AxB_WORKER (_max, GB_MNAME, _uint64)
84                 case GB_FP32_code   : GB_AxB_WORKER (_max, GB_MNAME, _fp32  )
85                 case GB_FP64_code   : GB_AxB_WORKER (_max, GB_MNAME, _fp64  )
86                 default: ;
87             }
88             break ;
89 
90         case GB_TIMES_opcode:
91 
92             switch (xcode)
93             {
94                 // 10 real, non-boolean types, plus 2 complex
95                 case GB_INT8_code   : GB_AxB_WORKER (_times, GB_MNAME, _int8  )
96                 case GB_INT16_code  : GB_AxB_WORKER (_times, GB_MNAME, _int16 )
97                 case GB_INT32_code  : GB_AxB_WORKER (_times, GB_MNAME, _int32 )
98                 case GB_INT64_code  : GB_AxB_WORKER (_times, GB_MNAME, _int64 )
99                 case GB_UINT8_code  : GB_AxB_WORKER (_times, GB_MNAME, _uint8 )
100                 case GB_UINT16_code : GB_AxB_WORKER (_times, GB_MNAME, _uint16)
101                 case GB_UINT32_code : GB_AxB_WORKER (_times, GB_MNAME, _uint32)
102                 case GB_UINT64_code : GB_AxB_WORKER (_times, GB_MNAME, _uint64)
103                 case GB_FP32_code   : GB_AxB_WORKER (_times, GB_MNAME, _fp32  )
104                 case GB_FP64_code   : GB_AxB_WORKER (_times, GB_MNAME, _fp64  )
105                 #if defined ( GB_COMPLEX )
106                 case GB_FC32_code   : GB_AxB_WORKER (_times, GB_MNAME, _fc32  )
107                 case GB_FC64_code   : GB_AxB_WORKER (_times, GB_MNAME, _fc64  )
108                 #endif
109                 default: ;
110             }
111             break ;
112 
113         #endif
114 
115         case GB_ANY_opcode:
116 
117             switch (xcode)
118             {
119                 // 10 real, non-boolean types, plus 2 complex
120                 case GB_INT8_code   : GB_AxB_WORKER (_any, GB_MNAME, _int8  )
121                 case GB_INT16_code  : GB_AxB_WORKER (_any, GB_MNAME, _int16 )
122                 case GB_INT32_code  : GB_AxB_WORKER (_any, GB_MNAME, _int32 )
123                 case GB_INT64_code  : GB_AxB_WORKER (_any, GB_MNAME, _int64 )
124                 case GB_UINT8_code  : GB_AxB_WORKER (_any, GB_MNAME, _uint8 )
125                 case GB_UINT16_code : GB_AxB_WORKER (_any, GB_MNAME, _uint16)
126                 case GB_UINT32_code : GB_AxB_WORKER (_any, GB_MNAME, _uint32)
127                 case GB_UINT64_code : GB_AxB_WORKER (_any, GB_MNAME, _uint64)
128                 case GB_FP32_code   : GB_AxB_WORKER (_any, GB_MNAME, _fp32  )
129                 case GB_FP64_code   : GB_AxB_WORKER (_any, GB_MNAME, _fp64  )
130                 #if defined ( GB_COMPLEX )
131                 case GB_FC32_code   : GB_AxB_WORKER (_any, GB_MNAME, _fc32  )
132                 case GB_FC64_code   : GB_AxB_WORKER (_any, GB_MNAME, _fc64  )
133                 #endif
134                 default: ;
135             }
136             break ;
137 
138         #endif
139 
140         case GB_PLUS_opcode:
141 
142             switch (xcode)
143             {
144                 // 10 real, non-boolean types, plus 2 complex
145                 case GB_INT8_code   : GB_AxB_WORKER (_plus, GB_MNAME, _int8  )
146                 case GB_INT16_code  : GB_AxB_WORKER (_plus, GB_MNAME, _int16 )
147                 case GB_INT32_code  : GB_AxB_WORKER (_plus, GB_MNAME, _int32 )
148                 case GB_INT64_code  : GB_AxB_WORKER (_plus, GB_MNAME, _int64 )
149                 case GB_UINT8_code  : GB_AxB_WORKER (_plus, GB_MNAME, _uint8 )
150                 case GB_UINT16_code : GB_AxB_WORKER (_plus, GB_MNAME, _uint16)
151                 case GB_UINT32_code : GB_AxB_WORKER (_plus, GB_MNAME, _uint32)
152                 case GB_UINT64_code : GB_AxB_WORKER (_plus, GB_MNAME, _uint64)
153                 case GB_FP32_code   : GB_AxB_WORKER (_plus, GB_MNAME, _fp32  )
154                 case GB_FP64_code   : GB_AxB_WORKER (_plus, GB_MNAME, _fp64  )
155                 #if defined ( GB_COMPLEX )
156                 case GB_FC32_code   : GB_AxB_WORKER (_plus, GB_MNAME, _fc32  )
157                 case GB_FC64_code   : GB_AxB_WORKER (_plus, GB_MNAME, _fc64  )
158                 #endif
159                 default: ;
160             }
161             break ;
162 
163         default: ;
164     }
165 }
166 
167 #ifndef GB_NO_BOOLEAN
168 else
169 {
170         switch (add_opcode)
171         {
172             // 5 boolean monoids
173             #ifndef GB_MULT_IS_PAIR_OPERATOR
174             // EQ_PAIR, LOR_PAIR, LAND_PAIR, been renamed to ANY_PAIR
175             case GB_LOR_opcode  : GB_AxB_WORKER (_lor , GB_MNAME, _bool)
176             case GB_LAND_opcode : GB_AxB_WORKER (_land, GB_MNAME, _bool)
177             case GB_EQ_opcode   : GB_AxB_WORKER (_eq  , GB_MNAME, _bool)
178             #endif
179             case GB_LXOR_opcode : GB_AxB_WORKER (_lxor, GB_MNAME, _bool)
180             case GB_ANY_opcode  : GB_AxB_WORKER (_any , GB_MNAME, _bool)
181             default: ;
182         }
183 }
184 #endif
185 
186 #undef GB_NO_BOOLEAN
187 #undef GB_MNAME
188 #undef GB_COMPLEX
189 
190