1 //------------------------------------------------------------------------------
2 // GB_binop_to_monoid: convert a binary op into its corresponding monoid
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 #include "GB.h"
11 #include "GB_binop.h"
12 
GB_binop_to_monoid(const GrB_BinaryOp op_in)13 GrB_Monoid *GB_binop_to_monoid      // return the corresponding monoid, or NULL
14 (
15     const GrB_BinaryOp op_in        // binary op to convert
16 )
17 {
18 
19     //--------------------------------------------------------------------------
20     // check inputs
21     //--------------------------------------------------------------------------
22 
23     if (op_in == NULL ||
24         op_in->xtype != op_in->ztype ||
25         op_in->ytype != op_in->ztype)
26     {
27         return (NULL) ;
28     }
29 
30     //--------------------------------------------------------------------------
31     // convert the binary op_in to its corresponding monoid
32     //--------------------------------------------------------------------------
33 
34     ASSERT_BINARYOP_OK (op_in, "binary op to convert to monoid", GB0) ;
35     GrB_BinaryOp op = GB_boolean_rename_op (op_in) ;
36     GB_Type_code zcode = op->ztype->code ;
37     GB_Opcode opcode = op->opcode ;
38 
39     switch (opcode)
40     {
41 
42         case GB_MIN_opcode:
43 
44             switch (zcode)
45             {
46                 // 10 MIN monoids: for 10 real types
47                 case GB_INT8_code   : return (GrB_MIN_MONOID_INT8    ) ;
48                 case GB_INT16_code  : return (GrB_MIN_MONOID_INT16   ) ;
49                 case GB_INT32_code  : return (GrB_MIN_MONOID_INT32   ) ;
50                 case GB_INT64_code  : return (GrB_MIN_MONOID_INT64   ) ;
51                 case GB_UINT8_code  : return (GrB_MIN_MONOID_UINT8   ) ;
52                 case GB_UINT16_code : return (GrB_MIN_MONOID_UINT16  ) ;
53                 case GB_UINT32_code : return (GrB_MIN_MONOID_UINT32  ) ;
54                 case GB_UINT64_code : return (GrB_MIN_MONOID_UINT64  ) ;
55                 case GB_FP32_code   : return (GrB_MIN_MONOID_FP32    ) ;
56                 case GB_FP64_code   : return (GrB_MIN_MONOID_FP64    ) ;
57                 default: ;
58             }
59             break ;
60 
61         case GB_MAX_opcode:
62 
63             switch (zcode)
64             {
65                 // 10 MAX monoids: for 10 real types
66                 case GB_INT8_code   : return (GrB_MAX_MONOID_INT8    ) ;
67                 case GB_INT16_code  : return (GrB_MAX_MONOID_INT16   ) ;
68                 case GB_INT32_code  : return (GrB_MAX_MONOID_INT32   ) ;
69                 case GB_INT64_code  : return (GrB_MAX_MONOID_INT64   ) ;
70                 case GB_UINT8_code  : return (GrB_MAX_MONOID_UINT8   ) ;
71                 case GB_UINT16_code : return (GrB_MAX_MONOID_UINT16  ) ;
72                 case GB_UINT32_code : return (GrB_MAX_MONOID_UINT32  ) ;
73                 case GB_UINT64_code : return (GrB_MAX_MONOID_UINT64  ) ;
74                 case GB_FP32_code   : return (GrB_MAX_MONOID_FP32    ) ;
75                 case GB_FP64_code   : return (GrB_MAX_MONOID_FP64    ) ;
76                 default: ;
77             }
78             break ;
79 
80         case GB_TIMES_opcode:
81 
82             switch (zcode)
83             {
84                 // 12 TIMES monoids: 10 real types, and 2 complex types
85                 case GB_INT8_code   : return (GrB_TIMES_MONOID_INT8  ) ;
86                 case GB_INT16_code  : return (GrB_TIMES_MONOID_INT16 ) ;
87                 case GB_INT32_code  : return (GrB_TIMES_MONOID_INT32 ) ;
88                 case GB_INT64_code  : return (GrB_TIMES_MONOID_INT64 ) ;
89                 case GB_UINT8_code  : return (GrB_TIMES_MONOID_UINT8 ) ;
90                 case GB_UINT16_code : return (GrB_TIMES_MONOID_UINT16) ;
91                 case GB_UINT32_code : return (GrB_TIMES_MONOID_UINT32) ;
92                 case GB_UINT64_code : return (GrB_TIMES_MONOID_UINT64) ;
93                 case GB_FP32_code   : return (GrB_TIMES_MONOID_FP32  ) ;
94                 case GB_FP64_code   : return (GrB_TIMES_MONOID_FP64  ) ;
95                 case GB_FC32_code   : return (GxB_TIMES_FC32_MONOID  ) ;
96                 case GB_FC64_code   : return (GxB_TIMES_FC64_MONOID  ) ;
97                 default: ;
98             }
99             break ;
100 
101         case GB_PLUS_opcode:
102 
103             switch (zcode)
104             {
105                 // 12 PLUS monoids: 10 real types, and 2 complex types
106                 case GB_INT8_code   : return (GrB_PLUS_MONOID_INT8   ) ;
107                 case GB_INT16_code  : return (GrB_PLUS_MONOID_INT16  ) ;
108                 case GB_INT32_code  : return (GrB_PLUS_MONOID_INT32  ) ;
109                 case GB_INT64_code  : return (GrB_PLUS_MONOID_INT64  ) ;
110                 case GB_UINT8_code  : return (GrB_PLUS_MONOID_UINT8  ) ;
111                 case GB_UINT16_code : return (GrB_PLUS_MONOID_UINT16 ) ;
112                 case GB_UINT32_code : return (GrB_PLUS_MONOID_UINT32 ) ;
113                 case GB_UINT64_code : return (GrB_PLUS_MONOID_UINT64 ) ;
114                 case GB_FP32_code   : return (GrB_PLUS_MONOID_FP32   ) ;
115                 case GB_FP64_code   : return (GrB_PLUS_MONOID_FP64   ) ;
116                 case GB_FC32_code   : return (GxB_PLUS_FC32_MONOID   ) ;
117                 case GB_FC64_code   : return (GxB_PLUS_FC64_MONOID   ) ;
118                 default: ;
119             }
120             break ;
121 
122         case GB_ANY_opcode:
123 
124             switch (zcode)
125             {
126                 // 13 ANY monoids: bool, 10 real types, and 2 complex types
127                 case GB_BOOL_code   : return (GxB_ANY_BOOL_MONOID    ) ;
128                 case GB_INT8_code   : return (GxB_ANY_INT8_MONOID    ) ;
129                 case GB_INT16_code  : return (GxB_ANY_INT16_MONOID   ) ;
130                 case GB_INT32_code  : return (GxB_ANY_INT32_MONOID   ) ;
131                 case GB_INT64_code  : return (GxB_ANY_INT64_MONOID   ) ;
132                 case GB_UINT8_code  : return (GxB_ANY_UINT8_MONOID   ) ;
133                 case GB_UINT16_code : return (GxB_ANY_UINT16_MONOID  ) ;
134                 case GB_UINT32_code : return (GxB_ANY_UINT32_MONOID  ) ;
135                 case GB_UINT64_code : return (GxB_ANY_UINT64_MONOID  ) ;
136                 case GB_FP32_code   : return (GxB_ANY_FP32_MONOID    ) ;
137                 case GB_FP64_code   : return (GxB_ANY_FP64_MONOID    ) ;
138                 case GB_FC32_code   : return (GxB_ANY_FC32_MONOID    ) ;
139                 case GB_FC64_code   : return (GxB_ANY_FC64_MONOID    ) ;
140                 default: ;
141             }
142             break ;
143 
144         // 4 boolean monoids: (see also GxB_ANY_BOOL_MONOID above)
145         #define B(monoid) return ((zcode == GB_BOOL_code) ? monoid : NULL) ;
146         case GB_LOR_opcode   : B (GrB_LOR_MONOID_BOOL)   ;
147         case GB_LAND_opcode  : B (GrB_LAND_MONOID_BOOL)  ;
148         case GB_LXOR_opcode  : B (GrB_LXOR_MONOID_BOOL)  ;
149         case GB_EQ_opcode    : B (GrB_LXNOR_MONOID_BOOL) ;
150 
151         case GB_BOR_opcode:
152 
153             switch (zcode)
154             {
155                 // 4 BOR monoids
156                 case GB_UINT8_code  : return (GxB_BOR_UINT8_MONOID   ) ;
157                 case GB_UINT16_code : return (GxB_BOR_UINT16_MONOID  ) ;
158                 case GB_UINT32_code : return (GxB_BOR_UINT32_MONOID  ) ;
159                 case GB_UINT64_code : return (GxB_BOR_UINT64_MONOID  ) ;
160                 default: ;
161             }
162             break ;
163 
164         case GB_BAND_opcode:
165 
166             switch (zcode)
167             {
168                 // 4 BAND monoids
169                 case GB_UINT8_code  : return (GxB_BAND_UINT8_MONOID  ) ;
170                 case GB_UINT16_code : return (GxB_BAND_UINT16_MONOID ) ;
171                 case GB_UINT32_code : return (GxB_BAND_UINT32_MONOID ) ;
172                 case GB_UINT64_code : return (GxB_BAND_UINT64_MONOID ) ;
173                 default: ;
174             }
175             break ;
176 
177         case GB_BXOR_opcode:
178 
179             switch (zcode)
180             {
181                 // 4 BXOR monoids
182                 case GB_UINT8_code  : return (GxB_BXOR_UINT8_MONOID  ) ;
183                 case GB_UINT16_code : return (GxB_BXOR_UINT16_MONOID ) ;
184                 case GB_UINT32_code : return (GxB_BXOR_UINT32_MONOID ) ;
185                 case GB_UINT64_code : return (GxB_BXOR_UINT64_MONOID ) ;
186                 default: ;
187             }
188             break ;
189 
190         case GB_BXNOR_opcode:
191 
192             switch (zcode)
193             {
194                 // 4 BXNOR monoids
195                 case GB_UINT8_code  : return (GxB_BXNOR_UINT8_MONOID ) ;
196                 case GB_UINT16_code : return (GxB_BXNOR_UINT16_MONOID) ;
197                 case GB_UINT32_code : return (GxB_BXNOR_UINT32_MONOID) ;
198                 case GB_UINT64_code : return (GxB_BXNOR_UINT64_MONOID) ;
199                 default: ;
200             }
201             break ;
202 
203         default : ;
204             // user-defined binary operatory, or other built-in binary op
205     }
206 
207     //--------------------------------------------------------------------------
208     // op_in binary operator does not correspond to a known monoid
209     //--------------------------------------------------------------------------
210 
211     return (NULL) ;
212 }
213 
214