Skip to content

Environments (mtb.env)

Check, plan and install the environments mtb.run uses. install is a dry run until you pass dry_run=False. The environments are linux-64 only: on macOS and Windows only the dry run works.

Name Summary
mtb.env.status Report, per method, whether its conda env is installed on this machine.
mtb.env.plan List the conda envs a set of methods needs, one row per env.
mtb.env.install Install the conda envs a set of methods needs (a dry run by default).
mtb.env.doctor Report, per needed env, whether it is installed and has a lockfile.
mtb.env.recipe Return the hand-written environment recipe of a method.
mtb.env.env_prefix The on-disk prefix of a method environment, or None.
mtb.env.host_has_gpu Is an NVIDIA GPU visible on this host?
Details

On macOS and Windows, install(..., dry_run=False) raises RuntimeError unless force=True.

How the environment is entered describes how mtb.run enters an environment. The API overview describes the CPU and GPU builds and the GPU check.

mtb.env.status

status(conda: str | None = None, *, as_frame: bool = False)

Report, per method, whether its conda env is installed on this machine.

PARAMETERS DESCRIPTION
conda

conda/mamba executable, a path or a name on PATH, that lists the installed envs; None = conda if found, else mamba.

type str | None default None

as_frame

True returns a pandas.DataFrame with the same keys as columns.

type bool default False

RETURNS DESCRIPTION
list[dict] or DataFrame

One row per package method. Read method, env, exists and has_lock; all keys are listed in Notes.

RAISES DESCRIPTION
TypeError

conda is not a path or a name, e.g. a list of method ids.

ValueError

conda is a method id, or no executable has that path or name.

Examples

>>> import multibench as mtb
>>> df = mtb.env.status(as_frame=True)
>>> df.loc[~df.exists, ["method", "env", "has_lock"]]     # what is missing
>>> df.loc[df.method == "Matilda"].iloc[0].to_dict()
Notes

Selecting methods. status always reports every method and takes no method ids: status("Matilda") raises and names mtb.env.doctor(methods=["Matilda"]), which reports the envs of a selection. On the command line, multibench env status --methods ... prints only those methods.

Keys.

  • method - the method id.
  • env - the env the package uses for the method, the name mtb.scan and mtb.run use (mtb.method_info(m)['env']).
  • group - the same name as env.
  • own_env - the singleton name scmb_<method> (lower-case); the method also counts as installed when this env exists.
  • exists - env or own_env is installed here.
  • has_lock - a shipped lockfile can build env ([L] in multibench env status while the env is missing, as in multibench env doctor).
  • difficulty - a tag for how hard the env is to build (below).
  • verified_working - the env ran the method end-to-end on its reference dataset (the * after the tag in multibench env status).
  • has_recipe - the method declares a recipe (mtb.env.recipe).
  • flavor - 'cpu' / 'gpu' when the installed env came from a packed archive, 'single' for an env with one archive for CPU and GPU hosts, else None.

Difficulty tags. They describe how hard the env is to build from its recipe, not how well the method works (full text in mtb.env.DIFFICULTY):

  • easy - modern Python/torch stack; builds from the lockfile.
  • old-scvi / old-tensorflow - old scvi-tools or TensorFlow pins that need their own env.
  • R - an R env; the post-install script restores packages installed with install.packages().
  • verified - built from the lockfile on a fresh machine, and the method ran end-to-end on its reference dataset.
  • blocked-script - the env builds, but the upstream script cannot run unmodified from the public checkout.
  • unknown - no recipe declared.

What counts as installed. A prefix <envs_dir>/<env> with a bin/ directory (envs_dir = mtb.config.Config.envs_dir; no conda needed), or an env listed by conda env list of the conda given, else of the conda/mamba on PATH. The prefix probe runs whether or not conda is given.

See Also

mtb.env.doctor : the same information per env rather than per method.

mtb.env.install : builds or unpacks the missing envs.

mtb.env.plan

plan(
    category: str | None = None,
    methods: list[str] | None = None,
    *,
    as_frame: bool = False,
)

List the conda envs a set of methods needs, one row per env.

Methods that share an env collapse into one row.

PARAMETERS DESCRIPTION
category

Integration category (vertical, diagonal, mosaic or cross) whose methods to cover; None = every method.

type str | None default None

methods

