From ee4dd32a8b4d23bb2320036ac071967a4e922aef Mon Sep 17 00:00:00 2001 From: anvika-singhal Date: Sun, 12 Jul 2026 08:22:55 -0700 Subject: [PATCH] Add Julia precompilation for faster first-use latency --- src/komamripy/_session.py | 33 +++++++++++++++++++++++++++++++-- src/komamripy/precompile.jl | 28 ++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 src/komamripy/precompile.jl diff --git a/src/komamripy/_session.py b/src/komamripy/_session.py index 314a7be..e740b97 100644 --- a/src/komamripy/_session.py +++ b/src/komamripy/_session.py @@ -7,6 +7,9 @@ from __future__ import annotations +import sys +from pathlib import Path + _session = None # cached juliacall ``Main`` module, created on first use @@ -14,8 +17,8 @@ def get_julia(): """Return the initialized Julia ``Main`` module, starting it if needed. On the first call this imports juliacall (which provisions a private Julia - if one is not already available), loads KomaMRI, and caches the resulting - ``Main`` module for reuse. + if one is not already available), loads KomaMRI, runs precompilation to + reduce first-use latency, and caches the resulting ``Main`` module for reuse. ``using KomaMRI`` is evaluated as source because ``using`` is Julia syntax rather than a callable; every other interaction with KomaMRI uses ordinary @@ -26,5 +29,31 @@ def get_julia(): from juliacall import Main as jl jl.seval("using KomaMRI") + + # Run precompilation on first Julia session initialization + _run_precompilation(jl) + _session = jl return _session + + +def _run_precompilation(jl): + """Load and execute the Julia precompile script. + + This compiles common KomaMRI workflows to cache bytecode and reduce + first-use latency for typical Python workflows. If precompilation fails, + continue silently — it is not critical to functionality. + """ + precompile_path = Path(__file__).parent / "precompile.jl" + + if not precompile_path.exists(): + return + + try: + print("Precompiling KomaMRI...", file=sys.stderr, flush=True) + # Convert path to forward slashes for Julia (works on Windows too) + path_str = str(precompile_path).replace("\\", "/") + jl.seval(f'include("{path_str}")') + except Exception: + # Precompilation failure is non-fatal; continue silently + pass diff --git a/src/komamripy/precompile.jl b/src/komamripy/precompile.jl new file mode 100644 index 0000000..66c90cc --- /dev/null +++ b/src/komamripy/precompile.jl @@ -0,0 +1,28 @@ +"""Precompile common KomaMRI workflows to reduce first-use latency. + +This script uses PrecompileTools.jl to compile the most common entry points +used by Python code via komamripy. Precompiled code is cached and reused on +subsequent imports, making the first real use of komamripy much faster. +""" + +try + using PrecompileTools: @setup_workload, @compile_workload + + @setup_workload begin + @compile_workload begin + redirect_stderr(devnull) do + # Common scanner and phantom setup + sys = Scanner() + obj = brain_phantom2D() + + # Common sequence examples + seq = PulseDesigner.EPI_example() + + # Simulation parameters + sim_params = KomaMRICore.default_sim_params() + end + end + end +catch + # PrecompileTools not available; skip precompilation silently +end \ No newline at end of file