first whole bench
This commit is contained in:
parent
d7c10045ba
commit
a30a500564
@ -1,6 +1,6 @@
|
||||
[
|
||||
{"label":"FEM_3D_thermal2","rows":147900,"cols":147900,"nnz":3489300,"spmv_runs":32,"spmv_total_ns":3866100,"spmv_avg_ns":120815,"dense_rows":2048,"dense_cols":2048,"dense_runs":32,"dense_total_ns":957945100,"dense_avg_ns":29935784},
|
||||
{"label":"ldoor","rows":952203,"cols":952203,"nnz":46522475,"spmv_runs":32,"spmv_total_ns":286909100,"spmv_avg_ns":8965909,"dense_rows":4096,"dense_cols":4096,"dense_runs":32,"dense_total_ns":7653100100,"dense_avg_ns":239159378},
|
||||
{"label":"Cube_Coup_dt0","rows":2164760,"cols":2164760,"nnz":127206144,"spmv_runs":32,"spmv_total_ns":864947600,"spmv_avg_ns":27029612,"dense_rows":8192,"dense_cols":8192,"dense_runs":32,"dense_total_ns":59799139700,"dense_avg_ns":1868723115},
|
||||
{"label":"nlpkkt200","rows":16240000,"cols":16240000,"nnz":448225632,"spmv_runs":32,"spmv_total_ns":2383754600,"spmv_avg_ns":74492331,"dense_rows":16384,"dense_cols":16384,"dense_runs":32,"dense_total_ns":471942950199,"dense_avg_ns":14748217193}
|
||||
{"label":"FEM_3D_thermal2","rows":147900,"cols":147900,"nnz":3489300,"spmv_runs":32,"spmv_total_ns":9411500,"spmv_avg_ns":294109,"dense_rows":1024,"dense_cols":1024,"dense_runs":32,"dense_total_ns":129353000,"dense_avg_ns":4042281},
|
||||
{"label":"ldoor","rows":952203,"cols":952203,"nnz":46522475,"spmv_runs":32,"spmv_total_ns":284244500,"spmv_avg_ns":8882640,"dense_rows":2048,"dense_cols":2048,"dense_runs":32,"dense_total_ns":1979492200,"dense_avg_ns":61859131},
|
||||
{"label":"Cube_Coup_dt0","rows":2164760,"cols":2164760,"nnz":127206144,"spmv_runs":32,"spmv_total_ns":894006900,"spmv_avg_ns":27937715,"dense_rows":4096,"dense_cols":4096,"dense_runs":32,"dense_total_ns":8725314200,"dense_avg_ns":272666068},
|
||||
{"label":"nlpkkt200","rows":16240000,"cols":16240000,"nnz":448225632,"spmv_runs":32,"spmv_total_ns":2437591700,"spmv_avg_ns":76174740,"dense_rows":8192,"dense_cols":8192,"dense_runs":32,"dense_total_ns":63669801300,"dense_avg_ns":1989681290}
|
||||
]
|
||||
|
||||
58
goSparseResults.json
Normal file
58
goSparseResults.json
Normal file
@ -0,0 +1,58 @@
|
||||
[
|
||||
{
|
||||
"label": "FEM_3D_thermal2",
|
||||
"rows": 147900,
|
||||
"cols": 147900,
|
||||
"nnz": 3489300,
|
||||
"dense_rows": 1024,
|
||||
"dense_cols": 1024,
|
||||
"dense_runs": 32,
|
||||
"dense_total_ns": 678975700,
|
||||
"dense_avg_ns": 21217990,
|
||||
"spmv_runs": 32,
|
||||
"spmv_total_ns": 44127200,
|
||||
"spmv_avg_ns": 1378975
|
||||
},
|
||||
{
|
||||
"label": "ldoor",
|
||||
"rows": 952203,
|
||||
"cols": 952203,
|
||||
"nnz": 46522475,
|
||||
"dense_rows": 2048,
|
||||
"dense_cols": 2048,
|
||||
"dense_runs": 32,
|
||||
"dense_total_ns": 5421343500,
|
||||
"dense_avg_ns": 169416984,
|
||||
"spmv_runs": 32,
|
||||
"spmv_total_ns": 515245900,
|
||||
"spmv_avg_ns": 16101434
|
||||
},
|
||||
{
|
||||
"label": "Cube_Coup_dt0",
|
||||
"rows": 2164760,
|
||||
"cols": 2164760,
|
||||
"nnz": 127206144,
|
||||
"dense_rows": 4096,
|
||||
"dense_cols": 4096,
|
||||
"dense_runs": 32,
|
||||
"dense_total_ns": 43612138700,
|
||||
"dense_avg_ns": 1362879334,
|
||||
"spmv_runs": 32,
|
||||
"spmv_total_ns": 1300820500,
|
||||
"spmv_avg_ns": 40650640
|
||||
},
|
||||
{
|
||||
"label": "nlpkkt200",
|
||||
"rows": 16240000,
|
||||
"cols": 16240000,
|
||||
"nnz": 448225632,
|
||||
"dense_rows": 8192,
|
||||
"dense_cols": 8192,
|
||||
"dense_runs": 32,
|
||||
"dense_total_ns": 350072230900,
|
||||
"dense_avg_ns": 10939757215,
|
||||
"spmv_runs": 32,
|
||||
"spmv_total_ns": 6186462100,
|
||||
"spmv_avg_ns": 193326940
|
||||
}
|
||||
]
|
||||
111
plot.py
Normal file
111
plot.py
Normal file
@ -0,0 +1,111 @@
|
||||
import json
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
#font sizes
|
||||
plt.rcParams.update({
|
||||
"font.size": 18,
|
||||
"axes.titlesize": 22,
|
||||
"axes.labelsize": 20,
|
||||
"xtick.labelsize": 16,
|
||||
"ytick.labelsize": 16,
|
||||
"legend.fontsize": 16,
|
||||
})
|
||||
|
||||
def getResults(filename):
|
||||
|
||||
with open(filename) as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Prepare lists
|
||||
spmv_sizes = []
|
||||
spmv_times = []
|
||||
|
||||
dense_sizes = []
|
||||
dense_times = []
|
||||
|
||||
labels = []
|
||||
|
||||
for d in data:
|
||||
spmv_sizes.append(d["nnz"])
|
||||
spmv_times.append(d["spmv_avg_ns"])
|
||||
|
||||
dense_sizes.append(d["dense_rows"])
|
||||
dense_times.append(d["dense_avg_ns"])
|
||||
|
||||
labels.append(d["label"])
|
||||
|
||||
return spmv_sizes, spmv_times, dense_sizes, dense_times, labels
|
||||
|
||||
|
||||
c_spmv_sizes, c_spmv_times, c_dense_sizes, c_dense_times, c_labels = getResults("cSparseResults.json")
|
||||
go_spmv_sizes, go_spmv_times, go_dense_sizes, go_dense_times, go_labels = getResults("goSparseResults.json")
|
||||
|
||||
# make sure data aligns on x axis
|
||||
for i in range(len(go_spmv_sizes)):
|
||||
assert(c_spmv_sizes[i] == go_spmv_sizes[i])
|
||||
assert(go_dense_sizes[i] == c_dense_sizes[i])
|
||||
|
||||
|
||||
|
||||
#spmv plot
|
||||
x_spmv = c_spmv_sizes
|
||||
x_spmv = np.float64(x_spmv)/1e6
|
||||
go_spmv_float = np.float64(go_spmv_times)
|
||||
c_spmv_float = np.float64(c_spmv_times)
|
||||
ratio_spmv = go_spmv_float/c_spmv_float
|
||||
plt.figure("spmv")
|
||||
plt.plot(x_spmv, ratio_spmv, 'kd-')
|
||||
plt.title("Sparse Matrix-Vector multiplication ratio Go native / C MKL")
|
||||
plt.xlabel("SuiteSparse matrix millions of number of non-zeros")
|
||||
plt.ylabel("Average time ratio Go/C for SpMV-kernel")
|
||||
xtick_string = [f"{x:.1f}\n{label}" for x, label in zip(x_spmv, c_labels)]
|
||||
plt.xticks(x_spmv, xtick_string)
|
||||
plt.grid()
|
||||
|
||||
# dense plot
|
||||
x_dense = c_dense_sizes
|
||||
go_dense_float = np.float64(go_dense_times)
|
||||
c_dense_float = np.float64(c_dense_times)
|
||||
ratio_dense = go_dense_float/c_dense_float
|
||||
|
||||
plt.figure("dense")
|
||||
plt.plot(x_dense, ratio_dense, 'kd-')
|
||||
plt.title("Dense Matrix-Matrix multiplication ratio Go native / C MKL")
|
||||
plt.xlabel("Dense matrix size")
|
||||
plt.ylabel("Average time ratio Go/C for matmul kernel")
|
||||
xtick_string = [f"{x}^2" for x in x_dense]
|
||||
plt.xticks(x_dense, xtick_string)
|
||||
plt.grid()
|
||||
|
||||
plt.show()
|
||||
|
||||
## ---- SpMV Plot ----
|
||||
#plt.figure()
|
||||
#plt.plot(spmv_sizes, spmv_times, marker='o')
|
||||
#
|
||||
#for i, label in enumerate(labels):
|
||||
# plt.annotate(label, (spmv_sizes[i], spmv_times[i]))
|
||||
#
|
||||
#plt.xlabel("Number of Nonzeros (nnz)")
|
||||
#plt.ylabel("Average Time (ns)")
|
||||
#plt.title("SpMV: Avg Time vs Size")
|
||||
#plt.xscale("log")
|
||||
#plt.yscale("log")
|
||||
#plt.grid(True)
|
||||
#
|
||||
## ---- Dense Plot ----
|
||||
#plt.figure()
|
||||
#plt.plot(dense_sizes, dense_times, marker='o')
|
||||
#
|
||||
#for i, label in enumerate(labels):
|
||||
# plt.annotate(label, (dense_sizes[i], dense_times[i]))
|
||||
#
|
||||
#plt.xlabel("Matrix Size (rows × cols)")
|
||||
#plt.ylabel("Average Time (ns)")
|
||||
#plt.title("Dense: Avg Time vs Size")
|
||||
#plt.xscale("log")
|
||||
#plt.yscale("log")
|
||||
#plt.grid(True)
|
||||
#
|
||||
#plt.show()
|
||||
@ -629,7 +629,7 @@ Timing doSpMVTimings(const char *path) {
|
||||
int main() {
|
||||
|
||||
S32 numPaths = 4;
|
||||
int denseRows[] = {2048, 4096, 4096*2, 4096*4};
|
||||
int denseRows[] = {1024, 2048, 4096, 4096*2};
|
||||
|
||||
const char *paths[] = {
|
||||
"E:\\dev\\go_matmul_perf\\suitesparse_test_matrices\\FEM_3D_thermal2.mtx",
|
||||
|
||||
147
src/main.go
147
src/main.go
@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/james-bowman/sparse"
|
||||
"gonum.org/v1/gonum/blas/blas64"
|
||||
"gonum.org/v1/gonum/mat"
|
||||
)
|
||||
|
||||
@ -57,8 +58,6 @@ func writeTimingJSON(all []Timing, outPath string) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
@ -68,44 +67,142 @@ func matrixLoadMarket(path string) *sparse.CSR {
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
|
||||
// skip header
|
||||
scanner.Scan()
|
||||
// Read header
|
||||
if !scanner.Scan() {
|
||||
panic("failed to read Matrix Market header")
|
||||
}
|
||||
header := strings.Fields(scanner.Text())
|
||||
if len(header) < 5 {
|
||||
panic("invalid Matrix Market header")
|
||||
}
|
||||
|
||||
// skip comments
|
||||
field := header[3]
|
||||
symmetry := header[4]
|
||||
|
||||
isPattern := field == "pattern"
|
||||
isInteger := field == "integer"
|
||||
isReal := field == "real"
|
||||
isSymmetric := symmetry == "symmetric"
|
||||
|
||||
if !isPattern && !isInteger && !isReal {
|
||||
panic("unsupported Matrix Market field type")
|
||||
}
|
||||
if symmetry != "general" && symmetry != "symmetric" {
|
||||
panic("unsupported Matrix Market symmetry")
|
||||
}
|
||||
|
||||
// Skip comments, then read size line
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if !strings.HasPrefix(line, "%") {
|
||||
if !strings.HasPrefix(strings.TrimSpace(line), "%") {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
fields := strings.Fields(scanner.Text())
|
||||
if len(fields) != 3 {
|
||||
panic("invalid Matrix Market size line")
|
||||
}
|
||||
|
||||
rows, _ := strconv.Atoi(fields[0])
|
||||
cols, _ := strconv.Atoi(fields[1])
|
||||
nnz, _ := strconv.Atoi(fields[2])
|
||||
rows, err := strconv.Atoi(fields[0])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cols, err := strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
nnzInFile, err := strconv.Atoi(fields[2])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
r := make([]int, nnz)
|
||||
c := make([]int, nnz)
|
||||
v := make([]float64, nnz)
|
||||
capacity := nnzInFile
|
||||
if isSymmetric {
|
||||
capacity = 2 * nnzInFile
|
||||
}
|
||||
|
||||
i := 0
|
||||
r := make([]int, 0, capacity)
|
||||
c := make([]int, 0, capacity)
|
||||
v := make([]float64, 0, capacity)
|
||||
|
||||
for scanner.Scan() {
|
||||
f := strings.Fields(scanner.Text())
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if line == "" || strings.HasPrefix(line, "%") {
|
||||
continue
|
||||
}
|
||||
|
||||
ri, _ := strconv.Atoi(f[0])
|
||||
ci, _ := strconv.Atoi(f[1])
|
||||
val, _ := strconv.ParseFloat(f[2], 64)
|
||||
flds := strings.Fields(line)
|
||||
|
||||
r[i] = ri - 1
|
||||
c[i] = ci - 1
|
||||
v[i] = val
|
||||
i++
|
||||
var ri, ci int
|
||||
var val float64 = 1.0
|
||||
|
||||
if isPattern {
|
||||
if len(flds) != 2 {
|
||||
panic("bad pattern entry")
|
||||
}
|
||||
ri, err = strconv.Atoi(flds[0])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ci, err = strconv.Atoi(flds[1])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else if isInteger {
|
||||
if len(flds) != 3 {
|
||||
panic("bad integer entry")
|
||||
}
|
||||
ri, err = strconv.Atoi(flds[0])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ci, err = strconv.Atoi(flds[1])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ival, err := strconv.Atoi(flds[2])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
val = float64(ival)
|
||||
} else {
|
||||
if len(flds) != 3 {
|
||||
panic("bad real entry")
|
||||
}
|
||||
ri, err = strconv.Atoi(flds[0])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ci, err = strconv.Atoi(flds[1])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
val, err = strconv.ParseFloat(flds[2], 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
ri--
|
||||
ci--
|
||||
|
||||
r = append(r, ri)
|
||||
c = append(c, ci)
|
||||
v = append(v, val)
|
||||
|
||||
if isSymmetric && ri != ci {
|
||||
r = append(r, ci)
|
||||
c = append(c, ri)
|
||||
v = append(v, val)
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
coo := sparse.NewCOO(rows, cols, r, c, v)
|
||||
|
||||
return coo.ToCSR()
|
||||
}
|
||||
|
||||
@ -255,6 +352,10 @@ func doTimings(path string, denseRows int) Timing {
|
||||
func main() {
|
||||
mainBegin := time.Now()
|
||||
|
||||
fmt.Printf("BLAS backend: %T\n", blas64.Implementation())
|
||||
fmt.Printf("GOMAXPROCS: %d\n", runtime.GOMAXPROCS(0))
|
||||
fmt.Printf("NumCPU: %d\n", runtime.NumCPU())
|
||||
|
||||
paths := []string{
|
||||
"suitesparse_test_matrices/FEM_3D_thermal2.mtx",
|
||||
"suitesparse_test_matrices/ldoor.mtx",
|
||||
@ -263,7 +364,7 @@ func main() {
|
||||
}
|
||||
|
||||
denseRows := []int{
|
||||
2048, 4096, 4096 * 2, 4096 * 4,
|
||||
1024, 2048, 4096, 4096 * 2,
|
||||
}
|
||||
|
||||
numPaths := len(paths)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user