some more work
This commit is contained in:
parent
5ee722a96b
commit
f81c97bb1e
122
src/main.go
122
src/main.go
@ -4,6 +4,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -11,9 +12,29 @@ import (
|
|||||||
"github.com/james-bowman/sparse"
|
"github.com/james-bowman/sparse"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type SparseMatrixTiming struct {
|
||||||
|
Label string `json:"label"`
|
||||||
|
Rows int `json:"rows"`
|
||||||
|
Cols int `json:"cols"`
|
||||||
|
NNZ int `json:"nnz"`
|
||||||
|
|
||||||
|
MatMulRuns int `json:"matmul_runs"`
|
||||||
|
MatMulTotalNs int64 `json:"matmul_total_ns"`
|
||||||
|
MatMulAvgNs int64 `json:"matmul_avg_ns"`
|
||||||
|
|
||||||
|
SolveRuns int `json:"solve_runs"`
|
||||||
|
SolveTotalNs int64 `json:"solve_total_ns"`
|
||||||
|
SolveAvgNs int64 `json:"solve_avg_ns"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SparseBenchmarkCase struct {
|
||||||
|
Timing SparseMatrixTiming
|
||||||
|
Matrix *sparse.CSR
|
||||||
|
}
|
||||||
|
|
||||||
// The "SuiteSparse" collection of matrices come in a format called
|
// The "SuiteSparse" collection of matrices come in a format called
|
||||||
// "market matrix" and so we parse and load them to a sparse.COO format here.
|
// "market matrix" and so we parse and load them to a sparse.COO format here.
|
||||||
func matrix_load_market(path string) *sparse.COO {
|
func matrixLoadMarket(path string) *sparse.CSR {
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -60,47 +81,100 @@ func matrix_load_market(path string) *sparse.COO {
|
|||||||
|
|
||||||
coo := sparse.NewCOO(rows, cols, r, c, v)
|
coo := sparse.NewCOO(rows, cols, r, c, v)
|
||||||
|
|
||||||
return coo
|
return coo.ToCSR()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
// small helper just to strip path and file ending
|
||||||
// small_test_matrix_path := "suitesparse_test_matrices/1138_bus.mtx"
|
func matrixGetLabel(path string) string {
|
||||||
big_8mill_nnz_matrix_path := "suitesparse_test_matrices/thermal2.mtx"
|
base := filepath.Base(path) // f. ex "1138_bus.mtx"
|
||||||
m := matrix_load_market(big_8mill_nnz_matrix_path)
|
ext := filepath.Ext(base) // ".mtx"
|
||||||
rows, cols := m.Dims()
|
out := strings.TrimSuffix(base, ext) // just "1138_bus"
|
||||||
fmt.Printf("matrix size: %d x %d \n", rows, cols)
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSparseBenchmarkCase(path string) SparseBenchmarkCase {
|
||||||
|
var out SparseBenchmarkCase
|
||||||
|
|
||||||
|
loadMarketStart := time.Now()
|
||||||
|
label := matrixGetLabel(path)
|
||||||
|
m := matrixLoadMarket(path)
|
||||||
|
loadMarketEnd := time.Since(loadMarketStart)
|
||||||
|
loadedMarketMillisecs := float64(loadMarketEnd.Milliseconds())
|
||||||
|
fmt.Printf("Loaded market matrix %s in %.4f ms \n", label, loadedMarketMillisecs)
|
||||||
|
|
||||||
|
out.Matrix = m
|
||||||
|
out.Timing.Label = label
|
||||||
|
|
||||||
|
rows, cols := out.Matrix.Dims()
|
||||||
|
nnz := m.NNZ()
|
||||||
|
|
||||||
|
out.Timing.Rows = rows
|
||||||
|
out.Timing.Cols = cols
|
||||||
|
out.Timing.NNZ = nnz
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func timeSparseMatmuls(bcase *SparseBenchmarkCase) {
|
||||||
|
rows := bcase.Timing.Rows
|
||||||
|
cols := bcase.Timing.Cols
|
||||||
|
|
||||||
if rows != cols {
|
if rows != cols {
|
||||||
panic("sparse matmul benchmark assumes square matrix")
|
panic("sparse matmul benchmark assumes square matrix")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to Compressed-Sparse-Row-storage
|
fmt.Printf("Timing sparse matrix %s with size: %d x %d \n", bcase.Timing.Label, rows, cols)
|
||||||
m_csr := m.ToCSR()
|
|
||||||
// Warm up caches to not include "first call" effects
|
mCSR := bcase.Matrix
|
||||||
var warm sparse.CSR
|
var warm sparse.CSR
|
||||||
for i := 0; i < 3; i += 1 {
|
for i := 0; i < 3; i += 1 {
|
||||||
warm.Mul(m_csr, m_csr)
|
warm.Mul(mCSR, mCSR)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
number_of_mults := 100
|
numberOfMults := 100
|
||||||
|
|
||||||
time_begin := time.Now()
|
fmt.Printf("NNZ before matmuls: %d\n", mCSR.NNZ())
|
||||||
for i := 0; i < number_of_mults; i += 1 {
|
|
||||||
out.Mul(m_csr, m_csr)
|
timeBegin := time.Now()
|
||||||
|
for i := 0; i < numberOfMults; i += 1 {
|
||||||
|
out.Mul(mCSR, mCSR)
|
||||||
|
}
|
||||||
|
timeElapsed := time.Since(timeBegin)
|
||||||
|
|
||||||
|
fmt.Printf("NNZ after matmuls: %d\n", out.NNZ())
|
||||||
|
|
||||||
|
if warm.NNZ() != out.NNZ() {
|
||||||
|
panic("Sparsity pattern changed unexpectedly after matmul!")
|
||||||
}
|
}
|
||||||
|
|
||||||
elapsed := time.Since(time_begin)
|
bcase.Timing.MatMulRuns = numberOfMults
|
||||||
elapsed_ms := elapsed.Milliseconds()
|
bcase.Timing.MatMulTotalNs = timeElapsed.Nanoseconds()
|
||||||
|
|
||||||
time_per_matmul := float32(elapsed_ms) / float32(number_of_mults)
|
timeAvgNS := timeElapsed.Nanoseconds() / int64(numberOfMults)
|
||||||
|
bcase.Timing.MatMulAvgNs = timeAvgNS
|
||||||
out_rows, out_cols := out.Dims()
|
|
||||||
if out_rows != rows || out_cols != cols {
|
|
||||||
panic("Output matrix dimensions not same as input. We are supposed to matmul square matrices")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Elapsed time per mat mul: %.4f ms\n", time_per_matmul)
|
func timeNanoToMS(timeNS int64) float64 {
|
||||||
|
return float64(timeNS) / float64(1e6)
|
||||||
|
}
|
||||||
|
|
||||||
|
func doTimings(path string) {
|
||||||
|
bcase := getSparseBenchmarkCase(path)
|
||||||
|
timeSparseMatmuls(&bcase)
|
||||||
|
avgMatMulTimeMS := timeNanoToMS(bcase.Timing.MatMulAvgNs)
|
||||||
|
fmt.Printf("Avg matmul time for %s: %.4f ms \n", bcase.Timing.Label, avgMatMulTimeMS)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mainBegin := time.Now()
|
||||||
|
|
||||||
|
thermal2Path := "suitesparse_test_matrices/thermal2.mtx"
|
||||||
|
doTimings(thermal2Path)
|
||||||
|
|
||||||
|
mainElapsed := time.Since(mainBegin)
|
||||||
|
|
||||||
|
fmt.Printf("Program finished in %.4f seconds \n", float64(mainElapsed.Milliseconds())/1e3)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user