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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
//------------------------------------------------------------------------------
// GB_AxB_dot3_meta: C<M>=A'*B via dot products, where C is sparse/hypersparse
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
#define GB_DOT3
#define GB_DOT3_PHASE2
#include "GB_unused.h"
#include "GB_AxB_dot_cij.h"
// GB_DOT_ALWAYS_SAVE_CIJ: C(i,j) = cij
#if GB_CIJ_CHECK
#define GB_DOT_ALWAYS_SAVE_CIJ \
{ \
cij_exists = true ; \
GB_PUTC (cij, pC) ; \
Ci [pC] = i ; \
}
#else
#define GB_DOT_ALWAYS_SAVE_CIJ \
{ \
GB_PUTC (cij, pC) ; \
Ci [pC] = i ; \
}
#endif
// GB_DOT_SAVE_CIJ: C(i,j) = cij, if it exists
#define GB_DOT_SAVE_CIJ \
{ \
if (GB_CIJ_EXISTS) \
{ \
GB_PUTC (cij, pC) ; \
Ci [pC] = i ; \
} \
}
{
//--------------------------------------------------------------------------
// get M, A, B, and C
//--------------------------------------------------------------------------
// C and M have the same sparsity patter (both are sparse or hyper),
// except entries of C may become zombies. M is not complemented.
int64_t nzombies = 0 ;
ASSERT (GB_IS_SPARSE (C) || GB_IS_HYPERSPARSE (C)) ;
const int64_t *restrict Cp = C->p ;
const int64_t *restrict Ch = C->h ;
int64_t *restrict Ci = C->i ;
const int64_t cvlen = C->vlen ;
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 int64_t bnvec = B->nvec ;
const bool B_is_hyper = GB_IS_HYPERSPARSE (B) ;
const bool B_is_bitmap = GB_IS_BITMAP (B) ;
const bool B_is_sparse = GB_IS_SPARSE (B) ;
const bool B_iso = B->iso ;
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 anvec = A->nvec ;
const bool A_is_hyper = GB_IS_HYPERSPARSE (A) ;
const bool A_is_bitmap = GB_IS_BITMAP (A) ;
const bool A_is_sparse = GB_IS_SPARSE (A) ;
const bool A_iso = A->iso ;
const GrB_Matrix A_Y = A->Y ;
const int64_t *restrict A_Yp = (A_is_hyper) ? A_Y->p : NULL ;
const int64_t *restrict A_Yi = (A_is_hyper) ? A_Y->i : NULL ;
const int64_t *restrict A_Yx = (A_is_hyper) ? A_Y->x : NULL ;
const int64_t A_hash_bits = (A_is_hyper) ? (A_Y->vdim - 1) : 0 ;
const GrB_Matrix B_Y = B->Y ;
const int64_t *restrict B_Yp = (B_is_hyper) ? B_Y->p : NULL ;
const int64_t *restrict B_Yi = (B_is_hyper) ? B_Y->i : NULL ;
const int64_t *restrict B_Yx = (B_is_hyper) ? B_Y->x : NULL ;
const int64_t B_hash_bits = (B_is_hyper) ? (B_Y->vdim - 1) : 0 ;
#if !GB_A_IS_PATTERN
const GB_ATYPE *restrict Ax = (GB_ATYPE *) A->x ;
#endif
#if !GB_B_IS_PATTERN
const GB_BTYPE *restrict Bx = (GB_BTYPE *) B->x ;
#endif
#if !GB_IS_ANY_PAIR_SEMIRING
GB_CTYPE *restrict Cx = (GB_CTYPE *) C->x ;
#endif
const int64_t vlen = A->vlen ;
ASSERT (A->vlen == B->vlen) ;
const bool M_is_sparse = GB_IS_SPARSE (M) ;
ASSERT (M_is_sparse || GB_IS_HYPERSPARSE (M)) ;
const int64_t *restrict Mi = M->i ;
const size_t mvlen = M->vlen ;
//--------------------------------------------------------------------------
// C<M> = A'*B via dot products, where C and M are both sparse/hyper
//--------------------------------------------------------------------------
// 4 possible cases of the mask are handled:
// M can be sparse or hyper, and always present
// M can be structural or valued
// M is not complemented
// The other 12 cases of the mask, and the one no-mask case, are handled
// by dot2.
if (M_is_sparse && Mask_struct && A_is_sparse && B_is_sparse)
{
// special case: M is sparse and structural, and A and B are sparse
#define GB_MASK_SPARSE_AND_STRUCTURAL
#define GB_A_IS_SPARSE 1
#define GB_A_IS_HYPER 0
#define GB_A_IS_BITMAP 0
#define GB_A_IS_FULL 0
#define GB_B_IS_SPARSE 1
#define GB_B_IS_HYPER 0
#define GB_B_IS_BITMAP 0
#define GB_B_IS_FULL 0
#include "GB_AxB_dot3_template.c"
#undef GB_MASK_SPARSE_AND_STRUCTURAL
}
else
{
// general case
const GB_void *restrict Mx = (GB_void *) (Mask_struct ? NULL : (M->x)) ;
const size_t msize = M->type->size ;
#include "GB_meta16_factory.c"
}
C->nzombies = nzombies ;
}
#undef GB_DOT_ALWAYS_SAVE_CIJ
#undef GB_DOT_SAVE_CIJ
#undef GB_DOT3
#undef GB_DOT3_PHASE2
|