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