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