-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
54678ae
commit b756e11
Showing
3 changed files
with
190 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,82 @@ | ||
# Script for generating benchmark results in | ||
# https://henry2004y.github.io/Vlasiator.jl/dev/benchmark/ | ||
# | ||
# Note: this script is not intended for execution as a whole: each benchmark needs to be | ||
# executed independently after importing all the required packages. | ||
|
||
using Vlasiator | ||
using Vlasiator: RE | ||
using Vlasiator, PyPlot | ||
using BenchmarkTools | ||
using Glob | ||
|
||
## Reading DCCRG variables | ||
ENV["MPLBACKEND"]="agg" # no GUI for Matplotlib | ||
|
||
file1 = "bulk.singleprecision.vlsv" # 80 B | ||
file2 = "bulk.0000003.vlsv" # 900 KB | ||
file3 = "bulk1.0001000.vlsv" # 32 MB | ||
# Select file | ||
file = file1 | ||
# Load metadata | ||
@time meta = load(file); | ||
@time meta = load(file); | ||
@time meta = load(file); | ||
# Select variable name | ||
var = "proton/vg_rho"; | ||
# Read variable, sorted | ||
@time rho = meta[var]; | ||
@time rho = meta[var]; | ||
# Read variable, unsorted | ||
@time rho_unsorted = readvariable($meta, $var, false); | ||
@time rho_unsorted = readvariable($meta, $var, false); | ||
files = ["1d_single.vlsv", "bulk.2d.vlsv", "2d_double.vlsv", "2d_AFC.vlsv", "3d_EGI.vlsv"] | ||
versions = [5,5,5,4,5] | ||
|
||
## Plotting with PyPlot | ||
# Log color scale is used for comparison with Analysator. | ||
|
||
# 2D density contour on a uniform mesh | ||
filename = "bulk.0000501.vlsv" | ||
meta = load(filename) | ||
@time pcolormesh(meta, "rho", colorscale=Log) | ||
close() | ||
@time pcolormesh(meta, "rho", colorscale=Log) | ||
# Download test files if not found in the current path | ||
for i in eachindex(files) | ||
if isfile(files[i]) | ||
@info "Benchmark file $(files[i]) found..." | ||
continue | ||
elseif i == 4 | ||
url_base = "https://a3s.fi/swift/v1/AUTH_81f1cd490d494224880ea77e4f98490d/vlasiator-2d-afc/" | ||
filename = "production_halfres/bulk.0000000.vlsv" | ||
file_origin = basename(filename) | ||
url = joinpath(url_base, filename) | ||
@info "Downloading 1.8G test file..." | ||
run(`curl -o $file_new $url`) | ||
run(`mv $(file_origin) $file`) | ||
elseif i in (1,2,3) | ||
@info "Downloading test files..." | ||
run(`curl -o testdata.tar.gz https://raw.githubusercontent.com/henry2004y/vlsv_data/master/testdata.tar.gz`) | ||
run(`curl -o 1d_single.vlsv https://raw.githubusercontent.com/henry2004y/vlsv_data/master/1d_single.vlsv`) | ||
run(`curl -o 2d_double.vlsv https://raw.githubusercontent.com/henry2004y/vlsv_data/master/2d_double.vlsv`) | ||
run(`tar -xzvf testdata.tar.gz`) | ||
elseif i == 5 | ||
@warn "$(files[i]) is not open-access!" | ||
end | ||
end | ||
|
||
# 2D density slices from 3D AMR mesh | ||
filename = "bulk1.0001000.vlsv" | ||
meta = load(filename) | ||
@time pcolormesh(meta, "proton/vg_rho", colorscale=Log) | ||
close() | ||
@time pcolormesh(meta, "proton/vg_rho", colorscale=Log) | ||
# Define a parent BenchmarkGroup to contain our suite | ||
const suite = BenchmarkGroup() | ||
|
||
## Virtual satellite tracking at a static location | ||
# Add children groups and tags to our benchmark suite. | ||
suite["load"] = BenchmarkGroup(files) | ||
suite["read"] = BenchmarkGroup(files) | ||
suite["plot"] = BenchmarkGroup(["2d", "3d"]) | ||
|
||
# 3D EGI data on Turso, University of Helsinki | ||
dir = "/wrk-vakka/group/spacephysics/vlasiator/3D/EGI/bulk/dense_cold_hall1e5_afterRestart374/" | ||
# Add benchmarks | ||
for (i, file) in enumerate(files) | ||
suite["load"][file] = @benchmarkable load($file) | ||
if i == 4 | ||
var = "proton/rho" | ||
suite["read"][file*"_sorted"] = @benchmarkable meta[$var] setup=(meta=load($file)) | ||
suite["read"][file*"_unsorted"] = | ||
@benchmarkable readvariable(meta, $var, false) setup=(meta=load($file)) | ||
suite["plot"]["contour_uniform"] = | ||
@benchmarkable pcolormesh(meta, $var, colorscale=Log) setup=(meta=load($file)) | ||
else | ||
var = "proton/vg_rho" | ||
suite["read"][file*"_sorted"] = @benchmarkable meta[$var] setup=(meta=load($file)) | ||
suite["read"][file*"_unsorted"] = | ||
@benchmarkable readvariable(meta, $var, false) setup=(meta=load($file)) | ||
end | ||
if i == 5 | ||
var = "proton/vg_rho" | ||
suite["plot"]["contour_nonuniform"] = | ||
@benchmarkable pcolormesh(meta, $var, colorscale=Log) setup=(meta=load($file)) | ||
end | ||
|
||
filenames = glob("bulk1*.vlsv", dir) | ||
end | ||
|
||
var = "proton/vg_rho" | ||
loc = [12, 0, 0] .* RE | ||
# If a cache of tuned parameters already exists, use it, otherwise, tune and cache | ||
# the benchmark parameters. Reusing cached parameters is faster and more reliable | ||
# than re-tuning `suite` every time the file is included. | ||
paramspath = joinpath(dirname(@__FILE__), "params.json") | ||
|
||
println("Number of files: ", length(filenames)) | ||
# Static cell ID | ||
id = let | ||
meta = load(filenames[1]) | ||
getcell(meta, loc) | ||
if isfile(paramspath) | ||
loadparams!(suite, BenchmarkTools.load(paramspath)[1], :evals) | ||
else | ||
tune!(suite) | ||
BenchmarkTools.save(paramspath, params(suite)) | ||
end | ||
|
||
@btime data_series = extractsat($filenames, $var, $id) | ||
results = run(suite, verbose=true, samples=100, seconds=20) | ||
|
||
show(results) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +1,94 @@ | ||
# Script for generating benchmark results in | ||
# https://henry2004y.github.io/Vlasiator.jl/dev/benchmark/ | ||
# | ||
# Note: this script is not intended for execution as a whole: each benchmark | ||
# needs to be executed independently after importing all the required packages. | ||
|
||
import timeit | ||
import requests, tarfile, timeit, os, os.path, textwrap | ||
import pytools as pt | ||
import matplotlib | ||
matplotlib.use('agg') | ||
|
||
os.environ["PTNONINTERACTIVE"] = "1" | ||
|
||
files = ['1d_single.vlsv', 'bulk.2d.vlsv', '2d_double.vlsv', '2d_AFC.vlsv', '3d_EGI.vlsv'] | ||
|
||
for i, file in enumerate(files): | ||
if os.path.isfile(file): | ||
print(f"Benchmark file {file} found...") | ||
elif i == 3: | ||
url_base = 'https://a3s.fi/swift/v1/AUTH_81f1cd490d494224880ea77e4f98490d/vlasiator-2d-afc/' | ||
filename = 'production_halfres/bulk.0000000.vlsv' | ||
r = requests.get(url_base+filename, allow_redirects=True) | ||
open('2d_AFC.vlsv', 'wb').write(r.content) | ||
elif i in [0,1,2]: | ||
r = requests.get('https://raw.githubusercontent.com/henry2004y/vlsv_data/master/testdata.tar.gz', allow_redirects=True) | ||
open('testdata.tar.gz', 'wb').write(r.content) | ||
r = requests.get('https://raw.githubusercontent.com/henry2004y/vlsv_data/master/1d_single.vlsv', allow_redirects=True) | ||
open('1d_single.vlsv', 'wb').write(r.content) | ||
r = requests.get('https://raw.githubusercontent.com/henry2004y/vlsv_data/master/2d_double.vlsv', allow_redirects=True) | ||
open('2d_double.vlsv', 'wb').write(r.content) | ||
|
||
file = tarfile.open('testdata.tar.gz') | ||
file.extractall('./') | ||
file.close() | ||
elif i == 4: | ||
print(f"{file} is not open-access!") | ||
|
||
# Number of trails for each benchmark | ||
ntrail = 100 | ||
|
||
# Setup: importing packages | ||
p0 = """ | ||
import pytools as pt | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
import matplotlib | ||
matplotlib.use('agg') | ||
""" | ||
# Setup: selecting file and variable | ||
p1 = p0+""" | ||
file1 = 'bulk.singleprecision.vlsv' # 80 B | ||
file2 = 'bulk.0000003.vlsv' # 900 KB | ||
file3 = 'bulk1.0001000.vlsv' # 32 MB | ||
|
||
file = file1 | ||
var = 'proton/vg_rho' | ||
""" | ||
# Setup: reading metadata | ||
p2 = p0+p1+""" | ||
f = pt.vlsvfile.VlsvReader(file) | ||
""" | ||
# Setup: virtual satellite extraction | ||
p3 = p0+""" | ||
import glob | ||
dir = "/wrk-vakka/group/spacephysics/vlasiator/3D/EGI/bulk/dense_cold_hall1e5_afterRestart374/" | ||
var = "proton/vg_rho" | ||
Re = 6.371e6 # Earth radius, [m] | ||
loc = [12*Re, 0, 0] | ||
filenames = sorted(glob.glob(dir+"bulk1*.vlsv")) | ||
data_series = np.zeros(len(filenames)) | ||
f = pt.vlsvfile.VlsvReader(filenames[0]) | ||
id = f.get_cellid(loc) | ||
print(id) | ||
""" | ||
for i, file in enumerate(files): | ||
# Setup: reading metadata | ||
p2 = textwrap.dedent("""\ | ||
f = pt.vlsvfile.VlsvReader(file) | ||
cellID = f.read_variable('CellID') | ||
cell_sorted = np.argsort(cellID) | ||
""") | ||
|
||
if i != 3: | ||
# Setup: selecting file and variable | ||
p1 = p0 + textwrap.dedent(f"""\ | ||
file = '{file}' | ||
var = 'proton/vg_rho' | ||
""") | ||
else: | ||
# Setup: selecting file and variable | ||
p1 = p0 + textwrap.dedent(f"""\ | ||
file = '{file}' | ||
var = 'proton/rho' | ||
""") | ||
|
||
# Run: reading metadata | ||
s1 = p2 | ||
t1 = timeit.timeit(stmt=s1, setup=p1, number=ntrail) / ntrail * 1e3 | ||
print(f"{file}:") | ||
print(f"Reading metadata in {t1:0.4f} ms") | ||
# Run: obtaining sorted scalar variable | ||
s2 = textwrap.dedent(""" | ||
rho = f.read_variable(var)[cell_sorted] | ||
""") | ||
t2 = timeit.timeit(stmt=s2, setup=p0+p1+p2, number=ntrail) / ntrail * 1e3 | ||
print(f"{file}:") | ||
print(f"Reading scalar DCCRG variable in {t2:0.4f} ms") | ||
|
||
# Run: reading metadata | ||
s1 = """ | ||
f = pt.vlsvfile.VlsvReader(file) | ||
""" | ||
# Run: obtaining scalar variable | ||
s2 = """ | ||
cellID = f.read_variable('CellID') | ||
cell_sorted = np.argsort(cellID) | ||
rho = f.read_variable(var)[cell_sorted] | ||
""" | ||
# Run: plotting density contour on a uniform mesh | ||
s3 = """ | ||
pt.plot.plot_colormap(filename='bulk.0000501.vlsv', var='rho', draw=1) | ||
s3 = f""" | ||
pt.plot.plot_colormap(filename='{files[3]}', var='rho', draw=1) | ||
""" | ||
t3 = timeit.timeit(stmt=s3, setup=p0, number=5) / 5 | ||
print(f"Uniform 2d plotting in {t3:0.4f} s") | ||
|
||
# Run: plotting density slice from a 3D AMR mesh | ||
s4 = """ | ||
pt.plot.plot_colormap3dslice(filename='bulk1.0001000.vlsv', var='proton/vg_rho', draw=1, normal='y') | ||
""" | ||
# Run: virtual satellite extraction from a static location | ||
s5 = """ | ||
for (i,fname) in enumerate(filenames): | ||
f = pt.vlsvfile.VlsvReader(fname) | ||
data_series[i] = f.read_variable(name=var, cellids=id) | ||
s4 = f""" | ||
pt.plot.plot_colormap3dslice(filename='{files[4]}', var='proton/vg_rho', draw=1, normal='y') | ||
""" | ||
|
||
print(timeit.timeit(stmt=s1, setup=p1, number=10) / 10 * 1e3) # [ms] | ||
print(timeit.timeit(stmt=s2, setup=p2, number=10) / 10 * 1e3) # [ms] | ||
|
||
t1 = timeit.timeit(stmt=s1, setup=p1, number=10) / 10 | ||
print(f"Finished reading metadata in {t1:0.4f} ms") | ||
|
||
t2 = timeit.timeit(stmt=s2, setup=p2, number=10) / 10 | ||
print(f"Finished reading scalar DCCRG variable in {t2:0.4f} ms") | ||
|
||
t3 = timeit.timeit(stmt=s3, setup=p0, number=3) / 3 | ||
print(f"Finished plotting in {t3:0.4f} s") | ||
|
||
t4 = timeit.timeit(stmt=s4, setup=p0, number=3) / 3 | ||
print(f"Finished plotting in {t4:0.4f} s") | ||
|
||
t5 = timeit.timeit(stmt=s5, setup=p3, number=1) / 1 | ||
print(f"Finished virtual satellite tracking in {t5:0.4f} s") | ||
t4 = timeit.timeit(stmt=s4, setup=p0, number=5) / 5 | ||
print(f"AMR slice plotting in {t4:0.4f} s") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,65 @@ | ||
# Benchmarks | ||
|
||
The test file information are listed below: | ||
|
||
| Index | Filename | Number of Cells | Dimension | AMR | Public | | ||
|:-------|:----------------|:---------------:|:---------:|:---:|:------:| | ||
| 1 | 1d_single.vlsv | 20 | 1 | No | Yes | | ||
| 2 | bulk.2d.vlsv | 6,300 | 1 | No | Yes | | ||
| 3 | 2d_double.vlsv | 51,200 | 2 | No | Yes | | ||
| 4 | 2d_AFC.vlsv | 4,612,500 | 2 | No | Yes | | ||
| 5 | 3d_EGI.vlsv | 3,966,580 | 3 | Yes | No | | ||
|
||
Access to the public data can be found from [vlsv_data](https://github.com/henry2004y/vlsv_data). | ||
|
||
!!! note | ||
The numbers shown here are comparisons between Analysator v0.9 and Vlasiator.jl v0.9.32 running Python 3.6.9/3.9.7 and Julia 1.8.3 with the scripts [`perf.jl`](https://github.com/henry2004y/Vlasiator.jl/blob/master/benchmark/perf.jl) and [`perf.py`](https://github.com/henry2004y/Vlasiator.jl/blob/master/benchmark/perf.py). The timings are collected from a i5-10210U @ 1.6GHz CPU with 16 GB RAM if not specified. | ||
|
||
* Loading meta data[^1] | ||
| File Index | Julia [ms] | Python [ms] | Ratio | | ||
|:-----------|:----------:|:-----------:|:-----:| | ||
| 1 | 0.18 | 1.19 | 6.6 | | ||
| 2 | 0.51 | 1.66 | 3.1 | | ||
| 3 | 2.33 | 3.11 | 1.3 | | ||
| 4 | 506 | 277 | 0.5 | | ||
| 5 | 549 | 283 | 0.5 | | ||
|
||
[^1]: See the [issue](https://github.com/henry2004y/Vlasiator.jl/issues/124) about sorting. The performance of EzXML is also not ideal: we may need to find a better XML parser in Julia. | ||
|
||
* Reading DCCRG grid variables | ||
| Size | Julia [ms] | Python [ms] | Speedup | | ||
|:----------------|:----------:|:-----------:|:-------:| | ||
| 80 B Float32 | 0.002 | 0.14 | 55 | | ||
| 25 KiB Float64 | 0.017 | 0.44 | 26 | | ||
| 879 KiB Float64 | 0.3 | 8.7 | 29 | | ||
| 30 MiB Float64 | 10.8 | 295 | 27 | | ||
| File Index | Julia [ms] | Python [ms] | Ratio | | ||
|:-----------|:----------:|:-----------:|:------:| | ||
| 1 | 0.004 | 0.07 | 17 | | ||
| 2 | 0.02[^2] | 0.08 | 4 | | ||
| 3 | 0.17[^2] | 0.21 | 1.2 | | ||
| 4 | 20[^2] | 23 | 1.1 | | ||
| 5 | 11[^2] | 11 | 1.0 | | ||
|
||
[^1]: Vlasiator.jl can be even faster if there is no conversion from Float64 to Float32. See [Precision](log.md#precision). | ||
[^2]: Vlasiator.jl can be faster if there is no conversion from Float64 to Float32. See [Precision](log.md#precision). | ||
|
||
* Reading field solver grid variables[^2] | ||
| Size | Julia [s] | Python [s] | Speedup | | ||
|:----------------|:---------:|:----------:|:-------:| | ||
| 6.2 GiB Float32 | 8 | 61 | 7.6 | | ||
* Reading field solver grid variables[^3] | ||
| File Index | Size | Julia [s] | Python [s] | Ratio | | ||
|:-----------|:----------------|:---------:|:----------:|:-----:| | ||
| 5 | 6.2 GiB Float32 | 8 | 61 | 7.6 | | ||
|
||
[^2]: The field solver grid is a regular Cartesian grid at the finest refinement level. Therefore the storage requirement for fsgrid variables are quite significant: with limited memory (e.g. 16 GB RAM) you may encounter out-of-memory issues when reading `fg_b` more than once. In Vlasiator.jl, we provide the option `usemmap=true` for reading large arrays --- see [Memory](log.md#memory) for more. | ||
[^3]: The field solver grid is a regular Cartesian grid at the finest refinement level. Therefore the storage requirement for fsgrid variables are quite significant: with limited memory (e.g. 16 GB RAM) you may encounter out-of-memory issues when reading `fg_b` more than once. In Vlasiator.jl, we provide the option `usemmap=true` for reading large arrays --- see [Memory](log.md#memory) for more. | ||
|
||
* Plotting 2D density contours on a uniform mesh[^3] | ||
| Size | Julia, 1st time [s] | Julia, 2nd time [s] | Python [s] | Speedup | | ||
|:---------|:-------------------:|:-------------------:|:----------:|:-------:| | ||
| 26.7 MiB | 2.4 | 0.5 | 4.7 | 9.4 | | ||
* Plotting 2D density contours on a uniform mesh | ||
| File Index | Julia [s] | Python [s] | Ratio | | ||
|:-----------|:---------:|:----------:|:-----:| | ||
| 4 | 0.5 | 12.3 | 9.4 | | ||
|
||
* Plotting 2D density slices from a 3D AMR mesh | ||
| Size | Julia, 1st time [s] | Julia, 2nd time [s] | Python [s] | Speedup | | ||
|:---------|:-------------------:|:-------------------:|:----------:|:-------:| | ||
| 30.5 MiB | 2.7 | 0.5 | 5.0 | 10 | | ||
| Size | Julia [s][^4] | Python [s] | Ratio | | ||
|:---------|:-------------:|:----------:|:-----:| | ||
| 30.5 MiB | 0.5 | 4.6 | 10 | | ||
|
||
[^3]: The inefficieny of JIT for the first time execution is a famous problem in the Julia community known as "Time-To-First-X". | ||
[^4]: The first time execution will be slower due to JIT compilation (which is excluded in the timing here). This is known as "Time-To-First-X" in the Julia community. | ||
|
||
* Static virtual satellite tracking from 3D AMR data (26G per frame, 32 MB Cell IDs) on a cluster[^4] | ||
* Static virtual satellite tracking from 3D AMR data (26G per frame, 32 MB Cell IDs) on a cluster[^5] | ||
|
||
| Frames | Julia, 1 thread [s] | Julia, 2 threads [s] | Python [s] | | ||
|:-------|:-------------------:|:--------------------:|:----------:| | ||
| 845 | 45 | 34 | 1220 | | ||
|
||
[^4]: University of Helsinki cluster Vorna with Intel Xeon E5-2697 @ 2.70GHz. | ||
[^5]: University of Helsinki cluster Vorna with Intel Xeon E5-2697 @ 2.70GHz. |