Hi everyone! Hard to believe it’s already been 4 months — time really flew by. We’ve made some solid progress along the way, and I’m excited to share the detailed report I prepared for GSoC.
This definitely isn’t the end — I’ll keep contributing and doing my part to make Brian2 even better. 
Report : GSOC 2025
Google Summer of Code 2025: Work Product Submission
INCF: Brian2 Simulator
Replace Brian's just-in-time compilation mechanism
Project Abstract
Brian2 is a free, open-source simulator for spiking neural networks written in Python. It allows users to describe complex neural and synaptic models using intuitive mathematical notation without requiring knowledge of lower-level programming languages. Brian2’s power comes from its code generation framework that transforms high-level model descriptions into efficient compiled code.
However, Brian2’s current just-in-time (JIT) compilation mechanism faces significant performance bottlenecks. In “runtime mode,” Brian2 uses Cython as a bridge between Python and C++, which creates two major issues:
- Compilation Overhead: Cython generates extensive boilerplate code for error checking and Python API integration, leading to slow compilation times (25-45 seconds per code object)
- Runtime Inefficiencies: Generated code routes through multiple Python method calls before reaching C++ implementations, adding substantial overhead
This project aimed to replace Brian2’s Cython-based JIT compilation with a more efficient system that enables direct memory access between Python and C++ while eliminating redundant boundary crossings.
GitHub Repository: brian-team/brian2
Mentors: @mstimberg (@mstimberg), @dan (@thesamovar), @bdevans
Project Goals
The project was structured in two main phases:
Phase 1: Direct Access Implementation
- Replace Python-based runtime data structures (SpikeQueue, Dynamic Arrays) with direct C++ equivalents
- Enable direct memory sharing between Python and C++ objects with minimal overhead
- Optimize performance by eliminating redundant Python/C++ boundary crossings
Phase 2: Alternative Backend Research
- Research alternatives to Cython for actual JIT compilation
- Explore lightweight compilation backends like cppyy
- Prototype and evaluate new approaches for runtime code generation
Work Accomplished
Phase 1: Core Data Structure Optimization
SpikeQueue Direct Access Implementation
The SpikeQueue is a critical component that manages spike delivery between neurons. Previously, spike processing involved multiple inefficient Python method calls, just to give example :
# Original inefficient flow:
# Compiled Cython → Python → Python → Cython → C++
{% block maincode %}
_owner.push_spikes() # Python method call!
{% endblock %}
def push_spikes(self):
events = self.eventspace[: self.eventspace[len(self.eventspace) - 1]]
if len(events):
self.queue.push(events) # Another Python call!
Solution: Implemented direct C++ SpikeQueue data-structure and access that bypasses Python intermediaries entirely, enabling compiled code to directly call C++ SpikeQueue methods.
C++ Dynamic Arrays Implementation
Dynamic arrays store neuron state variables and previously suffered from Python-mediated access patterns. The new implementation:
- Replaced Python-based dynamic arrays with pure C++ implementations adapted from standalone mode
- Created efficient Cython wrappers that expose raw C++ pointers
- Enabled direct memory access from generated code without Python method calls
Phase 2: Next-Generation Backend Research
The AOT Compilation Problem
Through extensive research and prototyping, we identified that the fundamental issue wasn’t Cython specifically, but rather doing Ahead-of-Time (AOT) compilation at runtime. Traditional approaches still required:
- Writing large generated files to disk
- Launching external compiler processes
- Waiting for full compilation cycles (15-40 seconds)
- Managing temporary files and linking
cppyy Integration
After evaluating multiple alternatives, we identified cppyy as the most promising solution for true just-in-time compilation. cppyy provides:
- Real JIT compilation: Compiles C++ code directly in memory without file I/O
- Automatic Python bindings: No manual wrapper code required
- Interactive development: Code can be compiled and executed immediately
- Performance: Near-native C++ speed with minimal overhead
Implementation: Started integration of cppyy as a new code generation backend for Brian2’s runtime mode, enabling true JIT compilation that eliminates the file-based compilation bottleneck entirely.
Contributions During GSoC Period
Core Implementation Pull Requests
Pull Request |
Description |
Status |
#1643 |
SpikeQueue optimization: Remove Python overhead in spike processing |
Merged |
#1649 |
Implement direct C++ path for SpikeQueue operations |
Merged |
#1650 |
Add C++ DynamicArrays for runtime mode, replace Python arrays |
Open |
#1674 |
Add cppyy as new codegen backend for runtime mode |
Open |
Additional Contributions ( not related to project )
Pull Request |
Description |
Status |
#1644 |
Remove runtime dependency-version checks from init.py |
Merged |
#1657 |
Introduce abstract RateMonitor class for unified rate analysis |
Open |
Technical Documentation and Blog Posts
Throughout the project, I maintained comprehensive Blogs of my learnings and what we did :
Blog Post |
Topic |
Link |
Understanding Brian2 Codebase |
Comprehensive guide to Brian2’s architecture and code generation |
Read Here |
Code Generation Pipeline |
From Math to Machine Code: How Brian2 transforms equations |
Read Here |
SpikeQueue Optimization |
Eliminating Python overhead in spike processing |
Read Here |
Dynamic Arrays Optimization |
From Python indirection to direct C++ speed |
Read Here |
The AOT Trap |
Why Brian2 is exploring cppyy-powered runtime |
Read Here |
Understanding cppyy |
A true automatic Python-C++ binding system |
Read Here |
Current State
Successfully Implemented
SpikeQueue Direct Access: Eliminated Python overhead in neural spike processing
C++ Dynamic Arrays: Replaced Python-based arrays with efficient C++ implementations
cppyy Prototype: Initial integration of cppyy as alternative compilation backend
Performance Improvements Achieved
- SpikeQueue Operations: Eliminated multiple Python method calls in critical spike processing path
- Dynamic Array Access: Direct C++ memory access without Python intermediaries
- Compilation Research: Identified path forward with cppyy for true JIT compilation
What’s Next
Short-term Goals
- Complete cppyy Integration: Finalize the cppyy backend implementation and comprehensive testing
- Benchmarking Suite: Develop thorough performance comparison between Cython and cppyy backends
- Documentation: Complete user-facing documentation for new features
Long-term Vision
- Full Cython Replacement: Gradually migrate Brian2’s runtime mode to use cppyy exclusively
- Common set of C++ templates : Once cython is removed we’d like to reduce our burden of maintaining seperate templates for standalone and runtime modes , as both cppyy and now standalone will directly use C++ the idea is to have a common set of templates that both use …
Challenges and Key Learnings
The Fundamental Paradigm Shift
The most significant insight was recognizing that the problem wasn’t Cython itself, but the entire AOT-at-runtimeparadigm. This realization led us to cppyy, which represents a true paradigm shift to in-memory JIT compilation.
Technical Challenges Overcome
- Memory Management: Safely sharing memory between Python and C++ with proper lifetime management
- Code Generation: Adapting Brian2’s template system to work with direct pointer access
Impact and Future Contributions
This work represents a significant step toward making Brian2 more efficient and maintainable. The direct access implementations provide immediate performance benefits, while the cppyy research establishes a foundation for revolutionary improvements to Brian2’s compilation system.
The project has opened new possibilities for Brian2’s architecture and demonstrated the potential for dramatic performance improvements through careful systems-level optimization.
Acknowledgments
I’m incredibly grateful to my mentor @mstimberg for his guidance, patience, and technical brilliance throughout this project. What really stood out to me was not just how deeply he understands Brian2, but also how carefully he thinks about the ripple effects of even the smallest change in the codebase. The fact that he could casually bring up things like “what if this change affects making Brian2 run on Arduino?” honestly blew my mind — it showed me how much vision and creativity go into maintaining a project like this.
A big thanks as well to the Brian2 community for making me feel welcome and part of something so meaningful. It’s been a joy working on such a beautiful piece of code.
This project has been one of the most rewarding learning experiences I’ve had — it really pushed me to understand Python on a deeper level. And funny enough, it made me realize that when we run python3 main.py
, we’re not actually running Python itself, but just one of its implementations. That little detail still fascinates me.
I’m excited to keep contributing to Brian2 well beyond GSoC — there’s so much more to explore 