1 //------------------------------------------------------------------------------
2 // GB_AxB_dot_cij.h: definitions for GB_AxB_dot*_cij.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 // GB_DOT: cij += A(k,i) * B(k,j), then break if terminal
11 // Ai [pA] and Bi [pB] are both equal to the index k.
12 
13 // use the boolean flag cij_exists to set/check if C(i,j) exists
14 #undef  GB_CIJ_CHECK
15 #define GB_CIJ_CHECK true
16 #undef  GB_CIJ_EXISTS
17 #define GB_CIJ_EXISTS cij_exists
18 #undef  GB_DOT
19 
20 #if GB_IS_PLUS_PAIR_REAL_SEMIRING
21 
22     //--------------------------------------------------------------------------
23     // plus_pair_real semiring
24     //--------------------------------------------------------------------------
25 
26     #if GB_CTYPE_IGNORE_OVERFLOW
27 
28         // PLUS_PAIR for 64-bit integers, float, and double (not complex):
29         // To check if C(i,j) exists, test (cij != 0) when done.  The
30         // boolean flag cij_exists is not used.
31         #undef  GB_CIJ_CHECK
32         #define GB_CIJ_CHECK false
33         #undef  GB_CIJ_EXISTS
34         #define GB_CIJ_EXISTS (cij != 0)
35         #define GB_DOT(k,pA,pB) cij++ ;
36 
37     #else
38 
39         // PLUS_PAIR semiring for small integers
40         #define GB_DOT(k,pA,pB)                                         \
41         {                                                               \
42             cij_exists = true ;                                         \
43             cij++ ;                                                     \
44         }
45 
46     #endif
47 
48 #elif GB_IS_ANY_MONOID
49 
50     //--------------------------------------------------------------------------
51     // ANY monoid
52     //--------------------------------------------------------------------------
53 
54     #if defined ( GB_DOT3 )
55 
56         // for the dot3 method: C is sparse or hyper
57         #define GB_DOT(k,pA,pB)                                         \
58         {                                                               \
59             GB_GETA (aki, Ax, pA) ;  /* aki = A(k,i) */                 \
60             GB_GETB (bkj, Bx, pB) ;  /* bkj = B(k,j) */                 \
61             /* cij = (A')(i,k) * B(k,j), and add to the pattern */      \
62             cij_exists = true ;                                         \
63             GB_MULT (cij, aki, bkj, i, k, j) ;                          \
64             break ;                                                     \
65         }
66 
67     #else
68 
69         // for the dot2 method: C is bitmap
70         #define GB_DOT(k,pA,pB)                                         \
71         {                                                               \
72             GB_GETA (aki, Ax, pA) ;  /* aki = A(k,i) */                 \
73             GB_GETB (bkj, Bx, pB) ;  /* bkj = B(k,j) */                 \
74             /* cij = (A')(i,k) * B(k,j), and add to the pattern */      \
75             GB_MULT (cij, aki, bkj, i, k, j) ;                          \
76             int64_t pC = pC_start + i ;                                 \
77             GB_PUTC (cij, pC) ;                                         \
78             Cb [pC] = 1 ;                                               \
79             task_cnvals++ ;                                             \
80             break ;                                                     \
81         }
82 
83     #endif
84 
85 #else
86 
87     //--------------------------------------------------------------------------
88     // all other semirings
89     //--------------------------------------------------------------------------
90 
91     #define GB_DOT(k,pA,pB)                                             \
92     {                                                                   \
93         GB_GETA (aki, Ax, pA) ;  /* aki = A(k,i) */                     \
94         GB_GETB (bkj, Bx, pB) ;  /* bkj = B(k,j) */                     \
95         if (cij_exists)                                                 \
96         {                                                               \
97             /* cij += (A')(i,k) * B(k,j) */                             \
98             GB_MULTADD (cij, aki, bkj, i, k, j) ;                       \
99         }                                                               \
100         else                                                            \
101         {                                                               \
102             /* cij = (A')(i,k) * B(k,j), and add to the pattern */      \
103             cij_exists = true ;                                         \
104             GB_MULT (cij, aki, bkj, i, k, j) ;                          \
105         }                                                               \
106         /* if (cij is terminal) break ; */                              \
107         GB_DOT_TERMINAL (cij) ;                                         \
108     }
109 
110 #endif
111 
112