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
28 changes: 28 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Documentation
on:
push:
branches:
- main
permissions:
contents: read
pages: write
id-token: write
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/configure-pages@v5
- uses: actions/checkout@v5
- uses: actions/setup-python@v5
with:
python-version: 3.x
- run: pip install zensical
- run: zensical build --clean
- uses: actions/upload-pages-artifact@v4
with:
path: site
- uses: actions/deploy-pages@v4
id: deployment
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@ Thumbs.db

# Sockets (shouldn't be committed but just in case)
/tmp/ipi_*

# zensical
site/
215 changes: 215 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# API Reference

## RootstockCalculator

The main interface to Rootstock is the `RootstockCalculator` class, an ASE-compatible calculator.

### Basic Usage

```python
from ase.build import bulk
from rootstock import RootstockCalculator

atoms = bulk("Cu", "fcc", a=3.6) * (5, 5, 5)

with RootstockCalculator(
cluster="della",
model="mace",
checkpoint="medium",
device="cuda",
) as calc:
atoms.calc = calc
energy = atoms.get_potential_energy()
forces = atoms.get_forces()
stress = atoms.get_stress()
```

### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `cluster` | `str` | Yes* | Cluster name (e.g., `"della"`, `"sophia"`) |
| `root` | `str` | Yes* | Custom root path instead of a known cluster |
| `model` | `str` | Yes | MLIP family: `"mace"`, `"chgnet"`, `"uma"`, `"tensornet"` |
| `checkpoint` | `str` | No | Specific model weights (uses environment default if omitted) |
| `device` | `str` | No | `"cuda"` (default) or `"cpu"` |

*Either `cluster` or `root` must be provided, but not both.

### Examples

```python
# Using a known cluster with explicit checkpoint
RootstockCalculator(cluster="della", model="mace", checkpoint="medium")

# Using a known cluster with default checkpoint
RootstockCalculator(cluster="della", model="uma")

# Using a custom root path
RootstockCalculator(root="/scratch/gpfs/specific/install/path/rootstock", model="mace")
```

### Context Manager

`RootstockCalculator` should be used as a context manager to ensure proper cleanup of the worker subprocess:

```python
with RootstockCalculator(...) as calc:
# Use the calculator
atoms.calc = calc
energy = atoms.get_potential_energy()
# Worker process is automatically terminated when exiting the context
```

!!! tip "Manual Cleanup"
If you cannot use a context manager, call `calc.close()` manually to terminate the worker process.

## Available Models

Available models vary by cluster and change as new environments are added. See the [Example Configs](clusters.md) page for current deployments on each cluster.

### Model Reference

| Model | Environment | Default Checkpoint | Other Checkpoints |
|-------|-------------|-------------------|-------------------|
| `mace` | mace_env | `medium` | `small`, `large` |
| `chgnet` | chgnet_env | (pretrained) | — |
| `uma` | uma_env | `uma-s-1p1` | — |
| `tensornet` | tensornet_env | `TensorNet-MatPES-PBE-v2025.1-PES` | Other MatGL models |

### Checking Available Models

To see available models on your cluster, check the [Example Configs](clusters.md) page or run:

```bash
rootstock status
```

This command displays installed environments, their checkpoints, and cache sizes.

## CLI Reference

The Rootstock CLI provides commands for both administrators (setting up clusters) and users (querying available environments).

### User Commands

Commands users can run to explore available environments:

#### `rootstock status`

Display installation status, including all installed environments and cache usage.

```bash
rootstock status
```

#### `rootstock list`

List all registered environments in the shared environments directory.

```bash
rootstock list
```

#### `rootstock resolve`

Look up the root directory for a known cluster.

```bash
# Human-readable output
rootstock resolve --cluster della

# JSON output
rootstock resolve --cluster della --json
```

### Administrator Commands

Commands for cluster administrators to set up and manage Rootstock installations:

#### `rootstock init`

Interactive setup wizard for creating a new Rootstock installation. Prompts for:

- Root directory path
- API credentials for dashboard integration (optional)
- Maintainer information

```bash
rootstock init

# Skip directory creation
rootstock init --skip-dirs

# Skip manifest initialization
rootstock init --skip-manifest
```

#### `rootstock new-env`

Create a new environment template file with the required PEP 723 structure.

