11 Commits

Author SHA1 Message Date
lars 50d8368415 docs: record analysis_341dfb14 baseline rollout benchmark results
CI / Sync project version with tag (push) Has been skipped
CI / Lint (ruff check) (push) Successful in 26s
CI / Format (ruff format) (push) Successful in 33s
CI / Type check (ty) (push) Successful in 33s
CI / Tests (push) Successful in 3m4s
CI / Publish package to Gitea package registry (push) Has been skipped
CI / Bump version, tag, and update changelog on merge to master (push) Successful in 34s
Replaces the extrapolated pre-v0.3 weak-spot claims in baseline.toml's
header (which had the wrong sign on step-count error) with measured
numbers from the first full rollout validation of this exact config,
and adds a matching Roadmap entry in CLAUDE.md.
2026-08-28 15:01:35 +02:00
gitea-actions 95d5fc6d89 chore: update changelog for v0.3.15
CI / Publish package to Gitea package registry (push) Successful in 52s
CI / Lint (ruff check) (push) Successful in 24s
CI / Format (ruff format) (push) Successful in 1m8s
CI / Type check (ty) (push) Successful in 32s
CI / Tests (push) Successful in 3m2s
CI / Bump version, tag, and update changelog on merge to master (push) Has been skipped
CI / Sync project version with tag (push) Successful in 15s
2026-08-28 12:28:02 +00:00
gitea-actions b8bd1ec982 chore: bump version 0.3.14 -> 0.3.15 2026-08-28 12:28:01 +00:00
lars 70d018982b Merge pull request 'perf: defer heavy imports in giant/dwarf CLIs until commands run' (#91) from cli-lazy-imports into master
CI / Sync project version with tag (push) Has been skipped
CI / Lint (ruff check) (push) Successful in 1m33s
CI / Type check (ty) (push) Successful in 1m36s
CI / Format (ruff format) (push) Successful in 1m37s
CI / Tests (push) Successful in 3m40s
CI / Publish package to Gitea package registry (push) Has been skipped
CI / Bump version, tag, and update changelog on merge to master (push) Successful in 2m58s
Reviewed-on: #91
2026-08-28 14:21:08 +02:00
lars 8d1c29efdd Merge branch 'master' into cli-lazy-imports
CI / Format (ruff format) (pull_request) Successful in 29s
CI / Lint (ruff check) (pull_request) Successful in 34s
CI / Sync project version with tag (pull_request) Has been skipped
CI / Type check (ty) (pull_request) Successful in 32s
CI / Tests (pull_request) Successful in 2m51s
CI / Bump version, tag, and update changelog on merge to master (pull_request) Has been skipped
CI / Publish package to Gitea package registry (pull_request) Has been skipped
2026-08-28 14:11:11 +02:00
lars 516a8a9ee1 perf: defer heavy imports in giant/dwarf CLIs until commands run
CI / Sync project version with tag (push) Has been skipped
CI / Type check (ty) (push) Successful in 19s
CI / Format (ruff format) (push) Successful in 21s
CI / Lint (ruff check) (push) Successful in 25s
CI / Sync project version with tag (pull_request) Has been skipped
CI / Type check (ty) (pull_request) Successful in 4m5s
CI / Format (ruff format) (pull_request) Successful in 4m5s
CI / Lint (ruff check) (pull_request) Successful in 4m15s
CI / Tests (pull_request) Successful in 5m15s
CI / Bump version, tag, and update changelog on merge to master (pull_request) Has been skipped
CI / Tests (push) Successful in 9m55s
CI / Bump version, tag, and update changelog on merge to master (push) Has been skipped
torch/pandas/pyarrow/polars/uproot/awkward/particle were all imported
at module scope in giant/cli.py and giant/tools/dwarf.py, so even
`--help` paid ~1.6-1.9s of import cost. Move those imports into the
command bodies that actually need them (following the deferred-import
pattern already used for analysis/render/plots/sklearn/wandb), cutting
`giant --help` to ~0.3s and `dwarf --help` to ~0.2s with no change to
any command's actual behavior.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 14:10:19 +02:00
gitea-actions c12acfdade chore: update changelog for v0.3.14
CI / Bump version, tag, and update changelog on merge to master (push) Successful in 31s
CI / Lint (ruff check) (push) Successful in 2m29s
CI / Format (ruff format) (push) Successful in 2m27s
CI / Type check (ty) (push) Successful in 2m34s
CI / Tests (push) Successful in 6m1s
CI / Sync project version with tag (push) Has been skipped
CI / Publish package to Gitea package registry (push) Has been skipped
2026-08-28 11:19:14 +00:00
gitea-actions e06d9e9581 chore: bump version 0.3.13 -> 0.3.14 2026-08-28 11:18:49 +00:00
lars b0998a7d86 Merge pull request 'ci: give automated commits visible checks, scope CI triggers, publish releases' (#90) from ci/pr-scoped-checks-and-package-publish into master
CI / Sync project version with tag (push) Has been skipped
CI / Type check (ty) (push) Successful in 25s
CI / Lint (ruff check) (push) Successful in 38s
CI / Format (ruff format) (push) Successful in 36s
CI / Tests (push) Successful in 2m45s
CI / Publish package to Gitea package registry (push) Has been skipped
CI / Bump version, tag, and update changelog on merge to master (push) Successful in 2m36s
Reviewed-on: #90
2026-08-28 13:14:18 +02:00
lars cc11efb3ae ci: fix pull_request trigger not registering
CI / Sync project version with tag (pull_request) Has been skipped
CI / Lint (ruff check) (pull_request) Successful in 39s
CI / Format (ruff format) (pull_request) Successful in 43s
CI / Type check (ty) (pull_request) Successful in 1m6s
CI / Tests (pull_request) Successful in 3m29s
CI / Bump version, tag, and update changelog on merge to master (pull_request) Has been skipped
CI / Publish package to Gitea package registry (pull_request) Has been skipped
A bare "pull_request:" key parses to null in YAML, which the runner
apparently doesn't treat as "trigger with defaults" the way an empty
mapping does — the open PR for this branch got no CI run at all.
2026-08-28 13:08:25 +02:00
lars 7de3e92871 ci: give automated commits visible checks, scope CI triggers, publish releases
- Drop [skip ci] from the bump-version/changelog/tag-sync commits so
  master's tip always has a check run instead of only the merge commit.
- Filter those chore commits out of the changelog via message pattern
  instead of the now-removed [skip ci] tag.
- Only run CI on push to master (plus tags); pull requests to any branch
  still run the full suite.
- Add a publish-package job that builds and publishes to the Gitea PyPI
  registry on every tag push, after tests and version sync pass.
2026-08-28 13:06:26 +02:00
12 changed files with 176 additions and 69 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
[tool.bumpversion]
current_version = "0.3.13"
current_version = "0.3.15"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
serialize = ["{major}.{minor}.{patch}"]
search = "{current_version}"
@@ -8,7 +8,7 @@ regex = false
allow_dirty = false
commit = true
tag = false
message = "chore: bump version {current_version} -> {new_version} [skip ci]"
message = "chore: bump version {current_version} -> {new_version}"
pre_commit_hooks = ["uv lock", "git add uv.lock"]
[[tool.bumpversion.files]]
+34 -5
View File
@@ -2,10 +2,9 @@ name: CI
"on":
push:
branches: ["**"]
branches: ["master"]
tags: ["**"]
pull_request:
branches: [master]
pull_request: {}
env:
UV_CACHE_DIR: /uv-cache
@@ -156,7 +155,7 @@ jobs:
uv run git-cliff --tag "$TAG" --unreleased --prepend CHANGELOG.md
git add CHANGELOG.md
if ! git diff --cached --quiet -- CHANGELOG.md; then
git commit -m "chore: update changelog for $TAG [skip ci]"
git commit -m "chore: update changelog for $TAG"
else
git restore --staged CHANGELOG.md
fi
@@ -193,7 +192,7 @@ jobs:
git config user.name "gitea-actions"
git config user.email "actions@git.larsbogner.de"
git add pyproject.toml uv.lock
git commit -m "chore: sync project version to tag ${GITHUB_REF_NAME} [skip ci]"
git commit -m "chore: sync project version to tag ${GITHUB_REF_NAME}"
git push origin HEAD:master
git push origin ":refs/tags/${GITHUB_REF_NAME}"
git tag -f "${GITHUB_REF_NAME}" HEAD
@@ -201,3 +200,33 @@ jobs:
else
echo "Tag version matches project version ($CURRENT_VERSION)"
fi
publish-package:
name: Publish package to Gitea package registry
needs: [ruff-check, ruff-format, type-check, test, sync-version-on-tag]
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: docker.gitea.com/runner-images:ubuntu-latest
volumes:
- /srv/act-runner-cache/uv:/uv-cache
steps:
# Check out by tag name (not the triggering SHA) since sync-version-on-tag
# may have force-moved the tag to a version-corrected commit.
- uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- uses: astral-sh/setup-uv@v5
with:
enable-cache: false
- run: |
echo "UV_CACHE_DIR=/uv-cache" >> "$GITHUB_ENV"
echo "UV_LINK_MODE=copy" >> "$GITHUB_ENV"
- run: uv build
# CI_TOKEN needs write:package scope (in addition to write:repository,
# used elsewhere) for this upload to authenticate.
- run: |
uv publish \
--publish-url "https://git.larsbogner.de/api/packages/lars/pypi" \
--username gitea-actions \
--password "${{ secrets.CI_TOKEN }}"
+14
View File
@@ -1,5 +1,19 @@
# Changelog
## [0.3.15] - 2026-08-28
### Changed
- Perf: defer heavy imports in giant/dwarf CLIs until commands run
## [0.3.14] - 2026-08-28
### Changed
- Ci: give automated commits visible checks, scope CI triggers, publish releases
- Ci: fix pull_request trigger not registering
## [0.3.13] - 2026-08-28
### Added
+2
View File
@@ -113,6 +113,8 @@ Secondary energies are a **stick-breaking partition of the `e_sec` budget** from
**v0.3.0 — Stage-2 autoregressive redesign (implemented, released; on `master` since 2026-08-13):** motivated by the 2026-08-03 WGAN rollout benchmark, which failed specifically at the secondary-species level (zero photon secondaries, ~4M hallucinated `-14` muon antineutrinos). Stage 2 became autoregressive in descending-energy order with teacher forcing, and the particle-type representation went back to **categorical** (`particle_type.target = "onehot"`), reversing the 2026-07-17 continuous `(log-mass, charge)` target. The config break (`[conditioning]`/`[stage1_model]`/`[stage2_model]`/`[train]` replacing the flat `train.mode` + `[model]`) makes per-stage generators, stage-2-only training, and one-shot-vs-autoregressive comparison all expressible, and the `network.py` refactor into composable parts (encoder × trunk × objective) also makes routed WGAN work for the first time.
**Baseline benchmark (done, 2026-08-26):** `configs/baseline.toml`'s first full rollout-vs-Geant4 validation (`analysis_341dfb14`, checkpoint `20260814_1743_s2-flow_h512_s2h512_bs36864_ep50/best.pt`, epoch 50/50). Confirms the v0.3.0 pivot fixed the species collapse — zero photon secondaries / hallucinated `-14` muon antineutrinos are both gone (γ at 95% of truth, no `-14` in the top species) — and rules out `conditioning.*.type = "physical"` as the cause, since this checkpoint pairs it with `flow`/no-router and still doesn't collapse. Bulk shower observables are close to Geant4 (total deposited energy +1.9%, containment depth-90%/95% both 0.986×), but steps/event now *over*-shoots by 1.32× (the opposite sign from every pre-v0.3.0 checkpoint), no hadronic/nuclear secondaries are produced at all, and event-to-event energy variance is ~16× too narrow. Writeup: `/home/lars/knowledge-base/experiments/giant-baseline-flow-ar-rollout-validation.md`.
v0.2 configs and checkpoints are auto-migrated (`config.migrate_config`, `model._legacy._migrate_legacy_model_config`, both drawing on shared facts in `giant/_migration.py`). **v0.2 checkpoint-loading support has no expiry decided yet**: `/ceph` still holds pre-v0.3.0 checkpoints and analysis runs referencing them, so don't delete or substantially alter either migration function or `tests/legacy/network_v02_snapshot.py` (the frozen v0.2 snapshot they're tested against) without an explicit decision to do so first.
**Faster-eval architectures — both implemented, neither validated.** Target is a ~10× native-Geant4 eval budget; no eval-latency number exists for any configuration yet, so that budget is unverified across the board.
+1 -1
View File
@@ -37,7 +37,7 @@ commit_preprocessors = [
protect_breaking_commits = false
commit_parsers = [
{ message = "^Merge ", skip = true },
{ message = "\\[skip ci\\]", skip = true },
{ message = "^chore: (bump version|update changelog|sync project version)", skip = true },
{ message = "^Add", group = "<!-- 0 -->Added" },
{ message = "^(Fix|Clamp|Clip)", group = "<!-- 1 -->Fixed" },
{ message = "^(Remove|Drop|Deprecate)", group = "<!-- 2 -->Removed" },
+15 -5
View File
@@ -29,11 +29,21 @@
# capacity overfitting is not the binding constraint, and every recent
# run used 0.0.
#
# Known weak spots this baseline is expected to *exhibit* (they are the
# reason for the comparisons, not a reason to retune this file): every model
# on record under-produces steps per event by ~2x (rollout ~7e4 vs Geant4
# ~1.4e5) and secondaries per event by 2-3.5x (~2-3e4 vs 7.2e4), and n_sec
# head accuracy sits at 0.863-0.867 regardless of size or objective.
# Known weak spots, now measured against this exact config rather than
# extrapolated from the pre-v0.3 field (analysis_341dfb14, best.pt @ epoch
# 50/50, full writeup: knowledge-base/experiments/
# giant-baseline-flow-ar-rollout-validation.md). Unlike every pre-v0.3
# checkpoint (which under-produced steps/event by 1.6-5x), this baseline
# OVER-produces steps/event by 1.32x (1.86e5 vs Geant4 1.41e5) and
# under-produces secondaries/event by 0.84x (5.97e4 vs 7.14e4) — the sign on
# steps flipped with the v0.3 autoregressive pivot, so don't assume it still
# undershoots. Secondary-species hallucination (zero photons, hallucinated
# `-14` muon antineutrinos) that broke every prior checkpoint is gone; the
# remaining species gap is a total absence of hadronic/nuclear secondaries
# (protons, neutrons, ion recoils), not miscalibration of the ones produced.
# Total deposited energy/event is +1.9% high but its event-to-event spread is
# ~16x too narrow (31 MeV vs Geant4's 491 MeV). Per-step deposited energy is
# the worst per-step marginal (KS 0.179 vs 0.004-0.071 for the others).
[meta]
# REQUIRED. Without it config.migrate_config reads this file as v0.2 and
+49 -30
View File
@@ -1,21 +1,19 @@
from __future__ import annotations
from collections import Counter
from datetime import datetime, timezone
from enum import Enum
import math
from pathlib import Path
import re
from typing import Optional
from typing import TYPE_CHECKING, Optional
import uuid as uuid_mod
import numpy as np
import yaml
import torch
import typer
from typing_extensions import Annotated
import pyarrow as pa
import pyarrow.parquet as pq
from tqdm import tqdm
if TYPE_CHECKING:
import numpy as np
from giant import config as gconfig
from giant.constants import (
@@ -25,30 +23,11 @@ from giant.constants import (
PREDICT_SCHEMA_VERSION_KEY,
ROLLOUT_COORD_VALUE,
)
from giant.data.loader import (
event_id_offset,
find_parquet_files,
iter_file_chunks,
iter_cond_chunks,
)
from giant.data.transforms import (
build_features,
build_cond_features,
energy_simplex_decode,
inv_local_frame_rotation,
inv_log_transform,
reconstruct_post_pos,
)
from giant.checkpoint_io import CheckpointCompatibilityError, load_for_inference
from giant.geometry import GeometryOracle
# giant.materials only pulls in numpy (no torch/pandas), and MATERIAL_PROPERTIES
# is needed at decoration time below (a Typer option default), so it can't be
# deferred into a command body like the rest of this module's heavy imports.
from giant.materials import MATERIAL_PROPERTIES
from giant.pipeline import run_train_job
from giant.rollout import (
L1DistCollector,
decode_secondary_identity,
rollout as run_rollout,
)
from giant.sample import resolve_n_sec, sample_stage1, sample_stage2
app = typer.Typer(no_args_is_help=True)
@@ -210,6 +189,8 @@ def _write_prediction_ref(
comment: str | None = None,
) -> Path:
"""Write a YAML sidecar in the checkpoint directory and return its path."""
import yaml
ref = {
"prediction_id": pred_uuid,
"output": str(out),
@@ -639,6 +620,10 @@ def train(
] = None,
) -> None:
"""Train the GIANT surrogate model."""
import torch
from giant.pipeline import run_train_job
batch_size_auto = False
batch_size_value: Optional[int] = None
if batch_size is not None:
@@ -1048,6 +1033,25 @@ def predict(
] = None,
) -> None:
"""Run trained model on a parquet file and save predictions."""
import numpy as np
import pyarrow as pa
import pyarrow.parquet as pq
import torch
from tqdm import tqdm
from giant.checkpoint_io import CheckpointCompatibilityError, load_for_inference
from giant.data.loader import event_id_offset, find_parquet_files, iter_cond_chunks, iter_file_chunks
from giant.data.transforms import (
build_cond_features,
build_features,
energy_simplex_decode,
inv_local_frame_rotation,
inv_log_transform,
reconstruct_post_pos,
)
from giant.rollout import decode_secondary_identity
from giant.sample import resolve_n_sec, sample_stage1, sample_stage2
batch_size_auto = False
batch_size_value: Optional[int] = None
if batch_size.strip().lower() == "auto":
@@ -1343,6 +1347,10 @@ def _seed_from_data(files: list[Path], n_events: int | None) -> dict[str, np.nda
the codebase's convention for the primary (a secondary always carries less
energy than its parent). See giant/analysis/reduce.py:entry_axis.
"""
import numpy as np
from giant.data.loader import event_id_offset, iter_cond_chunks
best_E: dict[int, float] = {}
best: dict[int, tuple] = {}
for file_idx, path in enumerate(files):
@@ -1447,6 +1455,17 @@ def rollout(
] = None,
) -> None:
"""Roll the surrogate forward into full showers (autoregressive)."""
import numpy as np
import pyarrow as pa
import pyarrow.parquet as pq
import torch
import yaml
from giant.checkpoint_io import CheckpointCompatibilityError, load_for_inference
from giant.data.loader import find_parquet_files
from giant.geometry import GeometryOracle
from giant.rollout import L1DistCollector, rollout as run_rollout
if seed is not None:
torch.manual_seed(seed)
np.random.seed(seed)
+17 -4
View File
@@ -1,3 +1,5 @@
from __future__ import annotations
import copy
import difflib
import hashlib
@@ -10,12 +12,12 @@ from dataclasses import dataclass, field
from datetime import datetime, timezone
from enum import Enum
from pathlib import Path
import numpy as np
import torch
from typing import TYPE_CHECKING
from giant._migration import V02_FIXED_FACTS, V02_MODEL_KEY_TO_STAGES, reject_legacy_router_expert_sizing
from giant.model.history import HISTORY_REGISTRY
if TYPE_CHECKING:
import torch
class Conditioning(str, Enum):
@@ -941,6 +943,8 @@ def git_hash() -> str:
def auto_device() -> torch.device:
import torch
if torch.cuda.is_available():
return torch.device("cuda")
if torch.backends.mps.is_available():
@@ -986,6 +990,8 @@ def estimate_batch_size(
inference (e.g. `predict`), which uses a much lower per-sample memory
calibration since there's no backward graph or optimizer state.
"""
import torch
if device.type != "cuda":
raise ValueError(f"--batch-size auto is only supported on cuda devices, got {device.type!r}")
device_index = device.index if device.index is not None else torch.cuda.current_device()
@@ -1680,6 +1686,8 @@ def validate_config(cfg: dict, *, resume: bool = False) -> None:
"'energy_desc' (the only implemented ordering; see "
"AutoregressiveConfig.order's docstring)"
)
from giant.model.history import HISTORY_REGISTRY
history = _get_path(cfg, "stage2_model.autoregressive.history")
if history not in HISTORY_REGISTRY:
raise ValueError(
@@ -1881,6 +1889,9 @@ def resolve_default_out_dir(cfg: dict, base: Path = Path("checkpoints")) -> Path
def seed_everything(seed: int) -> None:
import numpy as np
import torch
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
@@ -1934,6 +1945,8 @@ def build_run_meta(
n_val_events: int,
n_train_steps: int,
) -> dict:
import torch
return {
"config_version": CONFIG_VERSION,
"git_hash": git_hash(),
+34 -14
View File
@@ -5,6 +5,8 @@ simulation-fanout tools into one Typer app so there's a single command name
(and `--help`) to remember instead of five differently-hyphenated ones.
"""
from __future__ import annotations
import os
from enum import Enum
from pathlib import Path
@@ -14,20 +16,15 @@ import typer
from typing_extensions import Annotated
from giant.config import Conditioning
from giant.tools.bump_dataset_version import (
run_bump_gen,
run_bump_schema,
run_create_manifest,
run_status,
run_update_manifest,
)
from giant.tools.create_root_files import run_make_root
from giant.tools.geometry_oracle import run_build_geometry_oracle
from giant.tools.hparam_scan import DATA_DEFAULT, SCAN_DIR_DEFAULT, run_hparam_scan
from giant.tools.migrate_geant_steps import run_migration
from giant.tools.steps_to_parquet import convert_steps_to_parquet
from giant.tools.steps_to_parquet_parallel import run_parallel_job
from giant.tools.warm_setup_cache import run_warm_setup_cache
# DATA_DEFAULT/SCAN_DIR_DEFAULT are Typer option defaults (evaluated at
# decoration time below), so that one name has to stay eager — the module
# itself is stdlib-only, so it costs nothing. Every other giant.tools.*
# import here is deferred into the one command body that uses it, since
# several (steps_to_parquet: uproot/awkward/polars; warm_setup_cache:
# giant.pipeline -> torch; geometry_oracle: pandas) are expensive and
# `dwarf --help`/tab-completion shouldn't pay for all of them upfront.
from giant.tools.hparam_scan import DATA_DEFAULT, SCAN_DIR_DEFAULT
app = typer.Typer(no_args_is_help=True)
@@ -121,6 +118,9 @@ def convert(
] = None,
) -> None:
"""Convert ROOT Steps tree(s) to Parquet."""
from giant.tools.steps_to_parquet import convert_steps_to_parquet
from giant.tools.steps_to_parquet_parallel import run_parallel_job
if jobs < 1:
typer.echo("error: --jobs must be >= 1", err=True)
raise typer.Exit(1)
@@ -183,6 +183,8 @@ def migrate(
] = False,
) -> None:
"""One-time migration into the versioned raw/processed/pools/derived layout."""
from giant.tools.migrate_geant_steps import run_migration
run_migration(str(root), execute=execute, copy=copy)
@@ -207,6 +209,8 @@ def bump_gen(
root: Annotated[Path, typer.Option("--root", help="Dataset root")] = _DATASET_ROOT_DEFAULT,
) -> None:
"""Cut a new raw generation."""
from giant.tools.bump_dataset_version import run_bump_gen
run_bump_gen(
kind=kind,
reason=reason,
@@ -240,6 +244,8 @@ def bump_schema(
root: Annotated[Path, typer.Option("--root", help="Dataset root")] = _DATASET_ROOT_DEFAULT,
) -> None:
"""Cut a new schema within a gen."""
from giant.tools.bump_dataset_version import run_bump_schema
run_bump_schema(
kind=kind,
gen=gen,
@@ -257,6 +263,8 @@ def status(
root: Annotated[Path, typer.Option("--root", help="Dataset root")] = _DATASET_ROOT_DEFAULT,
) -> None:
"""List existing gens/schemas per kind."""
from giant.tools.bump_dataset_version import run_status
run_status(str(root))
@@ -281,6 +289,8 @@ def update_manifest(
] = False,
) -> None:
"""Repoint manifest(s) to a new gen and/or schema, verifying all target files exist."""
from giant.tools.bump_dataset_version import run_update_manifest
run_update_manifest([str(m) for m in manifests], schema=schema, execute=execute, gen=gen)
@@ -311,6 +321,8 @@ def create_manifest(
] = False,
) -> None:
"""Create a new manifest from a list of parquet files."""
from giant.tools.bump_dataset_version import run_create_manifest
run_create_manifest(
[str(f) for f in files],
execute=execute,
@@ -358,6 +370,8 @@ def make_root(
] = False,
) -> None:
"""Generate new ROOT shards via a minicalosim executable."""
from giant.tools.create_root_files import run_make_root
_warn_if_exceeds_shared_quota(jobs, "--jobs")
run_make_root(
executable=executable,
@@ -423,6 +437,8 @@ def build_geometry_oracle(
] = 2000,
) -> None:
"""Fit a position -> (material, layer_id) oracle for `giant rollout`."""
from giant.tools.geometry_oracle import run_build_geometry_oracle
run_build_geometry_oracle(
data=data,
out=out,
@@ -515,6 +531,8 @@ def warm_cache(
such entry across every run) skips straight to training. See
giant/data/setup_cache.py.
"""
from giant.tools.warm_setup_cache import run_warm_setup_cache
flag_overrides = {
"--val-fraction": val_fraction,
"--seed": seed,
@@ -557,6 +575,8 @@ def hparam_scan(
dry_run: Annotated[bool, typer.Option("--dry-run")] = False,
) -> None:
"""Grid-scan dropout x n_blocks x hidden_dim via sequential `giant train` runs."""
from giant.tools.hparam_scan import run_hparam_scan
run_hparam_scan(data=data, scan_dir=scan_dir, seed=seed, dry_run=dry_run)
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "giant"
version = "0.3.13"
version = "0.3.15"
description = "Geant4 step-function surrogate via conditional flow matching"
readme = "README.md"
requires-python = ">=3.12"
+6 -6
View File
@@ -20,7 +20,7 @@ def _invoke_and_capture_cfg(monkeypatch, tmp_path: Path, args: list[str]) -> dic
def _fake_run_train_job(*, data, cfg, out_dir, **kwargs):
captured["cfg"] = cfg
monkeypatch.setattr(cli, "run_train_job", _fake_run_train_job)
monkeypatch.setattr("giant.pipeline.run_train_job", _fake_run_train_job)
result = runner.invoke(
cli.app,
@@ -125,7 +125,7 @@ def test_stage2_init_from_and_freeze_flags_land_in_cfg_and_dont_touch_stage1(mon
def test_batch_size_invalid_string_errors(monkeypatch, tmp_path):
monkeypatch.setattr(cli, "run_train_job", lambda *a, **kw: None)
monkeypatch.setattr("giant.pipeline.run_train_job", lambda *a, **kw: None)
result = runner.invoke(
cli.app,
["train", "dummy.parquet", "--out", str(tmp_path / "run"), "--batch-size", "not-a-number"],
@@ -140,7 +140,7 @@ def test_out_dir_resolution_prefers_explicit_out_over_resume(monkeypatch, tmp_pa
def _fake_run_train_job(*, data, cfg, out_dir, **kwargs):
captured["out_dir"] = out_dir
monkeypatch.setattr(cli, "run_train_job", _fake_run_train_job)
monkeypatch.setattr("giant.pipeline.run_train_job", _fake_run_train_job)
resume_dir = tmp_path / "resumed_run"
resume_dir.mkdir()
@@ -161,7 +161,7 @@ def test_out_dir_resolution_falls_back_to_resume_parent(monkeypatch, tmp_path):
def _fake_run_train_job(*, data, cfg, out_dir, **kwargs):
captured["out_dir"] = out_dir
monkeypatch.setattr(cli, "run_train_job", _fake_run_train_job)
monkeypatch.setattr("giant.pipeline.run_train_job", _fake_run_train_job)
resume_dir = tmp_path / "resumed_run"
resume_dir.mkdir()
@@ -178,7 +178,7 @@ def test_out_dir_resolution_defaults_when_neither_out_nor_resume_given(monkeypat
def _fake_run_train_job(*, data, cfg, out_dir, **kwargs):
captured["out_dir"] = out_dir
monkeypatch.setattr(cli, "run_train_job", _fake_run_train_job)
monkeypatch.setattr("giant.pipeline.run_train_job", _fake_run_train_job)
monkeypatch.chdir(tmp_path)
result = runner.invoke(cli.app, ["train", "dummy.parquet"])
@@ -192,7 +192,7 @@ def test_batch_size_auto_estimates_and_echoes(monkeypatch, tmp_path):
def _fake_run_train_job(*, data, cfg, out_dir, num_workers, **kwargs):
captured["batch_size"] = cfg["train"]["batch_size"]
monkeypatch.setattr(cli, "run_train_job", _fake_run_train_job)
monkeypatch.setattr("giant.pipeline.run_train_job", _fake_run_train_job)
monkeypatch.setattr(cli.gconfig, "estimate_batch_size", lambda hidden_dim, n_blocks, device: 123)
result = runner.invoke(
Generated
+1 -1
View File
@@ -675,7 +675,7 @@ wheels = [
[[package]]
name = "giant"
version = "0.3.13"
version = "0.3.15"
source = { editable = "." }
dependencies = [
{ name = "numpy" },