Agrim Patil
GSoCOpen SourceCondaCI/CDDevOps

My Google Summer of Code 2025 (GSoC) Journey with INCF

5 min read

My Google Summer of Code 2025 (GSoC) Journey with INCF: Bridging the Gap Between Research Software and Real-World Use

Turning a high-performance neural simulator into something people can actually install — and the engineering decisions that made it possible.

GSoC @ incf bannerGSoC @ incf banner

The moment that shaped my GSoC project wasn’t writing CUDA code or debugging a build failure.

It was realizing that excellent research software can still be practically unreachable.

GeNN — GPU-enhanced Neuronal Networks — is a powerful simulator used by computational neuroscientists. But for many potential users, getting it to run meant navigating compiler toolchains, CUDA versions, platform quirks, and undocumented assumptions. The code worked. The science was solid. The distribution was fragile.

That gap — between research-grade capability and real-world usability — became the central engineering problem I worked on throughout Google Summer of Code 2025 with the International Neuroinformatics Coordinating Facility (INCF).

What Is This Project?

The non-expert explanation

This project makes GeNN easy to install and use.

Instead of asking users to manually build C++ libraries, configure CUDA paths, and guess which dependencies work together, the goal was simple:

A single command should install GeNN correctly on your system.

That meant packaging GeNN for Conda, so users could install it reliably across Linux, Windows, and macOS — whether they had GPUs or not.

The technical summary

GeNN consists of:

  • A C++ core that performs high-performance neural simulations
  • Python bindings (PyGeNN) that make the system usable from Python workflows

My objective was twofold:

  1. Architecture: Build a unified Conda recipe that supports Linux, Windows, and macOS.
  2. Optimization: Enable GPU acceleration (CUDA) where available, while gracefully falling back to CPU for other users.

This work lives at the intersection of C++ build systems, Python packaging, CUDA toolchains, and Conda-Forge infrastructure.

Why This Problem Matters

In the world of High-Performance Computing (HPC), reproducibility is everything. If a researcher in Tokyo publishes a paper using GeNN, a student in Berlin should be able to reproduce those results immediately.

Without a standardized package manager:

  • Versioning Conflicts: Users install the wrong version of the CUDA toolkit (e.g., v11 vs v12), causing build failures.
  • OS Fragmentation: Windows users face entirely different compiler errors (MSBuild vs. Make) compared to Linux users.
  • Adoption Bottleneck: Non-CS researchers (biologists, neuroscientists) often abandon tools that require manual compilation.

Packaging is not a cosmetic problem — it directly affects who gets to use a tool.

By solving this at the distribution level, we aren’t just saving time; we are removing the technical barrier to entry for computational neuroscience.

Technical Deep Dive

1. Architecture Overview

The final design revolves around a single Conda recipe with multiple outputs, collectively called the PyGeNN Suite:

  1. PyGeNN-CPU
  • CPU-only build
  • Works across Linux, Windows, and macOS

2. PyGeNN-CUDA

  • GPU-accelerated build
  • Uses modular CUDA dependencies
  • Activates only when compatible hardware is present

This structure reduced duplication while keeping platform-specific logic isolated.

2. Key Design Decisions & Trade-offs

Building a Conda package for a hybrid C++/CUDA/Python project is rarely straightforward. Here is an overview of the architectural challenges I navigated and the design decisions I made.

1. The CUDA Modularization Challenge

One of the most significant technical hurdles was handling NVIDIA’s CUDA dependencies.

  • The Issue: In older versions of Conda-forge (< v12), CUDA was a monolithic package. You installed “cudatoolkit,” and you got everything. However, with version 12+, CUDA was split into modular components (nvcc, runtime, dev-tools).
  • The Decision: I refactored our recipe to strictly support modular CUDA. This future-proofs the package and allows for smaller environment sizes, as users only download the specific components GeNN requires (like cuda-nvcc and cuda-cudart-dev ) rather than the entire massive toolkit.

2. The Windows Build System Migration

Windows presented a unique failure mode.

  • The Bottleneck: GeNN’s native build system on Windows relied on MSBuild. However, during the Conda build process, MSBuild struggled to invoke the CUDA compiler correctly within the isolated environment.
  • The Fix: We engineered a migration to NMake. This required modifying the backend build logic in GeNN itself (PR #705). NMake offered better transparency and control over flags within the Conda build environment, solving the compilation deadlock.

3. Azure Pipelines & Headless Testing

Testing GPU software in a CI/CD environment is tricky because most standard runners (like Azure Pipelines used by Conda-forge) do not have GPUs attached.

The Strategy: I implemented a “Smoke Test” strategy with conditional logic.

  • The test suite detects the hardware environment.
  • If a GPU is absent (CI environment), it runs CPU validation tests to ensure the libraries link correctly.
  • If a GPU is present (User machine), it runs the full CUDA simulation suite.

The Trade-off: We sacrifice full end-to-end GPU testing on CI for the sake of build automation, relying on local validation for the GPU-specific logic.

Challenges & Failures: Learning from the Process

Development is rarely a straight line. Here are the specific failures and learnings that shaped the final result:

Learning 1: The macOS Linker Nightmare On macOS, the PyGeNN CPU package failed at runtime because Python couldn't locate the dynamic libraries.

  • Diagnosis: The standard build process wasn’t updating the relative paths (RPATH) of the .dylib files during installation.
  • Resolution: We had to modify the upstream build script to copy the libraries into the specific lib directory of the Conda environment, ensuring the dynamic linker could resolve them at runtime.

Learning 2: The Environment Variable Assumption I initially assumed users would know how to set their CUDA_PATH. I was wrong. Users were installing the package and immediately crashing because the compiler couldn't be found.

  • Pivot: We couldn’t set global environment variables (bad practice), so I implemented the post-link message strategy to guide users explicitly immediately after the transaction finishes.

Learning 3: The Recipe Refactor Midway through the project, the Conda-forge maintainers suggested a major structural change: merging our separate recipes into a unified suite.

  • Impact: This required undoing about 30% of my initial work. While frustrating, it was the correct engineering decision. It reduced code duplication and aligned with Conda-forge best practices. It taught me that maintainability > initial velocity.

What’s Next

The code is written, but the journey continues.

  • Conda Recipe v1 Migration: The Conda ecosystem is evolving towards a new recipe format (v1). I am currently investigating the migration path to ensure GeNN stays compatible with future Conda versions.
  • Conda-Forge Acceptance: The PR is currently in the staging area. Once merged, GeNN will be available to millions of users via a simple conda install -c conda-forge pygenn.

My long-term goal is to see GeNN become a standard tool in the arsenal of every computational neuroscientist, with zero setup time required.

How to Get Involved

If you are interested in Spiking Neural Networks, compiler infrastructure, or neuromorphic engineering, check out GeNN!

If you found this project helpful, please consider starring the repo!


Author Bio: Agrim Patil is a DevOps Engineer at SAP Labs and a GSoC 2025 Contributor. Passionate about distributed systems, cloud infrastructure, and making complex software accessible.