1 //------------------------------------------------------------------------------
2 // GB_bitmap_assign_fullM_noaccum: assign to C bitmap, M is bitmap or full
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 // C<!M>(I,J) = A assign
16 // C(I,J)<!M> = A subassign
17
18 // C<!M,repl>(I,J) = A assign
19 // C(I,J)<!M,repl> = A subassign
20 //------------------------------------------------------------------------------
21
22 // C: bitmap
23 // M: present, bitmap or full (not hypersparse or sparse)
24 // Mask_comp: true or false
25 // Mask_struct: true or false
26 // C_replace: true or false
27 // accum: not present
28 // A: matrix (hyper, sparse, bitmap, or full), or scalar
29 // kind: assign, row assign, col assign, or subassign
30
31 #include "GB_bitmap_assign_methods.h"
32
33 #define GB_FREE_ALL ;
34
GB_bitmap_assign_fullM_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_comp,const bool Mask_struct,const GrB_Matrix A,const void * scalar,const GrB_Type scalar_type,const int assign_kind,GB_Context Context)35 GrB_Info GB_bitmap_assign_fullM_noaccum
36 (
37 // input/output:
38 GrB_Matrix C, // input/output matrix in bitmap format
39 const bool C_replace, // descriptor for C
40 // inputs:
41 const GrB_Index *I, // I index list
42 const int64_t nI,
43 const int Ikind,
44 const int64_t Icolon [3],
45 const GrB_Index *J, // J index list
46 const int64_t nJ,
47 const int Jkind,
48 const int64_t Jcolon [3],
49 const GrB_Matrix M, // mask matrix, which is present here
50 const bool Mask_comp, // true for !M, false for M
51 const bool Mask_struct, // true if M is structural, false if valued
52 // const GrB_BinaryOp accum, // not present
53 const GrB_Matrix A, // input matrix, not transposed
54 const void *scalar, // input scalar
55 const GrB_Type scalar_type, // type of input scalar
56 const int assign_kind, // row assign, col assign, assign, or subassign
57 GB_Context Context
58 )
59 {
60
61 //--------------------------------------------------------------------------
62 // check inputs
63 //--------------------------------------------------------------------------
64
65 GBURBLE_BITMAP_ASSIGN ("bit2", M, Mask_comp, NULL,
66 Ikind, Jkind, assign_kind) ;
67 ASSERT (GB_IS_BITMAP (M) || GB_IS_FULL (M)) ;
68 ASSERT_MATRIX_OK (C, "C for bitmap assign, M full, noaccum", GB0) ;
69 ASSERT_MATRIX_OK (M, "M for bitmap assign, M full, noaccum", GB0) ;
70 ASSERT_MATRIX_OK_OR_NULL (A, "A for bitmap assign, M full, noaccum", GB0) ;
71
72 //--------------------------------------------------------------------------
73 // get inputs
74 //--------------------------------------------------------------------------
75
76 GB_GET_C_BITMAP ; // C must be bitmap
77 GB_GET_M
78 GB_GET_A_AND_SCALAR
79
80 //--------------------------------------------------------------------------
81 // to get the effective value of the mask entry mij
82 //--------------------------------------------------------------------------
83
84 #undef GB_GET_MIJ
85 #define GB_GET_MIJ(mij,pM) \
86 bool mij = (GBB (Mb, pM) && GB_mcast (Mx, pM, msize)) ^ Mask_comp ;
87
88 //--------------------------------------------------------------------------
89 // C_replace phase
90 //--------------------------------------------------------------------------
91
92 if (C_replace)
93 {
94 // if C FULL: use two passes: first pass checks if any
95 // entry must be deleted. If none: do nothing. Else: change C
96 // to full and do 2nd pass as below.
97
98 // for row assign: set Cb(i,:) to zero if mij == 0
99 // for col assign: set Cb(:,j) to zero if mij == 0
100 // for assign: set Cb(:,:) to zero if mij == 0
101 // for subassign set Cb(I,J) to zero if mij == 0
102 #undef GB_CIJ_WORK
103 #define GB_CIJ_WORK(pC) \
104 { \
105 if (!mij) \
106 { \
107 int8_t cb = Cb [pC] ; \
108 Cb [pC] = 0 ; \
109 task_cnvals -= (cb == 1) ; \
110 } \
111 }
112 #include "GB_bitmap_assign_C_template.c"
113 }
114
115 //--------------------------------------------------------------------------
116 // assignment phase
117 //--------------------------------------------------------------------------
118
119 if (A == NULL)
120 {
121
122 //----------------------------------------------------------------------
123 // scalar assignment: C<M or !M>(I,J) = scalar
124 //----------------------------------------------------------------------
125
126 // if C FULL: no change, just cb = GBB (CB,pC)
127
128 // for all entries in IxJ
129 #undef GB_IXJ_WORK
130 #define GB_IXJ_WORK(pC,pA) \
131 { \
132 int64_t pM = GB_GET_pM ; \
133 GB_GET_MIJ (mij, pM) ; \
134 if (mij) \
135 { \
136 int8_t cb = Cb [pC] ; \
137 /* Cx [pC] = scalar */ \
138 GB_ASSIGN_SCALAR (pC) ; \
139 Cb [pC] = 1 ; \
140 task_cnvals += (cb == 0) ; \
141 } \
142 }
143
144 ASSERT (assign_kind == GB_ASSIGN || assign_kind == GB_SUBASSIGN) ;
145
146 switch (assign_kind)
147 {
148 case GB_ASSIGN :
149 // C<M>(I,J) = scalar where M has the same size as C
150 #undef GB_GET_pM
151 #define GB_GET_pM pC
152 #include "GB_bitmap_assign_IxJ_template.c"
153 break ;
154 case GB_SUBASSIGN :
155 // C(I,J)<M> = scalar where M has the same size as A
156 #undef GB_GET_pM
157 #define GB_GET_pM pA
158 #include "GB_bitmap_assign_IxJ_template.c"
159 break ;
160 default: ;
161 }
162
163 }
164 else
165 {
166
167 //----------------------------------------------------------------------
168 // matrix assignment: C<M or !M>(I,J) = A
169 //----------------------------------------------------------------------
170
171 // assign A into C:
172
173 // for all entries aij in A
174 // get the effective value of the mask:
175 // for row assign: get mij = m(jC,0)
176 // for col assign: get mij = m(iC,0)
177 // for assign: get mij = M(iC,jC)
178 // for subassign: get mij = M(i,j)
179 // if complemented: mij = !mij
180 // if mij == 1:
181 // Cx(p) = aij // C(iC,jC) inserted or updated
182 // Cb(p) = 4
183
184 // clear entries from C that were not in A:
185
186 // for all entries in IxJ
187 // get the effective value of the mask
188 // if mij == 1
189 // 0 -> 0
190 // 1 -> 0 delete because aij not present
191 // 4 -> 1
192
193 // TODO: if A is bitmap or full, use a single pass
194
195 #define GB_AIJ_WORK(pC,pA) \
196 { \
197 int64_t pM = GB_GET_pM ; \
198 GB_GET_MIJ (mij, pM) ; \
199 if (mij) \
200 { \
201 int8_t cb = Cb [pC] ; \
202 /* Cx [pC] = Ax [pA] */ \
203 GB_ASSIGN_AIJ (pC, pA) ; \
204 Cb [pC] = 4 ; \
205 task_cnvals += (cb == 0) ; \
206 } \
207 }
208
209 #undef GB_IXJ_WORK
210 #define GB_IXJ_WORK(pC,pA) \
211 { \
212 int64_t pM = GB_GET_pM ; \
213 GB_GET_MIJ (mij, pM) ; \
214 if (mij) \
215 { \
216 int8_t cb = Cb [pC] ; \
217 Cb [pC] = (cb > 1) ; \
218 task_cnvals -= (cb == 1) ; \
219 } \
220 }
221
222 switch (assign_kind)
223 {
224 case GB_ROW_ASSIGN :
225 // C<m>(i,J) = A where m is a 1-by-C->vdim row vector
226 #undef GB_GET_pM
227 #define GB_GET_pM jC
228 #include "GB_bitmap_assign_A_template.c"
229 #include "GB_bitmap_assign_IxJ_template.c"
230 break ;
231
232 case GB_COL_ASSIGN :
233 // C<m>(I,j) = A where m is a C->vlen-by-1 column vector
234 #undef GB_GET_pM
235 #define GB_GET_pM iC
236 #include "GB_bitmap_assign_A_template.c"
237 #include "GB_bitmap_assign_IxJ_template.c"
238 break ;
239
240 case GB_ASSIGN :
241 // C<M>(I,J) = A where M has the same size as C
242 #undef GB_GET_pM
243 #define GB_GET_pM pC
244 #include "GB_bitmap_assign_A_template.c"
245 #include "GB_bitmap_assign_IxJ_template.c"
246 break ;
247
248 case GB_SUBASSIGN :
249 // C(I,J)<M> = A where M has the same size as A
250 #undef GB_GET_pM
251 #define GB_GET_pM (iA + jA * nI)
252 #include "GB_bitmap_assign_A_template.c"
253 #include "GB_bitmap_assign_IxJ_template.c"
254 break ;
255
256 default: ;
257 }
258 }
259
260 //--------------------------------------------------------------------------
261 // return result
262 //--------------------------------------------------------------------------
263
264 C->nvals = cnvals ;
265 ASSERT_MATRIX_OK (C, "final C for bitmap assign, M full, noaccum", GB0) ;
266 return (GrB_SUCCESS) ;
267 }
268
269