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