1 //------------------------------------------------------------------------------ 2 // GB_emult_03_template: C<M>= A.*B, M sparse/hyper, A and B bitmap/full 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 // C is sparse, with the same sparsity structure as M. 11 // A and B are both bitmap/full. 12 13 { 14 15 //-------------------------------------------------------------------------- 16 // get M, A, B, and C 17 //-------------------------------------------------------------------------- 18 19 const int8_t *restrict Ab = A->b ; 20 const int8_t *restrict Bb = B->b ; 21 22 const GB_ATYPE *restrict Ax = (GB_ATYPE *) A->x ; 23 const GB_BTYPE *restrict Bx = (GB_BTYPE *) B->x ; 24 25 const int64_t *restrict Mp = M->p ; 26 const int64_t *restrict Mh = M->h ; 27 const int64_t *restrict Mi = M->i ; 28 const GB_void *restrict Mx = (GB_void *) ((Mask_struct) ? NULL : M->x) ; 29 const int64_t vlen = M->vlen ; 30 const size_t msize = M->type->size ; 31 32 const int64_t *restrict Cp = C->p ; 33 int64_t *restrict Ci = C->i ; 34 GB_CTYPE *restrict Cx = (GB_CTYPE *) C->x ; 35 36 const int64_t *restrict kfirst_Mslice = M_ek_slicing ; 37 const int64_t *restrict klast_Mslice = M_ek_slicing + M_ntasks ; 38 const int64_t *restrict pstart_Mslice = M_ek_slicing + M_ntasks * 2 ; 39 40 //-------------------------------------------------------------------------- 41 // C<M>=A.*B where M is sparse/hyper, A and B are bitmap/full 42 //-------------------------------------------------------------------------- 43 44 int tid ; 45 #pragma omp parallel for num_threads(M_nthreads) schedule(dynamic,1) 46 for (tid = 0 ; tid < M_ntasks ; tid++) 47 { 48 int64_t kfirst = kfirst_Mslice [tid] ; 49 int64_t klast = klast_Mslice [tid] ; 50 for (int64_t k = kfirst ; k <= klast ; k++) 51 { 52 int64_t j = GBH (Mh, k) ; 53 int64_t pstart = j * vlen ; 54 int64_t pM, pM_end, pC ; 55 GB_get_pA_and_pC (&pM, &pM_end, &pC, tid, k, kfirst, klast, 56 pstart_Mslice, Cp_kfirst, Cp, vlen, Mp, vlen) ; 57 for ( ; pM < pM_end ; pM++) 58 { 59 int64_t i = Mi [pM] ; 60 if (GB_mcast (Mx, pM, msize) && 61 (GBB (Ab, pstart + i) 62 && // TODO: for GB_add, use || instead 63 GBB (Bb, pstart + i))) 64 { 65 int64_t p = pstart + i ; 66 // C (i,j) = A (i,j) .* B (i,j) 67 Ci [pC] = i ; 68 GB_GETA (aij, Ax, p) ; 69 GB_GETB (bij, Bx, p) ; 70 GB_BINOP (GB_CX (pC), aij, bij, i, j) ; 71 pC++ ; 72 } 73 } 74 } 75 } 76 } 77 78