Method ids to cover instead of category.

type list[str] | None default None

as_frame

True returns a pandas.DataFrame with the same keys as columns.

type bool default False

RETURNS DESCRIPTION
list[dict] or DataFrame

One row per env, the env serving the most methods first. Read env and methods; all keys are listed in Notes.

RAISES DESCRIPTION
ValueError

Unknown category; the message lists the valid ones.

KeyError

Unknown method id in methods; the message suggests a close match, if any.

TypeError

methods given as a bare string.

Examples

>>> import multibench as mtb
>>> mtb.env.plan("vertical", as_frame=True)[["env", "methods"]]
>>> mtb.env.plan(methods=["Matilda", "totalVI", "scMoMaT"])
Notes

Keys.

  • env - the conda env name, the one mtb.run activates.
  • shared - the env serves several methods (multibench env groups lists these shared envs).
  • methods - the selected methods this env serves, sorted.
  • flavor - 'cpu' / 'gpu' / 'single' when the env is installed here from a packed archive, else None.

Selection. methods takes precedence over category.

Command line. multibench env plan prints the same rows with each archive's download size and unpacked size on disk (the sizes recorded for this release; ? = not measured) and a total line.

See Also

mtb.env.install : builds or unpacks exactly these envs.

mtb.env.doctor : whether each of these envs exists here.

mtb.env.install

install(
    methods: list[str] | None = None,
    *,
    category: str | None = None,
    packed: bool = True,
    dry_run: bool = True,
    conda: str | None = None,
    force: bool = False,
    flavor: str = "auto",
) -> list[dict]

Install the conda envs a set of methods needs (a dry run by default).

The Python form of multibench env install. The default returns the plan; dry_run=False unpacks packed archives or builds from lockfiles, on Linux.

PARAMETERS DESCRIPTION
methods

Method ids to cover; None = every method of category, or every method.

type list[str] | None default None

category

Integration category (vertical, diagonal, mosaic or cross) whose methods to cover when methods is None.

type str | None default None

packed

Use a prebuilt conda-pack archive where one is published, else the lockfile; False = lockfile builds only.

type bool default True

dry_run

True = return the plan and install nothing; False = install the missing envs.

type bool default True

conda

conda/mamba executable; None = conda if found, else mamba. The packed path needs none.

type str | None default None

force

True = attempt a real install on a non-Linux host, which is refused otherwise.

type bool default False

flavor

Packed-archive build per env: 'cpu', 'gpu' or 'auto' ('cpu' unless an NVIDIA GPU is visible); unused when packed=False.

type str default 'auto'

RETURNS DESCRIPTION
list[dict]

One row per env, the env serving the most methods first. Read env, state and archive_bytes; all keys and state values are listed in Notes.

RAISES DESCRIPTION
ValueError

flavor is not 'auto', 'cpu' or 'gpu'; or unknown category.

KeyError

Unknown method id in methods; the message suggests a close match, if any.

TypeError

methods given as a bare string.

RuntimeError

dry_run=False only: a non-Linux host, no conda where needed, or a failed build.

WARNS DESCRIPTION
UserWarning

A CPU install finds no CPU archive for an env; its one archive is installed.

Examples

>>> import multibench as mtb
>>> mtb.env.install(["Matilda"])  # dry run: the plan, sizes, URLs
>>> mtb.env.install(["Matilda"], dry_run=False)  # packed archive, flavor='auto'
>>> mtb.env.install(category="vertical", dry_run=False, flavor="cpu")
>>> # lockfile build via conda
>>> mtb.env.install(["Matilda"], packed=False, dry_run=False)
Notes

Keys.

  • env / methods - the env and the selected methods it serves.
  • exists - the env is installed when the lockfile step runs: True for an env already there or just unpacked ('PACKED'), False for one this call builds or cannot build.
  • has_lock - a shipped lockfile can build the env.
  • state - what happened, or would happen (values below).
  • cmds - the lockfile commands run, or that would run.
  • packed_url / archive_bytes / unpacked_bytes - the archive the flavour selects and its sizes; None unless packed and known (a size not measured yet is None).
  • flavor - for an installed env, the archive it came from (None when unrecorded); for a missing env, the flavour the packed path would install, or None when packed=False.

