1 //------------------------------------------------------------------------------
2 // GB_bitmap_assign_methods.h: definitions for GB_bitmap_assign* methods
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 #ifndef GB_BITMAP_ASSIGN_METHODS_H
11 #define GB_BITMAP_ASSIGN_METHODS_H
12 #include "GB_bitmap_assign.h"
13 #include "GB_ek_slice.h"
14 #include "GB_partition.h"
15 #include "GB_ij.h"
16 #include "GB_subassign_IxJ_slice.h"
17 #include "GB_unused.h"
18 
19 //------------------------------------------------------------------------------
20 // burble
21 //------------------------------------------------------------------------------
22 
23 #if GB_BURBLE
24     #define GBURBLE_BITMAP_ASSIGN(method,M,Mask_comp,accum,Ikind,Jkind,akind) \
25         GBURBLE ("Method:" method " ") ;                                    \
26         GB_burble_assign (C_replace, Ikind, Jkind, M, Mask_comp,            \
27             Mask_struct, accum, A, akind) ;
28 #else
29     #define GBURBLE_BITMAP_ASSIGN(method,M,Mask_comp,accum,Ikind,Jkind,akind) ;
30 #endif
31 
32 //------------------------------------------------------------------------------
33 // GB_GET_C_BITMAP: get the C matrix (must be bitmap)
34 //------------------------------------------------------------------------------
35 
36 // C must be a bitmap matrix
37 
38 #define GB_GET_C_BITMAP                                                     \
39     GrB_Info info ;                                                         \
40     /* also get the max # of threads to use */                              \
41     GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;                    \
42     ASSERT_MATRIX_OK (C, "C for bitmap assign", GB0) ;                      \
43     ASSERT (GB_IS_BITMAP (C)) ;                                             \
44     int8_t  *Cb = C->b ;                                                    \
45     GB_void *Cx = (GB_void *) C->x ;                                        \
46     const size_t csize = C->type->size ;                                    \
47     const GB_Type_code ccode = C->type->code ;                              \
48     const int64_t cvdim = C->vdim ;                                         \
49     const int64_t cvlen = C->vlen ;                                         \
50     const int64_t vlen = cvlen ;    /* for GB_bitmap_assign_IxJ_template */ \
51     const int64_t cnzmax = cvlen * cvdim ;                                  \
52     int64_t cnvals = C->nvals ;
53 
54 //------------------------------------------------------------------------------
55 // GB_GET_M: get the mask matrix M and check for aliasing
56 //------------------------------------------------------------------------------
57 
58 // ALIAS of C and M for bitmap methods: For the assign methods, C==M is always
59 // permitted, since with arbitrary (I,J) indexing (I,J), the mask entry M(i,j)
60 // always controls C(i,j).  For row/col assign, aliasing of C and M would be
61 // unusual, since M is a single row or column.  But if C was also a single
62 // row/column, then C and M can be safely aliased.  For subassign, C==M can
63 // only occur if (I,J) are (:,:).
64 
65 #define GB_GET_M                                                            \
66     ASSERT_MATRIX_OK (M, "M for bitmap assign", GB0) ;                      \
67     const int64_t *Mp = M->p ;                                              \
68     const int8_t  *Mb = M->b ;                                              \
69     const int64_t *Mh = M->h ;                                              \
70     const int64_t *Mi = M->i ;                                              \
71     const GB_void *Mx = (GB_void *) (Mask_struct ? NULL : (M->x)) ;         \
72     const size_t msize = M->type->size ;                                    \
73     const size_t mvlen = M->vlen ;
74 
75 //------------------------------------------------------------------------------
76 // GB_SLICE_M: slice the mask matrix M
77 //------------------------------------------------------------------------------
78 
79 #define GB_SLICE_M                                                          \
80     GB_GET_M                                                                \
81     GB_WERK_DECLARE (M_ek_slicing, int64_t) ;                               \
82     int M_ntasks, M_nthreads ;                                              \
83     GB_SLICE_MATRIX (M, 8, chunk) ;
84 
85 //------------------------------------------------------------------------------
86 // GB_GET_A: get the A matrix or the scalar
87 //------------------------------------------------------------------------------
88 
89 // ALIAS of C and A for bitmap methods: OK only for C(:,:)=A assignment.
90 
91 #define GB_GET_A_AND_SCALAR                                                 \
92     const int64_t *Ap = NULL ;                                              \
93     const int64_t *Ah = NULL ;                                              \
94     const int8_t  *Ab = NULL ;                                              \
95     const int64_t *Ai = NULL ;                                              \
96     const GB_void *Ax = NULL ;                                              \
97     size_t asize ;                                                          \
98     GB_Type_code acode ;                                                    \
99     if (A == NULL)                                                          \
100     {                                                                       \
101         asize = scalar_type->size ;                                         \
102         acode = scalar_type->code ;                                         \
103     }                                                                       \
104     else                                                                    \
105     {                                                                       \
106         ASSERT_MATRIX_OK (A, "A for bitmap assign/subassign", GB0) ;        \
107         asize = A->type->size ;                                             \
108         acode = A->type->code ;                                             \
109         Ap = A->p ;                                                         \
110         Ah = A->h ;                                                         \
111         Ab = A->b ;                                                         \
112         Ai = A->i ;                                                         \
113         Ax = (GB_void *) A->x ;                                             \
114     }                                                                       \
115     GB_cast_function cast_A_to_C = GB_cast_factory (ccode, acode) ;         \
116     GB_void cwork [GB_VLA(csize)] ;                                         \
117     if (A == NULL)                                                          \
118     {                                                                       \
119         cast_A_to_C (cwork, scalar, asize) ;                                \
120     }                                                                       \
121 
122 //------------------------------------------------------------------------------
123 // GB_GET_ACCUM: get the accumulator op and its related typecasting functions
124 //------------------------------------------------------------------------------
125 
126 #define GB_GET_ACCUM_FOR_BITMAP                                             \
127     ASSERT_BINARYOP_OK (accum, "accum for bitmap assign", GB0) ;            \
128     ASSERT (!GB_OP_IS_POSITIONAL (accum)) ;                                 \
129     GxB_binary_function faccum = accum->function ;                          \
130     GB_cast_function cast_A_to_Y = GB_cast_factory (accum->ytype->code, acode);\
131     GB_cast_function cast_C_to_X = GB_cast_factory (accum->xtype->code, ccode);\
132     GB_cast_function cast_Z_to_C = GB_cast_factory (ccode, accum->ztype->code);\
133     size_t xsize = accum->xtype->size ;                                     \
134     size_t ysize = accum->ytype->size ;                                     \
135     size_t zsize = accum->ztype->size ;                                     \
136     GB_void ywork [GB_VLA(ysize)] ;                                         \
137     if (A == NULL)                                                          \
138     {                                                                       \
139         cast_A_to_Y (ywork, scalar, asize) ;                                \
140     }
141 
142 //------------------------------------------------------------------------------
143 // GB_ASSIGN_SCALAR:  Cx [pC] = cwork, already typecasted
144 //------------------------------------------------------------------------------
145 
146 #define GB_ASSIGN_SCALAR(pC)                                \
147 {                                                           \
148     memcpy (Cx +(pC)*csize, cwork, csize) ;                 \
149 }
150 
151 //------------------------------------------------------------------------------
152 // GB_ASSIGN_AIJ:  Cx [pC] = Ax [pA], with typecasting as needed
153 //------------------------------------------------------------------------------
154 
155 #define GB_ASSIGN_AIJ(pC,pA)                                \
156 {                                                           \
157     cast_A_to_C (Cx +(pC)*csize, Ax +(pA)*asize, csize) ;   \
158 }
159 
160 //------------------------------------------------------------------------------
161 // GB_ACCUM_SCALAR:  Cx [pC] += ywork
162 //------------------------------------------------------------------------------
163 
164 #define GB_ACCUM_SCALAR(pC)                                 \
165 {                                                           \
166     GB_void xwork [GB_VLA(xsize)] ;                         \
167     cast_C_to_X (xwork, Cx +((pC)*csize), csize) ;          \
168     GB_void zwork [GB_VLA(zsize)] ;                         \
169     faccum (zwork, xwork, ywork) ;                          \
170     cast_Z_to_C (Cx +((pC)*csize), zwork, csize) ;          \
171 }                                                           \
172 
173 //------------------------------------------------------------------------------
174 // GB_ACCUM_AIJ:  Cx [pC] += Ax [pA]
175 //------------------------------------------------------------------------------
176 
177 #define GB_ACCUM_AIJ(pC, pA)                                \
178 {                                                           \
179     /* ywork = Ax [pA], with typecasting as needed */       \
180     GB_void ywork [GB_VLA(ysize)] ;                         \
181     cast_A_to_Y (ywork, Ax +((pA)*asize), asize) ;          \
182     /* Cx [pC] += ywork */                                  \
183     GB_ACCUM_SCALAR (pC) ;                                  \
184 }
185 
186 //------------------------------------------------------------------------------
187 // prototypes
188 //------------------------------------------------------------------------------
189 
190 GrB_Info GB_bitmap_assign_fullM_accum
191 (
192     // input/output:
193     GrB_Matrix C,               // input/output matrix in bitmap format
194     // inputs:
195     const bool C_replace,       // descriptor for C
196     const GrB_Index *I,         // I index list
197     const int64_t nI,
198     const int Ikind,
199     const int64_t Icolon [3],
200     const GrB_Index *J,         // J index list
201     const int64_t nJ,
202     const int Jkind,
203     const int64_t Jcolon [3],
204     const GrB_Matrix M,         // mask matrix, which is not NULL here
205     const bool Mask_comp,       // true for !M, false for M
206     const bool Mask_struct,     // true if M is structural, false if valued
207     const GrB_BinaryOp accum,   // present here
208     const GrB_Matrix A,         // input matrix, not transposed
209     const void *scalar,         // input scalar
210     const GrB_Type scalar_type, // type of input scalar
211     const int assign_kind,      // row assign, col assign, assign, or subassign
212     GB_Context Context
213 ) ;
214 
215 GrB_Info GB_bitmap_assign_fullM_accum_whole
216 (
217     // input/output:
218     GrB_Matrix C,               // input/output matrix in bitmap format
219     // inputs:
220     const bool C_replace,       // descriptor for C
221     const GrB_Matrix M,         // mask matrix, which is present here
222     const bool Mask_comp,       // true for !M, false for M
223     const bool Mask_struct,     // true if M is structural, false if valued
224     const GrB_BinaryOp accum,   // present here
225     const GrB_Matrix A,         // input matrix, not transposed
226     const void *scalar,         // input scalar
227     const GrB_Type scalar_type, // type of input scalar
228     GB_Context Context
229 ) ;
230 
231 GrB_Info GB_bitmap_assign_fullM_noaccum
232 (
233     // input/output:
234     GrB_Matrix C,               // input/output matrix in bitmap format
235     const bool C_replace,       // descriptor for C
236     // inputs:
237     const GrB_Index *I,         // I index list
238     const int64_t nI,
239     const int Ikind,
240     const int64_t Icolon [3],
241     const GrB_Index *J,         // J index list
242     const int64_t nJ,
243     const int Jkind,
244     const int64_t Jcolon [3],
245     const GrB_Matrix M,         // mask matrix, which is present here
246     const bool Mask_comp,       // true for !M, false for M
247     const bool Mask_struct,     // true if M is structural, false if valued
248 //  const GrB_BinaryOp accum,   // not present
249     const GrB_Matrix A,         // input matrix, not transposed
250     const void *scalar,         // input scalar
251     const GrB_Type scalar_type, // type of input scalar
252     const int assign_kind,      // row assign, col assign, assign, or subassign
253     GB_Context Context
254 ) ;
255 
256 GrB_Info GB_bitmap_assign_fullM_noaccum_whole
257 (
258     // input/output:
259     GrB_Matrix C,               // input/output matrix in bitmap format
260     const bool C_replace,       // descriptor for C
261     // inputs:
262     const GrB_Matrix M,         // mask matrix, which is present here
263     const bool Mask_comp,       // true for !M, false for M
264     const bool Mask_struct,     // true if M is structural, false if valued
265 //  const GrB_BinaryOp accum,   // not present
266     const GrB_Matrix A,         // input matrix, not transposed
267     const void *scalar,         // input scalar
268     const GrB_Type scalar_type, // type of input scalar
269     GB_Context Context
270 ) ;
271 
272 GrB_Info GB_bitmap_assign_M_accum
273 (
274     // input/output:
275     GrB_Matrix C,               // input/output matrix in bitmap format
276     // inputs:
277     const bool C_replace,       // descriptor for C
278     const GrB_Index *I,         // I index list
279     const int64_t nI,
280     const int Ikind,
281     const int64_t Icolon [3],
282     const GrB_Index *J,         // J index list
283     const int64_t nJ,
284     const int Jkind,
285     const int64_t Jcolon [3],
286     const GrB_Matrix M,         // mask matrix, which is not NULL here
287 //  const bool Mask_comp,       // false here
288     const bool Mask_struct,     // true if M is structural, false if valued
289     const GrB_BinaryOp accum,   // present here
290     const GrB_Matrix A,         // input matrix, not transposed
291     const void *scalar,         // input scalar
292     const GrB_Type scalar_type, // type of input scalar
293     const int assign_kind,      // row assign, col assign, assign, or subassign
294     GB_Context Context
295 ) ;
296 
297 GrB_Info GB_bitmap_assign_M_accum_whole
298 (
299     // input/output:
300     GrB_Matrix C,               // input/output matrix in bitmap format
301     // inputs:
302     const bool C_replace,       // descriptor for C
303     const GrB_Matrix M,         // mask matrix, which is not NULL here
304 //  const bool Mask_comp,       // false here
305     const bool Mask_struct,     // true if M is structural, false if valued
306     const GrB_BinaryOp accum,   // present here
307     const GrB_Matrix A,         // input matrix, not transposed
308     const void *scalar,         // input scalar
309     const GrB_Type scalar_type, // type of input scalar
310     GB_Context Context
311 ) ;
312 
313 GrB_Info GB_bitmap_assign_M_noaccum
314 (
315     // input/output:
316     GrB_Matrix C,               // input/output matrix in bitmap format
317     // inputs:
318     const bool C_replace,       // descriptor for C
319     const GrB_Index *I,         // I index list
320     const int64_t nI,
321     const int Ikind,
322     const int64_t Icolon [3],
323     const GrB_Index *J,         // J index list
324     const int64_t nJ,
325     const int Jkind,
326     const int64_t Jcolon [3],
327     const GrB_Matrix M,         // mask matrix, which is not NULL here
328 //  const bool Mask_comp,       // false here
329     const bool Mask_struct,     // true if M is structural, false if valued
330 //  const GrB_BinaryOp accum,   // not present
331     const GrB_Matrix A,         // input matrix, not transposed
332     const void *scalar,         // input scalar
333     const GrB_Type scalar_type, // type of input scalar
334     const int assign_kind,      // row assign, col assign, assign, or subassign
335     GB_Context Context
336 ) ;
337 
338 GrB_Info GB_bitmap_assign_M_noaccum_whole
339 (
340     // input/output:
341     GrB_Matrix C,               // input/output matrix in bitmap format
342     // inputs:
343     const bool C_replace,       // descriptor for C
344     const GrB_Matrix M,         // mask matrix, which is not NULL here
345 //  const bool Mask_comp,       // false here
346     const bool Mask_struct,     // true if M is structural, false if valued
347 //  const GrB_BinaryOp accum,   // not present
348     const GrB_Matrix A,         // input matrix, not transposed
349     const void *scalar,         // input scalar
350     const GrB_Type scalar_type, // type of input scalar
351     GB_Context Context
352 ) ;
353 
354 GrB_Info GB_bitmap_assign_noM_accum
355 (
356     // input/output:
357     GrB_Matrix C,               // input/output matrix in bitmap format
358     // inputs:
359     const bool C_replace,       // descriptor for C
360     const GrB_Index *I,         // I index list
361     const int64_t nI,
362     const int Ikind,
363     const int64_t Icolon [3],
364     const GrB_Index *J,         // J index list
365     const int64_t nJ,
366     const int Jkind,
367     const int64_t Jcolon [3],
368 //  const GrB_Matrix M,         // mask matrix, not present here
369     const bool Mask_comp,       // true for !M, false for M
370     const bool Mask_struct,     // true if M is structural, false if valued
371     const GrB_BinaryOp accum,   // present
372     const GrB_Matrix A,         // input matrix, not transposed
373     const void *scalar,         // input scalar
374     const GrB_Type scalar_type, // type of input scalar
375     const int assign_kind,      // row assign, col assign, assign, or subassign
376     GB_Context Context
377 ) ;
378 
379 GrB_Info GB_bitmap_assign_noM_accum_whole
380 (
381     // input/output:
382     GrB_Matrix C,               // input/output matrix in bitmap format
383     // inputs:
384     const bool C_replace,       // descriptor for C
385 //  const GrB_Matrix M,         // mask matrix, not present here
386     const bool Mask_comp,       // true for !M, false for M
387     const bool Mask_struct,     // true if M is structural, false if valued
388     const GrB_BinaryOp accum,   // present
389     const GrB_Matrix A,         // input matrix, not transposed
390     const void *scalar,         // input scalar
391     const GrB_Type scalar_type, // type of input scalar
392     GB_Context Context
393 ) ;
394 
395 GrB_Info GB_bitmap_assign_noM_noaccum
396 (
397     // input/output:
398     GrB_Matrix C,               // input/output matrix in bitmap format
399     // inputs:
400     const bool C_replace,       // descriptor for C
401     const GrB_Index *I,         // I index list
402     const int64_t nI,
403     const int Ikind,
404     const int64_t Icolon [3],
405     const GrB_Index *J,         // J index list
406     const int64_t nJ,
407     const int Jkind,
408     const int64_t Jcolon [3],
409 //  const GrB_Matrix M,         // mask matrix, not present here
410     const bool Mask_comp,       // true for !M, false for M
411     const bool Mask_struct,     // true if M is structural, false if valued
412 //  const GrB_BinaryOp accum,   // not present
413     const GrB_Matrix A,         // input matrix, not transposed
414     const void *scalar,         // input scalar
415     const GrB_Type scalar_type, // type of input scalar
416     const int assign_kind,      // row assign, col assign, assign, or subassign
417     GB_Context Context
418 ) ;
419 
420 GrB_Info GB_bitmap_assign_noM_noaccum_whole
421 (
422     // input/output:
423     GrB_Matrix C,               // input/output matrix in bitmap format
424     // inputs:
425     const bool C_replace,       // descriptor for C
426 //  const GrB_Matrix M,         // mask matrix, not present here
427     const bool Mask_comp,       // true for !M, false for M
428     const bool Mask_struct,     // true if M is structural, false if valued
429 //  const GrB_BinaryOp accum,   // not present
430     const GrB_Matrix A,         // input matrix, not transposed
431     const void *scalar,         // input scalar
432     const GrB_Type scalar_type, // type of input scalar
433     GB_Context Context
434 ) ;
435 
436 GrB_Info GB_bitmap_assign_notM_accum
437 (
438     // input/output:
439     GrB_Matrix C,               // input/output matrix in bitmap format
440     // inputs:
441     const bool C_replace,       // descriptor for C
442     const GrB_Index *I,         // I index list
443     const int64_t nI,
444     const int Ikind,
445     const int64_t Icolon [3],
446     const GrB_Index *J,         // J index list
447     const int64_t nJ,
448     const int Jkind,
449     const int64_t Jcolon [3],
450     const GrB_Matrix M,         // mask matrix
451 //  const bool Mask_comp,       // true here, for !M only
452     const bool Mask_struct,     // true if M is structural, false if valued
453     const GrB_BinaryOp accum,   // present
454     const GrB_Matrix A,         // input matrix, not transposed
455     const void *scalar,         // input scalar
456     const GrB_Type scalar_type, // type of input scalar
457     const int assign_kind,      // row assign, col assign, assign, or subassign
458     GB_Context Context
459 ) ;
460 
461 GrB_Info GB_bitmap_assign_notM_accum_whole
462 (
463     // input/output:
464     GrB_Matrix C,               // input/output matrix in bitmap format
465     // inputs:
466     const bool C_replace,       // descriptor for C
467     const GrB_Matrix M,         // mask matrix
468 //  const bool Mask_comp,       // true here, for !M only
469     const bool Mask_struct,     // true if M is structural, false if valued
470     const GrB_BinaryOp accum,   // present
471     const GrB_Matrix A,         // input matrix, not transposed
472     const void *scalar,         // input scalar
473     const GrB_Type scalar_type, // type of input scalar
474     GB_Context Context
475 ) ;
476 
477 GrB_Info GB_bitmap_assign_notM_noaccum
478 (
479     // input/output:
480     GrB_Matrix C,               // input/output matrix in bitmap format
481     // inputs:
482     const bool C_replace,       // descriptor for C
483     const GrB_Index *I,         // I index list
484     const int64_t nI,
485     const int Ikind,
486     const int64_t Icolon [3],
487     const GrB_Index *J,         // J index list
488     const int64_t nJ,
489     const int Jkind,
490     const int64_t Jcolon [3],
491     const GrB_Matrix M,         // mask matrix
492 //  const bool Mask_comp,       // true here, for !M only
493     const bool Mask_struct,     // true if M is structural, false if valued
494 //  const GrB_BinaryOp accum,   // not present
495     const GrB_Matrix A,         // input matrix, not transposed
496     const void *scalar,         // input scalar
497     const GrB_Type scalar_type, // type of input scalar
498     const int assign_kind,      // row assign, col assign, assign, or subassign
499     GB_Context Context
500 ) ;
501 
502 GrB_Info GB_bitmap_assign_notM_noaccum_whole
503 (
504     // input/output:
505     GrB_Matrix C,               // input/output matrix in bitmap format
506     // inputs:
507     const bool C_replace,       // descriptor for C
508     const GrB_Matrix M,         // mask matrix
509 //  const bool Mask_comp,       // true here, for !M only
510     const bool Mask_struct,     // true if M is structural, false if valued
511 //  const GrB_BinaryOp accum,   // not present
512     const GrB_Matrix A,         // input matrix, not transposed
513     const void *scalar,         // input scalar
514     const GrB_Type scalar_type, // type of input scalar
515     GB_Context Context
516 ) ;
517 
518 #define GB_BITMAP_M_SCATTER_PLUS_2  0
519 #define GB_BITMAP_M_SCATTER_MINUS_2 1
520 #define GB_BITMAP_M_SCATTER_SET_2   2
521 #define GB_BITMAP_M_SCATTER_MOD_2   3
522 
523 void GB_bitmap_M_scatter        // scatter M into the C bitmap
524 (
525     // input/output:
526     GrB_Matrix C,
527     // inputs:
528     const GrB_Index *I,         // I index list
529     const int64_t nI,
530     const int Ikind,
531     const int64_t Icolon [3],
532     const GrB_Index *J,         // J index list
533     const int64_t nJ,
534     const int Jkind,
535     const int64_t Jcolon [3],
536     const GrB_Matrix M,         // mask to scatter into the C bitmap
537     const bool Mask_struct,     // true if M is structural, false if valued
538     const int assign_kind,      // row assign, col assign, assign, or subassign
539     const int operation,        // +=2, -=2, or %=2
540     const int64_t *M_ek_slicing,    // size M_ntasks+1
541     const int M_ntasks,
542     const int M_nthreads,
543     GB_Context Context
544 ) ;
545 
546 void GB_bitmap_M_scatter_whole  // scatter M into the C bitmap
547 (
548     // input/output:
549     GrB_Matrix C,
550     // inputs:
551     const GrB_Matrix M,         // mask to scatter into the C bitmap
552     const bool Mask_struct,     // true if M is structural, false if valued
553     const int operation,        // +=2, -=2, or %=2
554     const int64_t *M_ek_slicing,    // size M_ntasks+1
555     const int M_ntasks,
556     const int M_nthreads,
557     GB_Context Context
558 ) ;
559 
560 void GB_bitmap_assign_to_full   // set all C->b to 1, or free it and make C full
561 (
562     GrB_Matrix C,
563     int nthreads_max
564 ) ;
565 
566 #endif
567 
568