Skip to content

Commit b71d2cf

Browse files
Create GitHub workflow to run benchmark suite (#51)
Co-authored-by: Dilum Aluthge <[email protected]> Co-authored-by: Mosè Giordano <[email protected]>
1 parent af3d18f commit b71d2cf

File tree

3 files changed

+213
-57
lines changed

3 files changed

+213
-57
lines changed

.github/workflows/benchmarks.yml

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: Benchmarks
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- master
8+
tags: '*'
9+
workflow_dispatch:
10+
11+
concurrency:
12+
# Skip intermediate builds: all builds except for builds on the `master` or `release-*` branches
13+
# Cancel intermediate builds: only pull request builds
14+
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
15+
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
16+
17+
permissions:
18+
contents: read
19+
20+
jobs:
21+
test:
22+
runs-on: ${{ matrix.os }}
23+
defaults:
24+
run:
25+
shell: bash
26+
strategy:
27+
matrix:
28+
os: [ubuntu-latest]
29+
java-version: ['17']
30+
julia-version: ['1.7.1']
31+
python-version: ['3.9']
32+
numpy-version: ['1.22']
33+
gfortran-version: ['9'] # Note: unused since is built-in.
34+
rust-version: ['1.42.0'] # Note: unused since controlled by `rust/rust-toolchain`
35+
js-version: ['16']
36+
r-version: ['4.1.2']
37+
lua-version: ['2.0.5'] # Note: Not used as benchmark is broken.
38+
go-version: ['1.17.4'] # Note: Not used as benchmark is broken.
39+
40+
steps:
41+
- uses: actions/checkout@v3
42+
with:
43+
persist-credentials: false
44+
- name: "Cache Julia"
45+
id: cache-julia
46+
uses: actions/cache@v2
47+
with:
48+
path: ~/julia
49+
key: ${{ runner.os }}-v${{ matrix.julia-version }}
50+
- name: "Build Julia"
51+
if: steps.cache-julia.outputs.cache-hit != 'true'
52+
uses: julia-actions/build-julia@v1
53+
with:
54+
ref: v${{ matrix.julia-version }}
55+
- name: "Install Julia packages"
56+
run: |
57+
julia -e 'using Pkg; Pkg.add("Compat")'
58+
- name: "Set up dSFMT"
59+
run: |
60+
cd ~/
61+
mkdir -p dSFMT
62+
cd dSFMT
63+
wget https://github.com/MersenneTwister-Lab/dSFMT/archive/refs/tags/v2.2.4.tar.gz
64+
echo "39682961ecfba621a98dbb6610b6ae2b7d6add450d4f08d8d4edd0e10abd8174 v2.2.4.tar.gz" | sha256sum --check --status
65+
tar -xzf v2.2.4.tar.gz
66+
mv dSFMT-*/* ./
67+
- name: "Set up OpenBLAS"
68+
run: |
69+
sudo apt-get install -y libopenblas-dev
70+
- name: "Set up Python"
71+
uses: actions/setup-python@v1
72+
with:
73+
python-version: ${{ matrix.python-version }}
74+
- name: "Set up NumPy"
75+
run: pip install numpy==${{ matrix.numpy-version }}
76+
- name: "Set up Rust"
77+
uses: actions-rs/toolchain@v1
78+
with:
79+
toolchain: ${{ matrix.rust-version }}
80+
- name: "Set up Java"
81+
uses: actions/setup-java@v2
82+
with:
83+
distribution: 'temurin'
84+
java-version: ${{ matrix.java-version }}
85+
cache: 'maven'
86+
- name: "Set up JavaScript"
87+
uses: actions/setup-node@v2
88+
with:
89+
node-version: ${{ matrix.js-version }}
90+
- name: "Set up R"
91+
uses: r-lib/actions/setup-r@v2
92+
with:
93+
r-version: ${{ matrix.r-version }}
94+
- name: "Set up LuaJit"
95+
uses: leafo/[email protected]
96+
with:
97+
luaVersion: luajit-${{ matrix.lua-version }}
98+
- name: "Set up Go"
99+
uses: actions/setup-go@v2
100+
with:
101+
go-version: ${{ matrix.go-version }}
102+
- name: "Run benchmark"
103+
run: |
104+
JULIAHOME=~/julia DSFMTDIR=~/dSFMT/ make gh_action_benchmarks.html
105+
- name: "Print benchmark data"
106+
run: cat gh_action_benchmarks.csv

Makefile

+47-30
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
ifndef JULIAHOME
22
$(error JULIAHOME not defined. Set value to the root of the Julia source tree.)
33
endif
4+
ifndef DSFMTDIR
5+
$(error DSFMTDIR not defined. Set value to the root of the dSFMT source tree.)
6+
endif
7+
8+
9+
# Will make multi-line targets work
10+
# (so we can use @for on the second line)
11+
.ONESHELL:
12+
413
include $(JULIAHOME)/Make.inc
514
include $(JULIAHOME)/deps/Versions.make
615

7-
NODEJSBIN = node8
16+
NODEJSBIN = node
17+
18+
ITERATIONS=$(shell seq 1 5)
819

920
#Use python2 for Python 2.x
1021
PYTHON = python3
@@ -19,13 +30,6 @@ else
1930
MATHEMATICABIN = math
2031
endif
2132

22-
#Which BLAS library am I using?
23-
ifeq ($(USE_SYSTEM_BLAS), 0)
24-
BLASMANIFEST=$(shell cat $(JULIAHOME)/usr/manifest/openblas)
25-
BLASDIR=$(JULIAHOME)/deps/scratch/$(BLASMANIFEST)/
26-
LIBBLAS=$(BLASDIR)$(LIBBLASNAME).a
27-
endif
28-
2933
FFLAGS=-fexternal-blas
3034
#gfortran cannot multiply matrices using 64-bit external BLAS.
3135
ifeq ($(findstring gfortran, $(FC)), gfortran)
@@ -43,25 +47,21 @@ LIBM = $(LIBMDIR)libopenlibm.a
4347
endif
4448
endif
4549

46-
DSFMTDIR = $(JULIAHOME)/deps/scratch/dsfmt-$(DSFMT_VER)
47-
RMATHDIR = $(JULIAHOME)/deps/scratch/Rmath-julia-$(RMATH_JULIA_VER)
48-
4950
default: benchmarks.html
5051

5152
export OMP_NUM_THREADS=1
5253
export GOTO_NUM_THREADS=1
5354
export OPENBLAS_NUM_THREADS=1
5455

5556
perf.h: $(JULIAHOME)/deps/Versions.make
56-
echo '#include "$(BLASDIR)cblas.h"' > $@
57+
echo '#include "cblas.h"' > $@
5758
echo '#include "$(DSFMTDIR)/dSFMT.c"' >> $@
5859

5960
bin/perf%: perf.c perf.h
60-
$(CC) -std=c99 -O$* $< -o $@ -I$(DSFMTDIR) $(LIBBLAS) -L$(LIBMDIR) $(LIBM) $(CFLAGS) -lpthread
61+
$(CC) -std=c99 -O$* $< -o $@ -I$(DSFMTDIR) -lopenblas -L$(LIBMDIR) $(LIBM) $(CFLAGS) -lpthread
6162

6263
bin/fperf%: perf.f90
6364
mkdir -p mods/$@ #Modules for each binary go in separate directories
64-
# $(FC) $(FFLAGS) -Jmods/$@ -O$* $< -o $@ $(LIBBLAS) -L$(LIBMDIR) $(LIBM) -lpthread
6565
$(FC) $(FFLAGS) -Jmods/$@ -O$* $< -o $@ -lopenblas -L$(LIBMDIR) $(LIBM) -lpthread
6666

6767
benchmarks/c.csv: \
@@ -80,73 +80,90 @@ benchmarks/fortran.csv: \
8080

8181

8282
benchmarks/c%.csv: bin/perf%
83-
for t in 1 2 3 4 5; do $<; done >$@
83+
@for t in $(ITERATIONS); do $<; done >$@
8484

8585
benchmarks/fortran%.csv: bin/fperf%
86-
for t in 1 2 3 4 5; do $<; done >$@
86+
@for t in $(ITERATIONS); do $<; done >$@
8787

8888
benchmarks/go.csv: export GOPATH=$(abspath gopath)
8989
benchmarks/go.csv: perf.go
90-
#CGO_LDFLAGS="$(LIBBLAS) $(LIBM)" go get github.com/gonum/blas/cgo
90+
#CGO_LDFLAGS="-lopenblas $(LIBM)" go get github.com/gonum/blas/cgo
9191
go get github.com/gonum/blas/blas64
9292
go get github.com/gonum/blas/cgo
9393
go get github.com/gonum/matrix/mat64
9494
go get github.com/gonum/stat
95-
for t in 1 2 3 4 5; do go run $<; done >$@
95+
@for t in $(ITERATIONS); do go run $<; done >$@
9696

9797
benchmarks/julia.csv: perf.jl
98-
for t in 1 2 3 4 5; do $(JULIAHOME)/usr/bin/julia $<; done >$@
98+
@for t in $(ITERATIONS); do $(JULIAHOME)/usr/bin/julia $<; done >$@
9999

100100
benchmarks/python.csv: perf.py
101-
for t in 1 2 3 4 5; do $(PYTHON) $<; done >$@
101+
@for t in $(ITERATIONS); do $(PYTHON) $<; done >$@
102102

103103
benchmarks/matlab.csv: perf.m
104-
for t in 1 2 3 4 5; do matlab -nojvm -singleCompThread -r 'perf; perf; exit' | grep ^matlab | tail -8; done >$@
104+
@for t in $(ITERATIONS); do matlab -nojvm -singleCompThread -r 'perf; perf; exit' | grep ^matlab | tail -8; done >$@
105105

106106
benchmarks/octave.csv: perf.m
107-
for t in 1 2 3 4 5; do $(OCTAVE) -q --eval perf 2>/dev/null; done >$@
107+
@for t in $(ITERATIONS); do $(OCTAVE) -q --eval perf 2>/dev/null; done >$@
108108

109109
benchmarks/r.csv: perf.R
110-
for t in 1 2 3 4 5; do cat $< | R --vanilla --slave 2>/dev/null; done >$@
110+
@for t in $(ITERATIONS); do cat $< | R --vanilla --slave 2>/dev/null; done >$@
111111

112112
benchmarks/javascript.csv: perf.js
113-
for t in 1 2 3 4 5; do $(NODEJSBIN) $<; done >$@
113+
@for t in $(ITERATIONS); do $(NODEJSBIN) $<; done >$@
114114

115115
benchmarks/mathematica.csv: perf.nb
116-
for t in 1 2 3 4 5; do $(MATHEMATICABIN) -noprompt -run "<<$<; Exit[]"; done >$@
116+
@for t in $(ITERATIONS); do $(MATHEMATICABIN) -noprompt -run "<<$<; Exit[]"; done >$@
117117

118118
benchmarks/stata.csv: perf.do
119-
for t in 1 2 3 4 5; do stata -b do $^ $@; done
119+
@for t in $(ITERATIONS); do stata -b do $^ $@; done
120120

121121
benchmarks/lua.csv: perf.lua
122-
for t in 1 2 3 4 5; do scilua $<; done >$@
122+
@for t in $(ITERATIONS); do luajit $<; done >$@
123123

124124
benchmarks/java.csv: java/src/main/java/PerfBLAS.java
125-
cd java; sh setup.sh; for t in 1 2 3 4 5; do mvn -q exec:java; done >../$@
125+
cd java
126+
sh setup.sh
127+
@for t in $(ITERATIONS); do mvn -q exec:java; done >../$@
126128

127129
benchmarks/scala.csv: scala/src/main/scala/perf.scala scala/build.sbt
128-
cd scala; for t in 1 2 3 4 5; do sbt run; done >../$@
130+
cd scala
131+
@for t in $(ITERATIONS); do sbt run; done >../$@
129132

130133
benchmarks/rust.csv: rust/src/main.rs rust/src/util.rs rust/Cargo.lock
131-
cd rust; for t in 1 2 3 4 5; do cargo run --release -q; done >../$@
134+
cd rust
135+
@for t in $(ITERATIONS); do cargo run --release -q; done >../$@
132136

133137
LANGUAGES = c fortran go java javascript julia lua mathematica matlab octave python r rust
138+
GH_ACTION_LANGUAGES = c fortran java javascript julia python r rust
134139

135140
# These were formerly listed in LANGUAGES, but I can't get them to run
136141
# 2017-09-27 johnfgibson
137142
# scala, stata
138143

139144
BENCHMARKS = $(foreach lang,$(LANGUAGES),benchmarks/$(lang).csv)
145+
GH_ACTION_BENCHMARKS = $(foreach lang,$(GH_ACTION_LANGUAGES),benchmarks/$(lang).csv)
146+
147+
COLON_SEPARATED_GHA_LANGUAGES = $(shell echo $(GH_ACTION_LANGUAGES) | sed 's/ /:/g')
140148

141149
versions.csv: bin/versions.sh
142150
$^ >$@
143151

152+
gh_action_versions.csv: bin/versions.sh
153+
$^ $(COLON_SEPARATED_GHA_LANGUAGES) >$@
154+
144155
benchmarks.csv: bin/collect.jl $(BENCHMARKS)
145156
@$(call PRINT_JULIA, $^ >$@)
146157

158+
gh_action_benchmarks.csv: bin/collect.jl $(GH_ACTION_BENCHMARKS)
159+
@$(call PRINT_JULIA, $^ >$@)
160+
147161
benchmarks.html: bin/table.jl versions.csv benchmarks.csv
148162
@$(call PRINT_JULIA, $^ >$@)
149163

164+
gh_action_benchmarks.html: bin/table.jl gh_action_versions.csv gh_action_benchmarks.csv
165+
@$(call PRINT_JULIA, $^ >$@)
166+
150167
clean:
151168
@rm -rf perf.h bin/perf* bin/fperf* benchmarks/*.csv benchmarks.csv mods *~ octave-core perf.log gopath/*
152169

bin/versions.sh

+60-27
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,74 @@
11
#!/usr/bin/env bash
22

3-
echo -n "c,gcc "
4-
gcc -v 2>&1 | grep "gcc version" | cut -f3 -d" "
3+
# User argument declaring what languages to query:
4+
DEFAULT_LANGUAGES="c:fortran:go:java:javascript:julia:lua:mathematica:matlab:octave:python:r:rust"
5+
LANGUAGES=${1:-DEFAULT_LANGUAGES}
56

6-
echo -n "fortran,gcc "
7-
gfortran -v 2>&1 | grep "gcc version" | cut -f3 -d" "
7+
LANGUAGES=":${LANGUAGES}:"
88

9-
echo -n go,
10-
go version | cut -f3 -d" "
9+
# Check if ":c:" in languages:
10+
if [[ $LANGUAGES == *":c:"* ]]; then
11+
echo -n "c,gcc "
12+
gcc -v 2>&1 | grep "gcc version" | cut -f3 -d" "
13+
fi
1114

12-
echo -n java,
13-
java -version 2>&1 |grep "version" | cut -f3 -d " " | cut -c 2-9
15+
if [[ $LANGUAGES == *":fortran:"* ]]; then
16+
echo -n "fortran,gcc "
17+
gfortran -v 2>&1 | grep "gcc version" | cut -f3 -d" "
18+
fi
1419

15-
echo -n "javascript,V8 "
16-
node8 -e "console.log(process.versions.v8)"
20+
if [[ $LANGUAGES == *":go:"* ]]; then
21+
echo -n go,
22+
go version | cut -f3 -d" "
23+
fi
1724

18-
echo -n "julia,"
19-
$JULIAHOME/usr/bin/julia -v | cut -f3 -d" "
25+
if [[ $LANGUAGES == *":java:"* ]]; then
26+
echo -n java,
27+
java -version 2>&1 |grep "version" | cut -f3 -d " " | cut -c 2-9
28+
fi
2029

21-
echo -n "lua,"
22-
# scilua -v 2>&1 | grep Shell | cut -f3 -d" " | cut -f1 -d,
23-
echo scilua v1.0.0-b12
30+
if [[ $LANGUAGES == *":javascript:"* ]]; then
31+
echo -n "javascript,V8 "
32+
node -e "console.log(process.versions.v8)"
33+
fi
2434

25-
echo -n "mathematica,"
26-
echo quit | math -version | head -n 1 | cut -f2 -d" "
35+
if [[ $LANGUAGES == *":julia:"* ]]; then
36+
echo -n "julia,"
37+
$JULIAHOME/usr/bin/julia -v | cut -f3 -d" "
38+
fi
2739

28-
echo -n "matlab,R"
29-
matlab -nodisplay -nojvm -nosplash -r "version -release, quit" | tail -n3 | head -n1 | cut -f5 -d" " | sed "s/'//g"
40+
if [[ $LANGUAGES == *":lua:"* ]]; then
41+
echo -n "lua,"
42+
# scilua -v 2>&1 | grep Shell | cut -f3 -d" " | cut -f1 -d,
43+
echo scilua v1.0.0-b12
44+
fi
3045

31-
echo -n "octave,"
32-
octave-cli -v | grep version | cut -f4 -d" "
46+
if [[ $LANGUAGES == *":mathematica:"* ]]; then
47+
echo -n "mathematica,"
48+
echo quit | math -version | head -n 1 | cut -f2 -d" "
49+
fi
3350

34-
echo -n "python,"
35-
python3 -V 2>&1 | cut -f2 -d" "
51+
if [[ $LANGUAGES == *":matlab:"* ]]; then
52+
echo -n "matlab,R"
53+
matlab -nodisplay -nojvm -nosplash -r "version -release, quit" | tail -n3 | head -n1 | cut -f5 -d" " | sed "s/'//g"
54+
fi
3655

37-
echo -n "r,"
38-
R --version | grep "R version" | cut -f3 -d" "
56+
if [[ $LANGUAGES == *":octave:"* ]]; then
57+
echo -n "octave,"
58+
octave-cli -v | grep version | cut -f4 -d" "
59+
fi
3960

40-
echo -n "rust,"
41-
(cd rust; rustc --version | cut -c 7- | sed 's/ ([0-9a-f]* /<br>(/g')
61+
if [[ $LANGUAGES == *":python:"* ]]; then
62+
echo -n "python,"
63+
python3 -V 2>&1 | cut -f2 -d" "
64+
fi
65+
66+
if [[ $LANGUAGES == *":r:"* ]]; then
67+
echo -n "r,"
68+
R --version | grep "R version" | cut -f3 -d" "
69+
fi
70+
71+
if [[ $LANGUAGES == *":rust:"* ]]; then
72+
echo -n "rust,"
73+
(cd rust; rustc --version | cut -c 7- | sed 's/ ([0-9a-f]* /<br>(/g')
74+
fi

0 commit comments

Comments
 (0)