1 //------------------------------------------------------------------------------
2 // GB_emult_01_meta:  phase1 and phase2 for C=A.*B, C<M>=A.*B, C<!M>=A.*B
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 // Computes C=A.*B, C<M>=A.*B, or C<!M>=A.*B.
11 
12 // C is sparse, hypersparse, or bitmap.  M, A, and B can have any sparsity
13 // structure.  If both A and B are full, then GB_add is used instead (this is
14 // the only case where C can be full).
15 
16 // phase1: does not compute C itself, but just counts the # of entries in each
17 // vector of C.  Fine tasks compute the # of entries in their slice of a
18 // single vector of C, and the results are cumsum'd.
19 
20 // phase2: computes C, using the counts computed by phase1.
21 
22 {
23 
24     // iB_first is unused if the operator is FIRST or PAIR
25     #include "GB_unused.h"
26 
27     //--------------------------------------------------------------------------
28     // get A, B, M, and C
29     //--------------------------------------------------------------------------
30 
31     const int64_t *restrict Ap = A->p ;
32     const int64_t *restrict Ah = A->h ;
33     const int8_t  *restrict Ab = A->b ;
34     const int64_t *restrict Ai = A->i ;
35     const int64_t vlen = A->vlen ;
36     const bool A_is_hyper = GB_IS_HYPERSPARSE (A) ;
37     const bool A_is_sparse = GB_IS_SPARSE (A) ;
38     const bool A_is_bitmap = GB_IS_BITMAP (A) ;
39     const bool A_is_full = GB_as_if_full (A) ;
40 
41     const int64_t *restrict Bp = B->p ;
42     const int64_t *restrict Bh = B->h ;
43     const int8_t  *restrict Bb = B->b ;
44     const int64_t *restrict Bi = B->i ;
45     const bool B_is_hyper = GB_IS_HYPERSPARSE (B) ;
46     const bool B_is_sparse = GB_IS_SPARSE (B) ;
47     const bool B_is_bitmap = GB_IS_BITMAP (B) ;
48     const bool B_is_full = GB_as_if_full (B) ;
49 
50     const int64_t *restrict Mp = NULL ;
51     const int64_t *restrict Mh = NULL ;
52     const int8_t  *restrict Mb = NULL ;
53     const int64_t *restrict Mi = NULL ;
54     const GB_void *restrict Mx = NULL ;
55     const bool M_is_hyper = GB_IS_HYPERSPARSE (M) ;
56     const bool M_is_sparse = GB_IS_SPARSE (M) ;
57     const bool M_is_bitmap = GB_IS_BITMAP (M) ;
58     const bool M_is_full = GB_as_if_full (M) ;
59     const bool M_is_sparse_or_hyper = M_is_sparse || M_is_hyper ;
60     size_t msize = 0 ;
61     if (M != NULL)
62     {
63         Mp = M->p ;
64         Mh = M->h ;
65         Mb = M->b ;
66         Mi = M->i ;
67         Mx = (GB_void *) (Mask_struct ? NULL : (M->x)) ;
68         msize = M->type->size ;
69     }
70 
71     #if defined ( GB_PHASE_2_OF_2 )
72     const GB_ATYPE *restrict Ax = (GB_ATYPE *) A->x ;
73     const GB_BTYPE *restrict Bx = (GB_BTYPE *) B->x ;
74     const int64_t  *restrict Cp = C->p ;
75     const int64_t  *restrict Ch = C->h ;
76           int64_t  *restrict Ci = C->i ;
77           GB_CTYPE *restrict Cx = (GB_CTYPE *) C->x ;
78     #endif
79 
80     //--------------------------------------------------------------------------
81     // C=A.*B, C<M>=A.*B, or C<!M>=A.*B: C is sparse or hypersparse
82     //--------------------------------------------------------------------------
83 
84     #if defined ( GB_PHASE_1_OF_2 )
85 
86         // phase1: symbolic phase
87         #include "GB_emult_01_template.c"
88 
89     #else
90 
91         // phase2: numerical phase
92         ASSERT (C_sparsity == GxB_SPARSE || C_sparsity == GxB_HYPERSPARSE) ;
93         #include "GB_emult_01_template.c"
94 
95     #endif
96 }
97 
98