Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ All notable changes to this project are documented here.

### Added

- `stack order --installed` stops the build order at modules already on
the machine. A file is a module listing and a directory is an Lmod
tree, read the same way as `stack gap --installed`. The version is the
full module version. A listed module is left out of the order, and so
are the dependencies that were installed with it. `--filter-deps`
still drops dependencies first. The modules that remain are chosen
with the synthetic GCC-family rule `recipe hierarchy --export`
prints. Stdout reports `installed=` as how many modules the walk
stopped at. `eb_stack_order` takes the same `installed` list.
- `stack shadow` reports a site-layer recipe that shadows a module the
EESSI base stack already provides. `--base` is an Lmod tree or a module
listing, loaded with the same inventory reader as `stack gap`. The same
Expand Down Expand Up @@ -270,6 +279,9 @@ include `stack gap`, `stack oom`, `stack from-commit`, `rebuild-set`,
`source probe:`. With no `--arch` all three are still probed. With one
family there is nothing to compare with, so a source it cannot fetch
is `unreachable` rather than `arch-missing`, and still exits 1.
Two families compare only with each other: a miss is `arch-missing`
when the other named family fetched that source slot, and
`unreachable` when neither did.
- `classify_build_failure` classes `No space left on device` and
`Disk quota exceeded` as `resource`. A full disk in an EasyBuild log was
`compile` before.
Expand Down
36 changes: 36 additions & 0 deletions docs/orgmode/howto/arch-unsupported.org
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,40 @@ same source slot resolves to a file that exists on another
architecture. ~--arch x86_64~ on this fixture probes only the x86_64
wheel, which the server has, and exits 0.

** Two architectures

What it does: ~--arch x86_64 --arch aarch64 --probe-sources~ probes
those two families and no other. A target such as ~x86_64/amd/zen4~
is still the family before the slash. Naming a family and one of its
targets, ~--arch aarch64 --arch aarch64/neoverse_v1~, probes that
family once. The order of the flags does not change the report.

Why you'd use it: two bot targets failed the fetch and a third was
not in the run. The comparison is between the families that were
named. A family left off the command is not fetched, and it does not
turn ~arch-missing~ into ~unreachable~ or the other way around.

#+begin_src bash
eb-stack stack arch \
--arch x86_64 \
--arch aarch64 \
--easystack tests/source_probe_fixtures/easystacks/kaleido.yml \
--easyconfigs tests/source_probe_fixtures/easyconfigs \
--probe-sources
#+end_src

On the same copy and server it prints:

#+begin_example
Kaleido-0.2.1-GCCcore-15.2.0.eb source kaleido-0.2.1-manylinux2014-aarch64.whl is arch-missing on aarch64: __BASE_URL__/kaleido-0.2.1-manylinux2014-aarch64.whl (attempt 1/3 HEAD=status:404 RANGE=status:404)
parse_failed=0 unsupported=0 flagged=0 source_unreachable=0 source_arch_missing=1
#+end_example

How to read it: the x86_64 wheel is on the server, so the aarch64
wheel is ~arch-missing~. riscv64 is not named and is not probed. The
same command with ~--arch aarch64 --arch riscv64~ prints both wheels
as ~unreachable~, with ~source_unreachable=2~ and
~source_arch_missing=0~, because neither probed family fetched the
source slot. The x86_64 wheel is not consulted.

See [[file:../reference/cli.org][the command-line reference]].
19 changes: 19 additions & 0 deletions docs/orgmode/howto/solve-lock.org
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,25 @@ eb-stack stack order \
requirement. The hash file is one ~<sha256> <module>~ line per build.
See [[file:../reference/cli.org][the CLI reference]].

~--installed~ stops the walk at modules the site already has, the way
the robot does. ~--filter-deps~ still drops dependencies before that
walk. The two compose: a filtered dependency is gone, and a listed
module is a leaf whose own dependencies are not ordered.

#+begin_src bash
eb-stack stack order \
--easyconfigs fixtures/gromacs_2025_to_next/easyconfigs \
--root GROMACS \
--installed fixtures/stack_order_installed/installed.txt \
--filter-deps FFTW \
--out /tmp/build-order.txt
#+end_src

The order file has no ~OpenBLAS~ path and no ~FFTW~ path. ~GROMACS~ is
still in it. Standard output ends with ~installed=1~ and then
~order=/tmp/build-order.txt builds=~. ~installed=1~ is OpenBLAS. FFTW
was filtered, so it is not a leaf the walk stopped at.

* One lock per toolchain family

