1 //------------------------------------------------------------------------------
2 // GB_bitmap_assign: 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 
10 // Implements GrB_Row_assign, GrB_Col_assign, GrB_assign, GxB_subassign when C
11 // is in bitmap form, or when C is converted into bitmap form.
12 
13 // C is returned as bitmap in all cases except for C = A or C = scalar (the
14 // whole_C_matrix case with GB_bitmap_assign_noM_noaccum_whole).  For that
15 // method, C can be returned with any sparsity structure.
16 
17 #include "GB_bitmap_assign_methods.h"
18 #include "GB_dense.h"
19 
20 #define GB_FREE_ALL GB_phbix_free (C) ;
21 
GB_bitmap_assign(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_BinaryOp accum,const GrB_Matrix A,const void * scalar,const GrB_Type scalar_type,const int assign_kind,GB_Context Context)22 GrB_Info GB_bitmap_assign
23 (
24     // input/output:
25     GrB_Matrix C,               // input/output matrix
26     // inputs:
27     const bool C_replace,       // descriptor for C
28     const GrB_Index *I,         // I index list
29     const int64_t nI,
30     const int Ikind,
31     const int64_t Icolon [3],
32     const GrB_Index *J,         // J index list
33     const int64_t nJ,
34     const int Jkind,
35     const int64_t Jcolon [3],
36     const GrB_Matrix M,         // mask matrix, NULL if not present
37     const bool Mask_comp,       // true for !M, false for M
38     const bool Mask_struct,     // true if M is structural, false if valued
39     const GrB_BinaryOp accum,   // NULL if not present
40     const GrB_Matrix A,         // input matrix, NULL for scalar assignment
41     const void *scalar,         // input scalar, if A == NULL
42     const GrB_Type scalar_type, // type of input scalar
43     const int assign_kind,      // row assign, col assign, assign, or subassign
44     GB_Context Context
45 )
46 {
47 
48     //--------------------------------------------------------------------------
49     // check inputs
50     //--------------------------------------------------------------------------
51 
52     GrB_Info info ;
53     ASSERT_MATRIX_OK (C, "C for bitmap assign", GB0) ;
54 
55     //--------------------------------------------------------------------------
56     // ensure C is in bitmap form
57     //--------------------------------------------------------------------------
58 
59     GB_OK (GB_convert_any_to_bitmap (C, Context)) ;
60     ASSERT (GB_IS_BITMAP (C)) ;
61 
62     bool whole_C_matrix = (Ikind == GB_ALL && Jkind == GB_ALL) ;
63 
64     //--------------------------------------------------------------------------
65     // do the assignment
66     //--------------------------------------------------------------------------
67 
68     if (M == NULL)
69     {
70         if (accum == NULL)
71         {
72             if (whole_C_matrix)
73             {
74                 // C = A or scalar, no mask.  C may become sparse, hyper, or
75                 // full, or it may remain bitmap.
76                 GB_OK (GB_bitmap_assign_noM_noaccum_whole (C, C_replace,
77                     /* no M, */ Mask_comp, Mask_struct, /* no accum, */
78                     A, scalar, scalar_type, Context)) ;
79             }
80             else
81             {
82                 // C(I,J) = A or scalar, no mask
83                 GB_OK (GB_bitmap_assign_noM_noaccum (C, C_replace,
84                     I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
85                     /* no M, */ Mask_comp, Mask_struct, /* no accum, */
86                     A, scalar, scalar_type, assign_kind, Context)) ;
87             }
88         }
89         else
90         {
91             if (whole_C_matrix)
92             {
93                 // C += A or scalar, no mask.
94                 GB_OK (GB_bitmap_assign_noM_accum_whole (C, C_replace,
95                     /* no M, */ Mask_comp, Mask_struct, accum,
96                     A, scalar, scalar_type, Context)) ;
97             }
98             else
99             {
100                 // C(I,J) += A or scalar, no mask.
101                 GB_OK (GB_bitmap_assign_noM_accum (C, C_replace,
102                     I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
103                     /* no M, */ Mask_comp, Mask_struct, accum,
104                     A, scalar, scalar_type, assign_kind, Context)) ;
105             }
106         }
107     }
108     else if (GB_IS_BITMAP (M) || GB_IS_FULL (M))
109     {
110         if (accum == NULL)
111         {
112             if (whole_C_matrix)
113             {
114                 // C<M or !M, where M is full> = A or scalar
115                 GB_OK (GB_bitmap_assign_fullM_noaccum_whole (C, C_replace,
116                     M, Mask_comp, Mask_struct, /* no accum, */
117                     A, scalar, scalar_type, Context)) ;
118             }
119             else
120             {
121                 // C<M or !M, where M is full>(I,J) = A or scalar
122                 GB_OK (GB_bitmap_assign_fullM_noaccum (C, C_replace,
123                     I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
124                     M, Mask_comp, Mask_struct, /* no accum, */
125                     A, scalar, scalar_type, assign_kind, Context)) ;
126             }
127         }
128         else
129         {
130             if (whole_C_matrix)
131             {
132                 // C<M or !M, where M is full> = A or scalar
133                 GB_OK (GB_bitmap_assign_fullM_accum_whole (C, C_replace,
134                     M, Mask_comp, Mask_struct, accum,
135                     A, scalar, scalar_type, Context)) ;
136             }
137             else
138             {
139                 // C<M or !M, where M is full>(I,J) = A or scalar
140                 GB_OK (GB_bitmap_assign_fullM_accum (C, C_replace,
141                     I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
142                     M, Mask_comp, Mask_struct, accum,
143                     A, scalar, scalar_type, assign_kind, Context)) ;
144             }
145         }
146     }
147     else if (!Mask_comp)
148     {
149         if (accum == NULL)
150         {
151             if (whole_C_matrix)
152             {
153                 // C<M> = A or scalar, M is sparse or hypersparse
154                 GB_OK (GB_bitmap_assign_M_noaccum_whole (C, C_replace,
155                     M, /* Mask_comp false, */ Mask_struct, /* no accum, */
156                     A, scalar, scalar_type, Context)) ;
157             }
158             else
159             {
160                 // C<M>(I,J) = A or scalar, M is sparse or hypersparse
161                 GB_OK (GB_bitmap_assign_M_noaccum (C, C_replace,
162                     I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
163                     M, /* Mask_comp false, */ Mask_struct, /* no accum, */
164                     A, scalar, scalar_type, assign_kind, Context)) ;
165             }
166         }
167         else
168         {
169             if (whole_C_matrix)
170             {
171                 // C<M> += A or scalar, M is sparse or hypersparse
172                 GB_OK (GB_bitmap_assign_M_accum_whole (C, C_replace,
173                     M, /* Mask_comp false, */ Mask_struct, accum,
174                     A, scalar, scalar_type, Context)) ;
175             }
176             else
177             {
178                 // C<M>(I,J) += A or scalar, M is sparse or hypersparse
179                 GB_OK (GB_bitmap_assign_M_accum (C, C_replace,
180                     I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
181                     M, /* Mask_comp false, */ Mask_struct, accum,
182                     A, scalar, scalar_type, assign_kind, Context)) ;
183             }
184         }
185     }
186     else // Mask_comp is true
187     {
188         if (accum == NULL)
189         {
190             if (whole_C_matrix)
191             {
192                 // C<!M> = A or scalar, M is sparse or hypersparse
193                 GB_OK (GB_bitmap_assign_notM_noaccum_whole (C, C_replace,
194                     M, /* Mask_comp true, */ Mask_struct, /* no accum, */
195                     A, scalar, scalar_type, Context)) ;
196             }
197             else
198             {
199                 // C<!M>(I,J) = A or scalar, M is sparse or hypersparse
200                 GB_OK (GB_bitmap_assign_notM_noaccum (C, C_replace,
201                     I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
202                     M, /* Mask_comp true, */ Mask_struct, /* no accum, */
203                     A, scalar, scalar_type, assign_kind, Context)) ;
204             }
205         }
206         else
207         {
208             if (whole_C_matrix)
209             {
210                 // C<!M> += A or scalar, M is sparse or hypersparse
211                 GB_OK (GB_bitmap_assign_notM_accum_whole (C, C_replace,
212                     M, /* Mask_comp true, */ Mask_struct, accum,
213                     A, scalar, scalar_type, Context)) ;
214             }
215             else
216             {
217                 // C<!M>(I,J) += A or scalar, M is sparse or hypersparse
218                 GB_OK (GB_bitmap_assign_notM_accum (C, C_replace,
219                     I, nI, Ikind, Icolon, J, nJ, Jkind, Jcolon,
220                     M, /* Mask_comp true, */ Mask_struct, accum,
221                     A, scalar, scalar_type, assign_kind, Context)) ;
222             }
223         }
224     }
225 
226     //--------------------------------------------------------------------------
227     // return result
228     //--------------------------------------------------------------------------
229 
230     ASSERT_MATRIX_OK (C, "final C for bitmap assign", GB0) ;
231     return (GrB_SUCCESS) ;
232 }
233 
234