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