1 //------------------------------------------------------------------------------
2 // GB_bitmap_assign_notM_noaccum: 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>(I,J) = A assign
10 // C(I,J)<!M> = A subassign
11
12 // C<!M,repl>(I,J) = A assign
13 // C(I,J)<!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, row assign, col assign, or subassign
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(GrB_Matrix C,const bool C_replace,const GrB_Index * I,const int64_t nI,const int Ikind,const int64_t Icolon[3],const GrB_Index * J,const int64_t nJ,const int Jkind,const int64_t Jcolon[3],const GrB_Matrix M,const bool Mask_struct,const GrB_Matrix A,const void * scalar,const GrB_Type scalar_type,const int assign_kind,GB_Context Context)32 GrB_Info GB_bitmap_assign_notM_noaccum
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_Index *I, // I index list
39 const int64_t nI,
40 const int Ikind,
41 const int64_t Icolon [3],
42 const GrB_Index *J, // J index list
43 const int64_t nJ,
44 const int Jkind,
45 const int64_t Jcolon [3],
46 const GrB_Matrix M, // mask matrix
47 // const bool Mask_comp, // true here, for !M only
48 const bool Mask_struct, // true if M is structural, false if valued
49 // const GrB_BinaryOp accum, // not present
50 const GrB_Matrix A, // input matrix, not transposed
51 const void *scalar, // input scalar
52 const GrB_Type scalar_type, // type of input scalar
53 const int assign_kind, // row assign, col assign, assign, or subassign
54 GB_Context Context
55 )
56 {
57
58 //--------------------------------------------------------------------------
59 // check inputs
60 //--------------------------------------------------------------------------
61
62 GBURBLE_BITMAP_ASSIGN ("bit8", M, true, NULL,
63 Ikind, Jkind, assign_kind) ;
64 ASSERT (GB_IS_HYPERSPARSE (M) || GB_IS_SPARSE (M)) ;
65 ASSERT_MATRIX_OK (C, "C for bitmap assign, !M, noaccum", GB0) ;
66 ASSERT_MATRIX_OK (M, "M for bitmap assign, !M, noaccum", GB0) ;
67 ASSERT_MATRIX_OK_OR_NULL (A, "A for bitmap assign, !M, noaccum", GB0) ;
68
69 //--------------------------------------------------------------------------
70 // get inputs
71 //--------------------------------------------------------------------------
72
73 GB_GET_C_BITMAP ; // C must be bitmap
74 GB_SLICE_M
75 GB_GET_A_AND_SCALAR
76
77 //--------------------------------------------------------------------------
78 // scatter M into the bitmap of C
79 //--------------------------------------------------------------------------
80
81 // Cb [pC] += 2 for each entry M(i,j) in the mask
82 GB_bitmap_M_scatter (C, I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
83 M, Mask_struct, assign_kind, GB_BITMAP_M_SCATTER_PLUS_2,
84 M_ek_slicing, M_ntasks, M_nthreads, Context) ;
85
86 // Cb (i,j) = 0: cij not present, mij zero: can be modified
87 // Cb (i,j) = 1: cij present, mij zero: can be modified,
88 // but delete if aij not present
89 // Cb (i,j) = 2: cij not present, mij == 1: do not modify
90 // Cb (i,j) = 3: cij present, mij == 1: do not modify
91
92 //--------------------------------------------------------------------------
93 // assign A into C
94 //--------------------------------------------------------------------------
95
96 if (A == NULL)
97 {
98
99 //----------------------------------------------------------------------
100 // scalar assignment: C<!M>(I,J) = scalar
101 //----------------------------------------------------------------------
102
103 // for all IxJ
104 #define GB_IXJ_WORK(pC,ignore) \
105 { \
106 int8_t cb = Cb [pC] ; \
107 if (cb <= 1) \
108 { \
109 /* Cx [pC] = scalar */ \
110 GB_ASSIGN_SCALAR (pC) ; \
111 Cb [pC] = 1 ; \
112 task_cnvals += (cb == 0) ; \
113 } \
114 else if (C_replace) \
115 { \
116 /* delete this entry */ \
117 Cb [pC] = 0 ; \
118 task_cnvals -= (cb == 3) ; \
119 } \
120 else \
121 { \
122 /* keep this entry */ \
123 Cb [pC] = (cb == 3) ; \
124 } \
125 }
126 #include "GB_bitmap_assign_IxJ_template.c"
127
128 }
129 else
130 {
131
132 //----------------------------------------------------------------------
133 // matrix assignment: C<!M>(I,J) = A
134 //----------------------------------------------------------------------
135
136 // for all entries aij in A (A can be hyper, sparse, bitmap, or full)
137 // if Cb(p) == 0 // C(iC,jC) is now present, insert
138 // Cx(p) = aij //
139 // Cb(p) = 4 // keep it
140 // task_cnvals++
141 // if Cb(p) == 1 // C(iC,jC) still present, updated
142 // Cx(p) = aij //
143 // Cb(p) = 4 // keep it
144 // if Cb(p) == 2 // do nothing
145 // if Cb(p) == 3 // do nothing
146
147 #define GB_AIJ_WORK(pC,pA) \
148 { \
149 int8_t cb = Cb [pC] ; \
150 if (cb <= 1) \
151 { \
152 /* Cx [pC] = Ax [pA] */ \
153 GB_ASSIGN_AIJ (pC, pA) ; \
154 Cb [pC] = 4 ; \
155 task_cnvals += (cb == 0) ; \
156 } \
157 }
158 #include "GB_bitmap_assign_A_template.c"
159
160 //----------------------------------------------------------------------
161 // handle entries in IxJ
162 //----------------------------------------------------------------------
163
164 if (C_replace)
165 {
166 // for all IxJ
167 #undef GB_IXJ_WORK
168 #define GB_IXJ_WORK(pC,ignore) \
169 { \
170 int8_t cb = Cb [pC] ; \
171 Cb [pC] = (cb == 4) ; \
172 task_cnvals -= (cb == 1 || cb == 3) ; \
173 }
174 #include "GB_bitmap_assign_IxJ_template.c"
175 }
176 else
177 {
178 // for all IxJ
179 #undef GB_IXJ_WORK
180 #define GB_IXJ_WORK(pC,ignore) \
181 { \
182 int8_t cb = Cb [pC] ; \
183 Cb [pC] = (cb == 4 || cb == 3) ; \
184 task_cnvals -= (cb == 1) ; \
185 }
186 #include "GB_bitmap_assign_IxJ_template.c"
187 }
188 }
189
190 //--------------------------------------------------------------------------
191 // handle entries outside of IxJ
192 //--------------------------------------------------------------------------
193
194 if (assign_kind == GB_SUBASSIGN)
195 {
196 // see above. no more work to do
197 }
198 else
199 {
200 #define GB_NO_SUBASSIGN_CASE
201 if (C_replace)
202 {
203 // for all entries in C. Also clears M from C
204 #define GB_CIJ_WORK(pC) \
205 { \
206 int8_t cb = Cb [pC] ; \
207 Cb [pC] = (cb == 1) ; \
208 task_cnvals -= (cb == 3) ; \
209 }
210 #include "GB_bitmap_assign_C_template.c"
211 }
212 else
213 {
214 // clear M from C
215 // Cb [pC] %= 2 for each entry M(i,j) in the mask
216 GB_bitmap_M_scatter (C, I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
217 M, Mask_struct, assign_kind, GB_BITMAP_M_SCATTER_MOD_2,
218 M_ek_slicing, M_ntasks, M_nthreads, Context) ;
219 }
220 }
221
222 //--------------------------------------------------------------------------
223 // free workspace and return result
224 //--------------------------------------------------------------------------
225
226 C->nvals = cnvals ;
227 GB_FREE_ALL ;
228 ASSERT_MATRIX_OK (C, "final C for bitmap assign, !M, noaccum", GB0) ;
229 return (GrB_SUCCESS) ;
230 }
231
232