Skip to content
Open
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
169 changes: 169 additions & 0 deletions .agents/skills/ams-build/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
---
name: ams-build
description: >-
Build and install the AMS library (github.com/LLNL/AMS) from source on an HPC
cluster via CMake. Use this whenever the user wants to compile, configure,
build, or install AMS, or is choosing between build variants (with/without
RabbitMQ, GPU, MPI, Caliper, etc.). ALWAYS use this skill for AMS build/CMake
questions even when phrased loosely ("get AMS running on Tioga", "why can't
CMake find Torch", "AMS build with RabbitMQ"). It knows how to gather AMS's
dependencies two ways: via LLNL Livermore Computing's internal Spack
environment (the easy path on LC machines) or by pointing CMake at
manually-provided libraries on any other cluster.
---

# Installing AMS from source

AMS is a C++ library built with CMake. The build itself is easy; the hard part
is **gathering the dependencies** so `find_package` succeeds. This skill's job
is to (1) figure out which dependency-provisioning path applies, and (2) hand
the user a correct CMake configure line for their chosen feature set. For help
regarding the installation process, please check `INSTALL.md`.

## Where do the dependencies come from?

Run the check and branch **before** writing any CMake command:

- **On an LLNL Livermore Computing (LC) cluster** — the AMS team maintains a
prebuilt internal Spack environment. Source the repo's own
`scripts/gitlab/setup-env.sh`; it activates Spack, activates the per-host
environment, and exports `AMS_TORCH_PATH`, `AMS_HDF5_PATH`,
`AMS_CALIPER_PATH`, `AMS_AMQPCPP_PATH`, `AMS_CUDA_ARCH`, etc. Then you just
feed those into CMake. This is the path to prefer whenever it's available.

- **On any other cluster** — Assume there is no shared environment unless
stated otherwise.
Each dependency must be installed (Spack, a module system, or by hand)
and CMake pointed at each one via its `*_DIR` config-package hint
or `CMAKE_PREFIX_PATH`.
See `references/manual-deps.md`.

Detect LC by the presence of the internal environment directory:

```bash
if [[ -d /usr/workspace/AMS/ams-spack-environments ]]; then
echo "LC cluster: use scripts/gitlab/setup-env.sh"
else
echo "Non-LC: provide dependencies manually (references/manual-deps.md)"
fi
```

`$SYS_TYPE` is a secondary signal on LC (`toss_4_x86_64_ib` = Dane/CTS-1,
`toss_4_x86_64_ib_cray` = Tuolumne/Tioga/El Capitan-class ROCm machines).

## Dependencies at a glance (current `develop`)

Always required: **nlohmann_json**, **HDF5** (C/CXX), **libTorch**, plus a C++17
compiler and Threads. `fmt` and `tl::expected` are fetched automatically by
CMake — the user never installs them.

Enabled only by a flag: **MPI** (`WITH_MPI`), **CUDA** (`WITH_CUDA`) or **HIP/ROCm**
(`WITH_HIP`), **Caliper** (`WITH_CALIPER`), **RabbitMQ** back end (`WITH_RMQ` →
pulls in `amqp-cpp`, `OpenSSL`, `libevent`), **PerfFlowAspect**
(`WITH_PERFFLOWASPECT`).

The full option table, defaults, and the CMake hint variable for each package
are in `references/cmake-options.md`. Read it before answering flag-specific
questions — do not rely on the repo's `INSTALL.md`, which is stale (it lists
removed flags like `WITH_DB`, `WITH_TORCH`, `WITH_FAISS`, `WITH_EXAMPLES`).

## Use cases (pick the smallest set that meets the need)

