← 输入框|github.com|刷新
Skip to content

GPU offload via TornadoVM: 570× faster all-pairs alignment, 18× faster ASA, identical results #1158

Open

Description

@mikepapadim

Summary

  • All-pairs alignment scores (Alignments.getAllPairsScores / getAllPairsScorers, the guide-tree stage of getMultipleSequenceAlignment): 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: getAllPairsScores only needs the score, but every pair currently builds a full traceback matrix with an object per cell. A linear-memory DP on primitive ints 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);  // after

Without 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

  1. CPU-only, no new dependencies: a score-only fast path for getAllPairsScores (GLOBAL/LOCAL) and a faster AsaCalculator, validated against the current implementation.
  2. Optional GPU backend: a separate module (no TornadoVM dependency in any core module), off by default, with automatic CPU fallback.

Questions

  1. Would you accept (1)? Is (2) of interest?
  2. 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?
  3. 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

  1. changed the title [-]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)[/+] on Sep 30, 2026
  2. changed the title [-]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[/+] on Sep 30, 2026
  3. josemduarte commented on Oct 28, 2026

    @josemduarte
    Contributor

    Very interesting, thank you @mikepapadim .

    Would you accept (1)? Is (2) of interest?
    

    Definitely I'd be happy to check how (1) looks like. So PRs are welcome.

    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?
    

    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?

    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.
    

    Yes structure alignment algos (CE and jFatCat) are indeed good candidates.

  4. mikepapadim commented on Oct 28, 2026

    @mikepapadim
    Author

    Thanks @josemduarte!

    (1) is up as #1161: the all-pairs scores for GLOBAL/LOCAL (also the guide-tree stage of getMultipleSequenceAlignment). 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-gap SmithWaterman throws on pairs with no positive cell, and runPairwiseScorers silently drops that score.

    On ASA: your #1147/#1148 already closed most of the gap. On one thread master is 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-api from 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.dpAlign and the jFATCAT AFP chaining next, with the same approach: an exact CPU path first, then the GPU as an optional extra.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions