File: GB_AxB_dot_cij.h

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, 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 (131 lines) | stat: -rw-r--r-- 6,167 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
//------------------------------------------------------------------------------
// GB_AxB_dot_cij.h: definitions for GB_AxB_dot*_cij.c
//------------------------------------------------------------------------------

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

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

// The GB_AxB_dot_cij.c method is used only by
// mxm/template/GB_AxB_dot2_template.c and mxm/template/GB_AxB_dot3_template.c.
// That method declares the cij scalar, and initializes it to zero for the
// PLUS_PAIR_REAL semiring.

// GB_DOT: cij += (A(k,i) or A(i,k)) * B(k,j), then break if terminal
// Ai [pA] and Bi [pB] are both equal to the index k.
// pA points to A(k,i) for most GxB_AxB_dot* methods, except for C=A*B in
// GB_AxB_dot2, with A_not_transposed where it points to A(i,k).

// The #include'ing file must use GB_DECLARE_TERMINAL_CONST (zterminal),
// or define zterminal another way (see mxm/template/GB_AxB_dot_generic.c).

// use the boolean flag cij_exists to set/check if C(i,j) exists
#undef  GB_CIJ_CHECK
#define GB_CIJ_CHECK true
#undef  GB_CIJ_EXISTS
#define GB_CIJ_EXISTS cij_exists
#undef  GB_DOT

#if GB_IS_PLUS_PAIR_REAL_SEMIRING

    //--------------------------------------------------------------------------
    // plus_pair_real semiring
    //--------------------------------------------------------------------------

    // this method requires that cij = 0 be initialized when it is declared.
    // See mxm/template/GB_AxB_dot2_template.c and
    // mxm/template/GB_AxB_dot3_template.c

    #if GB_Z_IGNORE_OVERFLOW

        // PLUS_PAIR for 64-bit integers, float, and double (not complex):
        // To check if C(i,j) exists, test (cij != 0) when done.  The
        // boolean flag cij_exists is not used.
        #undef  GB_CIJ_CHECK
        #define GB_CIJ_CHECK false
        #undef  GB_CIJ_EXISTS
        #define GB_CIJ_EXISTS (cij != 0)
        #define GB_DOT(k,pA,pB) cij++ ;

    #else

        // PLUS_PAIR semiring for small integers (not bool)
        #define GB_DOT(k,pA,pB)                                         \
        {                                                               \
            cij_exists = true ;                                         \
            cij++ ;                                                     \
        }

    #endif

#elif GB_IS_ANY_MONOID

    //--------------------------------------------------------------------------
    // ANY monoid, including the ANY_PAIR semiring
    //--------------------------------------------------------------------------

    #if defined ( GB_DOT3 )

        // for the dot3 method: C is sparse or hyper
        #define GB_DOT(k,pA,pB)                                         \
        {                                                               \
            GB_DECLAREA (aki) ;                                         \
            GB_GETA (aki, Ax, pA, A_iso) ;  /* aki = A(k,i) or A(i,k) */\
            GB_DECLAREB (bkj) ;                                         \
            GB_GETB (bkj, Bx, pB, B_iso) ;  /* bkj = B(k,j) */          \
            /* cij = (A' or A)(i,k) * B(k,j), and add to the pattern */ \
            cij_exists = true ;                                         \
            GB_MULT (cij, aki, bkj, i, k, j) ;                          \
            break ;                                                     \
        }

    #else

        // for the dot2 method: C is bitmap
        #define GB_DOT(k,pA,pB)                                         \
        {                                                               \
            GB_DECLAREA (aki) ;                                         \
            GB_GETA (aki, Ax, pA, A_iso) ;  /* aki = A(k,i) or A(i,k) */\
            GB_DECLAREB (bkj) ;                                         \
            GB_GETB (bkj, Bx, pB, B_iso) ;  /* bkj = B(k,j) */          \
            /* cij = (A' or A)(i,k) * B(k,j), and add to the pattern */ \
            GB_MULT (cij, aki, bkj, i, k, j) ;                          \
            int64_t pC = pC_start + i ;                                 \
            GB_PUTC (cij, Cx, pC) ;         /* Cx [pC] = cij */         \
            Cb [pC] = 1 ;                                               \
            task_cnvals++ ;                                             \
            break ;                                                     \
        }

    #endif

#else

    //--------------------------------------------------------------------------
    // all other semirings
    //--------------------------------------------------------------------------

    #define GB_DOT(k,pA,pB)                                             \
    {                                                                   \
        GB_DECLAREA (aki) ;                                             \
        GB_GETA (aki, Ax, pA, A_iso) ;  /* aki = A(k,i) or A(i,k) */    \
        GB_DECLAREB (bkj) ;                                             \
        GB_GETB (bkj, Bx, pB, B_iso) ;  /* bkj = B(k,j) */              \
        if (cij_exists)                                                 \
        {                                                               \
            /* cij += (A' or A)(i,k) * B(k,j) */                        \
            GB_MULTADD (cij, aki, bkj, i, k, j) ;                       \
        }                                                               \
        else                                                            \
        {                                                               \
            /* cij = (A' or A)(i,k) * B(k,j), and add to the pattern */ \
            cij_exists = true ;                                         \
            GB_MULT (cij, aki, bkj, i, k, j) ;                          \
        }                                                               \
        /* if (cij is terminal) break ; */                              \
        GB_IF_TERMINAL_BREAK (cij, zterminal) ;                         \
    }

#endif