```bash
# Create template in current directory
rootstock new-env mace

# Specify output path
rootstock new-env mace -o ./environments/mace_env.py

# Overwrite existing file
rootstock new-env mace --force
```

#### `rootstock install`

Install environment(s) from a file, directory, or rebuild by name.

```bash
# Install from a single file
rootstock install ./mace_env.py --models small,medium

# Install all environments from a directory
rootstock install ./environments/

# Rebuild an existing environment
rootstock install mace_env --force

# Install without pushing manifest to backend
rootstock install mace_env.py --no-push
```

Options:

- `--root <path>`: Specify root directory (or use `$ROOTSTOCK_ROOT`)
- `--models <list>`: Comma-separated list of models to pre-download
- `--force`: Update registration and rebuild if environment exists
- `--verbose`, `-v`: Verbose output
- `--no-push`: Skip pushing manifest to backend

#### `rootstock serve`

Start a worker process for an external i-PI server (advanced usage).

```bash
rootstock serve mace \
--socket /tmp/ipi_socket \
--checkpoint medium \
--device cuda
```

#### `rootstock manifest`

Manage the installation manifest that tracks environment state.

```bash
# Show current manifest
rootstock manifest show
rootstock manifest show --json

# Push manifest to dashboard
rootstock manifest push

# Initialize new manifest
rootstock manifest init --cluster della
rootstock manifest init --cluster della --force
```
77 changes: 77 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Architecture

## Overview

When you create a `RootstockCalculator`, Rootstock spawns a subprocess that runs the MLIP in its own pre-built virtual environment. The main process and worker communicate over a Unix domain socket using the [i-PI protocol](http://ipi-code.org/). All communication occurs on a single node with no remote network calls.

```
Your script (on cluster node) Worker subprocess
+-------------------------+ +-----------------------------+
| RootstockCalculator | | Pre-built MLIP environment |
| (ASE-compatible) | | |
| | | |
| server.py (i-PI server) |<-------->| worker.py (i-PI client) |
| - sends positions | Unix | - receives positions |
| - receives forces | socket | - calculates forces |
+-------------------------+ +-----------------------------+
```

## Design Benefits

This design eliminates environment conflicts when experimenting with different MLIPs or using multiple MLIPs in a single workflow:

- **No environment conflicts**: Each MLIP runs in isolation with its exact required dependencies
- **One-line model swapping**: Change `model="mace"` to `model="uma"` without reinstalling anything
- **Multi-model workflows**: Use multiple MLIPs in the same script (sequentially)
- **Clean user environments**: Users only install the lightweight `rootstock` package

## Tradeoffs

The architecture introduces minimal overhead due to inter-process communication:

- **~4% overhead** on an 864-atom system
- Communication occurs via Unix domain socket (fast, local-only)
- Positions and forces are serialized using the i-PI protocol

For most use cases, this overhead is negligible compared to MLIP forward pass time.

## Directory Structure

After setup, the Rootstock root directory looks like this:

```
{root}/
├── .python/ # uv-managed Python interpreters
├── environments/ # Environment source files (*.py with PEP 723 metadata)
│ ├── mace_env.py
│ ├── chgnet_env.py
│ ├── uma_env.py
│ └── tensornet_env.py
├── envs/ # Pre-built virtual environments
│ ├── mace_env/
│ │ ├── bin/python
│ │ ├── lib/python3.11/site-packages/
│ │ └── env_source.py
│ └── ...
├── home/ # Redirected HOME for not-well-behaved libraries
│ ├── .cache/fairchem/
│ └── .matgl/
└── cache/ # XDG_CACHE_HOME and HF_HOME for well-behaved libraries
├── mace/
└── huggingface/
```

### Why the `home/` Directory?

Some ML libraries (FAIRChem, MatGL) ignore `XDG_CACHE_HOME` and write to `~/.cache/` unconditionally. Rootstock redirects `HOME` during environment builds and worker runtime to ensure model weights are stored in the shared directory rather than in individual user home directories.

## i-PI Protocol

Rootstock uses the [i-PI protocol](http://ipi-code.org/) for communication between the main process and worker:

1. Main process sends atomic positions and cell parameters
2. Worker receives positions and runs the MLIP forward pass
3. Worker sends back energy, forces, and stress
4. Main process receives results and returns them to ASE

The protocol is text-based and designed for interoperability between simulation codes.
Loading