1 //------------------------------------------------------------------------------
2 // GB_stringify_mask: construct macros to access the mask
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7
8 //------------------------------------------------------------------------------
9
10 // User-defined types cannot be used as a valued mask. They can be used
11 // as structural masks.
12
13 #include "GB.h"
14 #include "GB_stringify.h"
15
16 //------------------------------------------------------------------------------
17 // GB_stringify_mask: return string to define mask macros
18 //------------------------------------------------------------------------------
19
GB_stringify_mask(char ** mask_macros,const GB_Type_code mcode,bool Mask_struct,bool Mask_comp)20 void GB_stringify_mask // return string to define mask macros
21 (
22 // output:
23 char **mask_macros, // string that defines the mask macros
24 // input:
25 const GB_Type_code mcode, // typecode of the mask matrix M,
26 // or 0 if M is not present
27 bool Mask_struct, // true if M structural, false if valued
28 bool Mask_comp // true if M complemented
29 )
30 {
31
32 int mask_ecode ;
33
34 // get mask_ecode from mask type (mask_ecode) and mask descriptor
35 GB_enumify_mask (&mask_ecode, mcode, Mask_struct, Mask_comp) ;
36
37 // convert ecode to string containing mask macros
38 GB_macrofy_mask (mask_macros, mask_ecode) ;
39 }
40
41 //------------------------------------------------------------------------------
42 // GB_enumify_mask: return mask_ecode to define mask macros
43 //------------------------------------------------------------------------------
44
GB_enumify_mask(int * mask_ecode,const GB_Type_code mcode,bool Mask_struct,bool Mask_comp)45 void GB_enumify_mask // return enum to define mask macros
46 (
47 // output:
48 int *mask_ecode, // enumified mask
49 // input
50 const GB_Type_code mcode, // typecode of the mask matrix M,
51 // or 0 if M is not present
52 bool Mask_struct, // true if M structural, false if valued
53 bool Mask_comp // true if M complemented
54 )
55 {
56
57 // Mask_comp becomes the least significant bit, so that
58 // Mask_comp = (mask_ecode & 0x1) can be computed later.
59 // Mask_struct = (mask_ecode == 2 || mask_ecode == 3)
60
61 int e = -1 ;
62
63 if (mcode == 0)
64 {
65
66 //----------------------------------------------------------------------
67 // no mask is present
68 //----------------------------------------------------------------------
69
70 // Mask_struct is ignored, but the mask may be complemented or not
71
72 // user-defined types are OK. The values of M are not accessed.
73 e = (!Mask_comp) ? 0 : 1 ;
74
75 }
76 else if (Mask_struct)
77 {
78
79 //----------------------------------------------------------------------
80 // M is present, and structural (not valued).
81 //----------------------------------------------------------------------
82
83 // user-defined types are OK. The values of M are not accessed.
84 e = (!Mask_comp) ? 2 : 3 ;
85
86 }
87 else
88 {
89
90 //----------------------------------------------------------------------
91 // M is present, and valued
92 //----------------------------------------------------------------------
93
94 switch (mcode)
95 {
96
97 case GB_BOOL_code:
98 case GB_INT8_code:
99 case GB_UINT8_code:
100
101 // valued mask, values are 1 byte in size
102 e = (!Mask_comp) ? 4 : 5 ;
103 break ;
104
105 case GB_INT16_code:
106 case GB_UINT16_code:
107
108 // valued mask, values are 2 bytes in size
109 e = (!Mask_comp) ? 6 : 7 ;
110 break ;
111
112 case GB_INT32_code:
113 case GB_UINT32_code:
114 case GB_FP32_code:
115
116 // valued mask, values are 4 bytes in size
117 e = (!Mask_comp) ? 8 : 9 ;
118 break ;
119
120 case GB_INT64_code:
121 case GB_UINT64_code:
122 case GB_FC32_code:
123 case GB_FP64_code:
124
125 // valued mask, values are 8 bytes in size
126 e = (!Mask_comp) ? 10 : 11 ;
127 break ;
128
129 case GB_FC64_code:
130
131 // valued mask, values are 16 bytes in size
132 e = (!Mask_comp) ? 12 : 13 ;
133 break ;
134
135 default: ;
136 // user-defined types are not allowed
137 e = -1 ;
138 break ;
139 }
140 }
141
142 (*mask_ecode) = e ;
143 }
144
145 //------------------------------------------------------------------------------
146 // GB_macrofy_mask: return string to define mask macros
147 //------------------------------------------------------------------------------
148
GB_macrofy_mask(char ** mask_macros,int mask_ecode)149 void GB_macrofy_mask // return enum to define mask macros
150 (
151 // output:
152 char **mask_macros, // string that defines the mask macros
153 // input
154 int mask_ecode // enumified mask
155 )
156 {
157
158 const char *f ;
159
160 switch (mask_ecode)
161 {
162
163 //----------------------------------------------------------------------
164 // no mask
165 //----------------------------------------------------------------------
166
167 case 0 : // mask not complemented
168 f = "#define GB_MTYPE (no mask present)\n"
169 "#define MX(p) (no mask present)\n"
170 "#define GB_MASK_COMP false" ;
171 break ;
172
173 case 1 : // mask complemented
174 f = "#define GB_MTYPE (no mask present)\n"
175 "#define MX(p) (no mask present)\n"
176 "#define GB_MASK_COMP true" ;
177 break ;
178
179 //----------------------------------------------------------------------
180 // M is present, and structural (not valued)
181 //----------------------------------------------------------------------
182
183 case 2 :
184 // mask not complemented, type: structural
185 f = "#define GB_MTYPE void\n"
186 "#define MX(p) true\n"
187 "#define GB_MASK_COMP false" ;
188 break ;
189
190 case 3 :
191 // mask complemented, type: structural
192 f = "#define GB_MTYPE void\n"
193 "#define MX(p) true\n"
194 "#define GB_MASK_COMP true" ;
195 break ;
196
197 //----------------------------------------------------------------------
198 // M is present, valued, size: 1 byte
199 //----------------------------------------------------------------------
200
201 case 4 :
202 // mask not complemented, type: bool, int8, uint8
203 f = "#define GB_MTYPE uint8_t\n"
204 "#define MX(p) (Mx [p] != 0)\n"
205 "#define GB_MASK_COMP false" ;
206 break ;
207
208 case 5 :
209 // mask complemented, type: bool, int8, uint8
210 f = "#define GB_MTYPE uint8_t\n"
211 "#define MX(p) (Mx [p] != 0)\n"
212 "#define GB_MASK_COMP true" ;
213 break ;
214
215 //----------------------------------------------------------------------
216 // M is present, valued, size: 2 bytes
217 //----------------------------------------------------------------------
218
219 case 6 :
220 // mask not complemented, type: int16, uint16
221 f = "#define GB_MTYPE uint16_t\n"
222 "#define MX(p) (Mx [p] != 0)\n"
223 "#define GB_MASK_COMP false" ;
224 break ;
225
226 case 7 :
227 // mask complemented, type: int16, uint16
228 f = "#define GB_MTYPE uint16_t\n"
229 "#define MX(p) (Mx [p] != 0)\n"
230 "#define GB_MASK_COMP true" ;
231 break ;
232
233 //----------------------------------------------------------------------
234 // M is present, valued, size: 4 bytes
235 //----------------------------------------------------------------------
236
237 case 8 :
238 // mask not complemented, type: float, int32, uint32
239 f = "#define GB_MTYPE uint32_t\n"
240 "#define MX(p) (Mx [p] != 0)\n"
241 "#define GB_MASK_COMP false" ;
242 break ;
243
244 case 9 :
245 // mask complemented, type: float, int32, uint32
246 f = "#define GB_MTYPE uint32_t\n"
247 "#define MX(p) (Mx [p] != 0)\n"
248 "#define GB_MASK_COMP true" ;
249 break ;
250
251 //----------------------------------------------------------------------
252 // M is present, valued, size: 8 bytes
253 //----------------------------------------------------------------------
254
255 case 10 :
256 // mask not complemented, type: double, float complex, int64, uint64
257 f = "#define GB_MTYPE uint64_t\n"
258 "#define MX(p) (Mx [p] != 0)\n"
259 "#define GB_MASK_COMP false" ;
260 break ;
261
262 case 11 :
263 // mask complemented, type: double, float complex, int64, uint64
264 f = "#define GB_MTYPE uint64_t\n"
265 "#define MX(p) (Mx [p] != 0)\n"
266 "#define GB_MASK_COMP true" ;
267 break ;
268
269 //----------------------------------------------------------------------
270 // M is present, valued, size: 16 bytes
271 //----------------------------------------------------------------------
272
273 case 12 :
274 // mask not complemented, type: double complex
275 f = "#define GB_MTYPE uint64_t\n"
276 "#define MX(p) (Mx [2*(p)] != 0 || Mx [2*(p)+1] != 0)\n"
277 "#define GB_MASK_COMP false" ;
278 break ;
279
280 case 13 :
281 // mask complemented, type: double complex
282 f = "#define GB_MTYPE uint64_t\n"
283 "#define MX(p) (Mx [2*(p)] != 0 || Mx [2*(p)+1] != 0)\n"
284 "#define GB_MASK_COMP true" ;
285 break ;
286
287 //----------------------------------------------------------------------
288 // invalid case
289 //----------------------------------------------------------------------
290
291 default: ;
292 f = NULL ;
293 break ;
294 }
295
296 (*mask_macros) = f ;
297 }
298
299