NeuroCUDA Docker Guide
NeuroCUDA Docker on GitHub is the ROS2 Jazzy plus Gazebo image, not a tiny compiler-only container. Clone github.com/Krishnav1/neurocuda, then docker build -t neurocuda-ros2 . and docker compose up. Foxglove is ws://localhost:8765. For CI conversion tests, use python:3.11 and pip install neurocuda instead of the ~26GB ROS image.
Reproducible containers for labs and CI: what the public Dockerfile actually is, how to start Foxglove, and a slim pip pattern that does not pretend to be an official compiler-only image.
TL;DR
The public NeuroCUDA Docker file in github.com/Krishnav1/neurocuda is a ROS2 Jazzy + Gazebo Harmonic + foxglove-bridge environment. Build with docker build -t neurocuda-ros2 .. Start with docker compose up. Dashboard: ws://localhost:8765. README badge: 26GB. Do not advertise a tiny official compiler image. For conversion CI, FROM python:3.11 then pip install neurocuda. Architecture: /neurocuda-ros2. Notebook: Colab. Paper: paper.pdf.
This page vs nearby URLs: this URL is NeuroCUDA Docker for labs and CI. /neurocuda-ros2 is robot architecture (nodes, topics, launch). /blog/neurocuda-google-colab is an ephemeral notebook. pip install guide is a local venv. cite NeuroCUDA is BibTeX and labels. Google should index this page for the container query, not as a clone of the ROS2 product page.
Teams search neurocuda docker when a lab machine must look like another lab machine, or when a GitHub Actions runner must convert a checkpoint without "works on my CUDA driver." They are not asking what a spiking ROS2 node publishes. They are asking which file to build, how large it is, and whether they can avoid pulling a robotics desktop into a five-minute unit-test job. Answering "just use Colab" is the wrong job. Answering "there is a tiny official compiler image" is the wrong fact. The published Dockerfile installs ROS2 Jazzy and Gazebo. This guide starts from that fact and then shows a slim CI pattern you write yourself.
NeuroCUDA is the MIT compiler: pip install neurocuda, then snn, meta = neurocuda.convert(model, calib_loader). Source: https://github.com/Krishnav1/neurocuda. Author: Krishna Santosh Varma. Containers do not change backend honesty. GPU numbers stay multi-seed full-test software results. SpiNNaker-1 stays a 2-neuron physical smoke test (EBRAINS jobs #420148 and #420186), not ResNet-on-chip. Loihi 2 stays an IF-neuron simulator. FPGA HLS stays a PoC, not a bitstream. Akida stays not claimed physical. Cite those labels from cite NeuroCUDA. This page only packages the software.
What the public NeuroCUDA Docker file actually is
Open the repository root. The file named Dockerfile (not a hypothetical Dockerfile.compiler) is commented as a complete ROS2 environment. The build line in that file is the one this page repeats:
git clone https://github.com/Krishnav1/neurocuda.git cd neurocuda docker build -t neurocuda-ros2 .
That image is Ubuntu 24.04 plus:
- ROS2 Jazzy (
ros-jazzy-ros-base,ros-jazzy-ros-gz-bridge,ros-jazzy-foxglove-bridge,rosbag2, colcon) - Gazebo Harmonic (
gz-harmonicand related libraries) - PyTorch / torchvision, numpy, snntorch
pip install neurocudawith a git fallback if the wheel is missing at build time- Mesa / EGL packages so Gazebo can render offscreen
The same directory also ships Dockerfile.ros2 (FROM nvidia/cuda:12.9.2-devel-ubuntu24.04, GPU-oriented) and Dockerfile.gazebo (FROM neurocuda:ros2, TurtleBot4 plus headless Gazebo). Those are variants. The command docker build -t neurocuda-ros2 . uses the root file. If your lab needs CUDA inside the container, build -f Dockerfile.ros2 and plan for NVIDIA Container Toolkit. If your lab needs TurtleBot4 bringup, build -f Dockerfile.gazebo after the ROS2 CUDA image exists. Do not collapse the three files into one imaginary "official slim NeuroCUDA Docker" artifact.
Size honesty: the GitHub README Docker badge currently reads 26GB. The root Dockerfile comment estimates about 8GB disk and about 15 minutes to build. Those two numbers can both be true in different accounting (layers versus pulled cache versus a CUDA devel base). The operational conclusion does not depend on which meter you trust: this is a robotics stack. It is not a 300MB compiler wheel. Do not put "tiny official image" on a slide.
Build and run the published image
After docker build -t neurocuda-ros2 ., the compose file is the lab path. Comments in docker-compose.yml say:
docker compose up -d docker compose exec ros2 bash docker compose down # Foxglove dashboard: ws://localhost:8765
The published compose service name is ros2, image neurocuda-ros2:latest, container name neurocuda_ros2, host port 8765. A README snippet may say docker compose exec neurocuda bash. If those strings disagree in your clone, trust the compose file in that commit. Exec into whatever service name the YAML defines.
docker compose up -d docker compose exec ros2 bash # inside the container, after colcon (compose already builds packages): source /opt/ros/jazzy/setup.bash source /neurocuda_ws/install/setup.bash ros2 topic list
Compose mounts ./neurocuda_msgs and ./neurocuda_ros2 into the workspace and keeps named volumes for bags and reports. That is the point of a lab container: bags survive docker compose down if they live on those volumes. Environment variables force offscreen rendering (QT_QPA_PLATFORM=offscreen, EGL_PLATFORM=surfaceless, LIBGL_ALWAYS_SOFTWARE=1) so a headless workstation does not need a local display for Gazebo. Foxglove still needs the published websocket. Connect a Foxglove Studio session to ws://localhost:8765.
Robot commands after the image is up belong on NeuroCUDA ROS2 and the robotics posts (ROS2 robot deployment, ROS2 SNN guide, event camera DVS). This page stops at "the container is running and Foxglove accepts a socket." If you need Humble versus Jazzy, that is ROS2 Jazzy vs Humble, not a second Docker tutorial.
Foxglove, ports, and what "up" means
ros-jazzy-foxglove-bridge is installed in the root Dockerfile. Compose publishes 8765:8765. The documented dashboard URL is:
ws://localhost:8765
If the socket refuses connections, check four things before rebuilding the 26GB stack: the compose process is still running, nothing else bound 8765 on the host, the bridge node is actually launched (compose's default command builds packages and tails /dev/null, so you may still need to start the bridge or a launch file), and you are connecting with the websocket scheme, not http://. "Compose is up" means the container is alive. It does not always mean every ROS2 node you care about is alive. Read the launch file you intended to run.
Optional Hub pull, documented on the ROS2 product page, is a different artifact:
docker pull kvarma/neurocuda-ros2:latest docker run --gpus all kvarma/neurocuda-ros2:latest
Building from the GitHub Dockerfile and pulling a Hub tag are reproducible only if you pin a digest and record which git SHA produced that digest. A floating :latest is convenient for a demo robot. It is a poor CI pin. Labs that must neurocuda docker the same way for a year should pin image: neurocuda-ros2@sha256:... in compose or retag after build.
NeuroCUDA Docker versus ROS2 architecture versus Colab
Three URLs, three jobs. Mixing them is how a student waits an hour for Gazebo layers when they only needed convert() in a notebook.
| URL | Job | Lifetime | Typical size / cost |
|---|---|---|---|
| This page: NeuroCUDA Docker | Build/run/pin a container for labs and CI | Image layers persist on disk | Large ROS2+Gazebo image (README 26GB badge) |
| /neurocuda-ros2 | Nodes, topics, launch, camera to spikes | Process lifetime on a robot or sim | Does not tell you how to build Docker |
| Colab guide | Browser GPU, one-cell pip | Ephemeral VM; pip vanishes on restart | No local 26GB pull; session disconnects |
| pip install guide | Local venv and CUDA wheels | Until you delete the venv | Wheel-sized, not robotics-sized |
| Slim CI pattern below | Conversion tests on PRs | CI cache | python:3.11 + pip, not Gazebo |
Colab is the right answer when there is no Docker daemon and no lab GPU. It is the wrong answer when you need Foxglove, rosbag2, or a runner that is not a browser tab. Docker is the right answer when two workstations must share the same ROS distro. It is the wrong answer when a linter job only imports neurocuda. Architecture is the right answer when you need /snn/detections. It is the wrong answer when you need the difference between Dockerfile and Dockerfile.ros2.
Slim CI pattern: python:3.11 plus pip install neurocuda
This section is a pattern, not a claim that QuantaraCore publishes a tiny official compiler-only image. The official public Dockerfile remains the ROS2 Jazzy environment. For pull-request conversion tests you should still write a small image that only does what CI needs: install the wheel, import the package, run convert() on a fixture, maybe compile target="cpu".
# ci/Dockerfile.convert (lab-maintained, not the GitHub root Dockerfile)
FROM python:3.11-slim-bookworm
RUN apt-get update && apt-get install -y --no-install-recommends \
git build-essential \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir neurocuda
WORKDIR /src
COPY tests /src/tests
CMD ["python", "-m", "pytest", "-q"]
A GitHub Actions job that must not pull 26GB:
# .github/workflows/convert-ci.yml
name: convert-ci
on: [pull_request]
jobs:
cpu-convert:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install compiler only
run: pip install neurocuda
- name: Smoke import and convert fixture
run: |
python - <<'PY'
import neurocuda, torch
print("neurocuda", neurocuda.__version__)
# replace with your tiny fixture model + calib_loader
print("import ok")
PY
If the job only needed the extra extra, use pip install neurocuda[all]. If the job is matching published N-MNIST numbers, that is no longer a slim smoke test: follow reproduce NeuroCUDA results on a GPU runner or a nightly schedule. Do not hide a 3-seed ResNet in a PR gate that times out at 20 minutes, and do not hide Gazebo in a gate that only checks import.
CPU is enough for many conversion assertions. Published CPU versus GPU spike parity is 0 deviations across 256000 spikes. Wall-clock time is not a published metric. CI should assert spikes or accuracy bands, not "finished in 4 minutes." The 4-minute N-MNIST figure is a GPU convenience estimate on the reproduce page.
import neurocuda snn, meta = neurocuda.convert(model, calib_loader) neurocuda.compile(snn, target="cpu") # evaluate a fixture batch; archive meta next to the log
Cache pip in Actions. Do not cache the ROS2 image in the same workflow unless the workflow is explicitly the robotics nightly. Mixing caches is how a convert job "suddenly" downloads Gazebo because someone copied docker compose up into convert-ci.yml.
GPU passthrough, Dockerfile.ros2, and when you need CUDA in the container
The root Dockerfile does not start FROM nvidia/cuda. It starts FROM ubuntu:24.04 and pip-installs torch. That may give you a CPU wheel or a GPU wheel depending on the index at build time. If the lab requirement is "CUDA 12.9 devel plus ROS2 Jazzy," use the published variant:
docker build -t neurocuda:ros2 -f Dockerfile.ros2 . docker run -it --gpus all --network=host neurocuda:ros2 bash
--gpus all needs NVIDIA Container Toolkit on the host. Without it, the container starts and torch.cuda.is_available() is false. That is a host install problem, not a NeuroCUDA bug. The pip install neurocuda guide covers wheel pairing on bare metal. Inside Docker the same rule holds: the wheel must match the CUDA libraries the image actually contains. Dockerfile.ros2 pins nvidia/cuda:12.9.2-devel-ubuntu24.04. Do not assume the README's CUDA 13.0 badge and this 12.9.2 tag are the same pin. Read the file you built.
Gazebo-from-ROS2 CUDA image:
docker build -f Dockerfile.gazebo -t neurocuda:gazebo . docker run --rm -it neurocuda:gazebo # documented test launch: # ros2 launch neurocuda_ros2 demo_gazebo_headless.launch.py
Headless Gazebo is for integration tests that need a simulated camera, not for QCFS threshold unit tests. Keep those jobs on different workflows. A failing Gazebo launch does not mean convert() regressed. A failing convert fixture does not mean Foxglove is down.
What NeuroCUDA Docker does not prove
A container is not silicon. Repeating the honest labels here is required because Docker screenshots end up in papers.
- GPU / CPU accuracy remains multi-seed full-test software results (N-MNIST SNN 99.88% ± 0.02%; ResNet-18/CIFAR-10 SNN 94.61% ± 0.14% at T=32). Cite paper.pdf.
- SpiNNaker-1 remains physical silicon smoke tests on jobs #420148 and #420186, not ResNet-on-chip. Write-up: SpiNNaker physical silicon.
- Loihi 2 remains an IF-neuron simulator, not Loihi silicon. Guide: PyTorch to Loihi 2.
- FPGA HLS remains a C++ PoC, not a bitstream. Status: NeuroCUDA FPGA HLS.
- Akida remains not claimed physical. Status: Akida BrainChip NeuroCUDA.
If a paper used the container, cite the software as in cite NeuroCUDA: PDF plus GitHub plus version plus image digest. "We used NeuroCUDA Docker" without a digest is as weak as "we used NeuroCUDA" without a SHA. Field vocabulary for CUDA lives on neuromorphic CUDA. Do not cite that field page as the container HowTo.
Conversion theory still lives on the convert pages: convert PyTorch to SNN, QCFS, timesteps, batchnorm folding, export NIR. Docker does not fold BatchNorm for you. It only makes the Python that folds BatchNorm easier to share.
Lab cookbook (copy once)
Workstation that needs Foxglove and Gazebo:
git clone https://github.com/Krishnav1/neurocuda.git cd neurocuda docker build -t neurocuda-ros2 . docker compose up -d docker compose exec ros2 bash # Foxglove: ws://localhost:8765
CI that only checks the compiler:
pip install neurocuda python -c "import neurocuda; print(neurocuda.__version__)"
Nightly that matches published numbers (not on every PR):
pip install neurocuda[all] python examples/prep_nmnist.py python reproduce.py --quick
Person who has no Docker daemon:
Use NeuroCUDA Google Colab. Reinstall pip after every runtime restart. Save checkpoints to Drive. Do not call that a container strategy.
Person who needs topics and launch files, not Dockerfiles:
Use /neurocuda-ros2. Then come back here when the node must run on a second machine that should not hand-install Jazzy.
Troubleshooting
- Build dies on ROS keys or Gazebo keys. The Dockerfile curls ROS and OSRF keyrings. Transient CDN failures are not compiler bugs. Retry. Pin a mirror only if your lab already does that for ROS.
- pip install neurocuda fails during docker build. The root Dockerfile already falls back to
pip install git+https://github.com/Krishnav1/neurocuda.git. If both fail, your build has no network to PyPI or GitHub. - Foxglove cannot connect. Confirm port 8765, scheme
ws://, and that a bridge process exists. Compose's default command may only colcon-build and sleep. - GPU not visible. You built the Ubuntu root file, or you skipped Container Toolkit. Use
Dockerfile.ros2plus--gpus allwhen you actually need CUDA. - CI minutes exploded. You ran
docker compose upon a conversion PR. Move Gazebo to nightly. Keeppython:3.11+pip install neurocudaon the PR. - Numbers miss the PDF. That is a reproduce problem, not a Docker problem. Follow reproduce NeuroCUDA results.
- Image is "only" 8GB locally but README says 26GB. Different bases and caches. Still not tiny. Still not an official compiler-only image.
Install reminder for every environment, container or not: pip install neurocuda. MIT license. GitHub is the source of the Dockerfiles. PyPI is the source of the wheel the slim CI pattern should prefer.
Primary sources
- Public Dockerfiles and compose, github.com/Krishnav1/neurocuda (
Dockerfile,Dockerfile.ros2,Dockerfile.gazebo,docker-compose.yml) - NeuroCUDA hub, quantaracore.in/neurocuda
- ROS2 architecture, quantaracore.in/neurocuda-ros2
- Technical report, quantaracore.in/neurocuda/paper.pdf
- Colab (ephemeral, not Docker), /blog/neurocuda-google-colab
- Citation labels, /blog/cite-neurocuda
Frequently asked questions
What is the public NeuroCUDA Docker image?
The public Dockerfile in github.com/Krishnav1/neurocuda is a ROS2 Jazzy plus Gazebo environment, not a tiny compiler-only image. Build with docker build -t neurocuda-ros2 . and start with docker compose up. Foxglove is ws://localhost:8765. The README Docker badge lists 26GB.
How do I build NeuroCUDA Docker?
Clone https://github.com/Krishnav1/neurocuda, then docker build -t neurocuda-ros2 . from the repo root. docker compose up starts the ros2 service and publishes port 8765.
Is there a tiny official NeuroCUDA compiler-only image?
No. Do not claim a tiny official compiler-only image while the published Dockerfile installs ROS2 Jazzy, Gazebo Harmonic, and foxglove-bridge. For conversion tests in CI, write your own slim pattern: python:3.11 plus pip install neurocuda.
How is NeuroCUDA Docker different from /neurocuda-ros2?
/neurocuda-ros2 is the robot architecture page. This URL is the container HowTo for labs and CI. Architecture does not tell you which Dockerfile to build or why a 26GB image should not run on every pull request.
How is NeuroCUDA Docker different from Google Colab?
Colab is an ephemeral hosted notebook. Docker is a persistent, scriptable environment you can pin in CI. Use Colab to try convert() in a browser; use Docker for labs and runners. Colab guide: NeuroCUDA Google Colab.
How do I run slim CI conversion tests?
FROM python:3.11-slim, then pip install neurocuda, then import and run convert tests. That image is a CI pattern you maintain, not the official GitHub Dockerfile.
Why is the NeuroCUDA Docker image large?
ROS2 Jazzy, Gazebo Harmonic, PyTorch, and foxglove-bridge are a robotics stack. The GitHub README Docker badge currently reads 26GB. The root Dockerfile comment estimates about 8GB disk and 15 minutes to build.
Does NeuroCUDA Docker prove SpiNNaker or Loihi silicon?
No. GPU numbers remain multi-seed full-test software results. SpiNNaker-1 is a 2-neuron physical smoke test (jobs #420148, #420186). Loihi 2 is an IF-neuron simulator. FPGA HLS is a PoC, not a bitstream. Akida is not claimed physical.
What is the Foxglove URL for NeuroCUDA Docker?
ws://localhost:8765, published as host port 8765 in docker-compose.yml.
Can I docker pull kvarma/neurocuda-ros2:latest instead of building?
The ROS2 product page documents that Hub image. This page treats the public GitHub Dockerfile as the source of truth for labs that build from source. Pin a digest if you pull.
Do I need a GPU inside NeuroCUDA Docker?
No for convert() and CPU compile. Yes for the CUDA-devel Dockerfile.ros2 path. Use NVIDIA Container Toolkit for --gpus all.
Should CI run docker compose up on every pull request?
Not for conversion unit tests. Use python:3.11 plus pip install neurocuda for convert tests. Reserve compose for a nightly robotics job or a lab workstation.
Start now: docker build -t neurocuda-ros2 . · docker compose up · ws://localhost:8765 · slim CI: pip install neurocuda · GitHub · Product hub · PDF