1 //------------------------------------------------------------------------------ 2 // GB_dense_subassign_05d_template: C<M> = x where C is dense 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 { 11 12 //-------------------------------------------------------------------------- 13 // get C and M 14 //-------------------------------------------------------------------------- 15 16 ASSERT (GB_JUMBLED_OK (M)) ; 17 18 const int64_t *restrict Mp = M->p ; 19 const int8_t *restrict Mb = M->b ; 20 const int64_t *restrict Mh = M->h ; 21 const int64_t *restrict Mi = M->i ; 22 const GB_void *restrict Mx = (GB_void *) (Mask_struct ? NULL : (M->x)) ; 23 const size_t msize = M->type->size ; 24 const size_t mvlen = M->vlen ; 25 26 GB_CTYPE *restrict Cx = (GB_CTYPE *) C->x ; 27 const int64_t cvlen = C->vlen ; 28 29 const int64_t *restrict kfirst_Mslice = M_ek_slicing ; 30 const int64_t *restrict klast_Mslice = M_ek_slicing + M_ntasks ; 31 const int64_t *restrict pstart_Mslice = M_ek_slicing + M_ntasks * 2 ; 32 33 //-------------------------------------------------------------------------- 34 // C<M> = x 35 //-------------------------------------------------------------------------- 36 37 int taskid ; 38 #pragma omp parallel for num_threads(M_nthreads) schedule(dynamic,1) 39 for (taskid = 0 ; taskid < M_ntasks ; taskid++) 40 { 41 42 // if kfirst > klast then taskid does no work at all 43 int64_t kfirst = kfirst_Mslice [taskid] ; 44 int64_t klast = klast_Mslice [taskid] ; 45 46 //---------------------------------------------------------------------- 47 // C<M(:,kfirst:klast)> = x 48 //---------------------------------------------------------------------- 49 50 for (int64_t k = kfirst ; k <= klast ; k++) 51 { 52 53 //------------------------------------------------------------------ 54 // find the part of M(:,k) to be operated on by this task 55 //------------------------------------------------------------------ 56 57 int64_t j = GBH (Mh, k) ; 58 int64_t pM_start, pM_end ; 59 GB_get_pA (&pM_start, &pM_end, taskid, k, 60 kfirst, klast, pstart_Mslice, Mp, mvlen) ; 61 62 // pC points to the start of C(:,j) if C is dense 63 int64_t pC = j * cvlen ; 64 65 //------------------------------------------------------------------ 66 // C<M(:,j)> = x 67 //------------------------------------------------------------------ 68 69 if (Mx == NULL && Mb == NULL) 70 { 71 GB_PRAGMA_SIMD_VECTORIZE 72 for (int64_t pM = pM_start ; pM < pM_end ; pM++) 73 { 74 int64_t p = pC + GBI (Mi, pM, mvlen) ; 75 GB_COPY_SCALAR_TO_C (p, cwork) ; // Cx [p] = scalar 76 } 77 } 78 else 79 { 80 GB_PRAGMA_SIMD_VECTORIZE 81 for (int64_t pM = pM_start ; pM < pM_end ; pM++) 82 { 83 if (GBB (Mb, pM) && GB_mcast (Mx, pM, msize)) 84 { 85 int64_t p = pC + GBI (Mi, pM, mvlen) ; 86 GB_COPY_SCALAR_TO_C (p, cwork) ; // Cx [p] = scalar 87 } 88 } 89 } 90 } 91 } 92 } 93 94