compute_mode#

Back to L0 | Browse all axes | Browse all options

Axis compute_mode on sub-layer l0_a (layer l0).

Sub-layer#

l0_a

Axis metadata#

  • Default: 'serial'

  • Sweepable: False

  • Status: operational

  • Leaf-config keys: parallel_unit, n_workers

Operational status summary#

  • Operational: 2 option(s)

  • Future: 0 option(s)

Options#

serial – operational#

Run every sweep cell sequentially in the calling process.

The cell loop iterates expanded cells one at a time. No worker pool, no extra processes, no thread pool. parallel_unit is ignored.

This is the default because (a) most authoring sweeps are small enough that the cell loop dwarfs scheduling overhead, and (b) every parallel mode introduces an additional surface for scheduling-induced non-determinism that has to be ruled out explicitly. Pick parallel when wall-clock matters and the study has been validated under serial first.

When to use

Default. Authoring iteration, small sweeps, debugging, any case where a stack trace from a particular cell needs to be readable without thread / process noise.

When NOT to use

Multi-cell sweeps where each cell takes more than a minute and the machine has multiple CPU cores. Switch to parallel and record the speed-up in the manifest.

References

  • macroforecast design Part 1, L0 §A: ‘compute_mode = serial is the deterministic default; parallel modes are opt-in for wall-clock-sensitive sweeps.’

Related options: parallel

Examples

Default serial study

0_meta:
  fixed_axes:
    compute_mode: serial

Last reviewed 2026-05-04 by macroforecast author.

parallel – operational#

Distribute work over multiple workers; pick the unit via parallel_unit.

Activates the parallel cell loop. The granularity is controlled by the parallel_unit conditional leaf_config key:

  • cells – one process per sweep cell (ProcessPoolExecutor). Cell-level parallelism is the safest path because cells are by construction independent.

  • models – threads over fit_model nodes inside a single cell (issue #204). Sklearn-family estimators release the GIL; the thread pool avoids the pickling overhead of processes.

  • oos_dates – threads over walk-forward origins inside a fit node (issue #250). Per-origin RNG state is derived deterministically from base_seed + position (issue #279) so thread scheduling cannot affect the forecasts.

  • horizons / targets – map to the same fan-out when L4 produces single-horizon / single-target output per fit node.

leaf_config.n_workers caps the pool size.

When to use

Long sweeps on multi-core machines. Validate the manifest under compute_mode = serial first to confirm the recipe is deterministic, then flip to parallel and verify replicate() still passes.

When NOT to use

Recipes that mutate global state (e.g., a custom L3 op that writes to a shared file or a base estimator with a non-thread-safe C extension). Audit thread / process safety before flipping the switch.

References

  • macroforecast PR #173 – cell-level ProcessPoolExecutor.

  • macroforecast PR #204 / #250 – sub-cell ThreadPoolExecutor.

  • macroforecast PR #279 – deterministic per-origin seed propagation.

Related options: serial

Examples

Cell-level parallel sweep

0_meta:
  fixed_axes:
    compute_mode: parallel
    parallel_unit: cells
  leaf_config:
    n_workers: 4

Parameters

name

type

default

constraint

description

parallel_unit

str enum {cells, models, horizons, targets, oos_dates}

required when compute_mode=parallel; validator hard-rejects missing

Parallelization granularity. cells runs each sweep cell in a ProcessPoolExecutor worker; models/horizons/targets/oos_dates use sub-cell ThreadPoolExecutor at L4.

n_workers

`int

None`

None

None -> os.cpu_count() (or smaller per system); positive int caps the pool

Last reviewed 2026-05-04 by macroforecast author.