Matrix multiplication in SaC
Set-notation
double[.,.] matMult(double[.,.] X, double[.,.] Y)
{
res = { [i, j] -> sum(X[[i,.]] * Y[[.,j]]) };
return(res);
}
Set-notation with transposing
double[.,.] matMult(double[.,.] X, double[.,.] Y)
{
res = { [i,j] -> sum(X[[i,.]] * transpose(Y)[[j,.]]) };
return(res);
}
With-loop
double[.,.] matMult(double[.,.] X, double[.,.] Y)
{
res = with {
(. <= [i,j] <= .): with {
([0] <= [k] < [shape(X)[[1]]]): X[[i, k]] * Y[[k, j]];
}: fold(+, 0.0);
}: genarray([shape(X)[[0]], shape(Y)[[1]]], 0.0);
return(res);
}
With-loop with transposing
double[.,.] matMult(double[.,.] X, double[.,.] Y)
{
y = with {
(. <= [i, j] <= .): Y[[j, i]];
}: genarray(shape(Y), 0.0);
res = with {
(. <= [i,j] <= .): with {
([0] <= [k] < [shape(X)[[1]]]): X[[i, k]] * y[[j, k]];
}: fold(+, 0.0);
}: genarray([shape(X)[[0]], shape(Y)[[1]]], 0.0);
return(res);
}
Run-time results
Time for 1000×1000 matrices
Time for 2000×2000 matrices
Time for 4000×4000 matrices
Time for 8000×8000 matrices
Run-time results with explicit specialization
specialize double[1000,1000] matMult(double[1000,1000] X, double[1000,1000] Y);
specialize double[2000,2000] matMult(double[2000,2000] X, double[2000,2000] Y);
specialize double[4000,4000] matMult(double[4000,4000] X, double[4000,4000] Y);
specialize double[8000,8000] matMult(double[8000,8000] X, double[8000,8000] Y);
Time for 1000×1000 matrices
Time for 2000×2000 matrices
Time for 4000×4000 matrices
Time for 8000×8000 matrices
Measurements with PAPI timer
Time for 100×100 matrices
Time for 500×500 matrices
Time for 1000×1000 matrices