1 //------------------------------------------------------------------------------
2 // GB_mxm.h: definitions for C=A*B
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 #ifndef GB_MXM_H
11 #define GB_MXM_H
12 #include "GB_AxB_saxpy.h"
13 
14 //------------------------------------------------------------------------------
15 
16 GrB_Info GB_mxm                     // C<M> = A*B
17 (
18     GrB_Matrix C,                   // input/output matrix for results
19     const bool C_replace,           // if true, clear C before writing to it
20     const GrB_Matrix M,             // optional mask for C, unused if NULL
21     const bool Mask_comp,           // if true, use !M
22     const bool Mask_struct,         // if true, use the only structure of M
23     const GrB_BinaryOp accum,       // optional accum for Z=accum(C,T)
24     const GrB_Semiring semiring,    // defines '+' and '*' for C=A*B
25     const GrB_Matrix A,             // input matrix
26     const bool A_transpose,         // if true, use A' instead of A
27     const GrB_Matrix B,             // input matrix
28     const bool B_transpose,         // if true, use B' instead of B
29     const bool flipxy,              // if true, do z=fmult(b,a) vs fmult(a,b)
30     const GrB_Desc_Value AxB_method,// for auto vs user selection of methods
31     const int do_sort,              // if nonzero, try to return C unjumbled
32     GB_Context Context
33 ) ;
34 
35 GrB_Info GB_AxB_dot                 // dot product (multiple methods)
36 (
37     GrB_Matrix C,                   // output matrix, static header
38     GrB_Matrix C_in_place,          // input/output matrix, if done in-place
39     GrB_Matrix M,                   // optional mask matrix
40     const bool Mask_comp,           // if true, use !M
41     const bool Mask_struct,         // if true, use the only structure of M
42     const GrB_Matrix A,             // input matrix A
43     const GrB_Matrix B,             // input matrix B
44     const GrB_Semiring semiring,    // semiring that defines C=A*B
45     const bool flipxy,              // if true, do z=fmult(b,a) vs fmult(a,b)
46     bool *mask_applied,             // if true, mask was applied
47     bool *done_in_place,            // if true, C_in_place was computed in-place
48     GB_Context Context
49 ) ;
50 
51 GB_PUBLIC   // accessed by the MATLAB tests in GraphBLAS/Test only
52 GrB_Info GB_AxB_meta                // C<M>=A*B meta algorithm
53 (
54     GrB_Matrix C,                   // output, static header (if not in-place)
55     GrB_Matrix C_in,                // input/output matrix, if done in-place
56     bool C_replace,                 // C matrix descriptor
57     const bool C_is_csc,            // desired CSR/CSC format of C
58     GrB_Matrix MT,                  // return MT = M' (static header)
59     bool *M_transposed,             // true if MT = M' was computed
60     const GrB_Matrix M_in,          // mask for C<M> (not complemented)
61     const bool Mask_comp,           // if true, use !M
62     const bool Mask_struct,         // if true, use the only structure of M
63     const GrB_BinaryOp accum,       // accum operator for C_in += A*B
64     const GrB_Matrix A_in,          // input matrix
65     const GrB_Matrix B_in,          // input matrix
66     const GrB_Semiring semiring,    // semiring that defines C=A*B
67     bool A_transpose,               // if true, use A', else A
68     bool B_transpose,               // if true, use B', else B
69     bool flipxy,                    // if true, do z=fmult(b,a) vs fmult(a,b)
70     bool *mask_applied,             // if true, mask was applied
71     bool *done_in_place,            // if true, C was computed in-place
72     GrB_Desc_Value AxB_method,      // for auto vs user selection of methods
73     const int do_sort,              // if nonzero, try to return C unjumbled
74     GB_Context Context
75 ) ;
76 
77 GrB_Info GB_AxB_rowscale            // C = D*B, row scale with diagonal D
78 (
79     GrB_Matrix C,                   // output matrix, static header
80     const GrB_Matrix D,             // diagonal input matrix
81     const GrB_Matrix B,             // input matrix
82     const GrB_Semiring semiring,    // semiring that defines C=D*A
83     const bool flipxy,              // if true, do z=fmult(b,a) vs fmult(a,b)
84     GB_Context Context
85 ) ;
86 
87 GrB_Info GB_AxB_colscale            // C = A*D, column scale with diagonal D
88 (
89     GrB_Matrix C,                   // output matrix, static header
90     const GrB_Matrix A,             // input matrix
91     const GrB_Matrix D,             // diagonal input matrix
92     const GrB_Semiring semiring,    // semiring that defines C=A*D
93     const bool flipxy,              // if true, do z=fmult(b,a) vs fmult(a,b)
94     GB_Context Context
95 ) ;
96 
97 
98 bool GB_AxB_semiring_builtin        // true if semiring is builtin
99 (
100     // inputs:
101     const GrB_Matrix A,
102     const bool A_is_pattern,        // true if only the pattern of A is used
103     const GrB_Matrix B,
104     const bool B_is_pattern,        // true if only the pattern of B is used
105     const GrB_Semiring semiring,    // semiring that defines C=A*B
106     const bool flipxy,              // true if z=fmult(y,x), flipping x and y
107     // outputs, unused by caller if this function returns false
108     GB_Opcode *mult_opcode,         // multiply opcode
109     GB_Opcode *add_opcode,          // add opcode
110     GB_Type_code *xcode,            // type code for x input
111     GB_Type_code *ycode,            // type code for y input
112     GB_Type_code *zcode             // type code for z output
113 ) ;
114 
115 GB_PUBLIC   // accessed by the MATLAB tests in GraphBLAS/Test only
116 GrB_Info GB_AxB_dot2                // C=A'*B or C<!M>=A'*B, dot product method
117 (
118     GrB_Matrix C,                   // output matrix, static header
119     const GrB_Matrix M,             // mask matrix for C<!M>=A'*B
120     const bool Mask_comp,           // if true, use !M
121     const bool Mask_struct,         // if true, use the only structure of M
122     const GrB_Matrix A,             // input matrix
123     const GrB_Matrix B,             // input matrix
124     const GrB_Semiring semiring,    // semiring that defines C=A*B
125     const bool flipxy,              // if true, do z=fmult(b,a) vs fmult(a,b)
126     GB_Context Context
127 ) ;
128 
129 bool GB_is_diagonal             // true if A is diagonal
130 (
131     const GrB_Matrix A,         // input matrix to examine
132     GB_Context Context
133 ) ;
134 
135 GB_PUBLIC   // accessed by the MATLAB tests in GraphBLAS/Test only
136 GrB_Info GB_AxB_dot3                // C<M> = A'*B using dot product method
137 (
138     GrB_Matrix C,                   // output matrix, static header
139     const GrB_Matrix M,             // mask matrix for C<M>=A'*B or C<!M>=A'*B
140     const bool Mask_struct,         // if true, use the only structure of M
141     const GrB_Matrix A,             // input matrix
142     const GrB_Matrix B,             // input matrix
143     const GrB_Semiring semiring,    // semiring that defines C=A*B
144     const bool flipxy,              // if true, do z=fmult(b,a) vs fmult(a,b)
145     GB_Context Context
146 ) ;
147 
148 GrB_Info GB_AxB_dot3_slice
149 (
150     // output:
151     GB_task_struct **p_TaskList,    // array of structs, of size max_ntasks
152     size_t *p_TaskList_size,        // size of TaskList
153     int *p_ntasks,                  // # of tasks constructed
154     int *p_nthreads,                // # of threads to use
155     // input:
156     const GrB_Matrix C,             // matrix to slice
157     GB_Context Context
158 ) ;
159 
160 GrB_Info GB_AxB_dot3_one_slice
161 (
162     // output:
163     GB_task_struct **p_TaskList,    // array of structs, of size max_ntasks
164     size_t *p_TaskList_size,        // size of TaskList
165     int *p_ntasks,                  // # of tasks constructed
166     int *p_nthreads,                // # of threads to use
167     // input:
168     const GrB_Matrix M,             // matrix to slice
169     GB_Context Context
170 ) ;
171 
172 GrB_Info GB_AxB_dot4                // C+=A'*B, dot product method
173 (
174     GrB_Matrix C,                   // input/output matrix, must be dense
175     const GrB_Matrix A,             // input matrix
176     const GrB_Matrix B,             // input matrix
177     const GrB_Semiring semiring,    // semiring that defines C+=A*B
178     const bool flipxy,              // if true, do z=fmult(b,a) vs fmult(a,b)
179     GB_Context Context
180 ) ;
181 
182 void GB_AxB_pattern
183 (
184     // outputs:
185     bool *A_is_pattern,     // true if A is pattern-only, because of the mult
186     bool *B_is_pattern,     // true if B is pattern-only, because of the mult
187     // inputs:
188     const bool flipxy,      // if true,  z = mult (b,a) will be computed
189                             // if false, z = mult (a,b) will be computed
190     const GB_Opcode mult_opcode // opcode of multiply operator
191 ) ;
192 
193 //------------------------------------------------------------------------------
194 // GB_AxB_dot4_control: determine if the dot4 method should be used
195 //------------------------------------------------------------------------------
196 
197 // C += A'*B where C is modified in-place
198 
GB_AxB_dot4_control(const GrB_Matrix C_in,const GrB_Matrix M,const bool Mask_comp)199 static inline bool GB_AxB_dot4_control
200 (
201     const GrB_Matrix C_in,      // NULL if C cannot be modified in-place
202     const GrB_Matrix M,
203     const bool Mask_comp
204 )
205 {
206     return (C_in != NULL && M == NULL && !Mask_comp && !GB_IS_BITMAP (C_in)) ;
207 }
208 
209 //------------------------------------------------------------------------------
210 // GB_AxB_dot3_control: determine if the dot3 method should be used
211 //------------------------------------------------------------------------------
212 
213 // C<M>=A'*B where M is sparse or hypersparse, and not complemented
214 
GB_AxB_dot3_control(const GrB_Matrix M,const bool Mask_comp)215 static inline bool GB_AxB_dot3_control
216 (
217     const GrB_Matrix M,
218     const bool Mask_comp
219 )
220 {
221     return (M != NULL && !Mask_comp &&
222         (GB_IS_SPARSE (M) || GB_IS_HYPERSPARSE (M))) ;
223 }
224 
225 //------------------------------------------------------------------------------
226 // GB_AxB_dot2_control: determine if the dot2 method should be used
227 //------------------------------------------------------------------------------
228 
229 // C=A'*B, C<M>=A'*B, or C<!M>=A'*B where C is constructed in bitmap format.
230 // C must be small and likely very dense.
231 
232 bool GB_AxB_dot2_control  // true: use dot2, false: use saxpy
233 (
234     const GrB_Matrix A,
235     const GrB_Matrix B,
236     GB_Context Context
237 ) ;
238 
239 #endif
240 
241