A 2D molecular dynamics simulator built to explore GPU acceleration of scientific workloads. Implements pairwise force models and Velocity-Verlet integration, then benchmarks a serial CPU implementation against a CUDA-accelerated GPU version — achieving up to 568× speedup at 1,024 particles.
- CUDA acceleration via Numba
@cuda.jitkernels - Soft-repulsion and Lennard-Jones interparticle potentials
- NVT thermostat control
- Velocity-Verlet time integration
- Quantified CPU vs. GPU performance benchmarking on real hardware
- Modular Python codebase designed for experimentation and extension
Benchmarks were performed on an NVIDIA Tesla T4 GPU (Google Colab). Timings include kernel execution and host-to-device memory transfers.
| Particles | Speedup (GPU vs. CPU) |
|---|---|
| 256 | 66× |
| 1,024 | 568× |
These results illustrate how scientific workloads dominated by pairwise interactions — an O(N²) problem — scale exceptionally well under GPU parallelism.
Pairwise force evaluation is the computational bottleneck in molecular dynamics. For N particles, every particle interacts with every other, producing an O(N²) workload that grows rapidly with system size.
This project investigates how GPU parallelism can accelerate that bottleneck by assigning one CUDA thread per particle and computing all forces concurrently, then comparing execution times against a serial CPU reference.
The goal is not to compete with production MD packages such as GROMACS, NAMD, or LAMMPS — it's to demonstrate the principles of GPU acceleration, numerical simulation, and quantitative performance analysis in a clear, reproducible setting.
Particles interact through a finite-range harmonic repulsion:
This potential is numerically stable at relatively large timesteps and avoids the singularities present in harder potentials, making it well-suited for demonstrating GPU acceleration.
The simulator optionally supports the Lennard-Jones interaction:
which models short-range repulsion and long-range attraction commonly used in molecular simulation.
Particle trajectories are advanced using the Velocity-Verlet scheme:
Velocity-Verlet is time-reversible, symplectic, and the standard integrator in molecular dynamics.
The GPU kernel assigns one CUDA thread to each particle. Each thread independently accumulates the net force from all other particles, enabling thousands of force calculations to run concurrently:
@cuda.jit
def _soft_forces_kernel(...):
i = cuda.grid(1)
if i < n_particles:
for j in range(n_particles):
# compute pairwise force contribution
...This maps naturally onto the O(N²) structure of the problem and is the source of the large speedups observed at higher particle counts.
.github/workflows/
└── ci.yml # CI pipeline
md_sim/
├── __init__.py
├── benchmark.py # CPU vs. GPU timing harness
├── cpu_forces.py # Serial CPU force evaluation
├── gpu_forces.py # CUDA kernel force evaluation
├── integrator.py # Velocity-Verlet integrator
├── simulation.py # Simulation loop and NVT thermostat
└── utils.py # Shared utilities
tests/
├── __init__.py
└── test_md_sim.py # Test suite
.gitignore
Dockerfile
LICENSE
README.md
pyproject.toml
run_example.py
pip install numpy numbaGPU execution requires the NVIDIA CUDA Toolkit and a CUDA-capable GPU.
python run_example.pypython run_example.py --gpupython run_example.py --benchmarkThis project is an educational and performance-exploration tool, not a production MD engine. Current limitations include:
- O(N²) all-pairs force evaluation (no neighbor lists or cell lists)
- Two-dimensional simulation domain
- Single-GPU execution only
- No distributed-memory parallelism
- Verlet neighbor lists and cell-based spatial partitioning
- CUDA shared-memory tiling to reduce global memory traffic
- Multi-GPU execution
- Three-dimensional simulation domain
- Nsight profiling and kernel-level optimization
- Comparison against vectorized NumPy and compiled CPU baselines (e.g. Cython, Numba CPU)
Python · NumPy · Numba CUDA · NVIDIA CUDA · NVIDIA Tesla T4 · Google Colab
MIT