Giter Club home page Giter Club logo

abm_framework_comparisons's Introduction

Benchmarks and comparisons of leading ABM frameworks and Agents.jl

Many agent-based modeling frameworks have been constructed to ease the process of building and analyzing ABMs (see here for a review). Notable examples are NetLogo, Repast, MASON, Mesa and FLAMEGPU2.

This repository contains examples to compare the performance of muliple ABM Frameworks including:

Based on / Forked from https://github.com/JuliaDynamics/

It includes the following models for the comparison:

  • Flocking, a ContinuousSpace model, chosen over other models to include a MASON benchmark. Agents must move in accordance with social rules over the space.
  • Schelling's-segregation-model, a GridSpace model to compare with MASON.

Benchmark Timing

The benchmarking is setup to time the execution of N simulation steps in each simulator, excluding overhead costs of the runtime, model construction and the initial population of agents.

Each simulation is ran multiple times, and an average runtime is taken. This is not using the minimum as this is not a micro-benchmark, and not all models are seeded so stochasticity is a factor. MESA and NetLogo simulations may use fewer repetitions than Agents.jl and FLAME GPU due to total benchmark execution run time for the large scale of these simulations.

The FLAME GPU simulation outputs multiple different timing values, but the simulate (mean ms) values are the most representative compared to the other simulators, as this is just the execution of the simulation iterations/steps, rather than including CUDA context creation, model definiiton and population generation.

Status

