Skip to content

Julia Backend

Julia modules are called via a persistent forge_dispatcher.jl session using the ForgeStudio package. The API mirrors the Python backend exactly.


Module Structure

Every Julia module must define a run function:

julia
function run(config_path::String)::Vector{String}
    ...
    return [output_path]
end
  • config_path — path to the JSON config file written by FORGE Studio.
  • Return value — vector of absolute output file paths.

Minimal Example

julia
using ForgeStudio

function run(config_path::String)::Vector{String}
    config     = forge_read_config(config_path)
    output_dir = config["output_dir"]

    forge_log(:info, "minimal_module: starting")

    result = zeros(Float32, 64, 64, 32)  # replace with real recon

    out_path = joinpath(output_dir, "result.jld2")
    # JLD2.save(out_path, "data", result)

    forge_log(:info, "minimal_module: done")
    return [out_path]
end

Iterative Reconstruction Example

julia
using ForgeStudio

function run(config_path::String)::Vector{String}
    config     = forge_read_config(config_path)
    output_dir = config["output_dir"]

    n_iter    = forge_param(config, "n_iter";    default=100)
    step_size = forge_param(config, "step_size"; default=0.01f0)

    forge_log(:info, "starting: n_iter=%d step_size=%.4f", n_iter, step_size)

    x = zeros(ComplexF32, 64, 64, 32)
    for i in 1:n_iter
        # --- your reconstruction update here ---
        err = 1.0 / i
        pen = 0.5 / i

        forge_progress("iter", i, n_iter, "Iterating";
                       postfix="err=$(round(err; sigdigits=3))")
        forge_convergence("iter", i, err, pen)

        if i % 10 == 0
            forge_image_preview("iter", i, real(x))
        end
    end
    forge_progress_done("iter")

    out_path = joinpath(output_dir, "recon.jld2")
    # JLD2.save(out_path, "image", x)

    forge_log(:info, "done")
    return [out_path]
end

API Reference

forge_read_config(config_path::String) -> Dict

Loads and validates the step config JSON.

julia
config = forge_read_config(config_path)

config["job_id"]       # String
config["input_paths"]  # Vector{String}
config["output_dir"]   # String
config["input_format"] # String — "twix" | "ismrmrd" | "mat" | "jld2" | "npy"
config["params"]       # Dict — user parameter values
config["channels"]     # Int (optional)

forge_param(config, name; default=nothing)

Reads a parameter from config["params"]. Returns default if absent or empty.

julia
n_iter = forge_param(config, "n_iter"; default=100)
lambda = forge_param(config, "lambda"; default=0.01f0)

forge_log(level::Symbol, message::String, args...)

Emits a log event.

julia
forge_log(:info,  "Starting calibration")
forge_log(:warn,  "Low SNR: %d channels", n_channels)
forge_log(:error, "Convergence failed at iter %d", i)

Levels: :debug, :info, :warn, :error.


forge_progress(bar_id, current, max_val, label; postfix="")

Reports progress.

julia
forge_progress("recon", i, n_iter, "Reconstructing"; postfix="err=$(round(err;sigdigits=3))")

forge_progress_done(bar_id::String)

Marks a bar complete.

julia
forge_progress_done("recon")

forge_convergence(bar_id, iter, error_norm, penalty; kwargs...)

Emits metrics for the convergence chart.

julia
forge_convergence("recon", i, error_norm, penalty; step_size=alpha)

forge_image_preview(bar_id::String, iter::Int, volume::Array)

Emits orthogonal slice previews.

julia
forge_image_preview("recon", i, real(x))  # 3D real-valued array

forge_is_session() -> Bool

Returns true inside a FORGE Studio managed session.


Package Location

The ForgeStudio package lives at resources/julia/ForgeStudio/ within the app bundle. It is loaded via --project pointing to resources/julia/ — no installation needed.

Dependencies (JSON3, Statistics, Base64) are declared in resources/julia/Project.toml and pre-installed in the app's Julia depot.


Sysimage (Cold-Start Optimisation)

Julia's compilation overhead can be significant on first load. FORGE Studio supports pre-compiled sysimages to eliminate this:

  1. Build a sysimage that includes ForgeStudio and your common dependencies.
  2. Place it at resources/julia/forge_studio.so (Linux) or resources/julia/forge_studio.dylib (macOS).
  3. FORGE Studio automatically passes --sysimage to Julia when the file exists.
bash
# Example sysimage build (requires PackageCompiler.jl)
julia --project=resources/julia -e '
using PackageCompiler
create_sysimage([:ForgeStudio, :JLD2, :FFTW];
    sysimage_path="resources/julia/forge_studio.so",
    precompile_execution_file="scripts/precompile_workload.jl")
'

Testing Your Module

Use the forge-session dev tool → to run your module interactively:

bash
node scripts/forge-session.mjs --julia /path/to/julia --repl
julia> run resources/julia/examples/my_module.jl

FORGE Studio