1. **Minimal / CPU** — core library only. No MPI, no GPU, no RabbitMQ.
File-based (HDF5) storage. Good first build to prove the toolchain works.
2. **+ MPI** — add `-DWITH_MPI=On` for distributed applications.
3. **+ GPU** — add `-DWITH_CUDA=On` (NVIDIA) or `-DWITH_HIP=On` (AMD/ROCm).
Never both. On LC ROCm machines the setup script loads `rocm` and sets the
arch for you.
4. **+ RabbitMQ** — add `-DWITH_RMQ=On` to stream data to a running RabbitMQ
broker instead of (or alongside) HDF5 files. This is the "with RabbitMQ"
variant and requires a reachable broker at runtime; see the RMQ note below.
5. **+ profiling** — `-DWITH_CALIPER=On` and/or `-DWITH_PERFFLOWASPECT=On`.
6. **+ Python workflow drivers** — `-DWITH_WORKFLOW=On` installs the outer
`AMSWorkflow` Python drivers.

These compose freely, e.g. MPI + CUDA + RabbitMQ for a distributed GPU run that
streams training data.

## The workflow

### Step 1 — clone

```bash
git clone https://github.com/LLNL/AMS.git
cd AMS
```

### Step 2 — provision dependencies

**LC cluster:**

```bash
source scripts/gitlab/setup-env.sh # activates Spack + exports AMS_*_PATH
```

**Non-LC cluster:** install the required packages and export the hint
variables CMake expects (see `references/manual-deps.md`), e.g.

```bash
export CMAKE_PREFIX_PATH=/path/to/installs:$CMAKE_PREFIX_PATH
export Torch_DIR=/path/to/libtorch/share/cmake/Torch
export AMS_HDF5_DIR=/path/to/hdf5
```

### Step 3 — configure

Use the helper script `scripts/ams-configure.sh` (it assembles the flags, maps the
`AMS_*_PATH` exports to the right `-D…_DIR` on LC, and prints the full command
before running). Examples:

```bash
# Minimal CPU build
scripts/ams-configure.sh

# With RabbitMQ + MPI
scripts/ams-configure.sh --rmq --mpi

# GPU (CUDA) + Caliper, custom install prefix
scripts/ams-configure.sh --cuda --caliper --install-prefix $HOME/opt/ams

# See the exact cmake line without running it
scripts/ams-configure.sh --rmq --mpi --dry-run
```

Or write the CMake command directly — see the annotated templates in
`INSTALL.md`.

### Step 4 — build & install

```bash
cmake --build build -j "$(nproc)"
cmake --install build # honors -DCMAKE_INSTALL_PREFIX
```

## RabbitMQ note

`WITH_RMQ` compiles the AMQP client (`amqp-cpp` + `OpenSSL` + `libevent`). It
does **not** stand up a broker. At runtime AMS needs a reachable RabbitMQ
service and TLS/credentials config (host, port, vhost, cert). If the user only
wants local, file-based storage, leave `WITH_RMQ` off and AMS uses the HDF5
back end — no broker required.

## Common failure modes

- **`Could NOT find Torch` / `HDF5` / `nlohmann_json`** — on LC you forgot to
`source scripts/gitlab/setup-env.sh` (or are on a login node with no
`$SYS_TYPE`). Off LC, the corresponding `*_DIR` / `CMAKE_PREFIX_PATH` isn't
set. Torch and HDF5 are mandatory on current `develop`, so a bare `cmake`
with no dependency hints will not configure.
- **`Could NOT find amqpcpp` / `libevent`** — only appears with `-DWITH_RMQ=On`;
provide `amqpcpp_DIR` (LC: `$AMS_AMQPCPP_PATH`) and libevent.
- **Both CUDA and HIP set** — CMake hard-errors; choose one.
- **C++ standard clashes** — AMS uses C++17; an application/Flux stack forcing
C++20 can conflict with the RMQ path. See the comment at the top of
`CMakeLists.txt`.

## Files in this skill

- `references/manual-deps.md` — how to obtain each dependency on a non-LC
cluster and which CMake variable points at it.
4 changes: 4 additions & 0 deletions .agents/skills/ams-build/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "AMS Build"
short_description: "Skill to build the AMS library"
default_prompt: "Use $ams-build to build AMS"
75 changes: 75 additions & 0 deletions .agents/skills/ams-build/references/manual-deps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Providing AMS dependencies on a non-LC cluster

