PyParticles3
PyParticles3 is an independent modernization and continuation of Simone Riva's original PyParticles project.
The goal is to preserve the original project's unusually clear, educational architecture while updating it for modern Python, NumPy, SciPy, PyOpenGL and PyOpenCL environments. PyParticles3 is also a practical study project for GPU particle simulation, OpenCL acceleration and OpenCL/OpenGL interoperability.
PyParticles3 is not presented as an official release endorsed by Simone Riva. Original copyright notices and the GPL-3.0-or-later license are preserved.
Highlights
- simple
ParticlesSet -> Force -> Solver -> Animation/Rendererarchitecture; - Euler, Leapfrog, Runge-Kutta, Midpoint and Stormer-Verlet style integrators;
- gravity, springs, constant force, drag, damping, Lennard-Jones, electrostatic and electromagnetic models;
- constrained particles and constrained force interactions;
- OpenGL interactive visualization;
- optional PyOpenCL acceleration;
- persistent OpenCL buffers to avoid unnecessary PCIe transfers;
- fused OpenCL integration paths;
- OpenCL/OpenGL shared VBO rendering;
- double-buffered CL/GL synchronization with GL fences;
- asynchronous OpenGL GPU timer queries;
- an optimized
fountainexample used as a GPU performance case study.
Installation
The stable release line is PyParticles3 0.4.0. The Python import namespace remains pyparticles.
PyParticles3 requires Python 3.11 or newer.
1. Standard installation
Install PyParticles3 from PyPI:
python -m pip install --upgrade pip
python -m pip install 'PyParticles3==0.4.0'
Verify the installation:
pyparticles3 --version
python -m pyparticles --version
Both commands should report:
0.4.0
The historical console command remains available for compatibility:
pyparticles_app --version
2. Installation with OpenCL compute support
Install the optional OpenCL dependency set with:
python -m pip install 'PyParticles3[opencl]==0.4.0'
This installs PyOpenCL, but it does not install a system OpenCL driver/ICD. A working NVIDIA, Intel, AMD, PoCL or other OpenCL runtime must already be installed on the operating system.
List the OpenCL platforms and devices visible to PyOpenCL:
python - <<'PY'
import pyopencl as cl
for pi, platform in enumerate(cl.get_platforms()):
print(f"Platform {pi}: {platform.name}")
for di, device in enumerate(platform.get_devices()):
print(f" Device {di}: {device.name}")
PY
PyParticles3 follows PyOpenCL's PYOPENCL_CTX selector. For example:
PYOPENCL_CTX=0:0 pyparticles3 --demo fountain
PYOPENCL_CTX=1:0 pyparticles3 --demo fountain
An explicitly selected compute device is never silently replaced by a different OpenCL device merely to obtain OpenCL/OpenGL sharing.
3. Check whether PyOpenCL has OpenGL interoperability
The PyPI PyOpenCL wheel can provide fully working OpenCL compute while still being built without OpenGL interoperability. Check the installed build explicitly:
python - <<'PY'
import pyopencl as cl
print("PyOpenCL :", cl.VERSION_TEXT)
print("Module :", cl.__file__)
print("have_gl :", cl.have_gl())
PY
For ordinary OpenCL compute, either value of have_gl() is acceptable.
For the high-performance OpenCL/OpenGL shared-buffer path used by the fountain demo, PyOpenCL itself must report:
have_gl : True
If it reports:
have_gl : False
OpenCL compute still works, but PyParticles3 cannot create PyOpenCL GLBuffer objects. Rendering then uses host synchronization and can be dramatically slower for large particle counts.
4. Build PyOpenCL from source with have_gl=True
PyOpenCL's source-build documentation requires the build option PYOPENCL_ENABLE_GL=ON to enable OpenGL interoperability.
Debian 12 / Debian-family build prerequisites
A typical Debian installation can provide the native build dependencies with:
sudo apt update
sudo apt install \
build-essential \
python3-dev \
cmake \
ninja-build \
pkg-config \
ocl-icd-opencl-dev \
libgl-dev \
freeglut3-dev
ocl-icd-opencl-dev supplies the OpenCL development headers and loader needed to compile against the system OpenCL installation. Your actual OpenCL implementation/ICD, such as the NVIDIA or Intel runtime, remains a separate system component.
If Python comes from pyenv or another custom Python installation, make sure that installation includes its matching Python headers; the system python3-dev package applies to Debian's system Python.
Rebuild PyOpenCL
Inside the same virtual environment in which PyParticles3 is installed:
python -m pip uninstall -y pyopencl
PYOPENCL_ENABLE_GL=ON \
python -m pip install \
--no-binary=pyopencl \
--no-cache-dir \
-v \
'pyopencl==2026.1.4'
--no-binary=pyopencl is important: it forces a source build instead of reinstalling the precompiled wheel.
The 0.4.0 release line was qualified with PyOpenCL 2026.1.4. Newer compatible PyOpenCL releases can also be built from source, but should be tested before being used as a release-validation baseline.
Verify the resulting build
Do not assume that a successful compilation enabled GL support. Require it explicitly:
python - <<'PY'
import pyopencl as cl
print("PyOpenCL :", cl.VERSION_TEXT)
print("Module :", cl.__file__)
print("have_gl :", cl.have_gl())
assert cl.have_gl(), "PyOpenCL was built without OpenGL interoperability"
PY
The final line must be:
have_gl : True
Verify the PyParticles3 CL/GL path
Select an OpenCL GPU that can share the active OpenGL context and run:
PYOPENCL_CTX=0:0 pyparticles3 --demo fountain
A successful shared-buffer path reports messages similar to:
OpenCL/OpenGL interop enabled: positions render without host copies
CL/GL sync: double-buffered VBOs with per-buffer GL fences
CL/GL position path: X -> VBO device copy (stable)
Interop device: NVIDIA GeForce ...
pyopencl.have_gl() == True means that the PyOpenCL build contains GL interoperability support. It does not guarantee that every OpenCL device can share the current OpenGL context. The selected device must also support cl_khr_gl_sharing and be compatible with the active GL context.
For example, on a mixed NVIDIA-GPU/Intel-CPU system, an Intel CPU OpenCL device may run all simulation kernels correctly but not advertise cl_khr_gl_sharing. PyParticles3 then keeps the Intel device selected and explicitly falls back to host-synchronized rendering instead of moving the computation to NVIDIA.
5. System OpenGL requirements
Interactive rendering requires a working OpenGL implementation and FreeGLUT. These are operating-system dependencies and are not installed by pip.
On Debian-family systems, the development packages used above include the common OpenGL/FreeGLUT headers. The graphics driver must still provide a working OpenGL runtime.
6. Install from the Git repository
For development or testing the current repository state:
git clone https://github.com/jamaj69/pyparticles.git
cd pyparticles
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e '.[dev]'
For development with OpenCL support:
python -m pip install -e '.[dev,opencl]'
If CL/GL interoperability is required, rebuild PyOpenCL with PYOPENCL_ENABLE_GL=ON after installing the editable package, using the procedure above.
Current import namespace
The PyParticles3 0.4.x release line intentionally keeps the historical Python import namespace:
import pyparticles
This avoids mixing a package-wide namespace migration with the first modernized stable release. A future release may introduce a dedicated pyparticles3 namespace after a controlled compatibility migration.
Command line
The modern package exposes:
pyparticles3 --help
pyparticles3 --version
The historical command is also kept as a compatibility entry point:
pyparticles_app --help
Examples:
pyparticles3 --demo springs
pyparticles3 --demo solar_system
pyparticles3 --demo bubble
pyparticles3 --demo gas_lj
pyparticles3 --demo elmag_field
pyparticles3 --demo galaxy
pyparticles3 --demo fountain
Architecture
ParticlesSet
|
+--> Force / MultipleForce
| |
| v
+----> ODE Solver
|
v
Animation
|
v
Renderer
The accelerated paths preserve these conceptual roles rather than replacing the whole program with an opaque GPU pipeline.
OpenCL/OpenGL fountain path
The modern fountain demo can keep simulation state resident on the GPU and render from shared OpenGL buffers.
The stable default shared path copies positions from the canonical OpenCL position buffer into a shared OpenGL VBO entirely on the device. The code also contains an optional experimental fused render-mirror path that can write the shared render VBO directly from the integration kernel.
Profiling can be enabled with:
PYPARTICLES_PROFILE_CLGL=1 \
PYPARTICLES_PROFILE_FRAMES=1000 \
PYPARTICLES_PROFILE_WARMUP=200 \
pyparticles3 --demo fountain
The experimental fused render mirror is selected with:
PYPARTICLES_CLGL_FUSED_MIRROR=1 \
pyparticles3 --demo fountain
The final 0.4.0 release is based on the validated 0.4.0rc2 code path. The release-candidate baseline on a GeForce GTX 1060 6 GB with 2,000,000 fountain particles produced roughly 278-296 FPS, with the fused physics kernel around 0.760 ms and the device-side X-to-VBO copy around 0.324 ms. Treat these numbers as a hardware-specific regression baseline, not as a general performance guarantee.
Development
git clone https://github.com/jamaj69/pyparticles.git
cd pyparticles
python -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
python -m pip install -e '.[dev]'
python -m compileall -q pyparticles tests
python -W default -m unittest discover -v -s tests
Build the PyPI artifacts with:
python -m pip install -U build twine
rm -rf build dist *.egg-info
python -m build
python -m twine check dist/*
Project links
- Source: https://github.com/jamaj69/pyparticles
- Issues: https://github.com/jamaj69/pyparticles/issues
- Original project: https://github.com/simon-r/PyParticles
- PyOpenCL installation/build documentation: https://documen.tician.de/pyopencl/misc.html
When releases are published through PyPI Trusted Publishing from this GitHub repository, PyPI can verify the GitHub project links carried in the distribution metadata.
Origin and attribution
PyParticles was created by Simone Riva in 2012. PyParticles3 is an independent modernization built from that GPL-licensed codebase. The modernization focuses on Python 3 compatibility, modern scientific Python libraries, testing, GPU acceleration, CL/GL interoperability and documentation while preserving the original educational structure.
License
GPL-3.0-or-later. See LICENSE-gpl-3.0.txt.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyparticles3-0.4.0.tar.gz.
File metadata
- Download URL: pyparticles3-0.4.0.tar.gz
- Upload date:
- Size: 717.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0746d6ce942019719feb85898f901dd8e57b8401b94d464f4d6551037cc626d
|
|
| MD5 |
fd2880ae3cca7a41501e397a707ece83
|
|
| BLAKE2b-256 |
7361668b7a6a82aa7943f4931a146c6867a1e6d7d3f2aa04f653d58f8f11366d
|
Provenance
The following attestation bundles were made for pyparticles3-0.4.0.tar.gz:
Publisher:
release.yml on jamaj69/pyparticles
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyparticles3-0.4.0.tar.gz -
Subject digest:
d0746d6ce942019719feb85898f901dd8e57b8401b94d464f4d6551037cc626d - Sigstore transparency entry: 2681968022
- Sigstore integration time:
-
Permalink:
jamaj69/pyparticles@77fc80c8cf2d4b445ed9e9cc9b4b20f1dad8ff3f -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/jamaj69
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@77fc80c8cf2d4b445ed9e9cc9b4b20f1dad8ff3f -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyparticles3-0.4.0-py3-none-any.whl.
File metadata
- Download URL: pyparticles3-0.4.0-py3-none-any.whl
- Upload date:
- Size: 167.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea964d0fc482b495d0f680cc7ebbb550121d47653dccd93d3d4badd87e21171f
|
|
| MD5 |
35507f6c7613c2877e7ffdce1d79d686
|
|
| BLAKE2b-256 |
c619ff8d1a5f8071069f578aaa1dafa80ebf0beb68efa687ff194fc69c8a0ea5
|
Provenance
The following attestation bundles were made for pyparticles3-0.4.0-py3-none-any.whl:
Publisher:
release.yml on jamaj69/pyparticles
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyparticles3-0.4.0-py3-none-any.whl -
Subject digest:
ea964d0fc482b495d0f680cc7ebbb550121d47653dccd93d3d4badd87e21171f - Sigstore transparency entry: 2681968051
- Sigstore integration time:
-
Permalink:
jamaj69/pyparticles@77fc80c8cf2d4b445ed9e9cc9b4b20f1dad8ff3f -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/jamaj69
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@77fc80c8cf2d4b445ed9e9cc9b4b20f1dad8ff3f -
Trigger Event:
push
-
Statement type: