API
The exported types and functions are the public API. The internal helpers are listed for reference and may change without notice.
NSDETimeParallel.AbstractCriterion — Type
A stopping rule evaluated on the fine trajectories from the current starts.
NSDETimeParallel.AbstractPararealBackend — Type
AbstractPararealBackendHow the fine sweep of Parareal executes. The algorithm lives ONCE in parareal/parareal.jl; a backend supplies only these primitives:
is_root(backend)— whether this process runs the serial parts (coarse init, correction, convergence check).trueeverywhere except non-root MPI ranks.sync_starts!(backend, cache, k)— make the chunk starting valuesU[n]available wherever chunknwill be solved. No-op off MPI.fine_map!(backend, cache, solution, problem, parareal, k; …)— solve chunksk:Nwith the fine solver; deposit boundary values intocache.F[n+1]on the root and chunk solutions intosolution.lastiterate(MPI ranks keep their chunk local untilcollect_chunks!).snapshot!(backend, solution, k; …)— record iteratekwhensaveiteratesis on. In memory by default; on MPI the ranks have already written their chunk to the run directory insidefine_map!.sync_converged(backend, flag)— agree the convergence decision.collect_chunks!(backend, solution, cache; …)— bring final chunks (and, under MPI withsaveiterates, the per-iterate history) to the root.
NSDETimeParallel.AbstractPararealParameters — Type
An abstract type for parameters of Parareals.
NSDETimeParallel.AbstractTimeParallelCache — Type
An abstract type for caching intermediate computations in AbstractTimeParallelSolvers.
NSDETimeParallel.AbstractTimeParallelIterate — Type
An abstract type for iterates in AbstractTimeParallelSolutions.
NSDETimeParallel.AbstractTimeParallelParameters — Type
An abstract type for parameters in AbstractTimeParallelSolvers.
NSDETimeParallel.AbstractTimeParallelSolution — Type
An abstract type for time-parallel solutions of NSDEBase.AbstractInitialValueProblems.
NSDETimeParallel.AbstractTimeParallelSolver — Type
An abstract type for time-parallel solvers of NSDEBase.AbstractInitialValueProblems.
NSDETimeParallel.AbstractWeightRule — Type
Immutable weight-rule settings; bases are per unit time.
NSDETimeParallel.DistributedBackend — Type
Fine chunks via pmap over the default worker pool (Distributed.jl).
NSDETimeParallel.FixedWeight — Type
Use a fixed positive per-unit-time discount base.
NSDETimeParallel.FrontierRelativeUpdate — Type
Pipeline-only relative frontier test. It is not the bulk all-interface update test.
NSDETimeParallel.MPIBackend — Type
SPMD over MPI ranks: rank r owns chunk r + 1. Requires MPI.Init().
NSDETimeParallel.MeanRelativeUpdate — Type
Legacy mean relative interface-update criterion.
NSDETimeParallel.NeighbourWeight — Type
Legacy neighbouring-chunk running maximum; prefer an explicit fixed or secant rule.
NSDETimeParallel.NoStop — Type
Disable tolerance acceptance while retaining budgets, failure checks, and exact completion.
NSDETimeParallel.Parareal — Type
Immutable Parareal settings. Per-run propagation plans and weights live in the cache.
NSDETimeParallel.PararealCache — Type
PararealCache <: AbstractTimeParallelCachePre-allocated state for one Parareal run: the chunk boundary values U, the fine and coarse boundary results F and G, the previous-iterate snapshot U_ for the error function, the chunk time grid T, the chunk problems (built once, their u0 slots referencing U so the correction updates them in place), and reusable solver caches. Method-dependent fields can be replaced when switching solver, RHS, or weight-rule types; the state shape and chunk count stay fixed. Each run refreshes the initial state from the supplied problem. Moving a cache to a different span requires shiftwindow!. RHS changes rebuild the chunk caches; do not mutate RHS internals in place while retaining their solver caches.
NSDETimeParallel.PararealDiagnostics — Type
Run accounting. Bulk-synchronous counts are unavailable (nothing) for a pipeline.
NSDETimeParallel.PararealIterate — Type
PararealIterate <: AbstractTimeParallelIterateA composite type for a single iterate in a PararealSolution: one fine chunk solution per time chunk. The chunk storage is CONCRETE — chunks are built eagerly from the fine solver, so eltype(iterate.chunks) is the fine solver's concrete solution type, not an abstract box. This matters: these objects cross thread and process boundaries in the hot path.
Constructors
PararealIterate(chunks::AbstractVector{𝕊}) where 𝕊<:AbstractInitialValueSolution
PararealIterate(problem::AbstractInitialValueProblem, parareal::Parareal)Functions
Methods
(iterate::PararealIterate)(t::Real)returns the value of iterate at t via interpolation of the owning chunk.
NSDETimeParallel.PararealParameters — Type
PararealParameters <: AbstractPararealParametersA composite type for the basic parameters of Parareal.
Constructors
PararealParameters(N, K)
PararealParameters(; N=10, K=N)Arguments
N :: Integer: number of time chunks/processors.K :: Integer: maximum number of fine batches. A bulk-synchronous return uses at mostK-1correction sweeps because its fine trajectories are evaluated from the returned starts.
NSDETimeParallel.PararealSolution — Type
PararealSolution <: AbstractTimeParallelSolutionA composite type for an AbstractTimeParallelSolution obtained using Parareal.
Constructors
PararealSolution(lastiterate, errors)
PararealSolution(problem::AbstractInitialValueProblem, parareal::Parareal)Arguments
lastiterate :: PararealIterateerrors :: AbstractVector{ℝ} where ℝ<:Real: iteration errors.
Functions
firstindex: first index.getindex: get iterate.lastindex: last index.numiterates: number of iterates.numchunks: number of chunks of last iterate.setindex!: set iterate.
Methods
(solution::PararealSolution)(t::Real)returns the value of solution at t via interpolation.
NSDETimeParallel.PipelinedMPIBackend — Type
PipelinedMPIBackend()MPI frontier scheduling with one rank per chunk. Supported criteria are WeightedDefect(p=Inf, weight=FixedWeight(...)), FrontierRelativeUpdate, and NoStop. Other criteria are rejected; the bulk all-interface update rule and changing secant weights require synchronized iterates.
Maximum-defect acceptance waits for the upstream start to freeze before accepting its outgoing defect. Thus the assembled accepted starts satisfy the selected defect tolerance. Converting that tolerance to a trajectory error additionally requires bounds on the fine-map amplification.
Call MPI.Init() first and launch at least N ranks. Global histories are unsupported. Diagnostics report actual total fine/coarse calls and per-chunk local_sweeps; sweeps and fine_batches are nothing because this schedule has no synchronized batches. residuals contains the maximum diagnostic among ranks active at each local iteration index, not a bulk residual.
The final gather returns each fine trajectory from its accepted start. With NoStop() and K >= N, completion reproduces reference(problem, solver).
NSDETimeParallel.RelativeUpdate — Type
All-interface mixed update test, with explicit absolute and relative tolerances.
NSDETimeParallel.SecantWeight — Type
Latest-pair same-chunk secant rule with a scaled denominator guard and a floor of one.
NSDETimeParallel.SerialBackend — Type
Runs everything in the calling task. The reference implementation.
NSDETimeParallel.ThreadsBackend — Type
Fine chunks via Threads.@threads with dynamic scheduling in shared memory.
NSDETimeParallel.WeightedDefect — Type
Normalized weighted defect p-mean; p=1 is the average and p=Inf the maximum.
Base.firstindex — Method
firstindex(iterate::PararealIterate)returns the first index of iterate.
Base.firstindex — Method
firstindex(solution::PararealSolution)returns the first index of solution.
Base.getindex — Method
getindex(iterate::PararealIterate, n::Integer)returns the n-th chunk of iterate.
Base.getindex — Method
getindex(solution::PararealSolution, n::Integer)returns the n-th chunk of the last iteration of a PararealSolution.
Base.lastindex — Method
lastindex(iterate::PararealIterate)returns the last index of iterate.
Base.lastindex — Method
lastindex(solution::PararealSolution)returns the last index of solution.
Base.length — Method
length(iterate::PararealIterate)returns the number of chunks of iterate.
Base.length — Method
length(solution::PararealSolution)returns the number of chunks of solution.
Base.setindex! — Method
setindex!(iterate::PararealIterate, value::AbstractInitialValueSolution, n::Integer)stores value into the n-th chunk of iterate.
Base.setindex! — Method
setindex!(solution::PararealSolution, chunk::AbstractInitialValueSolution, n::Integer)stores an AbstractInitialValueSolution as the n-th chunk of the last iteration of a PararealSolution.
NSDEBase.initialize_cache — Method
NSDEBase.initialize_cache(problem, parareal::Parareal) :: PararealCachereturns a reusable PararealCache for problem, honouring the same contract NSDERungeKutta honours for its solvers. Build once, then call parareal(cache, solution, problem; ...) repeatedly — e.g. in timing loops, to report setup costs separately from repeated solve costs. Reuse is not a zero-allocation guarantee.
NSDEBase.initialize_solution — Method
NSDEBase.initialize_solution(problem, parareal::Parareal; history=:none) :: PararealSolutionreturns a PararealSolution for problem. Reusable across solves.
NSDEBase.remake — Method
Build changed Parareal settings without changing the original.
NSDEBase.solve! — Method
solve!(solution::AbstractTimeParallelSolution, problem, solver::AbstractTimeParallelSolver; kwargs...) :: AbstractTimeParallelSolutioncomputes the solution of problem using solver.
NSDEBase.solve — Method
solve(problem, solver::AbstractTimeParallelSolver; kwargs...) :: AbstractTimeParallelSolutioncomputes the solution of problem using solver.
NSDETimeParallel.TimeParallelSolution — Method
TimeParallelSolution(problem::AbstractInitialValueProblem, parareal::Parareal)returns a PararealSolution constructor for the solution of problem with parareal.
NSDETimeParallel.Wnorm — Method
Wnorm(iterate, reference, weight; base=:time)Weighted Euclidean distance at the chunk interfaces. reference may be a solution or the vector returned by reference(problem, parareal). The base is per unit time, matching all weight rules. base=:chunk explicitly selects the per-chunk convention. Supply a scalar or FixedWeight; adaptive rule objects contain only their initial settings and are refused. To use a measured weight, pass solution.diagnostics.weights[end], or call Wnorm(solution, reference).
NSDETimeParallel.Wnorm — Method
Wnorm(solution::PararealSolution, reference)Weighted interface error using the last measured per-unit-time weight. A run with no finite fine batch has no measured weight and raises ArgumentError.
NSDETimeParallel.accept — Method
returns whether a criterion accepts its evaluated residual.
NSDETimeParallel.boundarytimes — Method
boundarytimes(iterate::PararealIterate)returns the N + 1 chunk-boundary times of iterate: each chunk's start, plus the final chunk's end. These are the points Parareal iterates on — the grid every convergence measure (Wnorm, per-iterate error studies) is taken over.
NSDETimeParallel.boundaryvalues — Method
boundaryvalues(iterate::PararealIterate)returns the N + 1 chunk-boundary values of iterate: each chunk's first state, plus the final chunk's last state — the U vector of the Parareal iteration, read off the chunk solutions. The returned states ALIAS the chunk storage; copy them before mutating.
NSDETimeParallel.chunk_endpoint — Method
chunk_endpoint(sol, t)returns the value of sol at the chunk endpoint t: the stored final value when the solver stopped exactly at t, otherwise the interpolant (for generic solvers that overshoot).
NSDETimeParallel.coarseinit! — Method
coarseinit!(cache, parareal; mpi=false)runs the serial coarse pass over the chunk grid, filling G and — where makeGs allows — seeding the chunk starting values U. Chunks whose makeGs[n] is false keep whatever U[n] already holds (injected guesses, e.g. from a moving-window driver).
NSDETimeParallel.collect_iterates! — Method
collect_iterates!(solution::PararealSolution; directory)reads the per-iterate chunk files written by the MPI backend under saveiterates back into solution.iterates. Chunks below the diagonal (n < k) are final from earlier iterations and are copied forward.
NSDETimeParallel.contractionrate — Method
contractionrate(errors::AbstractVector{<:Real}) :: Float64
contractionrate(solution::AbstractTimeParallelSolution) :: Float64the observed per-iteration contraction rate β of an error trace: the least-squares slope of log(errors[k]) against k, exponentiated, so that errors[k] ≈ C βᵏ. Non-finite entries and EXACT ZEROS are excluded before fitting — finite termination drives the last error to bitwise zero, which is a property of the algorithm's fixed point, not of its rate. Returns NaN when fewer than two usable points remain: a run that converges in one iteration exhibits no observable rate, and downstream bounds (e.g. the outer radius R = r/βᴷ) must treat that as unbounded rather than fabricate a number.
NSDETimeParallel.correct! — Method
correct!(cache, parareal, k; mpi=false)the serial Parareal correction sweep after fine batch k: re-run the coarse solver from the freshest starts and update U[n+1] = F[n+1] + (Gnew − Gold), writing in place against the U_ snapshot maintained by the iteration loop.
Two details make finite termination exact in floating point, not just in real arithmetic:
- Order of operations.
F + (Gnew − Gold)returnsFbitwise whenever the two coarse values cancel bitwise;(Gnew + F) − Golddoes not — it roundsFintoGnewfirst and loses low bits (withGnew = Gold = 1e16andF = 1it returns0). Do not "simplify" this expression. - The newly exact interface is assigned, not computed. After batch
kthe startU[k]is already exact, soF[k+1]is the exact value ofU[k+1]andU[k]has not moved sinceG[k+1]was last computed: the coarse re-run atn = kwould reproduceG[k+1]bitwise. Skip it and copyF[k+1]across — one coarse solve saved per sweep, and no arithmetic on the exact prefix at all.
NSDETimeParallel.costratio — Method
costratio(problem, parareal; repeats=3) :: Realmeasures ζ, the coarse/fine cost ratio over ONE chunk of problem under parareal's chunking — the input theoretical_speedup needs. Both solvers are timed on the first chunk with @elapsed (best of repeats, after a compile warm-up). Measure ζ rather than guessing it from step-size ratios: those ignore per-step cost differences between the two solvers.
NSDETimeParallel.flatten — Method
flatten(iterate::PararealIterate)concatenates the chunk solutions into one pair of vectors (u, t), dropping each chunk's FIRST point after chunk 1: boundaries are stored twice (chunk n's last point and chunk n+1's corrected start), and keeping both would double-weight every boundary in any downstream statistic. The kept value is the fine endpoint; the dropped corrected start agrees with it only to the solve tolerance. t is monotone.
NSDETimeParallel.flatten — Method
flatten(solution::PararealSolution)flattens the last iterate: one (u, t) pair for the whole span, chunk boundaries deduplicated.
NSDETimeParallel.iteration_budget — Method
iteration_budget(S::Real, N::Integer, ζ::Real; estimate=:wallclock) :: Intreturns the largest fine-batch budget K ∈ 1:N that reaches the target modelled speed-up S; returns zero if none does. A returned K permits K-1 corrections. This is a cost budget, not a prediction that the iteration converges within that budget.
Integer bisection inverts theoretical_speedup with the same cost model and exact-prefix coarse count. Both :wallclock (default) and :work are supported; :naive and :improved are aliases for them, respectively.
NSDETimeParallel.maxseam — Method
maxseam(iterate::PararealIterate) :: Realreturns the largest chunk-boundary seam of iterate (see seams), or 0.0 for a single-chunk iterate.
NSDETimeParallel.maxseam — Method
maxseam(solution::PararealSolution) :: Realmaxseam of the last iterate.
NSDETimeParallel.numchunks — Method
numchunks(iterate::PararealIterate)returns the number of chunks of iterate.
NSDETimeParallel.numchunks — Method
numchunks(solution::PararealSolution)returns the number of chunks of solution.
NSDETimeParallel.numiterates — Method
numiterates(solution::PararealSolution)returns the number of iterates of solution.
NSDETimeParallel.parareal! — Method
parareal!(cache, solution, problem, parareal, backend; saveiterates, directory, nocollect)runs Parareal with the given AbstractPararealBackend. Under MPI this is SPMD: every rank calls it; is_root guards the serial parts.
NSDETimeParallel.prepare_chunks! — Method
prepare_chunks!(cache::PararealCache, parareal::Parareal)rebuilds the chunk schedules and solver caches after a change of window or method.
NSDETimeParallel.prepare_problem! — Method
prepare_problem!(cache::PararealCache, problem, parareal)refreshes the initial data and RHS caches from problem; moving the time grid needs shiftwindow!.
NSDETimeParallel.reference — Method
reference(problem, parareal::Parareal) :: Vectorreturns the serial fine solution at the N + 1 chunk interfaces, computed on exactly the same absolute-time chunk grid and schedule as parareal.
NSDETimeParallel.residual — Method
evaluates a criterion from the current fine batch and its cached starts.
NSDETimeParallel.seams — Method
seams(iterate::PararealIterate) :: Vector{<:Real}returns the N − 1 chunk-boundary seam sizes of iterate: at each interior boundary, ‖(start of chunk n+1) − (end of chunk n)‖ — the distance between the corrected starting value U[n+1] and the fine endpoint F(U[n]) it should agree with at convergence. This is exactly the discontinuity that flatten hides by dropping the corrected start, so any statistical claim made on flattened output should report maxseam alongside it: under the weighted criterion ψ₂, late-window seams are unconstrained BY DESIGN (the discount forgives them), and only the seam sizes say which regime a run actually exercised. Empty for a single-chunk iterate.
NSDETimeParallel.seams — Method
seams(solution::PararealSolution) :: Vector{<:Real}seams of the last iterate.
NSDETimeParallel.shiftwindow! — Method
shiftwindow!(cache::PararealCache, τ0, τN)re-targets a cache at the window [τ0, τN]: recomputes the chunk grid T and updates every chunk problem's tspan in place. This is the official seam for window drivers (e.g. NSDEMovingWindow) — chunk problems are built once at cache construction, so their time spans must be moved through this function, never by poking cache.T alone.
NSDETimeParallel.theoretical_speedup — Method
theoretical_speedup(K::Integer, N::Integer, ζ::Real; estimate=:wallclock) :: Real
theoretical_speedup(diagnostics::PararealDiagnostics, ζ::Real; estimate=:wallclock) :: Real
theoretical_speedup(solution::PararealSolution, ζ::Real; estimate=:wallclock) :: Realreturns the modelled speed-up over N serial fine chunks. K is the number of fine batches, not corrections: a finite bulk return has s = K-1, with 1 ≤ K ≤ N. The cost ratio ζ is coarse/fine time per chunk; see costratio.
The exact-prefix implementation uses K_G = K*(N-1) - K*(K-1)/2 coarse calls and K*N - K*(K-1)/2 fine calls, including the initial coarse pass and final fine batch. The diagnostics overload uses the recorded call counts directly.
:wallclock(default) charges one fine-chunk time per batch and sequential coarse calls:N/(K + ζ*K_G). It assumes at least N workers and equal chunk costs, and excludes communication, synchronization, and load imbalance.:workdivides the total fine-call cost by N, retaining the same sequential coarse cost. This assumes perfect redistribution of the shrinking fine work; it is not the critical path of the bulk backend.
These are cost models, not measured speed-ups or unconditional performance bounds. The compatibility keyword wallclock=false selects :work, while an explicit estimate takes precedence. Pipeline diagnostics, nonfinite or unstarted runs, and runs with no fine batch are refused: a pipeline needs its task schedule.