Add unit tests, refactor simulation code, improve Makefile, and add documentation
This commit is contained in:
@@ -1,44 +1,456 @@
|
||||
# Advanced Systems Lab - Spring 2026
|
||||
This is the GitLab repository of group 70.
|
||||
Project topic: Social Force Model for Pedestrian Dynamics
|
||||
|
||||
The goal of this project was to implement a fast version of Helbing's social force model. The final report includes an analysis and results of the work.
|
||||
This is the GitLab repository of **Group 70**.
|
||||
|
||||
This repository contains all C++ and Python code that was used to generate and analyze the data.
|
||||
**Project topic:** Social Force Model for Pedestrian Dynamics
|
||||
|
||||
The goal of this project was to implement and optimize Helbing's social force model for pedestrian dynamics. The final report includes the implementation details, performance analysis, and results of the work.
|
||||
|
||||
## Compilation
|
||||
Linux
|
||||
This repository contains the C++ simulation code and Python visualization code used to generate and analyze the data.
|
||||
|
||||
``
|
||||
---
|
||||
|
||||
Windows
|
||||
## Requirements
|
||||
|
||||
``
|
||||
The project uses a `Makefile` to simplify building, running, benchmarking, testing, and visualization.
|
||||
|
||||
Apple
|
||||
Make sure `make` is installed:
|
||||
|
||||
`clang++ -O3 -march=native -o main_test_visualisation main.cpp forces.cpp`
|
||||
```bash
|
||||
make --version
|
||||
```
|
||||
|
||||
Compile the code with running the bash script 'src/main/run_simulation.sh'. After compilation was succesfull the user has 3 different option:
|
||||
1. Benchmark
|
||||
2. Test
|
||||
3. Visualization
|
||||
You also need a C++ compiler. The Makefile automatically uses `g++` if available, otherwise it falls back to `clang++`.
|
||||
|
||||
The flags used are:
|
||||
`gcc -lm -O3 -mavx2 -mfma -ffast-math -g`
|
||||
Check your compiler with:
|
||||
|
||||
## Storing coordinates in a csv
|
||||
`./main_test_visualisation <number of pedestrians> <number of iterations> <csv file>`
|
||||
```bash
|
||||
g++ --version
|
||||
clang++ --version
|
||||
```
|
||||
|
||||
The visualization script requires Python and the following packages:
|
||||
|
||||
```bash
|
||||
python3 -m pip install numpy pandas matplotlib
|
||||
```
|
||||
|
||||
To generate MP4 videos, `ffmpeg` must also be installed.
|
||||
|
||||
On Ubuntu/Debian:
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install make g++ clang python3 python3-pip ffmpeg libgtest-dev
|
||||
python3 -m pip install numpy pandas matplotlib
|
||||
```
|
||||
|
||||
On macOS:
|
||||
|
||||
```bash
|
||||
xcode-select --install
|
||||
brew install ffmpeg googletest
|
||||
python3 -m pip install numpy pandas matplotlib
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Makefile commands
|
||||
|
||||
The main commands are:
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
|
||||
Runs the simulation and writes pedestrian states to a CSV file.
|
||||
|
||||
```bash
|
||||
make video
|
||||
```
|
||||
|
||||
Runs the simulation and generates a visualization video.
|
||||
|
||||
```bash
|
||||
make run-bench
|
||||
```
|
||||
|
||||
Compiles and runs benchmark measurements.
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
Compiles and runs all unit tests.
|
||||
|
||||
```bash
|
||||
make asm
|
||||
```
|
||||
|
||||
Generates assembly files.
|
||||
|
||||
```bash
|
||||
make sizes
|
||||
```
|
||||
|
||||
Compiles the helper executable used to inspect data-structure sizes.
|
||||
|
||||
```bash
|
||||
make clean
|
||||
```
|
||||
|
||||
Deletes generated build files.
|
||||
|
||||
```bash
|
||||
make clean-all
|
||||
```
|
||||
|
||||
Deletes generated build files and all `.csv` / `.mp4` outputs in the current directory.
|
||||
|
||||
**Warning:** `make clean-all` removes all CSV and MP4 files in the directory. Move any output files you want to keep before running it.
|
||||
|
||||
---
|
||||
|
||||
## Default parameters
|
||||
|
||||
The default simulation parameters are:
|
||||
|
||||
```text
|
||||
N_P=60
|
||||
N_ITER=4000
|
||||
CSV=positions.csv
|
||||
MP4=simulation.mp4
|
||||
RANDOM_SEED=0
|
||||
```
|
||||
|
||||
They can be overridden from the shell. Parameters can be provided selectively and in any order.
|
||||
|
||||
Run the simulation with custom parameters:
|
||||
|
||||
```bash
|
||||
make run N_P=100 N_ITER=5000 CSV=my_positions.csv
|
||||
```
|
||||
|
||||
Generate a video with custom output names:
|
||||
|
||||
```bash
|
||||
make video N_P=100 N_ITER=5000 CSV=my_positions.csv MP4=my_simulation.mp4
|
||||
```
|
||||
|
||||
Run benchmark measurements with custom parameters:
|
||||
|
||||
```bash
|
||||
make run-bench N_P=100 N_ITER=5000
|
||||
```
|
||||
|
||||
Use non-reproducible random initialization:
|
||||
|
||||
```bash
|
||||
make run RANDOM_SEED=1
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```bash
|
||||
make video RANDOM_SEED=1
|
||||
```
|
||||
|
||||
By default, `RANDOM_SEED=0` uses a fixed seed for reproducible simulations and benchmarks.
|
||||
|
||||
---
|
||||
|
||||
## Building
|
||||
|
||||
To compile the main executable:
|
||||
|
||||
```bash
|
||||
make main
|
||||
```
|
||||
|
||||
This produces the executable:
|
||||
|
||||
```text
|
||||
main
|
||||
```
|
||||
|
||||
The Makefile uses the following compiler flags:
|
||||
|
||||
```text
|
||||
-O3 -march=native -std=c++23 -Wall -Wextra -flto
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
- `-O3` enables high-level optimization.
|
||||
- `-march=native` optimizes for the current machine.
|
||||
- `-std=c++23` uses the C++23 standard.
|
||||
- `-Wall -Wextra` enables useful compiler warnings.
|
||||
- `-flto` enables link-time optimization across `.cpp` files, allowing cross-file optimizations such as function inlining.
|
||||
|
||||
---
|
||||
|
||||
## Running the simulation
|
||||
|
||||
The recommended way to run the simulation is:
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
|
||||
This compiles the code and runs the simulation with the default parameters. It produces a CSV file containing pedestrian states at each saved time step.
|
||||
|
||||
You can also run the executable manually after compiling:
|
||||
|
||||
```bash
|
||||
./main <number_of_pedestrians> <number_of_iterations> [csv_output_path]
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
./main 60 4000 positions.csv
|
||||
```
|
||||
|
||||
The third argument is optional. If it is provided, simulation states are written to the given CSV file.
|
||||
|
||||
---
|
||||
|
||||
## CSV output
|
||||
|
||||
The CSV file contains the pedestrian states used for visualization.
|
||||
|
||||
The output columns are:
|
||||
|
||||
```text
|
||||
time,id,x,y,p.e.x,p.e.y,color
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
- `time` is the simulation time step.
|
||||
- `id` is the pedestrian index.
|
||||
- `x`, `y` are the pedestrian position coordinates.
|
||||
- `p.e.x`, `p.e.y` are the components of the desired direction.
|
||||
- `color` indicates the pedestrian group / walking direction.
|
||||
|
||||
---
|
||||
|
||||
## Visualization
|
||||
`python3 visualization.py <csv file> <mp4 file>`
|
||||
|
||||
To run the simulation and directly generate a video:
|
||||
|
||||
## Benchmark
|
||||
```bash
|
||||
make video
|
||||
```
|
||||
|
||||
This produces an MP4 file, by default:
|
||||
|
||||
```text
|
||||
simulation.mp4
|
||||
```
|
||||
|
||||
## Test
|
||||
To visualize an existing CSV file manually:
|
||||
|
||||
```bash
|
||||
python3 visualization.py <csv_file> <mp4_file>
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
python3 visualization.py positions.csv simulation.mp4
|
||||
```
|
||||
|
||||
The generated video shows the pedestrian dynamics produced by the social force simulation.
|
||||
|
||||
---
|
||||
|
||||
## Benchmarking
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
make run-bench
|
||||
```
|
||||
|
||||
This compiles the executable with benchmarking enabled and measures the simulation performance.
|
||||
|
||||
On ARM/AArch64 machines, the Makefile automatically prepends `sudo` for benchmark compilation and execution because access to PMU performance counters may require elevated privileges.
|
||||
|
||||
For reproducible benchmark results, keep:
|
||||
|
||||
```text
|
||||
RANDOM_SEED=0
|
||||
```
|
||||
|
||||
which is the default.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
make run-bench N_P=100 N_ITER=5000
|
||||
```
|
||||
|
||||
The benchmark output includes estimated work, operational intensity, measured cycles, and estimated performance in flops per cycle.
|
||||
|
||||
---
|
||||
|
||||
## Tests
|
||||
|
||||
Run all unit tests with:
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
The tests use GoogleTest, so `libgtest-dev` or an equivalent GoogleTest installation must be available.
|
||||
|
||||
The test target compiles and runs the unit tests for the simulation components.
|
||||
|
||||
---
|
||||
|
||||
## Assembly generation
|
||||
|
||||
To generate assembly files:
|
||||
|
||||
```bash
|
||||
make asm
|
||||
```
|
||||
|
||||
This generates assembly output for the main source files, such as:
|
||||
|
||||
```text
|
||||
main.s
|
||||
forces.s
|
||||
social_force_baseline.s
|
||||
```
|
||||
|
||||
This can be useful for inspecting compiler optimizations and generated instructions.
|
||||
|
||||
---
|
||||
|
||||
## Structure-size helper
|
||||
|
||||
To compile the helper executable used to inspect data-structure sizes:
|
||||
|
||||
```bash
|
||||
make sizes
|
||||
```
|
||||
|
||||
This produces:
|
||||
|
||||
```text
|
||||
sizes
|
||||
```
|
||||
|
||||
Run it with:
|
||||
|
||||
```bash
|
||||
./sizes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cleaning generated files
|
||||
|
||||
Remove generated build files:
|
||||
|
||||
```bash
|
||||
make clean
|
||||
```
|
||||
|
||||
This deletes files such as:
|
||||
|
||||
```text
|
||||
main
|
||||
sizes
|
||||
run_tests
|
||||
*.o
|
||||
*.s
|
||||
```
|
||||
|
||||
Remove build files and generated CSV/MP4 outputs:
|
||||
|
||||
```bash
|
||||
make clean-all
|
||||
```
|
||||
|
||||
This deletes:
|
||||
|
||||
```text
|
||||
main
|
||||
sizes
|
||||
run_tests
|
||||
*.o
|
||||
*.s
|
||||
*.csv
|
||||
*.mp4
|
||||
```
|
||||
|
||||
**Warning:** `make clean-all` deletes all `.csv` and `.mp4` files in the current directory. Move any files you want to keep before running it.
|
||||
|
||||
---
|
||||
|
||||
## Notes on reproducibility
|
||||
|
||||
By default, the simulation uses a fixed random seed:
|
||||
|
||||
```text
|
||||
SEED=42
|
||||
```
|
||||
|
||||
This makes simulation runs reproducible.
|
||||
|
||||
To use non-reproducible initialization, run:
|
||||
|
||||
```bash
|
||||
make run RANDOM_SEED=1
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```bash
|
||||
make video RANDOM_SEED=1
|
||||
```
|
||||
|
||||
For benchmarking, reproducible initialization is recommended, so the default `RANDOM_SEED=0` should normally be kept.
|
||||
|
||||
---
|
||||
|
||||
## Example workflow
|
||||
|
||||
Compile and run the simulation:
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
|
||||
Generate a video:
|
||||
|
||||
```bash
|
||||
make video
|
||||
```
|
||||
|
||||
Run tests:
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
Run benchmark measurements:
|
||||
|
||||
```bash
|
||||
make run-bench
|
||||
```
|
||||
|
||||
Clean generated build files:
|
||||
|
||||
```bash
|
||||
make clean
|
||||
```
|
||||
|
||||
Clean everything generated, including CSV and MP4 outputs:
|
||||
|
||||
```bash
|
||||
make clean-all
|
||||
```
|
||||
Reference in New Issue
Block a user