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