File: GB_emult_08e.c

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (146 lines) | stat: -rw-r--r-- 4,932 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//------------------------------------------------------------------------------
// GB_emult_08e: C<M>=A.*B when C and M are sparse/hyper
//------------------------------------------------------------------------------

// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2025, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//------------------------------------------------------------------------------

// C and M are both sparse/hyper.  M is not complemented.
// A and B can have any format, except at least one is sparse/hyper.

{

    //--------------------------------------------------------------
    // Method8(e): C and M are sparse or hypersparse
    //--------------------------------------------------------------

    //      ------------------------------------------
    //      C       <M>=        A       .*      B
    //      ------------------------------------------
    //      sparse  sparse      sparse          sparse  (method: 8)
    //      sparse  sparse      sparse          bitmap  (9 or 2)
    //      sparse  sparse      sparse          full    (9 or 2)
    //      sparse  sparse      bitmap          sparse  (10 or 3)
    //      sparse  sparse      full            sparse  (10 or 3)

    // Methods 9 and 10 are not yet implemented; using Method 8
    // (GB_emult_08_phase[012]) instead.

    // ether A or B are sparse/hyper
    ASSERT (A_is_sparse || A_is_hyper || B_is_sparse || B_is_hyper);

    //------------------------------------------------------------------
    // get M(:,j)
    //------------------------------------------------------------------

    int64_t pM = -1 ;
    int64_t pM_end = -1 ;

    if (fine_task)
    { 
        // A fine task operates on Mi,Mx [pM...pM_end-1], which is
        // a subset of the vector M(:,j)
        pM     = TaskList [taskid].pM ;
        pM_end = TaskList [taskid].pM_end ;
    }
    else
    {
        int64_t kM = -1 ;
        if ((void *) Ch == (void *) Mh)
        { 
            // Ch is the same as Mh (a shallow copy), or both NULL
            kM = k ;
        }
        else
        { 
            kM = (C_to_M == NULL) ? j : C_to_M [k] ;
        }
        if (kM >= 0)
        { 
            pM     = GBp_M (Mp, kM, vlen) ;
            pM_end = GBp_M (Mp, kM+1, vlen) ;
        }
    }

    //--------------------------------------------------------------------------
    // iterate across M(:,j)
    //--------------------------------------------------------------------------

    for ( ; pM < pM_end ; pM++)
    {

        //----------------------------------------------------------------------
        // get M(i,j) for A(i,j) .* B (i,j)
        //----------------------------------------------------------------------

        int64_t i = GBi_M (Mi, pM, vlen) ;
        bool mij = GB_MCAST (Mx, pM, msize) ;
        if (!mij) continue ;

        //----------------------------------------------------------------------
        // get A(i,j)
        //----------------------------------------------------------------------

        bool afound ;
        if (adense)
        { 
            // A(:,j) is dense, bitmap, or full; use quick lookup
            pA = pA_start + i - iA_first ;
            afound = GBb_A (Ab, pA) ;
        }
        else
        { 
            // A(:,j) is sparse; use binary search for A(i,j)
            int64_t apright = pA_end - 1 ;
            afound = GB_binary_search (i, Ai, GB_Ai_IS_32, &pA, &apright) ;
        }
        if (!afound) continue ;
        ASSERT (GBi_A (Ai, pA, vlen) == i) ;

        //----------------------------------------------------------------------
        // get B(i,j)
        //----------------------------------------------------------------------

        bool bfound ;
        if (bdense)
        { 
            // B(:,j) is dense; use direct lookup for B(i,j)
            pB = pB_start + i - iB_first ;
            bfound = GBb_B (Bb, pB) ;
        }
        else
        { 
            // B(:,j) is sparse; use binary search for B(i,j)
            int64_t bpright = pB_end - 1 ;
            bfound = GB_binary_search (i, Bi, GB_Bi_IS_32, &pB, &bpright) ;
        }
        if (!bfound) continue ;
        ASSERT (GBi_B (Bi, pB, vlen) == i) ;

        //----------------------------------------------------------------------
        // C(i,j) = A(i,j) .* B(i,j)
        //----------------------------------------------------------------------

        // C (i,j) = A (i,j) .* B (i,j)
        #if ( GB_EMULT_08_PHASE == 1 )
        cjnz++ ;
        #else
        GB_ISET (Ci, pC, i) ;       // Ci [pC] = i ;
        #ifndef GB_ISO_EMULT
        GB_DECLAREA (aij) ;
        GB_GETA (aij, Ax, pA, A_iso) ;
        GB_DECLAREB (bij) ;
        GB_GETB (bij, Bx, pB, B_iso) ;
        GB_EWISEOP (Cx, pC, aij, bij, i, j) ;
        #endif
        pC++ ;
        #endif
    }

    #if ( GB_EMULT_08_PHASE == 2 )
    ASSERT (pC == pC_end) ;
    #endif
}