A foss solve only sees the foss hierarchy.
Expand Down
28 changes: 25 additions & 3 deletions docs/orgmode/reference/cli.org
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ eb-stack stack order \
--easyconfigs TREE [--easyconfigs OVERLAY]... \
--root NAME [--root NAME==VERSION]... \
[--filter-deps NAME,NAME...] \
[--installed LIST]... \
[--out /tmp/build-order.txt] \
[--oldest] \
[--easystack-out /tmp/order.yml] \
Expand Down Expand Up @@ -644,7 +645,20 @@ not repin a recipe. See [[file:../howto/solve-lock.org][Order every pinned build
~name==version~ pins one build. ~--filter-deps~ drops each named
dependency before that order is built, together with the subtree under
it, using the same matching as ~stack solve~; when the flag is absent
the command reads ~EASYBUILD_FILTER_DEPS~. ~--oldest~ takes the oldest
the command reads ~EASYBUILD_FILTER_DEPS~. ~--installed~ repeats. A file
is ~module -t avail~, ~module spider -t~, or ~Name/version~, and a
directory is an Lmod tree, both read the same way as
~stack gap --installed~. The version is the full module version,
~1.3.1-GCCcore-15.2.0~, the spelling under ~modules/all~. A system
toolchain contributes no toolchain segment. A listed module is a leaf:
it stays out of the order, and so do the dependencies that were
installed with it. A dependency the tree cannot resolve is still an
error. The walk that remains uses the synthetic GCC-family rule
~recipe hierarchy --export~ prints, so an unpinned dependency of a
~GCC~ or ~GCCcore~ recipe stays in that family. ~--filter-deps~ is
applied first, so a filtered dependency is not counted as a leaf. The
line ~installed=<N>~ just before ~order=~ is how many distinct modules
the walk stopped at. ~--oldest~ takes the oldest
admissible version of an unpinned requirement, and the default is the
newest. ~--out~ is one easyconfig path per line (default
~build-order.txt~). ~--easystack-out~ writes that same sequence as an
Expand Down Expand Up @@ -863,6 +877,9 @@ fallback, on each family ~--arch~ names, or on ~x86_64~, ~aarch64~,
and ~riscv64~ with no ~--arch~. A source no probed family can fetch is
~unreachable~. A source another probed family can fetch is
~arch-missing~, so with one ~--arch~ a missing source is ~unreachable~.
Two ~--arch~ values compare only that pair: a miss is ~arch-missing~
when the other named family fetched the same source slot, and
~unreachable~ when neither did.
~--probe-retries~ and ~--probe-timeout-s~ tune that network check.

[[file:../howto/arch-unsupported.org][Refuse a plan an architecture cannot build]]
Expand Down Expand Up @@ -1792,8 +1809,12 @@ table and the derived-key rules. ~eb_recipe_hierarchy~ takes ~export~.
The plain call prints the fixture generations. ~export~ true adds the
synthetic GCC-family rule, the same split as ~recipe hierarchy --export~.
~eb_stack_order~ requires ~easyconfigs~ and ~root~, and takes ~out~,
~oldest~, ~easystack_out~, ~hashes_out~, and ~filter_deps~.
~oldest~, ~easystack_out~, ~hashes_out~, ~filter_deps~, and ~installed~.
~filter_deps~ drops the same dependencies ~--filter-deps~ drops.
~installed~ is the module list or Lmod tree ~--installed~ reads. A
module it names is left out of the order. The result field ~installed~
is how many modules the walk stopped at, and is null when the argument
is omitted.
~eb_stack_easystack~ requires ~lock~ and takes ~out~ and ~option~, each
option a ~<file.eb>:<option>=<value>~ string, and ~eessi_version~,
~easybuild_version~, ~generation~, and ~out_dir~ for the software-layer
Expand All @@ -1815,7 +1836,8 @@ text is the same report as ~stack provided~. ~eb_stack_arch~ requires
~probe_sources~, ~probe_retries~, and ~probe_timeout_s~. It returns the
same report as ~stack arch~, with ~parse_failed~ and ~source_findings~,
and a hit is a tool error. ~probe_sources~ probes the families ~arch~
names, as ~--arch~ does. ~eb_stack_files~ requires ~easystack~ and takes
names, as ~--arch~ does. Two names are compared only with each other.
~eb_stack_files~ requires ~easystack~ and takes
~easyconfigs~, ~commit_tree~, ~easyconfigs_repo~, ~sourcepath~, and
~path_map~. It returns the same report as ~stack files~, and a missing
file is a tool error. ~eb_stack_cuda_cc~ requires ~easystack~ and ~easyconfigs~,
Expand Down
9 changes: 6 additions & 3 deletions docs/orgmode/reference/formats.org
Original file line number Diff line number Diff line change
Expand Up @@ -219,16 +219,19 @@ solver selection, not a scan of installed software.

One easyconfig path per line, in dependency order. A name EasyBuild
installs twice lists both paths: another toolchain, a system bootstrap
pair, or a build-only tool. ~--oldest~ changes which unpinned version is
chosen; it does not change the file shape. When runtime requirements of
pair, or a build-only tool. ~--installed~ leaves a listed module, and
the dependencies that were installed with it, out of this file.
~--oldest~ changes which unpinned version is chosen; it does not change
the file shape. When runtime requirements of
one name at one toolchain have no version that satisfies every one of
them, the command writes no file and exits 1. Standard error names each
requester and the version it resolved. The file is not a place where a
pin is rewritten.

Stdout names a co-installable repeated build as
~multiple builds of <name>: <ver-tc>, ...~ and ends with
~order=<path> builds=<N>~.
~order=<path> builds=<N>~. When ~--installed~ is set, the line before
that is ~installed=<N>~, how many listed modules the walk stopped at.

* Input hashes (~--hashes-out~)

Expand Down
2 changes: 2 additions & 0 deletions fixtures/stack_order_installed/installed.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# OpenBLAS is already installed. The version is the full module version.
OpenBLAS/0.3.27-foss-2025b
92 changes: 86 additions & 6 deletions llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,25 @@ eb-stack stack order \
requirement. The hash file is one `<sha256> <module>` line per build.
See [the CLI reference](https://eb-stack.rgoswami.me/../reference/cli.html.md).

`--installed` stops the walk at modules the site already has, the way
the robot does. `--filter-deps` still drops dependencies before that
walk. The two compose: a filtered dependency is gone, and a listed
module is a leaf whose own dependencies are not ordered.

```bash
eb-stack stack order \
--easyconfigs fixtures/gromacs_2025_to_next/easyconfigs \
--root GROMACS \
--installed fixtures/stack_order_installed/installed.txt \
--filter-deps FFTW \
--out /tmp/build-order.txt
```

The order file has no `OpenBLAS` path and no `FFTW` path. `GROMACS` is
still in it. Standard output ends with `installed=1` and then
`order=/tmp/build-order.txt builds=`. `installed=1` is OpenBLAS. FFTW
was filtered, so it is not a leaf the walk stopped at.

# One lock per toolchain family

A foss solve only sees the foss hierarchy.
Expand Down Expand Up @@ -3850,6 +3869,42 @@ same source slot resolves to a file that exists on another
architecture. `--arch x86_64` on this fixture probes only the x86_64
wheel, which the server has, and exits 0.

## Two architectures

What it does: `--arch x86_64 --arch aarch64 --probe-sources` probes
those two families and no other. A target such as `x86_64/amd/zen4`
is still the family before the slash. Naming a family and one of its
targets, `--arch aarch64 --arch aarch64/neoverse_v1`, probes that
family once. The order of the flags does not change the report.

Why you'd use it: two bot targets failed the fetch and a third was
not in the run. The comparison is between the families that were
named. A family left off the command is not fetched, and it does not
turn `arch-missing` into `unreachable` or the other way around.

```bash
eb-stack stack arch \
--arch x86_64 \
--arch aarch64 \
--easystack tests/source_probe_fixtures/easystacks/kaleido.yml \
--easyconfigs tests/source_probe_fixtures/easyconfigs \
--probe-sources
```

On the same copy and server it prints:

```
Kaleido-0.2.1-GCCcore-15.2.0.eb source kaleido-0.2.1-manylinux2014-aarch64.whl is arch-missing on aarch64: __BASE_URL__/kaleido-0.2.1-manylinux2014-aarch64.whl (attempt 1/3 HEAD=status:404 RANGE=status:404)
parse_failed=0 unsupported=0 flagged=0 source_unreachable=0 source_arch_missing=1
```

How to read it: the x86_64 wheel is on the server, so the aarch64
wheel is `arch-missing`. riscv64 is not named and is not probed. The
same command with `--arch aarch64 --arch riscv64` prints both wheels
as `unreachable`, with `source_unreachable=2` and
`source_arch_missing=0`, because neither probed family fetched the
source slot. The x86_64 wheel is not consulted.

See [the command-line reference](https://eb-stack.rgoswami.me/../reference/cli.html.md).

# Find a missing patch before the bot does
Expand Down Expand Up @@ -6534,6 +6589,7 @@ eb-stack stack order \
--easyconfigs TREE [--easyconfigs OVERLAY]... \
--root NAME [--root NAME==VERSION]... \
[--filter-deps NAME,NAME...] \
[--installed LIST]... \
[--out /tmp/build-order.txt] \
[--oldest] \
[--easystack-out /tmp/order.yml] \
Expand Down Expand Up @@ -6746,7 +6802,20 @@ not repin a recipe. See [Order every pinned build](https://eb-stack.rgoswami.me/
`name==version` pins one build. `--filter-deps` drops each named
dependency before that order is built, together with the subtree under
it, using the same matching as `stack solve`; when the flag is absent
the command reads `EASYBUILD_FILTER_DEPS`. `--oldest` takes the oldest
the command reads `EASYBUILD_FILTER_DEPS`. `--installed` repeats. A file
is `module -t avail`, `module spider -t`, or `Name/version`, and a
directory is an Lmod tree, both read the same way as
`stack gap --installed`. The version is the full module version,
`1.3.1-GCCcore-15.2.0`, the spelling under `modules/all`. A system
toolchain contributes no toolchain segment. A listed module is a leaf:
it stays out of the order, and so do the dependencies that were
installed with it. A dependency the tree cannot resolve is still an
error. The walk that remains uses the synthetic GCC-family rule
`recipe hierarchy --export` prints, so an unpinned dependency of a
`GCC` or `GCCcore` recipe stays in that family. `--filter-deps` is
applied first, so a filtered dependency is not counted as a leaf. The
line `installed=<N>` just before `order=` is how many distinct modules
the walk stopped at. `--oldest` takes the oldest
admissible version of an unpinned requirement, and the default is the
newest. `--out` is one easyconfig path per line (default
`build-order.txt`). `--easystack-out` writes that same sequence as an
Expand Down Expand Up @@ -6965,6 +7034,9 @@ fallback, on each family `--arch` names, or on `x86_64`, `aarch64`,
and `riscv64` with no `--arch`. A source no probed family can fetch is
`unreachable`. A source another probed family can fetch is
`arch-missing`, so with one `--arch` a missing source is `unreachable`.
Two `--arch` values compare only that pair: a miss is `arch-missing`
when the other named family fetched the same source slot, and
`unreachable` when neither did.
`--probe-retries` and `--probe-timeout-s` tune that network check.

[Refuse a plan an architecture cannot build](https://eb-stack.rgoswami.me/../howto/arch-unsupported.html.md)
Expand Down Expand Up @@ -7894,8 +7966,12 @@ table and the derived-key rules. `eb_recipe_hierarchy` takes `export`.
The plain call prints the fixture generations. `export` true adds the
synthetic GCC-family rule, the same split as `recipe hierarchy --export`.
`eb_stack_order` requires `easyconfigs` and `root`, and takes `out`,
`oldest`, `easystack_out`, `hashes_out`, and `filter_deps`.
`oldest`, `easystack_out`, `hashes_out`, `filter_deps`, and `installed`.
`filter_deps` drops the same dependencies `--filter-deps` drops.
`installed` is the module list or Lmod tree `--installed` reads. A
module it names is left out of the order. The result field `installed`
is how many modules the walk stopped at, and is null when the argument
is omitted.
`eb_stack_easystack` requires `lock` and takes `out` and `option`, each
option a `<file.eb>:<option>=<value>` string, and `eessi_version`,
`easybuild_version`, `generation`, and `out_dir` for the software-layer
Expand All @@ -7917,7 +7993,8 @@ text is the same report as `stack provided`. `eb_stack_arch` requires
`probe_sources`, `probe_retries`, and `probe_timeout_s`. It returns the
same report as `stack arch`, with `parse_failed` and `source_findings`,
and a hit is a tool error. `probe_sources` probes the families `arch`
names, as `--arch` does. `eb_stack_files` requires `easystack` and takes
names, as `--arch` does. Two names are compared only with each other.
`eb_stack_files` requires `easystack` and takes
`easyconfigs`, `commit_tree`, `easyconfigs_repo`, `sourcepath`, and
`path_map`. It returns the same report as `stack files`, and a missing
file is a tool error. `eb_stack_cuda_cc` requires `easystack` and `easyconfigs`,
Expand Down Expand Up @@ -9239,16 +9316,19 @@ solver selection, not a scan of installed software.

One easyconfig path per line, in dependency order. A name EasyBuild
installs twice lists both paths: another toolchain, a system bootstrap
pair, or a build-only tool. `--oldest` changes which unpinned version is
chosen; it does not change the file shape. When runtime requirements of
pair, or a build-only tool. `--installed` leaves a listed module, and
the dependencies that were installed with it, out of this file.
`--oldest` changes which unpinned version is chosen; it does not change
the file shape. When runtime requirements of
one name at one toolchain have no version that satisfies every one of
them, the command writes no file and exits 1. Standard error names each
requester and the version it resolved. The file is not a place where a
pin is rewritten.

Stdout names a co-installable repeated build as
`multiple builds of <name>: <ver-tc>, ...` and ends with
`order=<path> builds=<N>`.
`order=<path> builds=<N>`. When `--installed` is set, the line before
that is `installed=<N>`, how many listed modules the walk stopped at.

# Input hashes (`--hashes-out`)

Expand Down
Loading
Loading