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