1 //------------------------------------------------------------------------------
2 // GB_bitmap_assign_notM_accum: 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: 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_accum(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_BinaryOp accum,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_accum
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, // 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 ("bit7", M, true, accum,
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, accum", GB0) ;
66 ASSERT_MATRIX_OK (M, "M for bitmap assign, !M, accum", GB0) ;
67 ASSERT_MATRIX_OK_OR_NULL (A, "A for bitmap assign, !M, accum", 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 GB_GET_ACCUM_FOR_BITMAP
77
78 //--------------------------------------------------------------------------
79 // scatter the mask M into C
80 //--------------------------------------------------------------------------
81
82 // Cb [pC] += 2 for each entry M(i,j) in the mask
83 GB_bitmap_M_scatter (C, I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
84 M, Mask_struct, assign_kind, GB_BITMAP_M_SCATTER_PLUS_2,
85 M_ek_slicing, M_ntasks, M_nthreads, Context) ;
86
87 //--------------------------------------------------------------------------
88 // do the assignment
89 //--------------------------------------------------------------------------
90
91 if (A == NULL)
92 {
93
94 //----------------------------------------------------------------------
95 // scalar assignment: C<!M>(I,J) += scalar
96 //----------------------------------------------------------------------
97
98 // for all IxJ
99 #define GB_IXJ_WORK(pC,ignore) \
100 { \
101 int8_t cb = Cb [pC] ; \
102 if (cb == 0) \
103 { \
104 /* Cx [pC] = scalar */ \
105 GB_ASSIGN_SCALAR (pC) ; \
106 Cb [pC] = 1 ; \
107 task_cnvals++ ; \
108 } \
109 else if (cb == 1) \
110 { \
111 /* Cx [pC] += scalar */ \
112 GB_ACCUM_SCALAR (pC) ; \
113 } \
114 }
115 #include "GB_bitmap_assign_IxJ_template.c"
116
117 }
118 else
119 {
120
121 //----------------------------------------------------------------------
122 // matrix assignment: C<!M>(I,J) += A
123 //----------------------------------------------------------------------
124
125 // for all entries aij in A (A can be hyper, sparse, bitmap, or full)
126 // if Cb(p) == 0
127 // Cx(p) = aij
128 // Cb(p) = 1 // C(iC,jC) is now present, insert
129 // task_cnvals++
130 // if Cb(p) == 1
131 // Cx(p) += aij // C(iC,jC) still present, updated
132 // Cb(p) still 1
133 // if Cb(p) == 2 // do nothing
134 // if Cb(p) == 3 // do nothing
135
136 #define GB_AIJ_WORK(pC,pA) \
137 { \
138 int8_t cb = Cb [pC] ; \
139 if (cb == 0) \
140 { \
141 /* Cx [pC] = Ax [pA] */ \
142 GB_ASSIGN_AIJ (pC, pA) ; \
143 Cb [pC] = 1 ; \
144 task_cnvals++ ; \
145 } \
146 else if (cb == 1) \
147 { \
148 /* Cx [pC] += Ax [pA] */ \
149 GB_ACCUM_AIJ (pC, pA) ; \
150 } \
151 }
152 #include "GB_bitmap_assign_A_template.c"
153 }
154
155 //--------------------------------------------------------------------------
156 // clear M from C and handle the C_replace phase
157 //--------------------------------------------------------------------------
158
159 if (!C_replace)
160 {
161 // for each entry mij == 1
162 // 2 -> 0
163 // 3 -> 1 keep this entry
164 // Cb [pC] -= 2 for each entry M(i,j) in the mask
165 GB_bitmap_M_scatter (C, I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
166 M, Mask_struct, assign_kind, GB_BITMAP_M_SCATTER_MINUS_2,
167 M_ek_slicing, M_ntasks, M_nthreads, Context) ;
168 }
169 else
170 {
171 // for each entry mij == 1
172 // 2 -> 0
173 // 3 -> 0 delete this entry
174 #undef GB_MASK_WORK
175 #define GB_MASK_WORK(pC) \
176 { \
177 int8_t cb = Cb [pC] ; \
178 task_cnvals -= (cb == 3) ; \
179 Cb [pC] = 0 ; \
180 }
181 #include "GB_bitmap_assign_M_template.c"
182 }
183
184 //--------------------------------------------------------------------------
185 // free workspace and return result
186 //--------------------------------------------------------------------------
187
188 C->nvals = cnvals ;
189 GB_FREE_ALL ;
190 ASSERT_MATRIX_OK (C, "final C for bitmap assign, !M, accum", GB0) ;
191 return (GrB_SUCCESS) ;
192 }
193
194