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
|
//------------------------------------------------------------------------------
// GB_emult_08e: C<M>=A.*B when C and M are sparse/hyper
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2025, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
// C and M are both sparse/hyper. M is not complemented.
// A and B can have any format, except at least one is sparse/hyper.
{
//--------------------------------------------------------------
// Method8(e): C and M are sparse or hypersparse
//--------------------------------------------------------------
// ------------------------------------------
// C <M>= A .* B
// ------------------------------------------
// sparse sparse sparse sparse (method: 8)
// sparse sparse sparse bitmap (9 or 2)
// sparse sparse sparse full (9 or 2)
// sparse sparse bitmap sparse (10 or 3)
// sparse sparse full sparse (10 or 3)
// Methods 9 and 10 are not yet implemented; using Method 8
// (GB_emult_08_phase[012]) instead.
// ether A or B are sparse/hyper
ASSERT (A_is_sparse || A_is_hyper || B_is_sparse || B_is_hyper);
//------------------------------------------------------------------
// get M(:,j)
//------------------------------------------------------------------
int64_t pM = -1 ;
int64_t pM_end = -1 ;
if (fine_task)
{
// A fine task operates on Mi,Mx [pM...pM_end-1], which is
// a subset of the vector M(:,j)
pM = TaskList [taskid].pM ;
pM_end = TaskList [taskid].pM_end ;
}
else
{
int64_t kM = -1 ;
if ((void *) Ch == (void *) Mh)
{
// Ch is the same as Mh (a shallow copy), or both NULL
kM = k ;
}
else
{
kM = (C_to_M == NULL) ? j : C_to_M [k] ;
}
if (kM >= 0)
{
pM = GBp_M (Mp, kM, vlen) ;
pM_end = GBp_M (Mp, kM+1, vlen) ;
}
}
//--------------------------------------------------------------------------
// iterate across M(:,j)
//--------------------------------------------------------------------------
for ( ; pM < pM_end ; pM++)
{
//----------------------------------------------------------------------
// get M(i,j) for A(i,j) .* B (i,j)
//----------------------------------------------------------------------
int64_t i = GBi_M (Mi, pM, vlen) ;
bool mij = GB_MCAST (Mx, pM, msize) ;
if (!mij) continue ;
//----------------------------------------------------------------------
// get A(i,j)
//----------------------------------------------------------------------
bool afound ;
if (adense)
{
// A(:,j) is dense, bitmap, or full; use quick lookup
pA = pA_start + i - iA_first ;
afound = GBb_A (Ab, pA) ;
}
else
{
// A(:,j) is sparse; use binary search for A(i,j)
int64_t apright = pA_end - 1 ;
afound = GB_binary_search (i, Ai, GB_Ai_IS_32, &pA, &apright) ;
}
if (!afound) continue ;
ASSERT (GBi_A (Ai, pA, vlen) == i) ;
//----------------------------------------------------------------------
// get B(i,j)
//----------------------------------------------------------------------
bool bfound ;
if (bdense)
{
// B(:,j) is dense; use direct lookup for B(i,j)
pB = pB_start + i - iB_first ;
bfound = GBb_B (Bb, pB) ;
}
else
{
// B(:,j) is sparse; use binary search for B(i,j)
int64_t bpright = pB_end - 1 ;
bfound = GB_binary_search (i, Bi, GB_Bi_IS_32, &pB, &bpright) ;
}
if (!bfound) continue ;
ASSERT (GBi_B (Bi, pB, vlen) == i) ;
//----------------------------------------------------------------------
// C(i,j) = A(i,j) .* B(i,j)
//----------------------------------------------------------------------
// C (i,j) = A (i,j) .* B (i,j)
#if ( GB_EMULT_08_PHASE == 1 )
cjnz++ ;
#else
GB_ISET (Ci, pC, i) ; // Ci [pC] = i ;
#ifndef GB_ISO_EMULT
GB_DECLAREA (aij) ;
GB_GETA (aij, Ax, pA, A_iso) ;
GB_DECLAREB (bij) ;
GB_GETB (bij, Bx, pB, B_iso) ;
GB_EWISEOP (Cx, pC, aij, bij, i, j) ;
#endif
pC++ ;
#endif
}
#if ( GB_EMULT_08_PHASE == 2 )
ASSERT (pC == pC_end) ;
#endif
}
|