-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add automated benchmarks #256
Conversation
Example table produced by this pipeline:
|
Tables now include more info, plus fixed bug where the times were getting put in incorrect columns:
|
I've just integrated DrWatson.jl into the benchmarking suite. It's ability to handle different input parameters and keep track of file directories is awesome but it seems to have trouble with reading in the data from the saved benchmark table correctly. DrWatson really seems to prefer working with JLD2 but BenchmarkTools saves its results as JSON and also seems to include a lot of extra information. |
benchmarks/README.md
Outdated
using DrWatson | ||
@quickactivate :benchmarks | ||
``` | ||
which auto-activate the project, enable local path handling from DrWatson and provide several helper functions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I followed these instructions and got this error message
(Decapodes) pkg> instantiate
julia> @quickactivate :benchmarks
ERROR: ArgumentError: Package benchmarks not found in current path.
- Run `import Pkg; Pkg.add("benchmarks")` to install the benchmarks package.
Stacktrace:
[1] macro expansion
@ Base ./loading.jl:1766 [inlined]
[2] macro expansion
@ Base ./lock.jl:267 [inlined]
[3] __require(into::Module, mod::Symbol)
@ Base ./loading.jl:1747
[4] #invoke_in_world#3
@ Base ./essentials.jl:921 [inlined]
[5] invoke_in_world
@ Base ./essentials.jl:918 [inlined]
[6] require(into::Module, mod::Symbol)
@ Base ./loading.jl:1740
[7] macro expansion
@ ~/.julia/packages/DrWatson/qmLuV/src/project_setup.jl:213 [inlined]
[8] top-level scope
@ REPL[6]:1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Decapodes) pkg> dev ./benchmarks
fixed it. although I got a Circular dependency warning. so now i can't precompile Decapodes and benchmarks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems like the instructions should be
- Clone the Decapodes repo
- cd to the Decapodes/benchmarks directory
- run
julia>]dev ..
- run
julia> include("main.jl")
and this main.jl should run all the benchmarks that are configured in the main_config.toml file. This way it is more like docs builds than like an interactive tool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we want main.jl to define a function benchmark(name::String, config="main_config.toml")
that runs a simulation with the name
and benchmark(config="main_config.toml")
that runs all the configured benchmarks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, for the main.jl I can add that. Actually a lot of the code there can probably refactored.
I understand the confusion with the DrWatson instructions, the @quickactivate
works by searching upwards for a toml
name with benchmark
so running it from Decapodes
won't work, as you've seen. However, running it from within the benchmarks
dir should work. I'll add an instruction asking the user to cd
into benchmarks
.
benchmarks/README.md
Outdated
|
||
Please view ```main_config.toml``` as a guiding example on how to craft your own TOML. | ||
|
||
**Warning**: ```config_generate.jl``` is not called automatically so it is up to you to run the script before launching benchmarks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you don't call this the error message is quite cryptic. maybe the main.jl script should check that the configs exist and if not, then automatically call config_generate
for you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do this, we should just always call config_generate
to avoid stale configs. I'd like to update the that cryptic error, was the error you referenced the, "No configuration information found for $sim_name"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that was the cryptic error. I feel like a makefile approach of conditional compilation is such a good fit for what you are doing. If the individual configs don't exists, then you need to regenerate them. But I think we can get rid of that step entirely by a later comment
benchmarks/README.md
Outdated
1. ```setup_benchmark```, which will create the Decapode and run ```eval(gensim())``` on it. Return the evaluated function. | ||
2. ```create_mesh```, which will create the mesh upon which the simulation will run and also initialize the initial conditions and any constants/parameters. Return the mesh, initial conditions and constants/parameters in that order. | ||
3. ```create_simulate```, which will take the generated mesh and evaluated function and run the simulate function. Return the resulting function. | ||
4. ```run_simulation```, which will take the resulting simulation function, initial conditions and constants/parameters and run the solve. Return the result of the solve. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of relying on functions with particular names, we could make a struct in Decapodes that is SimulationConfig
that has these 4 functions as fields and then constructors can provide default implementations of these fields if it makes sense to go with a generic implementation.
That would give users a way of encapsulating a simulation into a reusable chunk for their benchmarks, which would live outside this repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that sounds good. This struct can live in the src
and be brought into scope with the @quickactive :benchmarks
. I'll also add a function field that takes in the file config information and organizes it into something the simulation can use throughout.
benchmarks/README.md
Outdated
|
||
**Warning**: Note that not all information from the benchmarking run is saved to the result files and any files in ```data/sims/"sim_name"``` will be deleted upon the next benchmark run. On the other hand, result files in the ```autogen``` directory mentioned before will never be deleted by the benchmarking. | ||
|
||
An example Markdown file is output in ```data/exp_pro/"sim_name"/"slurm_job_id"``` for user inspection, called ```final.md```. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does exp_pro
stand for? A more informative name would be helpful here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exp_pro
was a default folder provided by DrWatson, meant for "Data from processing experiments" per their docs. But it's fair enough to consider that we don't need to actually use these folders.
benchmarks/src/main_config.toml
Outdated
[heat.cuda] | ||
code_target = "CUDATarget" | ||
float_type = ["Float32", "Float64"] | ||
resolution = [5, 2, 1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I understand that:
- each simulation still needs code for its set up that needs to go in a folder
- the simulations could in theory have different dependencies (because they are in their own folder)
- there is a generate_configs script that is copying this data into individual config tomls for each simulation.
It makes sense to me that these config tomls actually live 1 per folder and specify all the configurations of the same simulation that you want to run. But the global main_config.toml
is actually just a list of all the configurations that you want to run. Much like in the docs, docs/main.jl
has a big list of all the pages in the docs to tell you which markdown files to include.
There is also the possibility to do a makefile with a rule like
for every folder f in benchmarks/src/$f
there is a target benchmarks/results/$f/run.out
and in order to make that target you need the dependencies benchmarks/src/$f/main.jl
and benchmarks/src/$f/config.toml
and then you could do
> make all
and have all the benchmarks run. Or run a specific benchmark with
> make benchmarks/results/f/run.out
A make rule that depends on all the run.out targets could then be used to make the final summary tables in HTML format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea with having different configs per architecture was that a user might want different configurations for each. For example, gpu sims could include larger mesh sizes or longer times. I think this flexibility is nice to have.
I like your idea of the role of the main_config.toml
since the data processing is the same, we just change where we read the data. Plus, if we keep separate tomls for each architecture then the user can choose to run just cpu benchmarks or just gpu benchmarks.
Just thinking through the pipeline, the user can just provide their main_config.toml
which lists all sims/arches to run. main.jl
can then read the main config and auto-run the config generation that looks for the user provided toml
for each of these sims and generates a list of configs for tasks. It'll then basically just run the benchmarks as it does now.
We can implement the make all
feature by scanning the src
dir for valid physics folders and then running through the same pipeline as above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for post-processing, the idea now is to collect all the data from the benchmarks into .jld2
files that can be collected into dataframes using DrWatson. I've provided a basic post-processing step in scripts/post_processing/default_out.jl
but we can add more scripts for different post-processing as we find the need for it. This could include deciding to output to markdown or HTML or whatever else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see that post processing script. Did you commit it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that's my bad, I just pushed those.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea with having different configs per architecture was that a user might want different configurations for each. For example, gpu sims could include larger mesh sizes or longer times. I think this flexibility is nice to have.
Yeah, I think you should be able to have multiple configurations in the same folder and then the main_config.toml should list out the ones you want to run.
So you could have heat.cpu and heat.cuda and heat.cuda-massive all in heat/config.toml and then in benchmarks/config.toml
only list out the ones you want to run.
This PR adds scripts to be able to run automated Decapodes benchmarks using SLURM. Close #255.