1 //------------------------------------------------------------------------------
2 // GB_bitmap_assign_A_template: traverse over A for bitmap assignment into C
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 // This template traverses over all the entries of the matrix A and operates on
11 // the corresponding entry in C(i,j), using the GB_AIJ_WORK macro.  A can be
12 // hypersparse, sparse, bitmap, or full.  It is not a scalar.  The matrix
13 // C must be bitmap or full.
14 
15 {
16 
17     //--------------------------------------------------------------------------
18     // matrix assignment: slice the entries of A for each task
19     //--------------------------------------------------------------------------
20 
21     GB_WERK_DECLARE (A_ek_slicing, int64_t) ;
22     int A_ntasks, A_nthreads ;
23     GB_SLICE_MATRIX (A, 8, chunk) ;
24 
25     //--------------------------------------------------------------------------
26     // traverse of the entries of the matrix A
27     //--------------------------------------------------------------------------
28 
29     int tid ;
30     #pragma omp parallel for num_threads(A_nthreads) schedule(dynamic,1) \
31         reduction(+:cnvals)
32     for (tid = 0 ; tid < A_ntasks ; tid++)
33     {
34 
35         // if kfirst > klast then task tid does no work at all
36         int64_t kfirst = kfirst_Aslice [tid] ;
37         int64_t klast  = klast_Aslice  [tid] ;
38         int64_t task_cnvals = 0 ;
39 
40         //----------------------------------------------------------------------
41         // traverse over A (:,kfirst:klast)
42         //----------------------------------------------------------------------
43 
44         for (int64_t k = kfirst ; k <= klast ; k++)
45         {
46 
47             //------------------------------------------------------------------
48             // find the part of A(:,k) for this task
49             //------------------------------------------------------------------
50 
51             int64_t jA = GBH (Ah, k) ;
52             int64_t pA_start, pA_end ;
53             GB_get_pA (&pA_start, &pA_end, tid, k, kfirst,
54                 klast, pstart_Aslice, Ap, nI) ;
55 
56             //------------------------------------------------------------------
57             // traverse over A(:,jA), the kth vector of A
58             //------------------------------------------------------------------
59 
60             int64_t jC = GB_ijlist (J, jA, Jkind, Jcolon) ;
61             int64_t pC0 = jC * cvlen ;      // first entry in C(:,jC)
62 
63             for (int64_t pA = pA_start ; pA < pA_end ; pA++)
64             {
65                 if (!GBB (Ab, pA)) continue ;
66                 int64_t iA = GBI (Ai, pA, nI) ;
67                 int64_t iC = GB_ijlist (I, iA, Ikind, Icolon) ;
68                 int64_t pC = iC + pC0 ;
69                 // operate on C(iC,jC) at pC, and A(iA,jA) at pA.  The mask
70                 // can be accessed at pC if M is bitmap or full.  A has any
71                 // sparsity format so only A(iA,jA) can be accessed at pA.
72                 // To access a full matrix M for the subassign case, use
73                 // the position (iA + jA*nI).
74                 GB_AIJ_WORK (pC, pA) ;
75             }
76         }
77         cnvals += task_cnvals ;
78     }
79 
80     //--------------------------------------------------------------------------
81     // free workspace
82     //--------------------------------------------------------------------------
83 
84     GB_WERK_POP (A_ek_slicing, int64_t) ;
85 }
86 
87