1function test75
2%TEST75 test GrB_mxm and GrB_vxm on all semirings
3
4% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
5% SPDX-License-Identifier: Apache-2.0
6
7[binops, ~, add_ops, types, ~, ~] = GB_spec_opsall ;
8% mult_ops = binops.positional ;
9mult_ops = binops.all ;
10types = types.all ;
11
12rng ('default') ;
13
14m = 200 ;
15n = 5 ;
16A_sparse = sprandn (m, n, 0.1) ;
17A_sparse (:,3) = 0 ;
18A_sparse (2,3) = 1.7 ;
19A_sparse (18,3) = 2.2 ;
20A_sparse (:,1:2) = sparse (rand (m,2)) ;
21A_sparse (1,1) = 0;
22A_sparse (18,1) = 0;
23A_sparse (:,5) = 0 ;
24A_sparse (1,5) = 11 ;
25A_sparse (2,5) = 23 ;
26A_sparse (18,5) = 33 ;
27
28B_sparse = sprandn (m, n, 0.1) ;
29B_sparse (:,1) = 0 ;
30B_sparse (1,1) = 3 ;
31B_sparse (18,1) = 2 ;
32B_sparse (:,[2 n]) = sparse (rand (m,2)) ;
33B_sparse (3,2) = 0 ;
34B_sparse (18,2) = 0 ;
35A_sparse (:,3) = 0 ;
36B_sparse (2,1) = 7 ;
37B_sparse (18,1) = 8 ;
38B_sparse (19,1) = 9 ;
39
40x_sparse = sparse (rand (m,1)) ;
41x_sparse (99) = 0 ;
42
43y_sparse = sparse (zeros (m,1)) ;
44y_sparse (99) = 1 ;
45
46A.matrix = A_sparse ;
47A.class = 'see below' ;
48A.pattern = logical (spones (A_sparse)) ;
49
50B.matrix = B_sparse ;
51B.class = 'see below' ;
52B.pattern = logical (spones (B_sparse)) ;
53
54X.matrix = x_sparse ;
55X.class = 'see below' ;
56X.pattern = logical (spones (x_sparse)) ;
57
58Y.matrix = y_sparse ;
59Y.class = 'see below' ;
60Y.pattern = logical (spones (y_sparse)) ;
61
62fprintf ('\n-------------- GrB_mxm, vxm (dot product) on all semirings\n') ;
63
64Cin = sparse (n, n) ;
65
66Din = 10 * sparse (rand (n, n)) ;
67D.matrix = Din ;
68D.class = 'see below' ;
69D.pattern = true (n,n) ;
70
71Xin = sparse (n, 1) ;
72
73Mask = sparse (ones (n,n)) ;
74mask = sparse (ones (n,1)) ;
75
76dnn = struct ;
77dtn = struct ( 'inp0', 'tran' ) ;
78dtn_dot   = struct ( 'inp0', 'tran', 'axb', 'dot' ) ;
79dtn_saxpy = struct ( 'inp0', 'tran', 'axb', 'saxpy' ) ;
80dnt = struct ( 'inp1', 'tran' ) ;
81dtt = struct ( 'inp0', 'tran', 'inp1', 'tran' ) ;
82
83n_semirings = 0 ;
84
85for k1 = 1:length(mult_ops)
86    mulop = mult_ops {k1} ;
87    fprintf ('\n%s', mulop) ;
88
89    for k2 = 1:length(add_ops)
90        addop = add_ops {k2} ;
91
92        for k3 = 1:length (types)
93            semiring_type = types {k3} ;
94
95            semiring.multiply = mulop ;
96            semiring.add = addop ;
97            semiring.class = semiring_type ;
98
99            % create the semiring.  some are not valid because the or,and,xor,eq
100            % monoids can only be used when z is boolean for z=mult(x,y).
101            try
102                [mult_op add_op id] = GB_spec_semiring (semiring) ;
103                [mult_opname mult_optype ztype xtype ytype] = GB_spec_operator (mult_op) ;
104                [ add_opname  add_optype] = GB_spec_operator (add_op) ;
105                identity = GB_spec_identity (semiring.add, add_optype) ;
106            catch
107                continue
108            end
109
110            A.class = semiring_type ;
111            B.class = semiring_type ;
112            X.class = semiring_type ;
113            Y.class = semiring_type ;
114            D.class = add_op.optype ;
115
116            n_semirings = n_semirings + 1 ;
117            fprintf ('.') ;
118
119            % C<M> = A'*B, with mask
120            C1 = GB_mex_mxm  (Cin, Mask, [ ], semiring, A, B, dtn_dot);
121            C2 = GB_spec_mxm (Cin, Mask, [ ], semiring, A, B, dtn) ;
122            GB_spec_compare (C1, C2, id) ;
123            C1 = GB_mex_mxm  (Cin, Mask, [ ], semiring, A, B, dtn_saxpy);
124            GB_spec_compare (C1, C2, id) ;
125
126            % C<M> += A'*B, C dense, typecasting of C
127            C1 = GB_mex_mxm  (Din, Mask, add_op, semiring, A, B, dtn_dot) ;
128            C2 = GB_spec_mxm (Din, Mask, add_op, semiring, A, B, dtn) ;
129            GB_spec_compare (C1, C2, id) ;
130            C1 = GB_mex_mxm  (Din, Mask, add_op, semiring, A, B, dtn_saxpy) ;
131            GB_spec_compare (C1, C2, id) ;
132
133            % C<M> += A'*B, C dense, no typecasting of C
134            C1 = GB_mex_mxm  (D, Mask, add_op, semiring, A, B, dtn_dot) ;
135            C2 = GB_spec_mxm (D, Mask, add_op, semiring, A, B, dtn) ;
136            GB_spec_compare (C1, C2, id) ;
137            C1 = GB_mex_mxm  (D, Mask, add_op, semiring, A, B, dtn_saxpy) ;
138            GB_spec_compare (C1, C2, id) ;
139
140            % C += A'*B, C dense, typecasting of C
141            C1 = GB_mex_mxm  (Din, [ ], add_op, semiring, A, B, dtn_dot) ;
142            C2 = GB_spec_mxm (Din, [ ], add_op, semiring, A, B, dtn) ;
143            GB_spec_compare (C1, C2, id) ;
144            C1 = GB_mex_mxm  (Din, [ ], add_op, semiring, A, B, dtn_saxpy) ;
145            GB_spec_compare (C1, C2, id) ;
146
147            % C += A'*B, C dense, no typecasting of C
148            C1 = GB_mex_mxm  (D, [ ], add_op, semiring, A, B, dtn_dot) ;
149            C2 = GB_spec_mxm (D, [ ], add_op, semiring, A, B, dtn) ;
150            GB_spec_compare (C1, C2, id) ;
151            C1 = GB_mex_mxm  (D, [ ], add_op, semiring, A, B, dtn_saxpy) ;
152            GB_spec_compare (C1, C2, id) ;
153
154            % X = u*A, with mask
155            C1 = GB_mex_vxm  (Xin, mask, [ ], semiring, X, A, [ ]) ;
156            C2 = GB_spec_vxm (Xin, mask, [ ], semiring, X, A, [ ]) ;
157            GB_spec_compare (C1, C2, id) ;
158
159            if (k3 == 1)
160                % repeat but with typecasting, to test generic A'*B
161                A.class = 'double' ;
162
163                % C = A'*B, with mask
164                C1 = GB_mex_mxm  (Cin, Mask, [ ], semiring, A, B, dtn);
165                C2 = GB_spec_mxm (Cin, Mask, [ ], semiring, A, B, dtn);
166                GB_spec_compare (C1, C2, id) ;
167
168                % X = u*A, with mask
169                C1 = GB_mex_vxm  (Xin, mask, [ ], semiring, X, A, [ ]);
170                C2 = GB_spec_vxm (Xin, mask, [ ], semiring, X, A, [ ]);
171                GB_spec_compare (C1, C2, id) ;
172
173                % X = u*A, with mask
174                C1 = GB_mex_vxm  (Xin, mask, [ ], semiring, Y, A, [ ]);
175                C2 = GB_spec_vxm (Xin, mask, [ ], semiring, Y, A, [ ]);
176                GB_spec_compare (C1, C2, id) ;
177
178            end
179        end
180    end
181end
182
183n_semirings
184
185fprintf ('\ntest75: all tests passed\n') ;
186
187