Repository navigation
GPU offload via TornadoVM: 570× faster all-pairs alignment, 18× faster ASA, identical results #1158
Description
Summary
- All-pairs alignment scores (
Alignments.getAllPairsScores/getAllPairsScorers, the guide-tree stage ofgetMultipleSequenceAlignment): 570–680× faster than current BioJava on 20k–40k pairs. For global alignment the GPU is also 3–7× faster than parasail, a SIMD C library, on 32 threads, with identical scores. - Surface area (
AsaCalculator): up to 18× faster on a 2.4M-atom capsid (6.8 s → 0.37 s), and 14× faster than FreeSASA. - Identical results: integer-identical alignment scores (BioJava, GPU and parasail all agree), identical guide trees, bit-identical per-atom ASA.
- Part of this needs no GPU. The same algorithms in plain Java are ~25× faster (alignment scores) and 4–6× faster (ASA) than BioJava on the CPU.
https://github.com/beehive-lab/TornadoVM
What is TornadoVM? An open-source framework for OpenJDK/GraalVM that compiles plain Java code to run on GPUs (NVIDIA CUDA, OpenCL on AMD/Intel, Apple Metal). You write GPU compute kernels in plain Java, and most of BioJava's existing loops map 1-1 onto them. No CUDA or C++ is needed: TornadoVM handles the kernels and data transfers, with a fallback to the JVM.
Numbers
i9-13900K (32 threads) vs RTX 4090, BioJava 7.3.0. Times are end-to-end, including host↔device transfers. "Lean Java" is the same algorithm as the GPU kernel in plain Java on all 32 threads, i.e. the fair Java baseline. The C libraries run on exactly the same inputs.
All-pairs alignment scores (BLOSUM62, gap open 10 / extend 1)
| Workload | BioJava (32 thr) | Lean Java (32 thr) | parasail, C SIMD (32 thr) | GPU |
|---|---|---|---|---|
| Global (NW), 200 proteins, 20k pairs | 9.72 s | 381 ms | 52 ms | 17 ms |
| Global (NW), Pfam PF00104, 40k pairs | 6.04 s | 246 ms | 62 ms | 9 ms |
| Global (NW), 2,000 proteins, 2M pairs | ~11 min (est.) | 34.1 s | 4.0 s | 0.60 s |
| Local (SW), 2,000 proteins, 2M pairs | ~11 min (est.) | 24.0 s | 0.65 s | 0.60 s |
Accessible surface area (Shrake-Rupley, 1000 points)
| Workload | BioJava (32 thr) | Lean Java (32 thr) | FreeSASA, C (16 thr, its max) | GPU |
|---|---|---|---|---|
| 4V6X (238k atoms) | 519 ms | 109 ms | 561 ms | 39 ms |
| 3J3Q (2.4M atoms) | 6.8 s | 1.13 s | 5.29 s | 0.37 s |
Caveats, to be upfront:
- Local alignment: for Smith-Waterman the GPU only matches parasail (1–2×), because parasail's 8-bit SIMD lanes are very efficient there. Against BioJava and lean Java, the gains for local alignment are the same as for global alignment.
- Small inputs: the GPU wins from about 1k pairs. Below that the lean Java path is used automatically.
- Other devices: the same code gives identical results on the RTX 4090 through OpenCL and on an Intel UHD 770 iGPU. The iGPU is slower than the CPU, though.
Why it's faster
- Alignment:
getAllPairsScoresonly needs the score, but every pair currently builds a full traceback matrix with an object per cell. A linear-memory DP on primitiveints gives the same scores ~25× faster on the CPU. On the GPU, each thread aligns one pair using a strip-mined DP, at about 250 GCUPS. - ASA: a cell-grid neighbour search and an early-exit occlusion test on flat arrays, with neighbours sorted by distance. It uses double precision and BioJava's sphere points, so the output is bit-identical. On the GPU it runs as one fused kernel per atom, with the neighbour list in on-chip memory.
Try it (one command)
Code, parity tests and benchmarks: https://github.com/mikepapadim/biojava-tornadovm-extensions
./bench.sh downloads TornadoVM and BioJava 7.3.0 from Maven Central. It then runs the parity tests (exact equality against BioJava) and the benchmarks. scripts/external/compare.sh reproduces the parasail and FreeSASA comparison. Methodology and full tables are in FINDINGS.md.
For users it is a one-line change with the same API and the same output:
new AsaCalculator(structure, 1.4, 1000, nThreads, false); // before
new TornadoAsaCalculator(structure, 1.4, 1000, nThreads, false); // afterWithout a GPU or TornadoVM, it runs the lean Java path, which also gives identical results and is still several times faster than today.
Proposed contributions
- CPU-only, no new dependencies: a score-only fast path for
getAllPairsScores(GLOBAL/LOCAL) and a fasterAsaCalculator, validated against the current implementation. - Optional GPU backend: a separate module (no TornadoVM dependency in any core module), off by default, with automatic CPU fallback.
Questions
- Would you accept (1)? Is (2) of interest?
- For (2), which home do you prefer: (a) a module in this repo, (b) a separate
biojava-*repo, or (c) an external plugin that you link to? - Are there other hot spots users complain about? For example, profiling CE puts ~71% of its time in
CECalculator.dpAlign, a DP that could get the same treatment. All-vs-all structure superposition (QCP) would map well onto GPU matrix multiplication.
We're happy to extend this to other parts of BioJava (e.g. CE), adapt it to your conventions, and support it long term, whichever home you prefer. I'm also happy to keep the first PR small and start with the CPU fast path.
Activity
[-]Support for GPU offload with TornadoVM: much faster all-pairs alignment scores and ASA, identical results[/-][+]Proposal: 25× faster on CPU alone, 570×+ on GPU, for all-pairs alignment and ASA (identical results)[/+][-]Proposal: 25× faster on CPU alone, 570×+ on GPU, for all-pairs alignment and ASA (identical results)[/-][+]GPU offload via TornadoVM: 570× faster all-pairs alignment, 18× faster ASA, identical results[/+]josemduarte commentedon Oct 28, 2026
Very interesting, thank you @mikepapadim .
Definitely I'd be happy to check how (1) looks like. So PRs are welcome.
I suppose introducing the tornado dep comes with a lot of baggage e.g. special build procedure, architecture dependence? If so, yes I'd say it's got to be in another repo. What I don't understand is option (c), could you elaborate?
Yes structure alignment algos (CE and jFatCat) are indeed good candidates.
mikepapadim commentedon Oct 28, 2026
Thanks @josemduarte!
(1) is up as #1161: the all-pairs scores for
GLOBAL/LOCAL(also the guide-tree stage ofgetMultipleSequenceAlignment). It is CPU-only with no new dependencies and gives the same scores, distances and MSA, 27–286× faster. It also turned up a small bug in the existing path, described in the PR: linear-gapSmithWatermanthrows on pairs with no positive cell, andrunPairwiseScorerssilently drops that score.On ASA: your #1147/#1148 already closed most of the gap. On one thread
masteris now on par with my lean version. On 32 threads it is still ~4× slower (4V6X: 578 ms vs 142 ms, per-atom results bit-identical): the neighbour search runs on one thread, and the pool waits in a busy loop. If that's of interest, I can send a small follow-up PR that parallelises those two parts and nothing else.(2): yes, it does come with that baggage. Compiling only needs
tornado-apifrom Maven Central, but running on a GPU needs a TornadoVM SDK for the platform (CUDA, OpenCL or Metal build) and a JDK 21+ launched with its JVM options.CE / jFATCAT: great, I'll look at
CECalculator.dpAlignand the jFATCAT AFP chaining next, with the same approach: an exact CPU path first, then the GPU as an optional extra.