trnsolver 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- trnsolver-0.3.0/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- trnsolver-0.3.0/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
- trnsolver-0.3.0/.github/pull_request_template.md +9 -0
- trnsolver-0.3.0/.github/workflows/ci.yml +20 -0
- trnsolver-0.3.0/.github/workflows/neuron.yml +63 -0
- trnsolver-0.3.0/.github/workflows/notify-umbrella.yml +36 -0
- trnsolver-0.3.0/.github/workflows/publish.yml +56 -0
- trnsolver-0.3.0/.gitignore +26 -0
- trnsolver-0.3.0/CHANGELOG.md +87 -0
- trnsolver-0.3.0/CLAUDE.md +105 -0
- trnsolver-0.3.0/CODE_OF_CONDUCT.md +25 -0
- trnsolver-0.3.0/CONTRIBUTING.md +69 -0
- trnsolver-0.3.0/LICENSE +201 -0
- trnsolver-0.3.0/PKG-INFO +127 -0
- trnsolver-0.3.0/README.md +98 -0
- trnsolver-0.3.0/benchmarks/bench_cuda.py +94 -0
- trnsolver-0.3.0/benchmarks/bench_solver.py +144 -0
- trnsolver-0.3.0/benchmarks/conftest.py +35 -0
- trnsolver-0.3.0/docs/api/eigen.md +30 -0
- trnsolver-0.3.0/docs/api/factor.md +53 -0
- trnsolver-0.3.0/docs/api/iterative.md +26 -0
- trnsolver-0.3.0/docs/api/nki.md +36 -0
- trnsolver-0.3.0/docs/architecture.md +54 -0
- trnsolver-0.3.0/docs/aws_setup.md +110 -0
- trnsolver-0.3.0/docs/benchmarks.md +71 -0
- trnsolver-0.3.0/docs/index.md +32 -0
- trnsolver-0.3.0/docs/installation.md +41 -0
- trnsolver-0.3.0/docs/quickstart.md +65 -0
- trnsolver-0.3.0/examples/scf_eigen.py +135 -0
- trnsolver-0.3.0/infra/terraform/README.md +58 -0
- trnsolver-0.3.0/infra/terraform/gpu.tf +84 -0
- trnsolver-0.3.0/infra/terraform/main.tf +150 -0
- trnsolver-0.3.0/mkdocs.yml +38 -0
- trnsolver-0.3.0/pyproject.toml +54 -0
- trnsolver-0.3.0/scripts/run_cuda_tests.sh +126 -0
- trnsolver-0.3.0/scripts/run_neuron_tests.sh +143 -0
- trnsolver-0.3.0/setup.cfg +4 -0
- trnsolver-0.3.0/tests/conftest.py +38 -0
- trnsolver-0.3.0/tests/test_eigen.py +72 -0
- trnsolver-0.3.0/tests/test_factor.py +140 -0
- trnsolver-0.3.0/tests/test_iterative.py +87 -0
- trnsolver-0.3.0/trnsolver/__init__.py +33 -0
- trnsolver-0.3.0/trnsolver/eigen.py +170 -0
- trnsolver-0.3.0/trnsolver/factor.py +157 -0
- trnsolver-0.3.0/trnsolver/iterative.py +179 -0
- trnsolver-0.3.0/trnsolver/nki/__init__.py +5 -0
- trnsolver-0.3.0/trnsolver/nki/dispatch.py +91 -0
- trnsolver-0.3.0/trnsolver.egg-info/PKG-INFO +127 -0
- trnsolver-0.3.0/trnsolver.egg-info/SOURCES.txt +50 -0
- trnsolver-0.3.0/trnsolver.egg-info/dependency_links.txt +1 -0
- trnsolver-0.3.0/trnsolver.egg-info/requires.txt +11 -0
- trnsolver-0.3.0/trnsolver.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report a bug in trnsolver
|
|
4
|
+
labels: bug
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Environment
|
|
8
|
+
|
|
9
|
+
- trnsolver version:
|
|
10
|
+
- Python version:
|
|
11
|
+
- PyTorch version:
|
|
12
|
+
- Hardware: CPU / trn1 / trn2 / inf2
|
|
13
|
+
- OS:
|
|
14
|
+
|
|
15
|
+
## Description
|
|
16
|
+
|
|
17
|
+
What happened?
|
|
18
|
+
|
|
19
|
+
## Steps to reproduce
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
# Minimal code to reproduce
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Expected behavior
|
|
26
|
+
|
|
27
|
+
What should have happened?
|
|
28
|
+
|
|
29
|
+
## Actual behavior
|
|
30
|
+
|
|
31
|
+
What happened instead? Include error messages/tracebacks if applicable.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest a new feature or enhancement
|
|
4
|
+
labels: enhancement
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Description
|
|
8
|
+
|
|
9
|
+
What feature would you like?
|
|
10
|
+
|
|
11
|
+
## Motivation
|
|
12
|
+
|
|
13
|
+
Why is this needed? What problem does it solve?
|
|
14
|
+
|
|
15
|
+
## Alternatives considered
|
|
16
|
+
|
|
17
|
+
Any other approaches you've thought about?
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v6
|
|
16
|
+
- uses: actions/setup-python@v6
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python-version }}
|
|
19
|
+
- run: pip install -e ".[dev]"
|
|
20
|
+
- run: pytest tests/ -v -x --tb=short -m "not neuron"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Neuron hardware tests
|
|
2
|
+
|
|
3
|
+
# Manually triggered workflow that runs the `@pytest.mark.neuron`-marked suite
|
|
4
|
+
# on a Trainium instance via SSM. The instance is provisioned separately with
|
|
5
|
+
# `infra/terraform/`. This workflow wraps `scripts/run_neuron_tests.sh`.
|
|
6
|
+
#
|
|
7
|
+
# Prerequisites (one-time, manual):
|
|
8
|
+
# 1. Provision the CI instance: `cd infra/terraform && terraform apply`.
|
|
9
|
+
# 2. Register an AWS IAM role that trusts the GitHub OIDC provider for this
|
|
10
|
+
# repo. The role needs ec2:{Start,Stop,Describe}Instances and
|
|
11
|
+
# ssm:{SendCommand,GetCommandInvocation,DescribeInstanceInformation}.
|
|
12
|
+
# 3. Add the role ARN to repo secrets as `AWS_ROLE_ARN`.
|
|
13
|
+
#
|
|
14
|
+
# Until step 3 is done, the workflow will fail at the OIDC assume-role step.
|
|
15
|
+
|
|
16
|
+
on:
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
inputs:
|
|
19
|
+
instance_type:
|
|
20
|
+
description: "Instance family tag suffix (trn1, trn2, inf2)"
|
|
21
|
+
required: false
|
|
22
|
+
default: "trn1"
|
|
23
|
+
aws_region:
|
|
24
|
+
description: "AWS region"
|
|
25
|
+
required: false
|
|
26
|
+
default: "us-east-1"
|
|
27
|
+
warm:
|
|
28
|
+
description: "Run suite twice (warm NEFF cache pass)"
|
|
29
|
+
type: boolean
|
|
30
|
+
required: false
|
|
31
|
+
default: false
|
|
32
|
+
|
|
33
|
+
concurrency:
|
|
34
|
+
# Only one hardware run at a time — the EC2 instance is shared.
|
|
35
|
+
group: neuron-hardware
|
|
36
|
+
cancel-in-progress: false
|
|
37
|
+
|
|
38
|
+
jobs:
|
|
39
|
+
neuron:
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
timeout-minutes: 45
|
|
42
|
+
permissions:
|
|
43
|
+
id-token: write
|
|
44
|
+
contents: read
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v6
|
|
47
|
+
|
|
48
|
+
- name: Configure AWS credentials (OIDC)
|
|
49
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
50
|
+
with:
|
|
51
|
+
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
|
52
|
+
aws-region: ${{ inputs.aws_region }}
|
|
53
|
+
|
|
54
|
+
- name: Run neuron-marked tests via SSM
|
|
55
|
+
env:
|
|
56
|
+
AWS_REGION: ${{ inputs.aws_region }}
|
|
57
|
+
run: |
|
|
58
|
+
chmod +x scripts/run_neuron_tests.sh
|
|
59
|
+
if [[ "${{ inputs.warm }}" == "true" ]]; then
|
|
60
|
+
./scripts/run_neuron_tests.sh --warm "${{ inputs.instance_type }}"
|
|
61
|
+
else
|
|
62
|
+
./scripts/run_neuron_tests.sh "${{ inputs.instance_type }}"
|
|
63
|
+
fi
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Notify trnsci umbrella of docs change
|
|
2
|
+
|
|
3
|
+
# Fires a repository_dispatch at trnsci/trnsci whenever this repo's docs or
|
|
4
|
+
# mkdocs.yml change on main, so the combined site at trnsci.dev rebuilds
|
|
5
|
+
# immediately rather than waiting for the daily cron.
|
|
6
|
+
#
|
|
7
|
+
# Requires repo/org secret TRNSCI_DISPATCH_TOKEN — a fine-grained PAT scoped
|
|
8
|
+
# to the trnsci/trnsci repo with "Contents: Read and write" (which covers
|
|
9
|
+
# repository_dispatch). See README for setup.
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
push:
|
|
13
|
+
branches: [main]
|
|
14
|
+
paths:
|
|
15
|
+
- "docs/**"
|
|
16
|
+
- "mkdocs.yml"
|
|
17
|
+
- "README.md"
|
|
18
|
+
- "CHANGELOG.md"
|
|
19
|
+
workflow_dispatch:
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
dispatch:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- name: Trigger umbrella rebuild
|
|
26
|
+
env:
|
|
27
|
+
GH_TOKEN: ${{ secrets.TRNSCI_DISPATCH_TOKEN }}
|
|
28
|
+
run: |
|
|
29
|
+
if [ -z "${GH_TOKEN:-}" ]; then
|
|
30
|
+
echo "::notice::TRNSCI_DISPATCH_TOKEN not set; umbrella will pick up this change on next daily cron or manual dispatch."
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
gh api --method POST repos/trnsci/trnsci/dispatches \
|
|
34
|
+
-f event_type=subproject-updated \
|
|
35
|
+
-f "client_payload[repo]=${GITHUB_REPOSITORY}" \
|
|
36
|
+
-f "client_payload[sha]=${GITHUB_SHA}"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v6
|
|
12
|
+
- uses: actions/setup-python@v6
|
|
13
|
+
with:
|
|
14
|
+
python-version: "3.12"
|
|
15
|
+
- run: pip install build
|
|
16
|
+
- run: python -m build
|
|
17
|
+
- uses: actions/upload-artifact@v4
|
|
18
|
+
with:
|
|
19
|
+
name: dist
|
|
20
|
+
path: dist/
|
|
21
|
+
|
|
22
|
+
publish-pypi:
|
|
23
|
+
needs: build
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
# Only publish stable releases (v1.2.3), not pre-releases (v1.2.3-rc1)
|
|
26
|
+
if: ${{ !contains(github.event.release.tag_name, '-') }}
|
|
27
|
+
environment:
|
|
28
|
+
name: pypi
|
|
29
|
+
url: https://pypi.org/project/trnsolver/
|
|
30
|
+
permissions:
|
|
31
|
+
id-token: write
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/download-artifact@v4
|
|
34
|
+
with:
|
|
35
|
+
name: dist
|
|
36
|
+
path: dist/
|
|
37
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
38
|
+
|
|
39
|
+
publish-testpypi:
|
|
40
|
+
needs: build
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
# Only publish pre-releases to TestPyPI
|
|
43
|
+
if: ${{ contains(github.event.release.tag_name, '-') }}
|
|
44
|
+
environment:
|
|
45
|
+
name: testpypi
|
|
46
|
+
url: https://test.pypi.org/project/trnsolver/
|
|
47
|
+
permissions:
|
|
48
|
+
id-token: write
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/download-artifact@v4
|
|
51
|
+
with:
|
|
52
|
+
name: dist
|
|
53
|
+
path: dist/
|
|
54
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
55
|
+
with:
|
|
56
|
+
repository-url: https://test.pypi.org/legacy/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.eggs/
|
|
8
|
+
*.egg
|
|
9
|
+
.pytest_cache/
|
|
10
|
+
.tox/
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
*.so
|
|
14
|
+
.idea/
|
|
15
|
+
.vscode/
|
|
16
|
+
*.swp
|
|
17
|
+
*.swo
|
|
18
|
+
*~
|
|
19
|
+
site/
|
|
20
|
+
.benchmarks/
|
|
21
|
+
.terraform/
|
|
22
|
+
*.tfstate
|
|
23
|
+
*.tfstate.backup
|
|
24
|
+
.terraform.lock.hcl
|
|
25
|
+
.claude/
|
|
26
|
+
.DS_Store
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.3.0] — 2026-04-12
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `inv_sqrt_spd_ns(A)` — Newton-Schulz iteration for `A^{-1/2}`. All-GEMM,
|
|
15
|
+
returns `(X, iters, residual)`. Progress on #14 (NKI-GEMM backend swap
|
|
16
|
+
lands when trnblas GEMM validates on hardware).
|
|
17
|
+
- scipy.linalg baselines (eigh, cholesky, cho_solve) in
|
|
18
|
+
`benchmarks/bench_solver.py` for LAPACK comparison. Progress on #13.
|
|
19
|
+
- `benchmarks/bench_cuda.py` — CUDA / cuSOLVER benchmarks, auto-skipped
|
|
20
|
+
when no GPU is available. Vintage-matched methodology (trn1 ↔ A10G,
|
|
21
|
+
trn2 ↔ H100). Progress on #13.
|
|
22
|
+
- `infra/terraform/gpu.tf` — opt-in GPU CI instance (default `g5.xlarge`
|
|
23
|
+
A10G, vintage peer of trn1; `p5.4xlarge` for trn2 via override).
|
|
24
|
+
Disabled by default via `enable_gpu_ci = false`.
|
|
25
|
+
- `scripts/run_cuda_tests.sh` — SSM-based runner mirroring
|
|
26
|
+
`run_neuron_tests.sh` for the GPU box.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- `docs/benchmarks.md` rewritten with vintage-matching methodology and
|
|
31
|
+
real CPU numbers; `docs/aws_setup.md` documents the GPU instance and
|
|
32
|
+
H100 opt-in.
|
|
33
|
+
- CI: bumped to `actions/checkout@v6` and `actions/setup-python@v6`
|
|
34
|
+
(Node.js 24 runtime); standalone Deploy Docs workflow removed — docs
|
|
35
|
+
are served from trnsci.dev.
|
|
36
|
+
- `pyproject.toml` normalized across the trnsci suite; added
|
|
37
|
+
`Documentation` URL pointing to `trnsci.dev/trnsolver/`.
|
|
38
|
+
|
|
39
|
+
## [0.2.0] — 2026-04-12
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- `jacobi_preconditioner(A)` in `trnsolver.iterative` — diagonal preconditioner
|
|
44
|
+
callable for `cg`. Partial progress on #16.
|
|
45
|
+
- Benchmark suite `benchmarks/bench_solver.py` covering eigh, factorizations,
|
|
46
|
+
solve, CG (with/without Jacobi preconditioner), and GMRES. Closes #8.
|
|
47
|
+
- Status badges in README (CI, PyPI, Python versions, license, docs). Closes #4.
|
|
48
|
+
- Manual Neuron hardware CI workflow (`.github/workflows/neuron.yml`) —
|
|
49
|
+
`workflow_dispatch`-only, OIDC-based, wraps `scripts/run_neuron_tests.sh`.
|
|
50
|
+
Closes #5.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- `cg(A, b, M=...)` tensor preconditioner is now applied as `M @ r` (already-
|
|
55
|
+
inverted operator), not `inv(M) @ r` recomputed every iteration.
|
|
56
|
+
- Repository transferred from `scttfrdmn/trnsolver` to `trnsci/trnsolver`.
|
|
57
|
+
Hardcoded URLs updated across docs, pyproject, terraform, and CI.
|
|
58
|
+
|
|
59
|
+
## [0.1.1] — 2026-04-12
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
|
|
63
|
+
- Bumped `neuronxcc` floor from `>=2.15` to `>=2.24` to unify with the
|
|
64
|
+
rest of the trnsci suite. `torch-neuronx` floor bumped to `>=2.9`.
|
|
65
|
+
|
|
66
|
+
## [0.1.0] - 2026-04-11
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
|
|
70
|
+
- Initial scaffold of `trnsolver` — linear solvers and eigendecomposition
|
|
71
|
+
for AWS Trainium via NKI. Third sibling in the `trn-*` suite alongside
|
|
72
|
+
`trnblas` and `trnfft`.
|
|
73
|
+
- Eigenvalue API: `eigh` (symmetric), `eigh_generalized` (Cholesky reduction
|
|
74
|
+
for `Ax = λBx`).
|
|
75
|
+
- Factorizations: `cholesky`, `lu`, `qr`, `solve`, `solve_spd`, `inv_spd`,
|
|
76
|
+
`inv_sqrt_spd`.
|
|
77
|
+
- Iterative solvers: `cg`, `gmres`.
|
|
78
|
+
- NKI Jacobi rotation kernel scaffold in `trnsolver/nki/dispatch.py` with
|
|
79
|
+
auto/pytorch/nki backend selection. PyTorch fallback active until
|
|
80
|
+
on-hardware validation lands.
|
|
81
|
+
- SCF demo (`examples/scf_eigen.py`) for the quantum-chemistry use case:
|
|
82
|
+
build Fock → solve `FC = SCε` → density → convergence loop.
|
|
83
|
+
- pytest test suite covering eigen, factorization, and iterative solvers
|
|
84
|
+
on CPU.
|
|
85
|
+
- mkdocs-material site, GitHub Actions CI/docs/publish workflows, Terraform
|
|
86
|
+
module for the Neuron CI instance, and `scripts/run_neuron_tests.sh`
|
|
87
|
+
SSM-driven hardware test runner — all mirroring the trnblas/trnfft layout.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# trnsolver
|
|
2
|
+
|
|
3
|
+
Linear solvers and eigendecomposition for AWS Trainium via NKI.
|
|
4
|
+
Part of the trnsci scientific computing suite.
|
|
5
|
+
|
|
6
|
+
## What This Is
|
|
7
|
+
|
|
8
|
+
Eigenvalue problems, matrix factorizations, and iterative solvers targeting
|
|
9
|
+
Trainium's Tensor Engine. Complements trnblas (BLAS) and trnfft (FFT).
|
|
10
|
+
|
|
11
|
+
**Primary use case:** SCF eigenvalue problem for quantum chemistry. The SCF
|
|
12
|
+
iteration solves FC = SCε at each step — a generalized symmetric eigenvalue
|
|
13
|
+
problem reduced to standard form via Cholesky of the overlap matrix S. This
|
|
14
|
+
feeds into DF-MP2 (trnblas) for the correlation energy.
|
|
15
|
+
|
|
16
|
+
## Architecture
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
trnsolver/
|
|
20
|
+
├── trnsolver/
|
|
21
|
+
│ ├── __init__.py # Re-exports all solver operations
|
|
22
|
+
│ ├── eigen.py # eigh, eigh_generalized (Jacobi + torch fallback)
|
|
23
|
+
│ ├── factor.py # cholesky, lu, qr, solve, solve_spd, inv_sqrt_spd
|
|
24
|
+
│ ├── iterative.py # cg, gmres
|
|
25
|
+
│ └── nki/
|
|
26
|
+
│ ├── __init__.py
|
|
27
|
+
│ └── dispatch.py # auto/pytorch/nki dispatch + Jacobi rotation kernel
|
|
28
|
+
├── tests/
|
|
29
|
+
│ ├── conftest.py # Fixtures: symmetric, SPD, random matrices
|
|
30
|
+
│ ├── test_eigen.py # Eigenvalue tests (reconstruction, orthogonality)
|
|
31
|
+
│ ├── test_factor.py # Cholesky, LU, QR, solve tests
|
|
32
|
+
│ └── test_iterative.py # CG, GMRES convergence tests
|
|
33
|
+
├── examples/
|
|
34
|
+
│ └── scf_eigen.py # SCF iteration demo (quantum chemistry)
|
|
35
|
+
├── pyproject.toml
|
|
36
|
+
├── README.md
|
|
37
|
+
├── LICENSE # Apache 2.0
|
|
38
|
+
└── CLAUDE.md # This file
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## SCF → Solver Mapping
|
|
42
|
+
|
|
43
|
+
| SCF Step | Math | trnsolver Call |
|
|
44
|
+
|----------|------|---------------|
|
|
45
|
+
| Overlap Cholesky | S = L L^T | `cholesky(S)` |
|
|
46
|
+
| Reduce to standard | A' = L^{-1} F L^{-T} | `eigh_generalized(F, S)` |
|
|
47
|
+
| Eigensolve | A' V = V Λ | `eigh(A')` (Jacobi on NKI) |
|
|
48
|
+
| Back-transform | C = L^{-T} V | `trsm` (in trnblas) |
|
|
49
|
+
| Density | P = C_occ @ C_occ^T | `syrk` (in trnblas) |
|
|
50
|
+
| Metric inverse | J^{-1/2} | `inv_sqrt_spd(J)` |
|
|
51
|
+
|
|
52
|
+
## NKI Jacobi Strategy
|
|
53
|
+
|
|
54
|
+
The Jacobi eigensolver maps to Trainium hardware:
|
|
55
|
+
|
|
56
|
+
- **Each Givens rotation** is a 2-row/col update — rank-2 matmul on Tensor Engine
|
|
57
|
+
- **Off-diagonal max finding** maps to Vector Engine reduction
|
|
58
|
+
- **Sweep convergence check** is a scalar reduction on Scalar Engine
|
|
59
|
+
- **Eigenvector accumulation** V' = V @ G is a batched column update
|
|
60
|
+
|
|
61
|
+
The Jacobi method is preferred over Householder tridiagonalization on
|
|
62
|
+
Trainium because each rotation is a fixed-size operation that maps cleanly
|
|
63
|
+
to the 128×128 tile, vs Householder which requires growing reflector chains.
|
|
64
|
+
|
|
65
|
+
## Known Gaps & Design Notes
|
|
66
|
+
|
|
67
|
+
- **NKI Jacobi kernel is a stub.** Falls back to torch.linalg.eigh until
|
|
68
|
+
validated on hardware. The rotation kernel scaffold is in nki/dispatch.py.
|
|
69
|
+
|
|
70
|
+
- **Jacobi is O(n³) per sweep with O(n) sweeps** — cubic overall but with
|
|
71
|
+
a large constant. For n > ~500, Householder + QR iteration would be faster.
|
|
72
|
+
The Jacobi method is chosen because it's embarrassingly parallel (rotations
|
|
73
|
+
on disjoint pairs can run concurrently) and maps cleanly to NKI tiles.
|
|
74
|
+
|
|
75
|
+
- **CG/GMRES are pure PyTorch.** The inner products and matvecs would
|
|
76
|
+
benefit from NKI Level 1/2 kernels in trnblas, but the iteration logic
|
|
77
|
+
stays on the host.
|
|
78
|
+
|
|
79
|
+
- **inv_sqrt_spd uses eigendecomposition**, not the Newton-Schulz iteration.
|
|
80
|
+
Newton-Schulz (X_{k+1} = 0.5 X_k (3I - A X_k²)) is all GEMMs and would
|
|
81
|
+
map better to trnblas, but needs good initial scaling.
|
|
82
|
+
|
|
83
|
+
## Dependencies
|
|
84
|
+
|
|
85
|
+
- `torch>=2.1` — tensor operations and CPU fallback
|
|
86
|
+
- `numpy>=1.24` — test reference
|
|
87
|
+
- `neuronxcc` — NKI kernels (optional, only on Neuron hardware)
|
|
88
|
+
|
|
89
|
+
## Development
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install -e ".[dev]"
|
|
93
|
+
pytest tests/ -v
|
|
94
|
+
python examples/scf_eigen.py --demo
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Naming Convention
|
|
98
|
+
|
|
99
|
+
Sibling repos in the trn-* suite:
|
|
100
|
+
- `trnfft` — FFT + complex ops (https://github.com/trnsci/trnfft)
|
|
101
|
+
- `trnblas` — BLAS operations (https://github.com/trnsci/trnblas)
|
|
102
|
+
- `trnsolver` — Linear solvers, eigendecomposition (this repo)
|
|
103
|
+
- `trnrand` — Random number generation (planned)
|
|
104
|
+
|
|
105
|
+
All repos: Python/NKI, Apache 2.0.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
This project adopts the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, as its code of conduct. The full text is available at:
|
|
4
|
+
|
|
5
|
+
https://www.contributor-covenant.org/version/2/1/code_of_conduct/
|
|
6
|
+
|
|
7
|
+
## Scope
|
|
8
|
+
|
|
9
|
+
This Code applies within all project spaces — the GitHub repositories under the [trnsci](https://github.com/trnsci) organization, issue trackers, pull request discussions, and any public forums where an individual is representing the project or its community.
|
|
10
|
+
|
|
11
|
+
## Reporting
|
|
12
|
+
|
|
13
|
+
Concerns about behaviour in project spaces may be reported confidentially to:
|
|
14
|
+
|
|
15
|
+
**scttfrdmn@gmail.com**
|
|
16
|
+
|
|
17
|
+
All reports will be reviewed and investigated promptly and fairly. The project maintainers are obligated to respect the privacy and security of the reporter.
|
|
18
|
+
|
|
19
|
+
## Enforcement
|
|
20
|
+
|
|
21
|
+
Maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
|
22
|
+
|
|
23
|
+
## Attribution
|
|
24
|
+
|
|
25
|
+
This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. It is licensed under CC BY 4.0.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Contributing to trnsolver
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing. This document covers the whole suite — the same guidelines apply to the umbrella and to each of the six sub-projects (`trnfft`, `trnblas`, `trnrand`, `trnsolver`, `trnsparse`, `trntensor`).
|
|
4
|
+
|
|
5
|
+
## Where does my change belong?
|
|
6
|
+
|
|
7
|
+
- **Scoped to a single library** — bug fix, new feature, added kernel in one sub-project → open a PR in that sub-project's repo.
|
|
8
|
+
- **Cross-cutting** — integration examples, umbrella docs, CUDA-rosetta content, coordinated version bumps, shared tooling → open a PR against [trnsci/trnsci](https://github.com/trnsci/trnsci).
|
|
9
|
+
|
|
10
|
+
If you aren't sure, open the PR where it's easiest and we'll move it.
|
|
11
|
+
|
|
12
|
+
## Development setup
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
git clone git@github.com:trnsci/trnsci.git
|
|
16
|
+
cd trnsci
|
|
17
|
+
# Clone sibling sub-projects if you don't already have them:
|
|
18
|
+
for p in trnfft trnblas trnrand trnsolver trnsparse trntensor; do
|
|
19
|
+
[ -d "$p" ] || git clone "git@github.com:trnsci/$p.git"
|
|
20
|
+
done
|
|
21
|
+
make install-dev
|
|
22
|
+
make test-all
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
A single sub-project in isolation:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd trnfft # or any other
|
|
29
|
+
pip install -e ".[dev]"
|
|
30
|
+
pytest tests/ -v -m "not neuron"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Tests
|
|
34
|
+
|
|
35
|
+
- `pytest tests/ -v -m "not neuron"` — the CPU-only suite. Must pass on every PR.
|
|
36
|
+
- `pytest tests/ -v -m neuron` — on-hardware suite, run from a machine with AWS credentials via `scripts/run_neuron_tests.sh`. Not part of standard CI.
|
|
37
|
+
|
|
38
|
+
## Conventions
|
|
39
|
+
|
|
40
|
+
- **License header** — new files get the Apache 2.0 notice and `Copyright 2026 Scott Friedman` where a notice is customary (long source files, not one-line configs).
|
|
41
|
+
- **Python** — ≥ 3.10; `torch` ≥ 2.1; `numpy` ≥ 1.24.
|
|
42
|
+
- **No emoji** in source, commits, or docs unless the feature is literally about emoji.
|
|
43
|
+
- **Docstrings** only where they help a reader who doesn't have the context you had when writing. Don't restate the signature.
|
|
44
|
+
- **No throwaway files** in the repo root — work-in-progress notes belong in PR descriptions or `docs/`.
|
|
45
|
+
|
|
46
|
+
## Commit style
|
|
47
|
+
|
|
48
|
+
Conventional-ish prefixes: `fix:`, `feat:`, `docs:`, `test:`, `bench:`, `chore:`, `refactor:`. Keep the subject line ≤ 72 characters. Longer context goes in the body.
|
|
49
|
+
|
|
50
|
+
## Pull requests
|
|
51
|
+
|
|
52
|
+
Before opening a PR:
|
|
53
|
+
|
|
54
|
+
- [ ] `pytest tests/ -v -m "not neuron"` passes
|
|
55
|
+
- [ ] If you changed public API or behaviour, `CHANGELOG.md` has an `[Unreleased]` entry
|
|
56
|
+
- [ ] If you added a public symbol, the project's `docs/api.md` lists it
|
|
57
|
+
- [ ] PR description says *what* changed and *why*, not just *what*
|
|
58
|
+
|
|
59
|
+
## Issues
|
|
60
|
+
|
|
61
|
+
Label each issue one of: `bug`, `feature`, `question`, `docs`, `infra`. Bugs include repro steps and expected-vs-actual output. Features describe the use case.
|
|
62
|
+
|
|
63
|
+
## Code of conduct
|
|
64
|
+
|
|
65
|
+
By participating, you agree to abide by the [Contributor Covenant v2.1](CODE_OF_CONDUCT.md). Report concerns to the contact listed there.
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
Contributions are Apache 2.0, per the repository's [LICENSE](LICENSE). You attest you have the right to submit the code.
|