State values on a dry run.

  • 'have' - already installed.
  • 'packed archive published' - an archive would be downloaded; the sizes and URL are filled in.
  • 'no archive - lockfile build' / 'no archive - NO-LOCK' - packed=True but no archive is published; the lockfile builds the env, or there is no lockfile either.
  • 'build(dry-run)' / 'NO-LOCK' - packed=False; the lockfile builds the env, or there is none.

State values after a real install (dry_run=False).

  • 'PACKED' - unpacked from an archive.
  • 'BUILD' - built from the lockfile.
  • 'have' - already installed.
  • 'NO-LOCK' - no lockfile and no archive unpacked; reported, not built.

Flavours. The env name and prefix are the same whatever the flavour.

  • 'gpu' - the '<env>' archive, which every env has.
  • 'cpu' - the '<env>-cpu' archive (the same env without the CUDA libraries, several times smaller) where published; otherwise the '<env>' archive and one UserWarning.
  • 'auto' - 'cpu' when mtb.env.host_has_gpu() is False (no nvidia-smi -L output and no /proc/driver/nvidia/version), else 'gpu'.

The dry-run sizes and URL follow the flavour: a CPU host sees the CPU archives' download total. The flavour installed is recorded in the env prefix and shown by mtb.env.status, mtb.env.doctor and mtb.env.plan.

Installing for other hosts. 'auto' decides by this host. When it picks the CPU builds, one line on stderr says so; pass flavor='gpu' (--flavor gpu) when the envs serve jobs on GPU nodes.

Order of work (dry_run=False). With packed, each missing env is first tried as an archive (the URL recorded for this release, else the default release URL). An HTTP error on the download or a failed unpack falls back to the lockfile build; envs with no lockfile are reported 'NO-LOCK', not built.

