File: GB_AxB_dot_cij.h

package info (click to toggle)
suitesparse-graphblas 7.4.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 67,112 kB
  • sloc: ansic: 1,072,243; cpp: 8,081; sh: 512; makefile: 503; asm: 369; python: 125; awk: 10
file content (113 lines) | stat: -rw-r--r-- 5,163 bytes parent folder | download | duplicates (3)
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
//------------------------------------------------------------------------------
// GB_AxB_dot_cij.h: definitions for GB_AxB_dot*_cij.c
//------------------------------------------------------------------------------

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

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

// 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).

// 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
    //--------------------------------------------------------------------------

    #if GB_CTYPE_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
        #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_GETA (aki, Ax, pA, A_iso) ;  /* aki = A(k,i) or A(i,k) */\
            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_GETA (aki, Ax, pA, A_iso) ;  /* aki = A(k,i) or A(i,k) */\
            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, pC) ;                                         \
            Cb [pC] = 1 ;                                               \
            task_cnvals++ ;                                             \
            break ;                                                     \
        }

    #endif

#else

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

    #define GB_DOT(k,pA,pB)                                             \
    {                                                                   \
        GB_GETA (aki, Ax, pA, A_iso) ;  /* aki = A(k,i) or A(i,k) */    \
        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_DOT_TERMINAL (cij) ;                                         \
    }

#endif