1 //------------------------------------------------------------------------------
2 // GB_bitmap_assign_notM_noaccum_whole: assign to C bitmap
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7
8 //------------------------------------------------------------------------------
9 // C<!M> = A assign
10 // C<!M> = A subassign
11
12 // C<!M,repl> = A assign
13 // C<!M,repl> = A subassign
14 //------------------------------------------------------------------------------
15
16 // C: bitmap
17 // M: present, hypersparse or sparse (not bitmap or full)
18 // Mask_comp: true
19 // Mask_struct: true or false
20 // C_replace: true or false
21 // accum: not present
22 // A: matrix (hyper, sparse, bitmap, or full), or scalar
23 // kind: assign or subassign (same action)
24
25 #include "GB_bitmap_assign_methods.h"
26
27 #define GB_FREE_ALL \
28 { \
29 GB_WERK_POP (M_ek_slicing, int64_t) ; \
30 }
31
GB_bitmap_assign_notM_noaccum_whole(GrB_Matrix C,const bool C_replace,const GrB_Matrix M,const bool Mask_struct,const GrB_Matrix A,const void * scalar,const GrB_Type scalar_type,GB_Context Context)32 GrB_Info GB_bitmap_assign_notM_noaccum_whole
33 (
34 // input/output:
35 GrB_Matrix C, // input/output matrix in bitmap format
36 // inputs:
37 const bool C_replace, // descriptor for C
38 const GrB_Matrix M, // mask matrix
39 // const bool Mask_comp, // true here, for !M only
40 const bool Mask_struct, // true if M is structural, false if valued
41 // const GrB_BinaryOp accum, // not present
42 const GrB_Matrix A, // input matrix, not transposed
43 const void *scalar, // input scalar
44 const GrB_Type scalar_type, // type of input scalar
45 GB_Context Context
46 )
47 {
48
49 //--------------------------------------------------------------------------
50 // check inputs
51 //--------------------------------------------------------------------------
52
53 GBURBLE_BITMAP_ASSIGN ("bit8:whole", M, true, NULL,
54 GB_ALL, GB_ALL, GB_ASSIGN) ;
55 ASSERT (GB_IS_HYPERSPARSE (M) || GB_IS_SPARSE (M)) ;
56 ASSERT_MATRIX_OK (C, "C for bitmap assign, !M, noaccum", GB0) ;
57 ASSERT_MATRIX_OK (M, "M for bitmap assign, !M, noaccum", GB0) ;
58 ASSERT_MATRIX_OK_OR_NULL (A, "A for bitmap assign, !M, noaccum", GB0) ;
59
60 //--------------------------------------------------------------------------
61 // get inputs
62 //--------------------------------------------------------------------------
63
64 GB_GET_C_BITMAP ; // C must be bitmap
65 GB_SLICE_M
66 GB_GET_A_AND_SCALAR
67
68 //--------------------------------------------------------------------------
69 // scatter M into the bitmap of C
70 //--------------------------------------------------------------------------
71
72 // Cb [pC] += 2 for each entry M(i,j) in the mask
73 GB_bitmap_M_scatter_whole (C,
74 M, Mask_struct, GB_BITMAP_M_SCATTER_PLUS_2,
75 M_ek_slicing, M_ntasks, M_nthreads, Context) ;
76 // the bitmap of C now contains:
77 // Cb (i,j) = 0: cij not present, mij zero
78 // Cb (i,j) = 1: cij present, mij zero
79 // Cb (i,j) = 2: cij not present, mij 1
80 // Cb (i,j) = 3: cij present, mij 1
81
82 //--------------------------------------------------------------------------
83 // do the assignment
84 //--------------------------------------------------------------------------
85
86 if (A == NULL)
87 {
88
89 //----------------------------------------------------------------------
90 // scalar assignment: C<!M, replace or !replace> = scalar
91 //----------------------------------------------------------------------
92
93 if (C_replace)
94 {
95
96 //------------------------------------------------------------------
97 // C<!M,replace> = scalar
98 //------------------------------------------------------------------
99
100 #undef GB_CIJ_WORK
101 #define GB_CIJ_WORK(pC) \
102 { \
103 switch (Cb [pC]) \
104 { \
105 case 0: /* C(i,j) not present, !M(i,j) = 1 */ \
106 /* Cx [pC] = scalar */ \
107 GB_ASSIGN_SCALAR (pC) ; \
108 Cb [pC] = 1 ; \
109 task_cnvals++ ; \
110 break ; \
111 case 1: /* C(i,j) present, !M(i,j) = 1 */ \
112 /* Cx [pC] = scalar */ \
113 GB_ASSIGN_SCALAR (pC) ; \
114 break ; \
115 case 2: /* C(i,j) not present, !M(i,j) = 0 */ \
116 /* clear the mask from C */ \
117 Cb [pC] = 0 ; \
118 break ; \
119 case 3: /* C(i,j) present, !M(i,j) = 0 */ \
120 /* delete this entry */ \
121 Cb [pC] = 0 ; \
122 task_cnvals-- ; \
123 break ; \
124 default: ; \
125 } \
126 }
127 #include "GB_bitmap_assign_C_whole_template.c"
128
129 }
130 else
131 {
132
133 //------------------------------------------------------------------
134 // C<!M> = scalar
135 //------------------------------------------------------------------
136
137 #undef GB_CIJ_WORK
138 #define GB_CIJ_WORK(pC) \
139 { \
140 switch (Cb [pC]) \
141 { \
142 case 0: /* C(i,j) not present, !M(i,j) = 1 */ \
143 /* Cx [pC] = scalar */ \
144 GB_ASSIGN_SCALAR (pC) ; \
145 Cb [pC] = 1 ; \
146 task_cnvals++ ; \
147 break ; \
148 case 1: /* C(i,j) present, !M(i,j) = 1 */ \
149 /* Cx [pC] = scalar */ \
150 GB_ASSIGN_SCALAR (pC) ; \
151 break ; \
152 case 2: /* C(i,j) not present, !M(i,j) = 0 */ \
153 /* clear the mask from C */ \
154 Cb [pC] = 0 ; \
155 break ; \
156 case 3: /* C(i,j) present, !M(i,j) = 0 */ \
157 /* C(i,j) remains; clear the mask from C */ \
158 Cb [pC] = 1 ; \
159 break ; \
160 default: ; \
161 } \
162 }
163 #include "GB_bitmap_assign_C_whole_template.c"
164 }
165
166 }
167 else
168 {
169
170 //----------------------------------------------------------------------
171 // matrix assignment: C<!M, replace or !replace> = A
172 //----------------------------------------------------------------------
173
174 if (GB_IS_BITMAP (A) || GB_IS_FULL (A))
175 {
176
177 //------------------------------------------------------------------
178 // C<!M, replace or !replace> = A where A is bitmap or full
179 //------------------------------------------------------------------
180
181 if (C_replace)
182 {
183
184 //--------------------------------------------------------------
185 // C<!M, replace> = A where A is bitmap or full
186 //--------------------------------------------------------------
187
188 #undef GB_CIJ_WORK
189 #define GB_CIJ_WORK(pC) \
190 { \
191 switch (Cb [pC]) \
192 { \
193 case 0: /* C(i,j) not present, !M(i,j) = 1 */ \
194 if (GBB (Ab, pC)) \
195 { \
196 /* Cx [pC] = Ax [pC] */ \
197 GB_ASSIGN_AIJ (pC, pC) ; \
198 Cb [pC] = 1 ; \
199 task_cnvals++ ; \
200 } \
201 break ; \
202 case 1: /* C(i,j) present, !M(i,j) = 1 */ \
203 if (GBB (Ab, pC)) \
204 { \
205 /* Cx [pC] = Ax [pC] */ \
206 GB_ASSIGN_AIJ (pC, pC) ; \
207 } \
208 else \
209 { \
210 /* delete this entry */ \
211 Cb [pC] = 0 ; \
212 task_cnvals-- ; \
213 } \
214 break ; \
215 case 2: /* C(i,j) not present, !M(i,j) = 0 */ \
216 /* clear the mask from C */ \
217 Cb [pC] = 0 ; \
218 break ; \
219 case 3: /* C(i,j) present, !M(i,j) = 0 */ \
220 /* delete this entry */ \
221 Cb [pC] = 0 ; \
222 task_cnvals-- ; \
223 break ; \
224 default: ; \
225 } \
226 }
227 #include "GB_bitmap_assign_C_whole_template.c"
228
229 }
230 else
231 {
232
233 //--------------------------------------------------------------
234 // C<!M> = A where A is bitmap or full
235 //--------------------------------------------------------------
236
237 #undef GB_CIJ_WORK
238 #define GB_CIJ_WORK(pC) \
239 { \
240 switch (Cb [pC]) \
241 { \
242 case 0: /* C(i,j) not present, !M(i,j) = 1 */ \
243 if (GBB (Ab, pC)) \
244 { \
245 /* Cx [pC] = Ax [pC] */ \
246 GB_ASSIGN_AIJ (pC, pC) ; \
247 Cb [pC] = 1 ; \
248 task_cnvals++ ; \
249 } \
250 break ; \
251 case 1: /* C(i,j) present, !M(i,j) = 1 */ \
252 if (GBB (Ab, pC)) \
253 { \
254 /* Cx [pC] = Ax [pC] */ \
255 GB_ASSIGN_AIJ (pC, pC) ; \
256 } \
257 else \
258 { \
259 /* delete this entry */ \
260 Cb [pC] = 0 ; \
261 task_cnvals-- ; \
262 } \
263 break ; \
264 case 2: /* C(i,j) not present, !M(i,j) = 0 */ \
265 /* clear the mask from C */ \
266 Cb [pC] = 0 ; \
267 break ; \
268 case 3: /* C(i,j) present, !M(i,j) = 0 */ \
269 /* keep the entry */ \
270 Cb [pC] = 1 ; \
271 break ; \
272 default: ; \
273 } \
274 }
275 #include "GB_bitmap_assign_C_whole_template.c"
276 }
277
278 }
279 else
280 {
281
282 //------------------------------------------------------------------
283 // C<!M, replace or !replace> = A where A is sparse or hyper
284 //------------------------------------------------------------------
285
286 // assign entries from A into C
287 #undef GB_AIJ_WORK
288 #define GB_AIJ_WORK(pC,pA) \
289 { \
290 int8_t cb = Cb [pC] ; \
291 if (cb <= 1) \
292 { \
293 /* Cx [pC] = Ax [pA] */ \
294 GB_ASSIGN_AIJ (pC, pA) ; \
295 Cb [pC] = 4 ; \
296 task_cnvals += (cb == 0) ; \
297 } \
298 }
299 #include "GB_bitmap_assign_A_whole_template.c"
300
301 // clear the mask and delete entries not assigned
302 if (C_replace)
303 {
304 #undef GB_CIJ_WORK
305 #define GB_CIJ_WORK(pC) \
306 { \
307 int8_t cb = Cb [pC] ; \
308 Cb [pC] = (cb == 4) ; \
309 task_cnvals -= (cb == 1 || cb == 3) ; \
310 }
311 #include "GB_bitmap_assign_C_whole_template.c"
312 }
313 else
314 {
315 #undef GB_CIJ_WORK
316 #define GB_CIJ_WORK(pC) \
317 { \
318 int8_t cb = Cb [pC] ; \
319 Cb [pC] = (cb == 4 || cb == 3) ; \
320 task_cnvals -= (cb == 1) ; \
321 }
322 #include "GB_bitmap_assign_C_whole_template.c"
323 }
324 }
325 }
326
327 //--------------------------------------------------------------------------
328 // free workspace and return result
329 //--------------------------------------------------------------------------
330
331 C->nvals = cnvals ;
332 GB_FREE_ALL ;
333 ASSERT_MATRIX_OK (C, "final C for bitmap assign, !M, noaccum, whole", GB0) ;
334 return (GrB_SUCCESS) ;
335 }
336
337