checking spmv also

This commit is contained in:
antonl 2026-03-15 12:16:22 +01:00
parent cb3887de0f
commit 8b24f2dcfd

View File

@ -13,10 +13,7 @@ import (
"gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/mat"
) )
var ( var gNumTestIterations = 30
gNumMatmuls = 10
gNumSolves = 10
)
type SparseMatrixTiming struct { type SparseMatrixTiming struct {
Label string `json:"label"` Label string `json:"label"`
@ -28,9 +25,9 @@ type SparseMatrixTiming struct {
MatMulTotalNs int64 `json:"matmul_total_ns"` MatMulTotalNs int64 `json:"matmul_total_ns"`
MatMulAvgNs int64 `json:"matmul_avg_ns"` MatMulAvgNs int64 `json:"matmul_avg_ns"`
SolveRuns int `json:"solve_runs"` SpMVRuns int `json:"spmv_runs"`
SolveTotalNs int64 `json:"solve_total_ns"` SpMVTotalNs int64 `json:"spmv_total_ns"`
SolveAvgNs int64 `json:"solve_avg_ns"` SpMVAvgNs int64 `json:"spmv_avg_ns"`
} }
type SparseBenchmarkCase struct { type SparseBenchmarkCase struct {
@ -131,7 +128,7 @@ func timeSparseMatmuls(bcase *SparseBenchmarkCase) {
// The CSR x CSR matrix multiplication is supposed to have a specific optimised // The CSR x CSR matrix multiplication is supposed to have a specific optimised
// path for matmuls // path for matmuls
var out sparse.CSR var out sparse.CSR
numberOfMults := gNumMatmuls numberOfMults := gNumTestIterations
fmt.Printf("NNZ before matmuls: %d\n", mCSR.NNZ()) fmt.Printf("NNZ before matmuls: %d\n", mCSR.NNZ())
@ -154,38 +151,41 @@ func timeSparseMatmuls(bcase *SparseBenchmarkCase) {
bcase.Timing.MatMulAvgNs = timeAvgNS bcase.Timing.MatMulAvgNs = timeAvgNS
} }
func timeSparseSolve(bcase *SparseBenchmarkCase) { func timeSparseMatVec(bcase *SparseBenchmarkCase) {
matrix := bcase.Matrix A := bcase.Matrix
rows, _ := matrix.Dims() rows, cols := A.Dims()
rhsData := make([]float64, rows) // We have checked square matrix already
for i := range rhsData {
rhsData[i] = 1.0
}
b := mat.NewVecDense(rows, rhsData)
x := mat.NewVecDense(rows, nil)
var chol sparse.Cholesky x := mat.NewVecDense(cols, nil)
y := mat.NewVecDense(rows, nil)
for i := 0; i < cols; i++ {
x.SetVec(i, 1.0)
}
// warmup // warmup
err := chol.SolveVecTo(x, b) A.MulVecTo(y.RawVector().Data, false, x.RawVector().Data)
if err != nil { norm := y.Norm(2)
panic(err)
if norm < 1e-12 {
panic("Norm of resulting SpMV is zero. Something went wrong.\n")
} }
numberOfSolves := gNumSolves numberOfRuns := gNumTestIterations
for i := 0; i < 3; i += 1 {
timeBegin := time.Now() timeBegin := time.Now()
chol.Factorize(matrix)
err = chol.SolveVecTo(x, b) for i := 0; i < numberOfRuns; i++ {
if err != nil { // fmt.Printf("spmv iteration %d\n", i)
panic(err) A.MulVecTo(y.RawVector().Data, false, x.RawVector().Data)
}
timeElapsed := time.Since(timeBegin)
} }
bcase.Timing.SolveRuns = numberOfSolves timeElapsed := time.Since(timeBegin)
bcase.Timing.SolveTotalNs = timeElapsed.Nanoseconds()
bcase.Timing.SolveAvgNs = timeElapsed.Nanoseconds() / int64(numberOfSolves) total := timeElapsed.Nanoseconds()
avg := total / int64(numberOfRuns)
bcase.Timing.SpMVTotalNs = total
bcase.Timing.SpMVAvgNs = avg
bcase.Timing.SpMVRuns = numberOfRuns
} }
func timeNanoToMS(timeNS int64) float64 { func timeNanoToMS(timeNS int64) float64 {
@ -201,16 +201,22 @@ func doTimings(path string) {
panic("Sparse benchmark assumes square matrix") panic("Sparse benchmark assumes square matrix")
} }
doMatMul := true
if doMatMul {
fmt.Printf("Timing sparse matrix %s with size: %d x %d \n", bcase.Timing.Label, rows, cols) fmt.Printf("Timing sparse matrix %s with size: %d x %d \n", bcase.Timing.Label, rows, cols)
fmt.Printf("Matmul:\n") fmt.Printf("Matmul:\n")
timeSparseMatmuls(&bcase) timeSparseMatmuls(&bcase)
avgMatMulTimeMS := timeNanoToMS(bcase.Timing.MatMulAvgNs) avgMatMulTimeMS := timeNanoToMS(bcase.Timing.MatMulAvgNs)
fmt.Printf("Avg matmul time for %s: %.4f ms \n", bcase.Timing.Label, avgMatMulTimeMS) fmt.Printf("Avg matmul time for %s: %.4f ms \n", bcase.Timing.Label, avgMatMulTimeMS)
}
fmt.Printf("Cholesky solve:\n") doSpMV := true
timeSparseSolve(&bcase) if doSpMV {
avgSolveTimeMS := timeNanoToMS(bcase.Timing.SolveAvgNs) fmt.Printf("SpMV:\n")
fmt.Printf("Avg Cholesky solve time for %s: %.4f ms \n", bcase.Timing.Label, avgSolveTimeMS) timeSparseMatVec(&bcase)
avgSpMVTimeMS := timeNanoToMS(bcase.Timing.SpMVAvgNs)
fmt.Printf("Avg SpMV time for %s: %.4f ms\n", bcase.Timing.Label, avgSpMVTimeMS)
}
} }
func main() { func main() {