Off the LLNL Livermore Computing systems there is no shared AMS Spack
environment, so you must provide each dependency yourself and point CMake at it.
Three broad approaches, roughly easiest → most manual:

## Option A — Spack (recommended if available)

If your site has Spack and an `ams` package in a reachable repo:

```bash
spack install ams # resolves the whole dependency tree
spack load ams # or build against it as a dev package
```

For active development, `spack dev-build ams` builds from your working copy.
If your Spack does not have an `ams` package, install the dependencies
individually and use Option C:

```bash
spack install nlohmann-json hdf5 py-torch # + amqp-cpp openssl libevent for RMQ
spack install caliper # if profiling
spack install mpi # if WITH_MPI (or use site MPI module)
```

Then locate each and pass its `*_DIR` (see the table below).

## Option B — module system

Many clusters expose these as modules:

```bash
module load cmake gcc hdf5 cuda openmpi
```

libTorch and (usually) nlohmann_json are rarely modules — get those from
Option A or C. After loading, the module `*_ROOT`/`PATH` usually lets CMake find
the package; otherwise fall back to explicit `*_DIR` hints.

## Option C — download / build by hand, then point CMake at each

| Dependency | Required? | Where to get it | CMake hint |
|---|---|---|---|
| `nlohmann_json` | yes | header-only; package or GitHub release | `nlohmann_json_DIR=<pfx>/lib/cmake/nlohmann_json` |
| `fmt` | yes | github.com/fmtlib/fmt | `fmt_DIR=<pfx>/share` |
| `tl::expected` | yes | github.com/TartanLlama/optional | `tl_expected_DIR=<pfx>/share` |
| HDF5 (C/CXX) | yes | hdfgroup.org, package manager, or Spack | `AMS_HDF5_DIR=<hdf5 root>` |
| libTorch | yes | pytorch.org "LibTorch" C++ zip (match CUDA/CPU) | `Torch_DIR=<libtorch>/share/cmake/Torch` |
| MPI | if `WITH_MPI` | OpenMPI/MPICH, or site module | found via compiler wrappers / `CMAKE_PREFIX_PATH` |
| CUDA | if `WITH_CUDA` | NVIDIA CUDA Toolkit | `CMAKE_CUDA_ARCHITECTURES=<sm_xx>` |
| ROCm/HIP | if `WITH_HIP` | AMD ROCm install | set `ROCM_PATH`; HIP found via `CMAKE_PREFIX_PATH` |
| Caliper | if `WITH_CALIPER` | github.com/LLNL/Caliper | `caliper_DIR=<pfx>/share/cmake/caliper` |
| amqp-cpp | if `WITH_RMQ` | github.com/CopernicaMarketingSoftware/AMQP-CPP | `amqpcpp_DIR=<pfx>/cmake` |
| OpenSSL | if `WITH_RMQ` | system package | found via `OPENSSL_ROOT_DIR` / `CMAKE_PREFIX_PATH` |
| libevent | if `WITH_RMQ` | libevent.org | on `CMAKE_PREFIX_PATH` |
| PerfFlowAspect | if `WITH_PERFFLOWASPECT` | github.com/flux-framework/PerfFlowAspect | `perfflowaspect_DIR=<pfx>/share` |

## General technique

Put all your hand-built installs under one prefix and add it to the search
path so most packages resolve without individual hints:

```bash
export CMAKE_PREFIX_PATH=/opt/ams-deps:$CMAKE_PREFIX_PATH
```

Then supply explicit `*_DIR` only for the ones CMake still can't find — libTorch
almost always needs its explicit `Torch_DIR` because of its nested cmake path.

## Sanity check before a full build

Configure a **minimal CPU build first** (no MPI/GPU/RMQ). If that succeeds, the
mandatory trio (nlohmann_json, HDF5, Torch) is wired correctly and you can add
feature flags one at a time — much easier to localize a missing dependency than
debugging a fully-loaded configure line.
105 changes: 105 additions & 0 deletions .agents/skills/changelog/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
name: changelog
description: >
Maintain a CHANGELOG.md in Keep a Changelog format: record new features, changes,
and fixes under an Unreleased section, and cut releases. Use whenever a
user-facing change ships or the user says "update the changelog", "add a
changelog entry", "record this feature/fix", "cut a release", "what changed
since <ref>", or mentions release notes or a CHANGELOG. Works for versioned and
unversioned projects — fall back to dates plus merge-request or commit IDs when
there are no version numbers. Trigger on any notable change worth recording, even
without the word "changelog".
---

