Files
263-0007-00L-Advanced-Syste…/README.md
T

536 lines
10 KiB
Markdown

# 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 and optimize Helbing's social force model for pedestrian dynamics. The final report includes the implementation details, performance analysis, and results of the work.
This repository contains the C++ simulation code and Python visualization code used to generate and analyze the data.
---
## Requirements
The project uses a `Makefile` to simplify building, running, benchmarking, testing, and visualization.
Make sure `make` is installed:
```bash
make --version
```
You also need a C++ compiler. The Makefile automatically uses `g++` if available, otherwise it falls back to `clang++`.
Check your compiler with:
```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.
All build commands accept a `VARIANT` parameter to select an optimization variant:
```bash
make run-bench VARIANT=v1_cutoff N_P=100 N_ITER=10000
```
The default is `VARIANT=baseline`. Each variant compiles its own binary (`main_baseline`, `main_v1_cutoff`, etc.).
```bash
make bench-suite
```
Compiles once and runs benchmarks across multiple pedestrian counts (default: 50, 100, 200, 500, 1000, 2000, 5000, 10000 with 1000 iterations each). Redirect output to save results:
```bash
make bench-suite > benchmarks/baseline.txt
make bench-suite VARIANT=v1_cutoff > benchmarks/v1_cutoff.txt
```
Both `BENCH_SIZES` and `BENCH_ITER` can be overridden:
```bash
make bench-suite BENCH_SIZES="100 500 1000" BENCH_ITER=500
```
```bash
make test
```
Compiles and runs all unit tests.
```bash
make verify
```
Runs the simulation with the reference parameters and compares the output to `reference/baseline_n60_i4000.csv` using `verify.py`. Useful to check that a variant gives the same result as the baseline:
```bash
make verify VARIANT=v1_cutoff
```
```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
VARIANT=baseline
```
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_baseline (or main_<variant>)
```
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_baseline <number_of_pedestrians> <number_of_iterations> [csv_output_path]
./main_<variant> <number_of_pedestrians> <number_of_iterations> [csv_output_path]
```
Example:
```bash
./main_baseline 60 4000 positions.csv
./main_<variant> 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
To run the simulation and directly generate a video:
```bash
make video
```
This produces an MP4 file, by default:
```text
simulation.mp4
```
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.
---
## Optimization Variants
The project supports multiple optimization variants through the `VARIANT` Makefile parameter. Each variant provides its own implementation of the force computations and simulation loop while sharing the same interface, benchmark harness, and test suite.
The default variant is `baseline`:
```bash
make run-bench # uses baseline
make run-bench VARIANT=baseline # equivalent
make run-bench VARIANT=v1_cutoff # uses a different variant
```
### File naming convention
Each variant consists of a single file in the project root:
```bash
variant_<name>.cpp # force computations and simulation loop
```
The file must implement the interfaces defined in `forces.hpp` and `social_force.hpp`. The baseline implementation is `variant_baseline.cpp`.
### Creating a new variant
1. Copy the baseline file:
```text
cp variant_baseline.cpp variant_v1_cutoff.cpp
```
2. Edit the new file with your optimization.
3. Build and test:
```bash
make test VARIANT=v1_cutoff
make run-bench VARIANT=v1_cutoff N_P=100 N_ITER=10000
```
### Verifying correctness
A reference CSV is stored in `reference/baseline_n60_i4000.csv`. To check that a variant produces the same simulation output, run:
```bash
make verify VARIANT=v1_cutoff
```
If the variant changes numerical results (e.g., distance cutoff skipping negligible forces), use a tolerance-based comparison (use the python script with a third argument (tolerance)) instead of exact diff and justify the deviation.
---
## 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 for the currently selected VARIANT:
```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
```