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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
function mxm_demo
%MXM_DEMO performance test of real and complex A*B
% Requires the ssget interface to the SuiteSparse Matrix Collection.
% See https://sparse.tamu.edu.
% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
% SPDX-License-Identifier: Apache-2.0
% reset to the default number of threads
ncores = demo_nproc ;
GrB.clear ;
rng ('default') ;
Prob = ssget (936)
Prob2 = ssget (2662)
% GrB.burble (true) ;
try
system ('hostname') ;
catch
end
v = GrB.ver ;
fprintf ('GraphBLAS version: %s (%s)\n', v.Version, v.Date) ;
% warmup
G = GrB (1) ;
G = G*G ;
clear G
if (demo_octave)
thread_list = ncores ;
else
thread_list = [ 1 ncores 2*ncores] ;
end
for nth = thread_list
% tell built-in method and GraphBLAS to use nth threads:
demo_nproc (nth) ;
GrB.threads (nth) ;
fprintf ('\n-------------------------------------------------\n') ;
if (nth == 1)
fprintf ('Testing single-threaded performance of C=A*B:\n') ;
else
fprintf ('Testing performance of C=A*B using %d threads:\n', nth) ;
end
fprintf ('-------------------------------------------------\n') ;
types = { 'single', 'double', 'single complex', 'double complex' } ;
for k = 1:4
type = types {k} ;
% GrB.random (A, ...) is like sprand (A), but it allows
% the range of values to be specified, as an array of size 2.
% The output matrix has the same type as the range parameter.
switch (type)
case 'single'
fprintf ('\n=== builtin: double (real) ') ;
range = single ([-1 1]) ;
case 'double'
fprintf ('\n=== builtin: double (real) ') ;
range = double ([-1 1]) ;
case 'single complex'
fprintf ('\n=== builtin: double complex ') ;
range = complex (single ([-1 1])) ;
case 'double complex'
fprintf ('\n=== builtin: double complex ') ;
range = complex (double ([-1 1])) ;
end
GA = GrB.random (Prob.A, 'range', range) ;
GB = GrB.random (Prob.A, 'range', range) ;
fprintf ('vs GraphBLAS: %s\n', GrB.type (GA)) ;
[m, n] = size (Prob.A) ;
% create built-in versions of GA and GB. The overloaded "double"
% function converts GA and GB to double or double complex, just like
% the built-in. Built-in sparse matrices cannot be 'single' or 'single
% complex', so all of these test use 'double' or 'double complex'.
A = double (GA) ;
B = double (GB) ;
tm_total = 0 ;
tg_total = 0 ;
ntrials = 4 ;
fprintf ('C=A*B: sparse matrix times sparse matrix:\n') ;
for trial = 1:ntrials
tic
C1 = A*B ;
tm = toc ;
tic
C2 = GA*GB ;
tg = toc ;
err = norm (C1-C2,1) / norm (C1, 1) ;
fprintf ('trial %d: builtin: %10.4f GrB: %10.4f', trial, tm, tg);
fprintf (' speedup: %10.2f err: %g\n', tm / tg, err) ;
tm_total = tm_total + tm ;
tg_total = tg_total + tg ;
end
tm = tm_total / ntrials ;
tg = tg_total / ntrials ;
fprintf ('average: builtin: %10.4f GrB: %10.4f', tm, tg) ;
fprintf (' speedup: %10.2f\n', tm / tg) ;
GA = GrB.random (Prob2.A, 'range', range) ;
[m, n] = size (Prob2.A) ;
Gx = GrB.random (n, 1, 0.5, 'range', range) ;
A = double (GA) ;
x = double (Gx) ;
fprintf ('C=A*x: sparse matrix times sparse vector:\n') ;
tm_total = 0 ;
tg_total = 0 ;
for trial = 1:ntrials
tic
C1 = A*x ;
tm = toc ;
tic
C2 = GA*Gx ;
tg = toc ;
err = norm (C1-C2,1) / norm (C1, 1) ;
fprintf ('trial %d: builtin: %10.4f GrB: %10.4f', trial, tm, tg);
fprintf (' speedup: %10.2f err: %g\n', tm / tg, err) ;
tm_total = tm_total + tm ;
tg_total = tg_total + tg ;
end
tm = tm_total / ntrials ;
tg = tg_total / ntrials ;
fprintf ('average: builtin: %10.4f GrB: %10.4f', tm, tg) ;
fprintf (' speedup: %10.2f\n', tm / tg) ;
Gx = GrB.random (n, 1, inf, 'range', range) ;
x = full (double (Gx)) ;
fprintf ('C=A*x: sparse matrix times dense vector:\n') ;
tm_total = 0 ;
tg_total = 0 ;
for trial = 1:ntrials
tic
C1 = A*x ;
tm = toc ;
tic
C2 = GA*Gx ;
tg = toc ;
err = norm (C1-C2,1) / norm (C1, 1) ;
fprintf ('trial %d: builtin: %10.4f GrB: %10.4f', trial, tm, tg);
fprintf (' speedup: %10.2f err: %g\n', tm / tg, err) ;
tm_total = tm_total + tm ;
tg_total = tg_total + tg ;
end
tm = tm_total / ntrials ;
tg = tg_total / ntrials ;
fprintf ('average: builtin: %10.4f GrB: %10.4f', tm, tg) ;
fprintf (' speedup: %10.2f\n', tm / tg) ;
end
end
% restore # of threads to their defaults
ncores = demo_nproc ;
GrB.clear ;
|