# Changelog

Maintain `CHANGELOG.md` at the repo root in **Keep a Changelog** format: a
human-readable, reverse-chronological list of notable changes, grouped by release.
A changelog is for humans — it is not a `git log` dump. The format follows
Keep a Changelog (https://keepachangelog.com).

## Structure

```markdown
# Changelog

## [Unreleased]

### Added
- User-facing description of a new feature (#123).

## [1.2.0] - 2026-07-08

### Added
- ...
### Fixed
- ...
```

- Newest first. Keep an `## [Unreleased]` section at the top as a staging area.
- Dates are ISO 8601 (`YYYY-MM-DD`).
- Group each change under one of six headings; omit headings with no entries:
- **Added** — new features.
- **Changed** — changes to existing behavior.
- **Deprecated** — features slated for removal.
- **Removed** — features now removed.
- **Fixed** — bug fixes.
- **Security** — vulnerability fixes.

Initialize on first use: if `CHANGELOG.md` is missing, create it with the header
above and an empty `## [Unreleased]`. Never overwrite existing history.

## Adding an entry

Add to `## [Unreleased]` when a change merges — not at release time — so nothing
is forgotten.

1. Pick the right group heading (create it under Unreleased if absent).
2. Write one bullet per notable change in **plain, user-facing language**: what
changed and why it matters, not the commit subject. Rewrite
"fix: handle keydown in modal (#412)" as "Fixed the dialog not closing on Escape."
3. Reference the source for an audit trail: the PR/merge-request ID (`#123`, `!57`)
or a short commit SHA when there is no PR. Optionally lead with a bold name:
`- **CSV export:** feedback entries can now be exported to CSV (#234).`
4. Skip internal churn (refactors, formatting, test-only changes) unless it is
notable to users or integrators.

Drafting from history is fine — inspect `git log <last-ref>..HEAD` or the merged
PRs — but always curate and rewrite into user-facing wording; never paste raw
commit messages.

## Cutting a release

Move the `## [Unreleased]` entries into a new release section, then leave an empty
`## [Unreleased]` at the top. The release identifier is flexible:

- **Versioned (SemVer):** `## [1.4.0] - YYYY-MM-DD`. Bump MAJOR for breaking
changes, MINOR for new features, PATCH for fixes.
- **Unversioned:** use a dated header, annotated with the merge request or commit
that marks the release point:
```
## [2026-07-08] — mr !57
## [2026-07-08] — a1b2c3d
```

Optionally, add comparison links at the bottom so headers are clickable. On a git
host these are compare URLs — by tag (`compare/v1.3.0...v1.4.0`) or, for
unversioned projects, by commit/MR range (`compare/<old-sha>...<new-sha>`):

```
[Unreleased]: https://<host>/<repo>/compare/<latest>...HEAD
[1.4.0]: https://<host>/<repo>/compare/v1.3.0...v1.4.0
```

## Conventions

- Write for readers who have never seen the code: no internal ticket shorthand or
component names without explanation.
- Be brief, we do not want the changelog to be millions of lines long. Not more than
one sentence for each change.
- Make "update the changelog" part of the definition of done — the person shipping
the change writes the entry, since they have the context.
- Do not reconstruct a changelog from memory; derive it from git history and curate.
- Do not update past entries of a changelog without very good reason and notify the user.
- If an architecture wiki is maintained (see the `codebase-map` skill), a change
notable enough for the changelog that also alters structure should update both.
4 changes: 4 additions & 0 deletions .agents/skills/changelog/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Changelog"
short_description: "Skill to build and maintain a CHANGELOG file"
default_prompt: "Use $changelog to build and/or update the CHANGELOG of a repository"
Loading
Loading