Compare commits
2 Commits
cb3887de0f
...
e7e9a7389c
| Author | SHA1 | Date | |
|---|---|---|---|
| e7e9a7389c | |||
| 8b24f2dcfd |
54
goSparseResults.json
Normal file
54
goSparseResults.json
Normal file
@ -0,0 +1,54 @@
|
||||
[
|
||||
{
|
||||
"label": "FEM_3D_thermal2",
|
||||
"rows": 147900,
|
||||
"cols": 147900,
|
||||
"nnz": 3489300,
|
||||
"matmul_runs": 16,
|
||||
"matmul_total_ns": 1413419300,
|
||||
"matmul_avg_ns": 88338706,
|
||||
"matmul_output_nnz": 14335500,
|
||||
"spmv_runs": 16,
|
||||
"spmv_total_ns": 21010700,
|
||||
"spmv_avg_ns": 1313168
|
||||
},
|
||||
{
|
||||
"label": "ldoor",
|
||||
"rows": 952203,
|
||||
"cols": 952203,
|
||||
"nnz": 23737339,
|
||||
"matmul_runs": 16,
|
||||
"matmul_total_ns": 6835373200,
|
||||
"matmul_avg_ns": 427210825,
|
||||
"matmul_output_nnz": 43783061,
|
||||
"spmv_runs": 16,
|
||||
"spmv_total_ns": 156246400,
|
||||
"spmv_avg_ns": 9765400
|
||||
},
|
||||
{
|
||||
"label": "Cube_Coup_dt0",
|
||||
"rows": 2164760,
|
||||
"cols": 2164760,
|
||||
"nnz": 64685452,
|
||||
"matmul_runs": 16,
|
||||
"matmul_total_ns": 32192429900,
|
||||
"matmul_avg_ns": 2012026868,
|
||||
"matmul_output_nnz": 234465452,
|
||||
"spmv_runs": 16,
|
||||
"spmv_total_ns": 392950200,
|
||||
"spmv_avg_ns": 24559387
|
||||
},
|
||||
{
|
||||
"label": "nlpkkt240",
|
||||
"rows": 27993600,
|
||||
"cols": 27993600,
|
||||
"nnz": 401232976,
|
||||
"matmul_runs": 16,
|
||||
"matmul_total_ns": 38319352500,
|
||||
"matmul_avg_ns": 2394959531,
|
||||
"matmul_output_nnz": 401232976,
|
||||
"spmv_runs": 16,
|
||||
"spmv_total_ns": 3164097400,
|
||||
"spmv_avg_ns": 197756087
|
||||
}
|
||||
]
|
||||
23
src/main.c
Normal file
23
src/main.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef int32_t S32;
|
||||
typedef uint32_t U32;
|
||||
typedef float F32;
|
||||
typedef double F64;
|
||||
typedef int32_t B32;
|
||||
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
|
||||
|
||||
printf(" ******* \n HELLO WARRUDU \n ****);
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
116
src/main.go
116
src/main.go
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -13,10 +14,7 @@ import (
|
||||
"gonum.org/v1/gonum/mat"
|
||||
)
|
||||
|
||||
var (
|
||||
gNumMatmuls = 10
|
||||
gNumSolves = 10
|
||||
)
|
||||
var gNumTestIterations = 16
|
||||
|
||||
type SparseMatrixTiming struct {
|
||||
Label string `json:"label"`
|
||||
@ -27,10 +25,11 @@ type SparseMatrixTiming struct {
|
||||
MatMulRuns int `json:"matmul_runs"`
|
||||
MatMulTotalNs int64 `json:"matmul_total_ns"`
|
||||
MatMulAvgNs int64 `json:"matmul_avg_ns"`
|
||||
MatMulOutputNNZ int `json:"matmul_output_nnz"`
|
||||
|
||||
SolveRuns int `json:"solve_runs"`
|
||||
SolveTotalNs int64 `json:"solve_total_ns"`
|
||||
SolveAvgNs int64 `json:"solve_avg_ns"`
|
||||
SpMVRuns int `json:"spmv_runs"`
|
||||
SpMVTotalNs int64 `json:"spmv_total_ns"`
|
||||
SpMVAvgNs int64 `json:"spmv_avg_ns"`
|
||||
}
|
||||
|
||||
type SparseBenchmarkCase struct {
|
||||
@ -38,6 +37,21 @@ type SparseBenchmarkCase struct {
|
||||
Matrix *sparse.CSR
|
||||
}
|
||||
|
||||
func writeTimingJSON(all []SparseMatrixTiming, outPath string) {
|
||||
f, err := os.Create(outPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
enc := json.NewEncoder(f)
|
||||
enc.SetIndent("", " ")
|
||||
|
||||
if err := enc.Encode(all); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
func matrixLoadMarket(path string) *sparse.CSR {
|
||||
@ -131,7 +145,7 @@ func timeSparseMatmuls(bcase *SparseBenchmarkCase) {
|
||||
// The CSR x CSR matrix multiplication is supposed to have a specific optimised
|
||||
// path for matmuls
|
||||
var out sparse.CSR
|
||||
numberOfMults := gNumMatmuls
|
||||
numberOfMults := gNumTestIterations
|
||||
|
||||
fmt.Printf("NNZ before matmuls: %d\n", mCSR.NNZ())
|
||||
|
||||
@ -147,6 +161,7 @@ func timeSparseMatmuls(bcase *SparseBenchmarkCase) {
|
||||
panic("Sparsity pattern changed unexpectedly after matmul!")
|
||||
}
|
||||
|
||||
bcase.Timing.MatMulOutputNNZ = out.NNZ()
|
||||
bcase.Timing.MatMulRuns = numberOfMults
|
||||
bcase.Timing.MatMulTotalNs = timeElapsed.Nanoseconds()
|
||||
|
||||
@ -154,45 +169,48 @@ func timeSparseMatmuls(bcase *SparseBenchmarkCase) {
|
||||
bcase.Timing.MatMulAvgNs = timeAvgNS
|
||||
}
|
||||
|
||||
func timeSparseSolve(bcase *SparseBenchmarkCase) {
|
||||
matrix := bcase.Matrix
|
||||
rows, _ := matrix.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)
|
||||
func timeSparseMatVec(bcase *SparseBenchmarkCase) {
|
||||
A := bcase.Matrix
|
||||
rows, cols := A.Dims()
|
||||
|
||||
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
|
||||
err := chol.SolveVecTo(x, b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
A.MulVecTo(y.RawVector().Data, false, x.RawVector().Data)
|
||||
norm := y.Norm(2)
|
||||
|
||||
if norm < 1e-12 {
|
||||
panic("Norm of resulting SpMV is zero. Something went wrong.\n")
|
||||
}
|
||||
|
||||
numberOfSolves := gNumSolves
|
||||
for i := 0; i < 3; i += 1 {
|
||||
numberOfRuns := gNumTestIterations
|
||||
|
||||
timeBegin := time.Now()
|
||||
chol.Factorize(matrix)
|
||||
err = chol.SolveVecTo(x, b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
timeElapsed := time.Since(timeBegin)
|
||||
|
||||
for i := 0; i < numberOfRuns; i++ {
|
||||
// fmt.Printf("spmv iteration %d\n", i)
|
||||
A.MulVecTo(y.RawVector().Data, false, x.RawVector().Data)
|
||||
}
|
||||
|
||||
bcase.Timing.SolveRuns = numberOfSolves
|
||||
bcase.Timing.SolveTotalNs = timeElapsed.Nanoseconds()
|
||||
bcase.Timing.SolveAvgNs = timeElapsed.Nanoseconds() / int64(numberOfSolves)
|
||||
timeElapsed := time.Since(timeBegin)
|
||||
|
||||
total := timeElapsed.Nanoseconds()
|
||||
avg := total / int64(numberOfRuns)
|
||||
bcase.Timing.SpMVTotalNs = total
|
||||
bcase.Timing.SpMVAvgNs = avg
|
||||
bcase.Timing.SpMVRuns = numberOfRuns
|
||||
}
|
||||
|
||||
func timeNanoToMS(timeNS int64) float64 {
|
||||
return float64(timeNS) / float64(1e6)
|
||||
}
|
||||
|
||||
func doTimings(path string) {
|
||||
func doTimings(path string) SparseMatrixTiming {
|
||||
bcase := getSparseBenchmarkCase(path)
|
||||
rows := bcase.Timing.Rows
|
||||
cols := bcase.Timing.Cols
|
||||
@ -201,23 +219,43 @@ func doTimings(path string) {
|
||||
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("Matmul:\n")
|
||||
timeSparseMatmuls(&bcase)
|
||||
avgMatMulTimeMS := timeNanoToMS(bcase.Timing.MatMulAvgNs)
|
||||
fmt.Printf("Avg matmul time for %s: %.4f ms \n", bcase.Timing.Label, avgMatMulTimeMS)
|
||||
}
|
||||
|
||||
fmt.Printf("Cholesky solve:\n")
|
||||
timeSparseSolve(&bcase)
|
||||
avgSolveTimeMS := timeNanoToMS(bcase.Timing.SolveAvgNs)
|
||||
fmt.Printf("Avg Cholesky solve time for %s: %.4f ms \n", bcase.Timing.Label, avgSolveTimeMS)
|
||||
doSpMV := true
|
||||
if doSpMV {
|
||||
fmt.Printf("SpMV:\n")
|
||||
timeSparseMatVec(&bcase)
|
||||
avgSpMVTimeMS := timeNanoToMS(bcase.Timing.SpMVAvgNs)
|
||||
fmt.Printf("Avg SpMV time for %s: %.4f ms\n", bcase.Timing.Label, avgSpMVTimeMS)
|
||||
}
|
||||
|
||||
return bcase.Timing
|
||||
}
|
||||
|
||||
func main() {
|
||||
mainBegin := time.Now()
|
||||
|
||||
thermal2Path := "suitesparse_test_matrices/thermal2.mtx"
|
||||
doTimings(thermal2Path)
|
||||
paths := []string{
|
||||
"suitesparse_test_matrices/FEM_3D_thermal2.mtx",
|
||||
"suitesparse_test_matrices/ldoor.mtx",
|
||||
"suitesparse_test_matrices/Cube_Coup_dt0.mtx",
|
||||
"suitesparse_test_matrices/nlpkkt240.mtx",
|
||||
}
|
||||
|
||||
results := make([]SparseMatrixTiming, 0, len(paths))
|
||||
|
||||
for _, path := range paths {
|
||||
results = append(results, doTimings(path))
|
||||
}
|
||||
|
||||
writeTimingJSON(results, "goSparseResults.json")
|
||||
|
||||
mainElapsed := time.Since(mainBegin)
|
||||
|
||||
|
||||
@ -1,6 +1,15 @@
|
||||
# This is just a small matrix for debugging / validating code
|
||||
https://suitesparse-collection-website.herokuapp.com/MM/HB/1138_bus.tar.gz
|
||||
|
||||
# 3.5M NNZ 3d thermal problem
|
||||
https://suitesparse-collection-website.herokuapp.com/MM/Botonakis/FEM_3D_thermal2.tar.gz
|
||||
|
||||
# This is a real large (not really, but ok) sparse matrix with 8.5 million non-zero elements
|
||||
https://suitesparse-collection-website.herokuapp.com/MM/Schmid/thermal2.tar.gz
|
||||
# Almost 43M NNZ, structural problem
|
||||
https://suitesparse-collection-website.herokuapp.com/MM/GHS_psdef/ldoor.tar.gz
|
||||
|
||||
# Almost 125M non-zero elements from a structural problem, 420mb compressed, 1.1GB uncompressed .mtx
|
||||
https://suitesparse-collection-website.herokuapp.com/MM/Janna/Cube_Coup_dt0.tar.gz
|
||||
|
||||
# 760M NNZ, optimization problem 1.23GB compressed, 8.4 GB uncompressed
|
||||
# This was too large for my 32 GB memory and I went into swap... probably should exclude
|
||||
https://suitesparse-collection-website.herokuapp.com/MM/Schenk/nlpkkt240.tar.gz
|
||||
Loading…
Reference in New Issue
Block a user