10 Commits
Author SHA1 Message Date
Alexander Eichhornand0xDELUXA 7001bf3780 feat(deps): install ROCm 10 from AMD's index on Linux and Windows
The rocm extra moves from PyTorch's 2.13.0+rocm7.2 (Linux only) to AMD's 2.13.0+rocm10.0.0 for Linux
x86_64 and Windows. The lock carries the GPU kernel packages of every target AMD builds, so the launcher
can leave out the ones a machine does not need. Linux loses gfx900/gfx906, which ROCm 10 dropped.
bitsandbytes moves to 0.50.2, the first release with a Windows ROCm binary.

A new setting, rocm_aotriton_experimental (auto/on/off), sets TORCH_ROCM_AOTRITON_ENABLE_EXPERIMENTAL
before anything runs attention. auto turns AOTriton's experimental fused kernels on only for a ROCm 10
build on GPUs where they were measured correct (gfx1200 so far); under torch 2.12+rocm7.14 the same
switch made every fused call fail on that GPU.

Builds on the dependency and documentation changes of #9606.

Co-authored-by: 0xDELUXA <[email protected]>
2026-10-02 03:52:29 +02:00
Alexander Eichhorn a4df8a754b chore(deps): move the cpu and cuda extras to torch 2.13.0 (cu130)
Pin cpu/cuda to 2.13.0+cpu/+cu130 (macOS and linux-aarch64 stay on 2.7.1), hold the no-extra lock to 2.13.0 and take xformers from the cu130 index.
Draw seeded noise in float32 by default (new `noise_dtype` setting), since torch changed its half-precision CPU random numbers.
Log a startup error for NVIDIA drivers older than the build's CUDA and GPUs below its lowest architecture, and document the new GPU floor.
2026-09-29 04:20:11 +02:00
Lincoln SteinandClaude Fable 5 6c8a81b4dc chore: bump the rocm extra to torch 2.13.0+rocm7.2
torch 2.13.0+rocm7.2 bundles AOTriton 0.12b, whose regenerated gfx1100
tuning database roughly triples flash-attention throughput on RDNA3 vs
the 2.10.0+rocm7.1 pin: measured 17.9 -> 57.3 TFLOPS effective at the
MiniMax H3 attention shape (56 heads, head_dim 128, bf16, seq 59.5k) on
a W7900, moving the card ahead of an RTX 5060 Ti (45.3) on the same
script. Companion pins follow the release pairing: torchvision
0.28.0+rocm7.2, triton-rocm 3.7.1; the xpu extra already ships torch
2.13.0. The cpu/cuda/darwin pins are unchanged.

The rocm7.1-era caution about torch 2.12.x breaking generation (#9410)
concerned that index's resolver default; the pinned 2.13.0+rocm7.2
pairing is microbench-verified on gfx1100, with end-to-end generation
validation tracked in the PR checklist before merge. The manual-install
docs' ROCm caution is updated accordingly (prefer rocm7.2/torch 2.13+,
with the old workaround retained for anyone staying on rocm7.1).

