1 //------------------------------------------------------------------------------
2 // GB_AxB_saxpy3_coarseHash_M_phase1: symbolic coarse hash method, with M
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     // Initially, Hf [...] < mark for all of Hf.
12     // Let h = Hi [hash] and f = Hf [hash].
13 
14     // f < mark: unoccupied, M(i,j)=0, C(i,j) ignored if
15     //           this case occurs while scanning A(:,k)
16     // h == i, f == mark   : M(i,j)=1, and C(i,j) not yet seen.
17     // h == i, f == mark+1 : M(i,j)=1, and C(i,j) has been seen.
18 
19     for (int64_t kk = kfirst ; kk <= klast ; kk++)
20     {
21         GB_GET_B_j ;            // get B(:,j)
22         Cp [kk] = 0 ;
23 
24         //----------------------------------------------------------------------
25         // special case when B(:,j) is empty
26         //----------------------------------------------------------------------
27 
28         #if ( GB_B_IS_SPARSE || GB_B_IS_HYPER )
29         if (bjnz == 0) continue ;
30         #endif
31 
32         //----------------------------------------------------------------------
33         // get M(:,j) and scatter it into the Hf workspace
34         //----------------------------------------------------------------------
35 
36         GB_GET_M_j ;                                // get M(:,j)
37         if (mjnz == 0) continue ;
38         GB_GET_M_j_RANGE (64) ;
39         mark += 2 ;
40         const int64_t f0 = mark ;
41         const int64_t f1 = mark+1 ;
42         GB_HASH_M_j ;                               // hash M(:,j)
43 
44         //----------------------------------------------------------------------
45         // count nnz in C(:,j)
46         //----------------------------------------------------------------------
47 
48         int64_t cjnz = 0 ;
49         for ( ; pB < pB_end ; pB++)     // scan B(:,j)
50         {
51             GB_GET_B_kj_INDEX ;         // get k of B(k,j)
52             GB_GET_A_k ;                // get A(:,k)
53             if (aknz == 0) continue ;
54             #define GB_IKJ                                              \
55             {                                                           \
56                 for (GB_HASH (i))               /* find i in hash */    \
57                 {                                                       \
58                     int64_t f = Hf [hash] ;                             \
59                     if (f < f0) break ;         /* M(i,j)=0; ignore */  \
60                     if (Hi [hash] == i)         /* if true, i found */  \
61                     {                                                   \
62                         if (f == f0)            /* if true, i is new */ \
63                         {                                               \
64                             Hf [hash] = f1 ;    /* flag i as seen */    \
65                             cjnz++ ;            /* C(i,j) is new */     \
66                         }                                               \
67                         break ;                                         \
68                     }                                                   \
69                 }                                                       \
70             }
71             GB_SCAN_M_j_OR_A_k (((GB_A_IS_SPARSE || GB_A_IS_HYPER) &&
72                 !A_jumbled)) ;
73             #undef GB_IKJ
74         }
75         Cp [kk] = cjnz ;                // count the entries in C(:,j)
76     }
77 }
78 
79