Currently several simulators are not being compared due to container issues, several models have been disabled while implementations are not present, and other planned improvements are neccesary.

  • Mason is not present in runall.sh (as in the upstream https://github.com/JuliaDynamics/)
  • FLAMEGPU 2 binaries must be compiled in the local filesystem rather than packaged into a container
  • Version pinning for reproducibility is incomplete / not ideal.
  • Benchmarking is at a single scale
  • Simulations are not (all) seeded for reproducibility for stochastic initialisation
    • Different implementations use different PRNG, so the same seed will not produce the same simulation
  • Multi-stage docker build with a development and runtime image would improve file size and portability (with an entrypoint to runall.sh)
  • Provide a smaller dockerfile not based on a CUDA dockerfile for non-GPU benchmarking.
  • Repast4Py would be a good addition.
  • Scripts included hardcoded path locations (from upstream, and for expected locations in-container).

Containers

To simplify reproduction of the benchmarks, a Dockerfile is provided which installs dependencies into a container, which can be used to execute the benchmarks

The included dockerfile can be used to create a container with the build/runtime dependencies required for running this benchmark. Alternatively, a singularity container can be generated from the Dockerfile if required.

Note: This requires an Nvidia or greater GPU, with a CUDA 11.8 compatible driver installed on the host system.

To make use of the docker container currently (as it is not pushed to a registry):

  1. Build docker image with CUDA development dependencies + everything needed to run (but not include) the examples
  2. Optionally convert to apptainer for apptainer use
  3. Configure and build FLAMEGPU2 binaries on the parent filesystem, bound in the container (so using the container build dependencies. The produced binaries might not be valid on the host system)
  4. Run the runall script(s) to run the benchmark (or run benchmarks individually)

Creating the Docker image

Create the docker container, named/tagged as abm-framework-comparisons

sudo docker build . -t abm-framework-comparisons

Arbitrary commands can then be executed in that docker image via:

sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons nvidia-smi

Creating an Apptainer/Singularity image

Once the docker container is available locally, it can be converted to apptainer/singularity for use on systems without docker.

sudo apptainer build abm-framework-comparisons.sif docker-daemon://abm-framework-comparisons:latest

Then can run via:

apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif nvidia-smi

Running packaged benchmarks

The docker / apptainer containers include a copy of this repository in /opt/ABM_Framework_Comparisons, including the FLAME GPU binaries.

The packaged FLAMEGPU2 binaries are compiled for SM 70 and SM 80 GPUs (Volta, Turing, Ampere and Ada), and will also run on SM 90 (Hopper) GPUs via embedded PTX, which may result in slightly slower performance for the first repetition.

To run the packaged version of the benchmarks:

# run all using docker
sudo docker run --rm --gpus all abm-framework-comparisons bash -c "./runall.sh" 
# run all using apptainer
apptainer exec --nv --pwd /opt/ABM_Framework_Comparisons abm-framework-comparisons.sif bash -c "./runall.sh" 

Or to run individual benchmarks using Docker:

# flamegpu
sudo docker run --rm --gpus all abm-framework-comparisons bash -c "python3 FLAMEGPU2/benchmark.py" 
# julia
sudo docker run --rm --gpus all abm-framework-comparisons bash -c "julia --project=@. Agents/benchmark.jl" 
# Netlogo
sudo docker run --rm --gpus all abm-framework-comparisons bash -c "./netlogo_flock.sh" 
sudo docker run --rm --gpus all abm-framework-comparisons bash -c "./netlogo_s.sh"
# Mesa 
sudo docker run --rm --gpus all abm-framework-comparisons bash -c "python3 Mesa/Flocking/benchmark.py" 
sudo docker run --rm --gpus all abm-framework-comparisons bash -c "python3 Mesa/Schelling/benchmark.py"

Or to run individual benchmarks using Apptainer:

# flamegpu
apptainer exec --nv --pwd /opt/ABM_Framework_Comparisons abm-framework-comparisons.sif bash -c "python3 FLAMEGPU2/benchmark.py" 
# julia
apptainer exec --nv --pwd /opt/ABM_Framework_Comparisons abm-framework-comparisons.sif bash -c "julia --project=@. Agents/benchmark.jl" 
# Netlogo
apptainer exec --nv --pwd /opt/ABM_Framework_Comparisons abm-framework-comparisons.sif bash -c "./netlogo_flock.sh" 
apptainer exec --nv --pwd /opt/ABM_Framework_Comparisons abm-framework-comparisons.sif bash -c "./netlogo_s.sh"
# Mesa 
apptainer exec --nv --pwd /opt/ABM_Framework_Comparisons abm-framework-comparisons.sif bash -c "python3 Mesa/Flocking/benchmark.py" 
apptainer exec --nv --pwd /opt/ABM_Framework_Comparisons abm-framework-comparisons.sif bash -c "python3 Mesa/Schelling/benchmark.py"

sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons ./netlogo_flock.sh sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons ./netlogo_s.sh

Using the container for dependencies only

It is also possible to just use the container for build dependencies, but not use the packaged version of scripts/models. E.g. if you wish to modify any files without rebuilding them into the container.

In this case, the working directory must be bound to the container,

Compiling the FLAME GPU 2 executables

Unlike Agents.jl, Mason, Messa and NetLogo, The included FLAMEGPU2 models are not implemented in an interpreted language (although python3 bindings are available), so the examples must be compiled prior to their use. This requires CMake, git NVCC, and a C++17 host compiler, such as gcc >= 9.

This is a two step process.

  1. Create a build directory and configure CMake (finding compilers etc), selecting build options
  2. Build the binaries via CMake

To do this using the container, into FLAMEGPU2/build, for a compute capability 70 GPU

# using docker
sudo sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons bash -c "cmake -S FLAMEGPU2 -B FLAMEGPU2/build .. -DCUDA_ARCH=70,80 -DSEATBELTS=OFF && cmake --build FLAMEGPU2/build --target all -j `nproc`"

# Using apptainer:
# sudo/root may be required for ssh based cloning to work
sudo apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif bash -c "cmake -S FLAMEGPU2 -B FLAMEGPU2/build .. -DCUDA_ARCH=70,80 -DSEATBELTS=OFF && cmake --build FLAMEGPU2/build --target all -j `nproc`"

This wil have produced binaries in FLAMEGPU/build/bin/Release/ which can be executed using the container (see below).

Note the generated binaries may not be compatible with your host system.

Running all benchmarks

Running the existing runall.sh

Note: This does not currently run all simulators or all models which source is included in this repository for.

# docker
sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons ./runall.sh
# apptainer
apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif ./runall.sh

Running individual benchmarks

If you do not wish to run the full benchmark suite in one go, individual executions can be performed / tested by executing individual simulations manually:

Mesa
sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons bash -c "python3 Mesa/Flocking/benchmark.py"
sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons bash -c "python3 Mesa/Schelling/benchmark.py"
apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif bash -c "python3 Mesa/Flocking/benchmark.py"
apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif bash -c "python3 Mesa/Schelling/benchmark.py"
Agents.jl
sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons bash -c "julia --project=@. Agents/benchmark.jl"
apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif bash -c "julia --project=@. Agents/benchmark.jl"
FLAMEGPU2

Once the FLAMEGPU 2 binaries have been compiled as above, they can be executed using the benchmark script, or individual runs by executing the binaries directly:

sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons bash -c "python3 FLAMEGPU2/benchmark.py"
sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons bash -c "./FLAMEGPU2/build/bin/Release/boids2D -s 100 -t"
sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons bash -c "./FLAMEGPU2/build/bin/Release/schelling -s 100 -t"
apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif bash -c "python3 FLAMEGPU2/benchmark.py"
apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif bash -c "./FLAMEGPU2/build/bin/Release/boids2D -s 100 -t"
apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif bash -c "./FLAMEGPU2/build/bin/Release/schelling -s 100 -t"
NetLogo
sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons ./netlogo_flock.sh
sudo docker run --rm --gpus all -v $(pwd):/app -w "/app" abm-framework-comparisons ./netlogo_s.sh
apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif ./netlogo_forest.sh
apptainer exec --nv --bind $(pwd):/app --pwd /app abm-framework-comparisons.sif ./netlogo_s.sh

abm_framework_comparisons's People

Contributors

datseris avatar libbum avatar ptheywood avatar rht avatar

Stargazers

 avatar  avatar  avatar

Forkers

twigglits

abm_framework_comparisons's Issues

Improve Benchmark Reporting

The benchmark reporting offers a mix of minimum repetition times, mean repetition times, with and without seeds depending on the benchmark.

It would be more useful to:

  • record all runtimes during benchmarking to disk, for post processing
  • Post-process benchamrk times to find min, mean, deviation etc.
  • Seed runs for more deterministic benchmarking, though as models initialisation is stochastic and initialisation RNG varies multiple seeds should still be benchmarked

Wofl Sheep Grass

The Wolf Sheep Grass / Predator Prey benchmarks ahve been removed from runall.sh, as they are not present for all implementations.

Forest Fire

Forest Fire is disbaled from run_all.sh, as there is not yet a FLAMEGPU2 implementation.

Julia Packages in container

Benchmarking of agents.jl is currently disabled as getting the pacakges to install within a container not based on a julia base was proving problematic, when installing from project.toml (for use with the pre-existing benchmark script)

Using JULIA_DEPOT_PATH was unsucceessful. It is currently disabled (commented out) in the dockerfile and in the run_all.sh

Netlogo Heap

If models are scaled up to the extent that more than 1024MB of JVM heap are requried, the netlogo_headless.sh distribtued with netlogo is insufficient.

If this occurs, the script does not return, hanging indefinately.

The postprocessing of stdout from this consumes this error message, so from a runall.sh it just looks like it's waiting for netlogo to run.


The explicit setting of -Xmx1024m in /opt/netlogo/netlogo-headless.sh prevents use of JAVA_TOOLS_OPTIONS=-Xmx8192m (or the implicit default of 1/4 system memory) to override this, allowing larger netlogo models.

This could be resolved, when using a container, by mutating this file during netlogo installation, removing the limit, then setting JAVA_TOOLS_OPTIONS to a sane value for the container if required (plus documenting for users)

Mason benchmarking not enabled

The Benchamrking of Mason is not enabled in the container, though the fetching and packaging of mason did work.

This is mostly due to mason benchmarks not being part of run_all.sh upstream, and a prioritisation issue.

Package Compiled Binaries into Container

It would be useful to build a (second?) container which includes compiled binaries / packaged source and an entrypoint for simple, portable (on x86_64 + nvidia) systems.

Then it would be as simple as getting the container onto a given system, and running the entry point.

CUDA_ARCH would ideally want to include all major CUDA architectures, which would bloat build time and filsize however.

Benchmark Scale

The problem sizes in this repository are relatively small compared to what would be required for FLAME GPU to fully utilise a modern high-end GPU, as serial CPU simulators will take a very long time to run at those scales.

Ideally this should benchmark at a number of scales.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.