pins.json and uv.lock regenerated; check_pins suite passes.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014xFbHnmFTLsHE9e1PAdvme
2026-08-27 13:50:23 -04:00
f2af8c6013 feat: add native Intel XPU (torch.xpu) device support (#9401)
* feat(backend): add Intel XPU (torch.xpu) device support

Additive xpu branches only: device selection and normalization, float16
default, VRAM queries with a passthrough-VM fallback (missing SYCL
free-memory aspect), fp8 layerwise casting via a runtime probe, VAE
auto-tiling, partial loading, stats/OOM handling, multi-GPU parallel
session execution (device enumeration, config/API validation, worker
pinning, and the generation-device options endpoint), and the auxiliary
image utilities (depth/SAM/DINO pipelines accept xpu instead of falling
back to CPU; cache clearing is device-agnostic). CUDA (incl. ROCm), MPS,
and CPU behavior unchanged. Verified end to end on Arc Pro B70 hardware,
including dual-GPU worker startup.

* test(backend): add XPU coverage for TorchDevice

Mock-based, mirroring the CUDA/MPS suites: device choice, dtype, normalize,
the xpu_mem_get_info fallback branches, and multi-GPU generation_devices
resolution/validation/labeling on XPU. Also makes the auto-without-CUDA
generation-devices test hermetic on XPU machines.

* build: add [xpu] extra

torch 2.7.1+xpu / torchvision 0.22.1+xpu / pytorch-triton-xpu 3.3.1 from the
torch-xpu index, gated to linux-x86_64 and win_amd64; uv.lock regenerated.

* feat(backend): extend idle-GPU text encoder offload to XPU

The idle-device arbiter and the session processor's borrow path both gated on
`device.type == "cuda"`, so on a multi-XPU system no device ever registered and
`offload_text_encoders_to_idle_gpus` (enabled by default) silently did nothing:
encoders kept churning the denoise model in and out of VRAM.

Register and lend XPU devices alongside CUDA. MPS is deliberately excluded --
it is always a single shared device, so there is never another GPU to borrow.

Verified on a dual Intel Arc Pro B70 host: a text encoder node now runs on the
idle GPU while the session denoises on the other ("Running compel on idle
device xpu:0 (session device xpu:1)").

* feat(ui): show the executing GPU for XPU sessions

Queue items already persist the executing device generically (e.g. "xpu:1"),
but both readers dropped it: the session event only forwarded devices starting
with "cuda", and the frontend index parser only matched /^cuda:(\d+)$/. On a
multi-XPU system the progress circle and queue-item badges were therefore
always blank.

Accept indexed XPU devices in both places, and correct the queue-item field
description, which claimed the device is set only on CUDA.

* fix(mm): gate Krea 2 fp8 encoder casting on fp8 storage support

The Qwen3-VL encoder kept its fp8 storage only on CUDA, so elsewhere an fp8
checkpoint was loaded as full bf16 (~8.9GB instead of ~4.4GB) and thrashed
partial loading when sharing a GPU with a large transformer.

Reuse the existing cached `_device_supports_fp8_storage` probe, which already
backs the layerwise-casting path. It returns True unconditionally on CUDA, so
CUDA behaviour is unchanged.

* chore: label XPU devices by index in load logs and fp8 help text

Model load lines printed the device index only for CUDA, so every model on a
multi-XPU host logged as a bare "xpu device", making it impossible to tell the
GPUs apart. The FP8 Storage tooltip likewise claimed CUDA-only support.

* test: cover XPU config validation, progress device and fp8 probe

Three paths changed by this branch had no coverage:

- The `device` field pattern was untested. `test_device_choice_xpu` looks like it
  covers it, but the config model does not enable `validate_assignment`, so
  assigning `config.device` skips validation entirely; only constructing the model
  exercises the pattern. Added constructor-based valid/invalid cases.
- `generation_devices` validation was parametrized for cuda/cpu/mps only.
- The progress event's device field, which now reports XPU sessions.

Also cover `_device_supports_fp8_storage`, which gates FP8 storage in both the
generic layerwise-casting path and the Krea 2 encoder: CUDA answers True without
probing, CPU is rejected, and a failing XPU probe returns False instead of raising.

Each new test was verified to fail when the corresponding fix is reverted.

* fix(nodes): recognise XPU out-of-memory errors in the Anima VAE retry

The Anima VAE decode catches OOM and retries once with tiling, which caps peak
allocation. Detection matched `torch.cuda.OutOfMemoryError` or the words "out of
memory" in the message, so it missed XPU entirely: torch's XPU backend does not
raise a recoverable `torch.OutOfMemoryError` on exhaustion, it surfaces the Level
Zero/UR result code as a plain RuntimeError -- and `UR_RESULT_ERROR_OUT_OF_DEVICE_MEMORY`
contains no spaces, so the existing substring never matched. The decode therefore
failed outright instead of retrying tiled.

Match the `*_OUT_OF_DEVICE_MEMORY` / `*_OUT_OF_HOST_MEMORY` spellings (both UR and
ZE prefixes) alongside the existing conditions, and fold the cuDNN/cuBLAS checks
into the same case-insensitive comparison.

Extends the existing parametrized retry test with the three XPU spellings; each was
verified to fail before this change. Note the driver behaviour itself is not
reproducible on the hardware used here -- this stack overcommits into host RAM and
hangs rather than raising -- so the tests pin the classifier, not the driver.

* style: wrap long vram_usage_gb ternary for ruff

* fix: drop CUDA-only wording from progress device description

Matches the committed openapi/schema artifacts, which already say "on a GPU".

* docs: regenerate settings data for xpu device values

* fix: stop xpu VRAM probe from reporting an unknown total as zero

(0, 0) made the cache's available-VRAM arithmetic collapse to a constant
-working_mem budget for the life of the process. Also widen the except:
the failure type moves between torch releases (RuntimeError for the missing
SYCL aspect, AssertionError from _lazy_init), and warn once when the blind
estimate is in use.

* fix: probe fp8 support on the target device, per device, without caching failures

The probe allocated via an index-less "xpu", which resolves through the thread's
current XPU device rather than the device being loaded onto -- so during idle-GPU
encoder offload it measured the busy denoise GPU. It was also keyed on device type,
letting one device decide for another, and memoised transient failures (it runs
during a load, when the device may be momentarily full) with no way back but a
restart. Also probe the bf16 upcast, which is the runtime path for Krea-2/FLUX.

* fix: pin torch current device when borrowing an idle GPU

Worker startup set both the session device and torch's per-thread current device;
the offload borrow set only the former, leaving index-less allocations on the
worker's own GPU. Extracted the shared helper and guarded it on backend
availability.

* fix: keep idle-GPU borrows within one device type

generation_devices accepts a mixed list, so a cuda session could be handed an
xpu device for its text encoder.

* feat: detect Intel integrated GPUs via Level Zero

torch exposes no is-integrated flag, but Level Zero does
(ZE_DEVICE_PROPERTY_FLAG_INTEGRATED), and its loader already ships with the
torch+xpu runtime -- so no new dependency and no compiled extension.

Use it to keep iGPUs out of `generation_devices: auto` when a discrete GPU
exists, and to stop budgeting them as dedicated VRAM (they share system RAM,
like MPS). An unknown answer keeps the previous behaviour, an iGPU-only machine
keeps its device, and an explicit device list can still opt one in.

* feat: add xpu torch index to pins.json

Gives the launcher an Intel install option instead of requiring a manual
pip install of the extra.

* fix: report VRAM diagnostics for the device in use

All three sites dispatched on torch.cuda.is_available() first, so a mixed
NVIDIA + Arc box running on xpu reported a constant 0.0 GB and logged
"CUDA Memory Allocated" -- which would make XPU bug reports unactionable.

* docs: record why xpu takes the CUDA VAE constants and keeps the broad OOM needle

XPU SDPA was measured on Arc Pro B70 / torch 2.13+xpu: peak memory doubles when
sequence length doubles (2.00x across 2048-16384; 2.0 MB at seq=16384 vs 512 MB
for a materialised score matrix). So XPU is in CUDA's O(area) regime, not ROCm's
math-attention regime, and the existing constants are correct rather than
accidental.

* fix: derive rand_device metadata from the backend's devices

Was hardcoded to 'cuda' for any non-CPU noise, which is wrong on Arc. Falls
back to 'cuda' when the device query has not resolved, so Nvidia metadata is
unchanged.

* docs: add Intel Arc install, driver and VRAM-reporting notes

* fix: probe fp8 device support only when a model requests it

The probe was the first statement in _should_use_fp8, so it allocated on the GPU
during the first load of any model at all -- tokenizer, VAE, scheduler -- and on
API/install threads it forced XPU lazy SYCL init on a thread that never generates.
Moved below the exclusions.

* fix: query Level Zero Sysman for driver-global free VRAM on xpu

The blind estimate (total minus this process's reserved bytes) is what made
_get_vram_available over-commit on a shared GPU: it feeds a formula that assumes
a driver-global figure. Sysman's zesMemoryGetState reports that figure and is
often available when the SYCL ext_intel_free_memory aspect is not, so try it
before estimating.

Measured on Arc Pro B70 with 16 GiB held by another process: Sysman reported
15.553 GiB free, the estimate 31.725 -- a 16.172 GiB error, exactly the foreign
allocation. Sysman is not a guaranteed substitute (torch's query bottoms out in
the same layer), so the estimate remains as a last resort.

* fix: make the fp8 probe mirror the runtime cast path

The storage cast happens on CPU while params are still CPU-resident, then the
fp8 tensor is copied to the device and the pre-hook upcasts there. Probing all
three steps on the device would pass on a build where the host->device fp8 copy
or one upcast target fails, and break at forward time instead.

Verified on Arc Pro B70 / torch 2.13+xpu: the full sequence works on both cards.

* fix: degrade gracefully when a backend cannot name a device

torch.xpu.get_device_name goes through _lazy_init, which raises AssertionError
on a build without XPU. Naming is used only for labels and logs, so fall back to
the device string rather than propagating.

* fix: resolve an index-less device in the Sysman VRAM query

Returning None for a device with no index would skip the driver-global query and
fall through to the blind estimate with no visible symptom. Callers currently
always pass a concrete device, so this is a latent hazard rather than a live bug.

* fix: declare ctypes prototypes for the Level Zero calls

Handles come back from (c_void_p * n)() as plain Python ints, and ctypes
converts an undeclared int argument to a C int -- 32 bits. Any handle above
2**31 was being silently truncated; a direct test of that path segfaults.
It happened to work on the B70 because the handles fit.

Also: release the idle-GPU borrow if re-pinning raises (the setup was outside
the try, so a failure there stranded the lock for the life of the process), and
report a failing fp8 probe once per device instead of on every model load.

* fix: drop the ZES_ENABLE_SYSMAN mutation from the Sysman probe

Setting a process-wide environment variable from a read-only query leaks into
child processes. It also bought nothing: the variable only gates Sysman on
runtimes predating zesInit and must be set before Level Zero initialises, which
torch has already done by then. Verified on Arc Pro B70 that zesInit succeeds
with the variable unset.

* refactor: tidy up the xpu additions after a cleanup review

level_zero: cache the loader so it is opened and its prototypes configured once
rather than twice, share the driver/device enumeration and its ordering guard
between the two probes, and collapse the Sysman pair of globals into one
nullable tuple.

Also: fp8 support cache is a set (it only ever stored True), the pbr_maps
empty_cache is routed through TorchDevice like the PR's other conversions, the
shared-memory VRAM branch stops re-testing the device type it matched on,
`_auto_generation_devices` partitions in one pass, and rand_device only answers
when every generation device is the same accelerator.

Merges three duplicate mem_get_info tests into one parametrized case and drops
two fp8 probe tests fully subsumed by the cast-sequence test.

* build: pin the xpu extra to torch 2.13.0

Intel's XPU backend matured considerably after 2.7.1: torch.xpu.mem_get_info()
works on driver/kernel combinations where it previously raised, and the oneAPI
user-space runtime ships with the wheel, so upgrading torch upgrades it too.
Follows the rocm extra, which already pins ahead of cpu/cuda.

pytorch-triton-xpu was renamed triton-xpu upstream. The darwin/aarch64
fallbacks stay on 2.7.1 to match the other extras and the project's
torch<2.8.0 constraint on darwin.

cpu/cuda/rocm exports are unchanged package-for-package (196/211/197); the only
delta is a dropped "via pytorch-triton-xpu" comment annotation from the rename.

* test: stub Sysman in the unknown-total xpu probe test

Without it the test only passes where Level Zero cannot answer -- never on the
Intel hardware the probe exists for, where Sysman returns before the tier under
test is reached.

* build: teach the pins check about the xpu index

Its per-platform allowlist rejects anything unlisted, so pins.json's xpu entry
fails it. PyTorch publishes XPU wheels for win32 and linux x86_64, matching the
extra's markers.

* fix: defer the xpu device pin like cuda's

torch.xpu.set_device() brings up a SYCL context that holds VRAM in an otherwise
idle process, the same reason the CUDA pin waits for the first claimed queue item.

* docs: regenerate settings data on linux

Regenerating on Windows flips two path defaults to backslashes, which the docs
check rejects.

* fix(mm): handle shared memory on integrated GPUs

Their VRAM is system RAM, so a RAM copy doubles each model's footprint against
the same pool. Drop it, letting a full load move weights rather than copy them.

Keep partial loading on -- it is the only path that respects vram_available --
and raise a clean error when a full-load-only model cannot fit, instead of
walking into an uncatchable OOM-kill. Warn once when a setting is overridden.

Scoped to integrated XPU; CPU and MPS are unchanged.

* docs: note intel device selection and integrated-GPU memory

`auto` prefers CUDA on a mixed Nvidia/Arc box, and keep_ram_copy_of_weights is
ignored on an integrated GPU.

* chore(ui): typegen for the xpu device values

* fix(mm): compare the integrated-GPU full-load guard against bytes still to move

A resident model's weights occupy the same DRAM that vram_available is read
from, so its total can exceed "available" precisely because it is loaded.
lock() runs on every use and full_load_to_vram() is a no-op when resident;
comparing the total refused the re-lock and evicted a healthy model on every
other generation. Compare what full_load_to_vram() will actually move instead.

Co-Authored-By: Claude Fable 5 <[email protected]>

* test: run the integrated-GPU cache tests on CPU-only torch

ModelCache.__init__ sizes the RAM cache from the device's total VRAM, which on
an xpu execution device reads torch.xpu.get_device_properties() -- an
AssertionError on the CPU-only builds CI runs, failing 9 of these tests before
they reached their subject. Stub a fixed total during construction, and add a
regression test for the resident-model re-lock guard.

Co-Authored-By: Claude Fable 5 <[email protected]>

---------

Co-authored-by: LexiconCode <[email protected]>
Co-authored-by: Lincoln Stein <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>
2026-08-15 17:48:31 -04:00
8486d47b7f ci: keep pins.json in sync with pyproject.toml (#9351)
* ci: add pins.json consistency check, bump ROCm index to 7.1

pins.json is consumed only by the Invoke Launcher (fetched at the release
tag) to pick the torch wheel index for legacy installs. Nothing in-repo
references it, so it silently drifted from pyproject.toml: its Linux ROCm
index stayed at rocm6.3 after the torch-rocm index moved to rocm7.1,
causing the launcher to install ROCm 6.3 wheels (#9328, launcher#131).

- Add scripts/check_pins.py, which fails if any torchIndexUrl entry in
  pins.json differs from the matching [[tool.uv.index]] URL in
  pyproject.toml.
- Run it from the uv-lock-checks workflow, triggered by changes to any of
  pyproject.toml, uv.lock, pins.json, or the check script.
- Bump pins.json rocm index to rocm7.1 (matches #9337) so the check
  passes.
- Bump the workflow's uv from 0.6.10 to 0.11.28: uv.lock is already lock
  format revision 3, which 0.6.x cannot parse.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix: cap torch below 2.12 on linux/windows

torch 2.12.x+rocm7.1 breaks generation (#9328; 2.11 works, and 2.10 is
what the rocm extra pins). The cap only matters for legacy (pre-6.14)
launcher installs, which resolve the base range live against the pytorch
wheel indexes instead of using uv.lock — with the range open to <3.0,
AMD users could land on the broken 2.12.x. Lockfile-based installs are
unaffected: uv.lock stays at 2.7.1 / 2.10.0+rocm7.1 (no locked versions
changed, only the recorded specifier).

Remove the cap once the 2.12 ROCm incompatibility is diagnosed.

Co-Authored-By: Claude Fable 5 <[email protected]>

* ci(check_pins): validate an explicit required platform/backend matrix

Addresses JPPhoto's review. The checker only iterated the entries that
already existed in pins.json, so deleting torchIndexUrl.linux.rocm still
exited 0 — recreating the exact silent-fallback failure the guardrail was
meant to prevent (the launcher only passes --index when the entry exists,
and its schema makes every backend key optional).

- Validate pins.json against REQUIRED_BACKENDS, an explicit matrix of the
  platform/backend combinations the launcher can select and Invoke supports.
  Missing entries, missing platform sections, unknown platforms and
  unsupported backends are now all errors, alongside the existing URL check.
- Split the logic into check_pins(), with main() taking a repo root, so the
  exit code is directly testable.
- Add tests/test_check_pins.py: removes each required entry in turn and
  asserts a nonzero exit, plus stale-URL, unknown-platform and
  unsupported-backend cases.
- pins.json: add the win32.cpu entry the matrix exposes as missing. Without
  it, a Windows "no dedicated GPU" legacy install gets no --index and pulls
  the CUDA-bundled PyPI torch wheel instead of the +cpu build. Linux already
  had this entry.
- python-tests: trigger on scripts/** and pins.json so these tests actually
  run when the checker or the pins change.
- Revert the uv 0.6.10 -> 0.11.28 bump in uv-lock-checks: 0.6.10 parses the
  revision-3 lock fine (verified), so the stated justification was wrong and
  the bump left this workflow out of step with python-tests.

* fix(deps): drop the blanket torch <2.12 cap; scope the ROCm caveat to docs

Addresses JPPhoto's second review. The cap was applied to the base
`sys_platform != 'darwin'` requirement, so it landed in published package
metadata for every Linux and Windows install — CUDA, CPU-only and Linux
ARM64 included — despite #9328 only ever reporting a ROCm 7.1 failure.

My original justification ("only affects legacy pre-6.14 launcher installs")
was wrong in both directions:

- It never protected legacy launcher installs. Those install an
  already-released version, resolving against that release's frozen PyPI
  metadata, not this pyproject.
- It never protected bootstrap (6.14+) launcher installs either. Those pass
  `invokeai[cpu|cuda|rocm]`, and every one of those extras pins torch
  exactly, so the base range is never consulted.
- What it did affect is manual installs, which per docs/start-here/manual
  use `--torch-backend=<x>` with no extra and therefore resolve the base
  range directly — on every platform, not just ROCm.

There is no environment marker for "resolving against the rocm7.1 index", so
the cap cannot be scoped in metadata. Constrain it where it can actually be
targeted instead: the `rocm` extra already pins torch==2.10.0+rocm7.1, and
the manual install docs now carry a ROCm-specific caution with the
`"torch<2.12"` workaround for users following the `--torch-backend=rocm7.1`
path.

pyproject.toml returns to `torch>=2.7.0,<3.0`, so uv.lock is untouched by
this PR again.

* docs: point the ROCm torch-2.12 caveat at an open tracking issue

#9328 was closed as completed once pins.json was corrected to the rocm7.1
index; the separate torch 2.12.x generation failure reported in that thread
had no open tracking issue, so the caveat had no removal condition. Filed
#9410 for it and link there instead.

Also narrow the cross-platform claim: we have no torch 2.12 smoke tests on
CUDA/CPU/Windows/ARM64/MPS, so say only that the workaround applies to the
reported ROCm case rather than asserting other backends are unaffected.

* ci(pins): validate pins.json's python pin against requires-python

The launcher's zod schema declares `python: z.string()` (required) and passes
pins.python to `uv venv --python` on both the bootstrap and legacy install
paths, before anything is installed. Bumping project.requires-python without
bumping pins.json therefore builds a venv the package metadata then rejects -
and the check passed, because it only looked at torchIndexUrl.

check_pins.py now also checks that pins.json's python satisfies
project.requires-python. It stays stdlib-only (CI runs it with a bare python3),
so the specifier handling is hand-rolled and deliberately narrow: ==, !=, >=,
<=, > and < against dotted numeric versions, zero-padded so 3.12 == 3.12.0.
Anything it cannot evaluate is reported rather than guessed at. Differentially
tested against packaging over 1014 version/operator/bound combinations with no
divergences.

Hardening found while attacking the above:

- check_python never raises. requires-python is optional in PEP 621 and can be
  mistyped as a bare TOML float; either used to throw out of check_pins(),
  which runs before the torchIndexUrl loop and so suppressed the ROCm drift
  check this script exists for.
- A present-but-null platform section ("linux": null) passed silently, because
  .get() cannot tell it from an absent one.
- Version components are bounded, so a pin like 3.12.99999999 - which satisfies
  every specifier but which uv cannot resolve to an interpreter - is rejected.
- A trailing comma in requires-python is no longer read as an empty clause.

Also drop the unverified 'isn't needed for the other torch backends' clause
from the ROCm caveat, per review: nothing on CUDA/CPU/Windows/ARM64/MPS was
smoke-tested with torch 2.12.

* ci(pins): reject unreal python pins by shape, not by digit count

The python pin was validated with a bounded regex, which made a bogus
version merely unlikely rather than impossible: "3.12.9999" passed, and
`uv python find 3.12.9999` finds no interpreter, so CI stayed green
while the launcher's install broke at the last step.

Replace the heuristic with two checks that make the bad values
unrepresentable:

- The pin must be exactly major.minor. `uv venv --python 3.12` already
  resolves to the newest 3.12.x, `--python 3.12.7` demands one exact
  build that can leave uv's index, and the launcher's reinstall check
  compares only major()/minor() of this field anyway. That removes the
  whole 3.12.<anything> family by shape.
- Its major.minor must appear in project.classifiers. requires-python
  says which versions the metadata allows; the classifiers say which
  ones we ship for. Without it, an unreal version inside an open-ended
  requires-python (">=3.11" and a "3.99" pin) satisfies every clause and
  no digit bound catches it.

Also fix the module docstring: only the path handed to python is
location-independent, not the working directory it is typed in.

Hardening found by attacking the above:

- Bound the classifier pattern's digits like its two siblings. int()
  refuses a string of more than 4300 digits, so an unbounded pattern let
  a classifier raise straight out of check_python - which runs first and
  would have taken the torchIndexUrl checks with it.
- Guard the pins.json top level. A non-object raised AttributeError from
  pins.get(), with the same suppressing effect (pre-existing).
- Reject leading zeros, so the pin has exactly one spelling.
- Report dynamic classifiers as dynamic rather than as absent.
- De-duplicate classifier versions so a repeat is not listed twice.

Tests assert the reason a patch pin is rejected, not just the exit code:
the classifier check rejects those too, so without that a loosened
version pattern would leave the suite green while advising the user to
add a classifier for "3.12.7".

---------

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: Jonathan <[email protected]>
2026-08-05 12:36:40 -04:00
chejh-amdandLincoln Stein b0462fc1c1 change rocm6.3 to rocm7.1 (#9337)
Co-authored-by: Lincoln Stein <[email protected]>
2026-07-11 16:26:02 +00:00
psychedelicious 699736486b chore: bump torch to 2.7.0
- Update `pyproject.toml`
- Update `pins.json` so launcher installs latest CUDA 12.8 & ROCm 6.3
2025-05-19 12:29:51 +10:00
psychedelicious ae3944b4e0 build: upgrade python to 3.12 in pins 2025-04-04 18:42:13 +11:00
psychedelicious 79e384e71c build: downgrade python to 3.11 in pins 2025-04-04 18:42:13 +11:00
psychedelicious 2b1a36ef4a experiment: add pins.json to repo
The launcher will query this file to get the pins needed for installation
2025-04-04 18:42:13 +11:00