Where envs go. Archives unpack into mtb.config.Config.envs_dir (or, when conda is given, that tool's envs dir). The runner activates the prefix directly, so the packed path works without conda (Colab, laptops without conda).

Errors. flavor is checked before anything else. With dry_run=False:

  • Archives and lockfiles are linux-64, so a non-Linux host raises RuntimeError before any download unless force=True.
  • Without conda/mamba, a missing env that needs a lockfile build raises RuntimeError before any download. It starts "Conda is not installed on this computer. Environment <env> has a packed archive." when packed=False skipped a published archive, and says "... has no packed archive. Install conda first." otherwise.
  • A failed build command raises RuntimeError with its stderr tail.

Command line. multibench env install --methods X --packed --run takes the packed path; multibench env install --run builds from lockfiles (the CLI's --packed is off by default). The per-env steps are mtb.env.install_packed (one archive) and mtb.env.create_all (lockfile builds).

See Also

mtb.env.plan : the envs a set of methods needs, before installing.

mtb.env.doctor : which of those envs exist here.

mtb.env.status : install status per method.

mtb.env.doctor

doctor(
    category: str | None = None,
    methods: list[str] | None = None,
    conda: str | None = None,
    *,
    as_frame: bool = False,
)

Report, per needed env, whether it is installed and has a lockfile.

Run it before mtb.run on a new machine; mtb.env.install installs the envs it reports missing.

PARAMETERS DESCRIPTION
category

Integration category (vertical, diagonal, mosaic or cross) whose methods to check; None = every method.

type str | None default None

methods

Method ids to check instead of category.

type list[str] | None default None

conda

conda/mamba executable that lists the installed envs; None = conda if found, else mamba.

type str | None default None

as_frame

True returns a pandas.DataFrame with the same keys as columns.

type bool default False

RETURNS DESCRIPTION
list[dict] or DataFrame

One row per env, the env serving the most methods first. Read env, exists and has_lock; all keys are listed in Notes.

RAISES DESCRIPTION
ValueError

Unknown category; the message lists the valid ones.

KeyError

Unknown method id in methods; the message suggests a close match, if any.

TypeError

methods given as a bare string.

Examples

>>> import multibench as mtb
>>> mtb.env.doctor("vertical", as_frame=True)
>>> rows = mtb.env.doctor(methods=["Matilda", "totalVI"])
>>> [r["env"] for r in rows if not r["exists"]]
Notes

Keys. The marks in brackets are the ones multibench env doctor prints per env and multibench env status prints per method.

  • env / methods - the env and the selected methods it serves.
  • exists - the env is installed here ([x]).
  • has_lock - the package ships a lockfile for the env, so multibench env install --run can build it ([L] while missing). A missing env without one ([!]) needs a packed archive or the recipe (mtb.env.recipe).
  • flavor - 'cpu' / 'gpu' / 'single' when the installed env came from a packed archive, else None.

Next step. A fresh machine reports exists=False everywhere. mtb.env.install(methods, dry_run=False) installs the missing envs, packed archives first; on the command line that is multibench env install --methods ... --packed --run (the # next line multibench env doctor prints), while plain multibench env install --run builds from lockfiles only. Linux only: on macOS and Windows the install is refused unless force=True.

See Also

mtb.env.install : builds or unpacks the envs reported missing.

mtb.env.status : the same information per method.

mtb.scan : its env_ok column uses the same installed-env check.

mtb.env.recipe

recipe(method: str) -> dict

Return the hand-written environment recipe of a method.

The readable alternative to the lockfile: which Python, conda and pip packages the method's env needs, with caveats.

PARAMETERS DESCRIPTION
method

Method id, e.g. "Matilda"; see mtb.list_methods().

type str

RETURNS DESCRIPTION
dict

The recipe as a dict; {} when the method declares none. Read conda_packages, pip_packages and caveats; all keys are listed in Notes.

RAISES DESCRIPTION
KeyError

Unknown method id; the message suggests a close match, if any.

Examples

>>> import multibench as mtb
>>> mtb.env.recipe("Matilda")["conda_packages"]
>>> mtb.env.recipe("Matilda").get("caveats")
Notes

Keys.

  • python_version - the Python pin of the create line.
  • conda_channels / conda_packages - the conda create line.
  • pip_packages / pip_git - installed with pip afterwards (pip_git from git URLs).
  • package_source - where the method's own code comes from (PyPI, CRAN, vendored in tools_scripts/ ...).
  • difficulty / verified_working - the same values as in mtb.env.status.
  • caveats - free-text notes on the recipe.

Command line. multibench env recipe METHOD prints the recipe as conda/pip commands and multibench env yml METHOD as an environment.yml; by default both name the env the way mtb.scan and mtb.run expect it. The env mtb.run relies on is the lockfile or packed-archive build (mtb.env.install); a recipe build can miss what mtb.run needs (see caveats).

See Also

mtb.env.install : installs the env mtb.run relies on (packed archive or lockfile).

mtb.env.status : has_recipe and difficulty per method.

Importable helpers

Two helpers for the run modes and the CPU and GPU builds. Import them from mtb.env; they are not in mtb.env.__all__.

mtb.env.env_prefix

env_prefix(env: str, conda: str | None = None) -> Path | None

The on-disk prefix of a method environment, or None.

PARAMETERS DESCRIPTION
env

Environment name, e.g. "matilda" (mtb.method_info(m)["env"]).

type str

conda

conda/mamba executable to ask when the env is not under envs_dir; None = the one on PATH, if any.

type str default None

RETURNS DESCRIPTION
Path or None

The environment's prefix; None when it is not installed.

Examples

>>> import multibench as mtb
>>> mtb.env.env_prefix("matilda")       # None until the env is installed
Notes

Lookup order. <mtb.config.DEFAULT.envs_dir>/<env> when that folder contains bin/ (an unpacked archive or a conda-built env there; no conda needed); otherwise, when a conda/mamba binary is found, the prefix conda env list reports for that name; otherwise None.

Where it is used. This is what "installed" means everywhere (mtb.env.doctor, env_ok in mtb.scan) and the prefix the runner activates.

mtb.env.host_has_gpu cached

host_has_gpu() -> bool

Is an NVIDIA GPU visible on this host?

RETURNS DESCRIPTION
bool

True when a GPU is visible; False on a CPU-only host.

Examples

>>> import multibench as mtb
>>> mtb.env.host_has_gpu()
Notes

Detection. True when nvidia-smi -L runs and lists at least one device, or when /proc/driver/nvidia/version exists (driver loaded, tool not on PATH). A torch install, CUDA_VISIBLE_DEVICES or a CUDA library on disk do not count.

Where it is used. mtb.env.install(flavor="auto") picks the GPU or CPU archives from it.

Caching. The result is cached per process; mtb.env.host_has_gpu.cache_clear() probes again.