From ad3d7db3332d6b93b325b0bf0867ba006dcdc0b2 Mon Sep 17 00:00:00 2001 From: Matthias Meschede Date: Wed, 22 Jul 2026 16:20:13 +0200 Subject: [PATCH 1/4] Add sponsor project: Numba and llvmlite in the browser --- src/pages/sponsor/NumbaInWasm/GetAQuote.tsx | 9 +++ src/pages/sponsor/NumbaInWasm/index.tsx | 9 +++ src/pages/sponsor/_projectsDetails.ts | 13 ++++ src/pages/sponsor/descriptions/NumbaInWasm.md | 77 +++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 src/pages/sponsor/NumbaInWasm/GetAQuote.tsx create mode 100644 src/pages/sponsor/NumbaInWasm/index.tsx create mode 100644 src/pages/sponsor/descriptions/NumbaInWasm.md diff --git a/src/pages/sponsor/NumbaInWasm/GetAQuote.tsx b/src/pages/sponsor/NumbaInWasm/GetAQuote.tsx new file mode 100644 index 00000000..963582a8 --- /dev/null +++ b/src/pages/sponsor/NumbaInWasm/GetAQuote.tsx @@ -0,0 +1,9 @@ +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import GetAQuotePage from '@site/src/components/fundable/GetAQuotePage'; + +export default function FundablePage() { + const { siteConfig } = useDocusaurusContext(); + return ( + + ); +} diff --git a/src/pages/sponsor/NumbaInWasm/index.tsx b/src/pages/sponsor/NumbaInWasm/index.tsx new file mode 100644 index 00000000..876857af --- /dev/null +++ b/src/pages/sponsor/NumbaInWasm/index.tsx @@ -0,0 +1,9 @@ +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import LargeProjectCardPage from '@site/src/components/fundable/LargeProjectCardPage'; + +export default function FundablePage() { + const { siteConfig } = useDocusaurusContext(); + return ( + + ); +} diff --git a/src/pages/sponsor/_projectsDetails.ts b/src/pages/sponsor/_projectsDetails.ts index b6916b9c..2ab90b2a 100644 --- a/src/pages/sponsor/_projectsDetails.ts +++ b/src/pages/sponsor/_projectsDetails.ts @@ -10,6 +10,7 @@ import Decimal32InArrowCppMD from "@site/src/pages/sponsor/descriptions/Decimal3 import Float16InArrowCppMD from "@site/src/pages/sponsor/descriptions/Float16InArrowCpp.md" import RunEndEncodedInArrowCppMD from "@site/src/pages/sponsor/descriptions/RunEndEncodedInArrowCpp.md" import ParquetNullOptimizationsMD from "@site/src/pages/sponsor/descriptions/ParquetNullOptimizations.md" +import NumbaInWasmMD from "@site/src/pages/sponsor/descriptions/NumbaInWasm.md" export const fundableProjectsDetails = { jupyterEcosystem: [ @@ -50,6 +51,18 @@ export const fundableProjectsDetails = { currentFundingPercentage: 0, repoLink: "https://github.com/geojupyter/jupytergis" }, + { + category: "Jupyter Ecosystem", + title: "Numba and llvmlite in the browser", + pageName: "NumbaInWasm", + shortDescription: "Numba, the standard JIT compiler for numerical Python, cannot run in Pyodide or emscripten-forge today. Its llvmlite backend relies on MCJIT, which WebAssembly does not allow. We have working demos of llvmlite and Numba scalar @jit in the browser. This proof-of-concept effort will resolve the remaining issues to make Numba work generally and initiate upstreaming of the patches.", + description: NumbaInWasmMD, + price: "TBD", + maxNbOfFunders: 1, + currentNbOfFunders: 0, + currentFundingPercentage: 0, + repoLink: "https://github.com/numba/llvmlite" + }, ], packageManagement: [ { diff --git a/src/pages/sponsor/descriptions/NumbaInWasm.md b/src/pages/sponsor/descriptions/NumbaInWasm.md new file mode 100644 index 00000000..d3cade62 --- /dev/null +++ b/src/pages/sponsor/descriptions/NumbaInWasm.md @@ -0,0 +1,77 @@ +#### Overview + +[Numba](https://numba.pydata.org/) is the standard +just-in-time (JIT) compiler for numerical Python, widely used +across the scientific stack to accelerate compute-heavy code. +[Pyodide](https://pyodide.org/) brings CPython to the browser +through WebAssembly and powers JupyterLite, while +[emscripten-forge](https://github.com/emscripten-forge) +provides a conda-based package distribution for the same +target. Today, Numba cannot run in either environment. + +We propose to make Numba and its JIT backend, +[llvmlite](https://github.com/numba/llvmlite), +browser-compatible using WebAssembly, and thus enabling +Pyodide and emscripten-forge users to JIT-compile numerical +code just like they do on a native CPython interpreter. + +#### Why Numba in the Browser Matters + +In a native CPython environment, many paths exist to make +numerical Python fast: Numba's JIT compilation, +multiprocessing, native C extensions, or offloading to a GPU. +In the browser, multithreading/processing and GPU access are +mostly unavailable, and shipping pre-compiled native +extensions for everything is impractical. In addition, the +overhead of the Python interpreter is larger in the browser +and many existing libraries use Numba, sometimes as hard +requirements. JIT compilation is therefore an interesting +route to improved performance in a fully client-side, +browser-based Python environment. + +#### Current Progress + +We have already patched llvmlite and demonstrated that it runs +in the browser including compilation and execution of the WASM +code it generates. A live demo is available at +https://notebook.link/@anutosh491/llvmlite. + +We also have a working demo of Numba's `@jit` decorator +operating on scalar functions in the browser. However, several +issues have been identified that must be overcome to make +Numba work generally (e.g. with arrays). These likely include +WebAssembly's lack of writable-and-executable memory pages +(which rules out MCJIT), unsupported atomic instructions +without shared memory, variadic C calls that cannot be lowered +to WASM, and linkage incompatibilities in the LLVM WASM PIC +backend. But these seem surmountable based on our experience. + +#### Why QuantStack + +QuantStack is uniquely positioned to deliver this work. We +have shipped several JIT and WebAssembly projects in the +scientific Python ecosystem, including +[xeus-cpp](https://github.com/jupyter-xeus/xeus-cpp), a C++ +interpreter running in the browser via Clang and LLVM compiled +to WebAssembly. Our team also includes Numba core developers, +giving us a direct upstream relationship. + +#### Proposed Work + +The goal of this project is to deliver: + +- upstream llvmlite compatibility with browser environments, + based on our existing patches. +- build a proof of concept for general Numba use in the browser to + - demonstrate, ideally all of Numba, or at least a large part of it, in the browser + - demonstrate the ability to run libraries that depend on it (such as pytensor/pymc) in the browser + - gather the changes required to upstream +- upstream the required changes to Numba + +Note that this is a proof of concept effort, we will advance +incrementally, deliver sub-parts, and adjust the plan based +on new learnings. + +##### Are you interested in this project? Either entirely or +partially, contact us for more information on how to help us +fund it. From cf14d77ceee997ffcb4f778affe4a2f709300a9a Mon Sep 17 00:00:00 2001 From: Matthias Meschede Date: Wed, 22 Jul 2026 16:22:31 +0200 Subject: [PATCH 2/4] fix text --- src/pages/sponsor/descriptions/NumbaInWasm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/sponsor/descriptions/NumbaInWasm.md b/src/pages/sponsor/descriptions/NumbaInWasm.md index d3cade62..e72dcdbc 100644 --- a/src/pages/sponsor/descriptions/NumbaInWasm.md +++ b/src/pages/sponsor/descriptions/NumbaInWasm.md @@ -58,7 +58,7 @@ giving us a direct upstream relationship. #### Proposed Work -The goal of this project is to deliver: +The goal of this project is to: - upstream llvmlite compatibility with browser environments, based on our existing patches. From 41b8101feb580b981deb936bbd2a7f125568fa89 Mon Sep 17 00:00:00 2001 From: Matthias Meschede Date: Wed, 22 Jul 2026 16:24:11 +0200 Subject: [PATCH 3/4] fix text --- src/pages/sponsor/descriptions/NumbaInWasm.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/sponsor/descriptions/NumbaInWasm.md b/src/pages/sponsor/descriptions/NumbaInWasm.md index e72dcdbc..dbe8ced9 100644 --- a/src/pages/sponsor/descriptions/NumbaInWasm.md +++ b/src/pages/sponsor/descriptions/NumbaInWasm.md @@ -65,8 +65,8 @@ The goal of this project is to: - build a proof of concept for general Numba use in the browser to - demonstrate, ideally all of Numba, or at least a large part of it, in the browser - demonstrate the ability to run libraries that depend on it (such as pytensor/pymc) in the browser - - gather the changes required to upstream -- upstream the required changes to Numba + - gather and understand the changes required +- upstream the required changes Note that this is a proof of concept effort, we will advance incrementally, deliver sub-parts, and adjust the plan based From 87d5abff593117ce28c339aa0f8d09aa65ae0e95 Mon Sep 17 00:00:00 2001 From: Matthias Meschede Date: Fri, 9 Oct 2026 10:02:03 +0200 Subject: [PATCH 4/4] Rewrite Numba WASM project around working browser implementation --- src/pages/sponsor/_projectsDetails.ts | 2 +- src/pages/sponsor/descriptions/NumbaInWasm.md | 113 ++++++++++-------- 2 files changed, 62 insertions(+), 53 deletions(-) diff --git a/src/pages/sponsor/_projectsDetails.ts b/src/pages/sponsor/_projectsDetails.ts index 2ab90b2a..2fca5373 100644 --- a/src/pages/sponsor/_projectsDetails.ts +++ b/src/pages/sponsor/_projectsDetails.ts @@ -55,7 +55,7 @@ export const fundableProjectsDetails = { category: "Jupyter Ecosystem", title: "Numba and llvmlite in the browser", pageName: "NumbaInWasm", - shortDescription: "Numba, the standard JIT compiler for numerical Python, cannot run in Pyodide or emscripten-forge today. Its llvmlite backend relies on MCJIT, which WebAssembly does not allow. We have working demos of llvmlite and Numba scalar @jit in the browser. This proof-of-concept effort will resolve the remaining issues to make Numba work generally and initiate upstreaming of the patches.", + shortDescription: "Numba, the standard JIT compiler for numerical Python, now runs in the browser: we have it compiling and executing code inside JupyterLite, along with packages that depend on it such as PyTensor and PyMC. Help us upstream the llvmlite and Numba changes, expand test coverage, add persistent caching, and bring the wider Numba ecosystem to emscripten-forge.", description: NumbaInWasmMD, price: "TBD", maxNbOfFunders: 1, diff --git a/src/pages/sponsor/descriptions/NumbaInWasm.md b/src/pages/sponsor/descriptions/NumbaInWasm.md index dbe8ced9..79da7dba 100644 --- a/src/pages/sponsor/descriptions/NumbaInWasm.md +++ b/src/pages/sponsor/descriptions/NumbaInWasm.md @@ -3,74 +3,83 @@ [Numba](https://numba.pydata.org/) is the standard just-in-time (JIT) compiler for numerical Python, widely used across the scientific stack to accelerate compute-heavy code. -[Pyodide](https://pyodide.org/) brings CPython to the browser -through WebAssembly and powers JupyterLite, while -[emscripten-forge](https://github.com/emscripten-forge) -provides a conda-based package distribution for the same -target. Today, Numba cannot run in either environment. +Until recently it could not run in the browser: its JIT +backend, [llvmlite](https://github.com/numba/llvmlite), relies +on execution engines that WebAssembly does not provide. -We propose to make Numba and its JIT backend, -[llvmlite](https://github.com/numba/llvmlite), -browser-compatible using WebAssembly, and thus enabling -Pyodide and emscripten-forge users to JIT-compile numerical -code just like they do on a native CPython interpreter. +We have made Numba work in the browser. Numba and llvmlite now +run inside [JupyterLite](https://jupyterlite.readthedocs.io/), +compiling Python functions to WebAssembly and executing them in +the same page, with no server involved. We are looking for +funding to turn this prototype into a capability the ecosystem +can rely on, maintained upstream in Numba and llvmlite. -#### Why Numba in the Browser Matters +See our announcement, +[Numba in the Browser](https://notebook.link/blog/numba-in-the-browser/), +for the full story. + +#### What Works Today -In a native CPython environment, many paths exist to make -numerical Python fast: Numba's JIT compilation, -multiprocessing, native C extensions, or offloading to a GPU. -In the browser, multithreading/processing and GPU access are -mostly unavailable, and shipping pre-compiled native -extensions for everything is impractical. In addition, the -overhead of the Python interpreter is larger in the browser -and many existing libraries use Numba, sometimes as hard -requirements. JIT compilation is therefore an interesting -route to improved performance in a fully client-side, -browser-based Python environment. +- llvmlite runs in the browser, through a WebAssembly execution + engine that emits WebAssembly objects from LLVM IR, links them + in-process with LLVM's linker LLD, and loads each result as an + Emscripten side module. +- Numba's `@jit` and `@njit` compile and execute inside a + JupyterLite kernel, on arrays as well as scalars. +- Packages that depend on Numba run in the browser, including + [PyTensor](https://github.com/pymc-devs/pytensor), + [PyMC](https://github.com/pymc-devs/pymc), + [Dolo.py](https://github.com/EconForge/dolo.py) and + [interpolation.py](https://github.com/EconForge/interpolation.py). +- On the example in our announcement, Numba gives a roughly + 250x speedup in WebAssembly, against about 90x for the same + code natively. -#### Current Progress +#### Why Numba in the Browser Matters -We have already patched llvmlite and demonstrated that it runs -in the browser including compilation and execution of the WASM -code it generates. A live demo is available at -https://notebook.link/@anutosh491/llvmlite. +A substantial part of the scientific Python stack depends on +Numba, frequently as a hard requirement rather than an optional +accelerator. PyTensor, PyMC, QuantEcon, stumpy and others are in +this category. Until now none of them could be installed in +Pyodide or emscripten-forge at all: not a matter of running +slower in the browser, but of not running. -We also have a working demo of Numba's `@jit` decorator -operating on scalar functions in the browser. However, several -issues have been identified that must be overcome to make -Numba work generally (e.g. with arrays). These likely include -WebAssembly's lack of writable-and-executable memory pages -(which rules out MCJIT), unsupported atomic instructions -without shared memory, variadic C calls that cannot be lowered -to WASM, and linkage incompatibilities in the LLVM WASM PIC -backend. But these seem surmountable based on our experience. +Numba also covers a case that pre-compiled extensions +structurally cannot. Code written interactively in a notebook +does not exist until the user types it, so it cannot be shipped +ahead of time in a wheel or a conda package. A JIT compiler is +the only way to make that code fast, and notebooks are precisely +where browser-based Python is used. #### Why QuantStack -QuantStack is uniquely positioned to deliver this work. We -have shipped several JIT and WebAssembly projects in the -scientific Python ecosystem, including +QuantStack has in-house Numba expertise, which is rare, combined +with long experience of LLVM in WebAssembly. We develop [xeus-cpp](https://github.com/jupyter-xeus/xeus-cpp), a C++ interpreter running in the browser via Clang and LLVM compiled -to WebAssembly. Our team also includes Numba core developers, -giving us a direct upstream relationship. +to WebAssembly, and the execution engine behind Numba in the +browser grew directly out of that work. We also maintain +[emscripten-forge](https://github.com/emscripten-forge) and are +core contributors to Jupyter and JupyterLite, where this work is +deployed. #### Proposed Work -The goal of this project is to: +The prototype establishes the end-to-end architecture. Making it +dependable means: -- upstream llvmlite compatibility with browser environments, - based on our existing patches. -- build a proof of concept for general Numba use in the browser to - - demonstrate, ideally all of Numba, or at least a large part of it, in the browser - - demonstrate the ability to run libraries that depend on it (such as pytensor/pymc) in the browser - - gather and understand the changes required -- upstream the required changes +- upstreaming the llvmlite and Numba changes as focused, + reviewable contributions; +- expanding test coverage, running the llvmlite and Numba test + suites in the browser; +- improving compilation performance and adding persistent + caching, so that compiled functions survive a page reload; +- validating and packaging more of the Numba ecosystem for + emscripten-forge. -Note that this is a proof of concept effort, we will advance -incrementally, deliver sub-parts, and adjust the plan based -on new learnings. +These are separable pieces of work: we advance incrementally and +deliver sub-parts, so the project can be funded in full or in +part. ##### Are you interested in this project? Either entirely or partially, contact us for more information on how to help us