1 //------------------------------------------------------------------------------ 2 // GB_AxB_dot2_meta: C=A'*B, C<M>=A'*B or C<!M>=A'*B via dot products 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 #define GB_DOT2 11 12 #include "GB_unused.h" 13 #include "GB_AxB_dot_cij.h" 14 15 // GB_DOT_ALWAYS_SAVE_CIJ: C(i,j) = cij 16 #define GB_DOT_ALWAYS_SAVE_CIJ \ 17 { \ 18 GB_PUTC (cij, pC) ; \ 19 Cb [pC] = 1 ; \ 20 task_cnvals++ ; \ 21 } 22 23 // GB_DOT_SAVE_CIJ: C(i,j) = cij, unless already done by GB_DOT 24 #if GB_IS_ANY_MONOID 25 26 // for the ANY monoid, GB_DOT saves C(i,j) as soon as a value is found 27 #define GB_DOT_SAVE_CIJ 28 29 #else 30 31 // all other monoids: C(i,j) = cij if it exists 32 #define GB_DOT_SAVE_CIJ \ 33 { \ 34 if (GB_CIJ_EXISTS) \ 35 { \ 36 GB_DOT_ALWAYS_SAVE_CIJ ; \ 37 } \ 38 } 39 40 #endif 41 42 { 43 44 //-------------------------------------------------------------------------- 45 // get A, B, and C 46 //-------------------------------------------------------------------------- 47 48 // A and B are never hypersparse. If they are hypersparse on input, they 49 // are converted to packed sparse form first, and the C matrix has smaller 50 // dimensions. The C bitmap matrix is unpacked into a sparse or 51 // hypersparse matrix when done. 52 53 int64_t cnvals = 0 ; 54 55 ASSERT (GB_IS_BITMAP (C)) ; 56 int8_t *restrict Cb = C->b ; 57 GB_CTYPE *restrict Cx = (GB_CTYPE *) C->x ; 58 const int64_t cvlen = C->vlen ; 59 60 const int64_t *restrict Bp = B->p ; 61 const int8_t *restrict Bb = B->b ; 62 const int64_t *restrict Bi = B->i ; 63 const GB_BTYPE *restrict Bx = (GB_BTYPE *) (B_is_pattern ? NULL : B->x) ; 64 const bool B_is_bitmap = GB_IS_BITMAP (B) ; 65 const bool B_is_sparse = GB_IS_SPARSE (B) ; 66 ASSERT (!GB_IS_HYPERSPARSE (B)) ; 67 #define B_is_hyper false 68 69 const int64_t *restrict Ap = A->p ; 70 const int8_t *restrict Ab = A->b ; 71 const int64_t *restrict Ai = A->i ; 72 const GB_ATYPE *restrict Ax = (GB_ATYPE *) (A_is_pattern ? NULL : A->x) ; 73 const bool A_is_bitmap = GB_IS_BITMAP (A) ; 74 const bool A_is_sparse = GB_IS_SPARSE (A) ; 75 ASSERT (!GB_IS_HYPERSPARSE (A)) ; 76 #define A_is_hyper false 77 78 const int64_t vlen = A->vlen ; 79 ASSERT (A->vlen == B->vlen) ; 80 81 const int ntasks = naslice * nbslice ; 82 83 //-------------------------------------------------------------------------- 84 // C=A'*B, C<M>=A'*B, or C<!M>=A'*B via dot products 85 //-------------------------------------------------------------------------- 86 87 if (M == NULL) 88 { 89 90 //---------------------------------------------------------------------- 91 // C = A'*B 92 //---------------------------------------------------------------------- 93 94 #undef GB_MASK_IS_PRESENT 95 #include "GB_meta16_factory.c" 96 97 } 98 else 99 { 100 101 //---------------------------------------------------------------------- 102 // C<M>=A'*B or C<!M>=A'*B 103 //---------------------------------------------------------------------- 104 105 // 12 possible cases of the mask are handled: 106 107 // if M is not complemented (Mask_comp is false): 4 cases 108 // M can be bitmap or full, not sparse or hyper (dot3 handles that) 109 // M can be structural or valued 110 111 // if M is complemented (Mask_comp is true): 8 cases 112 // M can be sparse, hyper, bitmap, or full 113 // M can be structural or valued 114 115 const int8_t *restrict Mb = M->b ; 116 const bool M_is_bitmap = GB_IS_BITMAP (M) ; 117 const bool M_is_full = GB_IS_FULL (M) ; 118 119 #if ( GB_IS_ANY_MONOID ) 120 if (B_is_bitmap && A_is_sparse && M_is_bitmap && Mask_struct 121 && Mask_comp) 122 { 123 124 //------------------------------------------------------------------ 125 // C<#M,struct> = A'*B, special case 126 //------------------------------------------------------------------ 127 128 // GB_ANY_SPECIALIZED is defined if the following conditions hold: 129 // semirings: all built-in semirings with the ANY monoid 130 // A: sparse 131 // B: bitmap 132 // M: bitmap 133 // Mask_comp: true 134 // Mask_struct: true 135 136 GBURBLE ("(specialized) ") ; 137 #define GB_ANY_SPECIALIZED 138 #define GB_MASK_IS_PRESENT 139 #define GB_A_IS_SPARSE 1 140 #define GB_A_IS_HYPER 0 141 #define GB_A_IS_BITMAP 0 142 #define GB_A_IS_FULL 0 143 #define GB_B_IS_SPARSE 0 144 #define GB_B_IS_SPARSE 0 145 #define GB_B_IS_BITMAP 1 146 #define GB_B_IS_FULL 0 147 #include "GB_AxB_dot2_template.c" 148 #undef GB_ANY_SPECIALIZED 149 #undef GB_MASK_IS_PRESENT 150 151 } 152 else 153 #endif 154 { 155 156 //------------------------------------------------------------------ 157 // C<M>=A'*B or C<!M>=A'*B 158 //------------------------------------------------------------------ 159 160 const GB_void *restrict Mx = (GB_void *) 161 (Mask_struct ? NULL : (M->x)) ; 162 const size_t msize = M->type->size ; 163 164 #define GB_MASK_IS_PRESENT 165 #include "GB_meta16_factory.c" 166 #undef GB_MASK_IS_PRESENT 167 168 } 169 } 170 171 C->nvals = cnvals ; 172 } 173 174 #undef A_is_hyper 175 #undef B_is_hyper 176 177 #undef GB_DOT_ALWAYS_SAVE_CIJ 178 #undef GB_DOT_SAVE_CIJ 179 180 #undef GB_DOT2 181 182