-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyproject.toml
More file actions
230 lines (213 loc) · 9.34 KB
/
Copy pathpyproject.toml
File metadata and controls
230 lines (213 loc) · 9.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "torchwright"
version = "0.1.0"
description = "A compiler that transforms computation graphs into transformer neural network weights"
readme = "README.md"
license = "Apache-2.0"
license-files = ["LICENSE"]
authors = [
{ name = "Rob Porter", email = "physicsrob@gmail.com" },
]
keywords = [
"transformer",
"compiler",
"weights",
"interpretability",
"onnx",
"huggingface",
]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Typing :: Typed",
]
requires-python = ">=3.10"
dependencies = [
"torch",
"onnx",
"ortools>=9.10",
"pydantic>=2.0",
]
[project.urls]
Homepage = "https://github.com/physicsrob/torchwright"
Repository = "https://github.com/physicsrob/torchwright"
Changelog = "https://github.com/physicsrob/torchwright/blob/main/RELEASE_NOTES.md"
[project.optional-dependencies]
# Pinned: the CUDA-graph capture path (torchwright_doom render runtime)
# depends on 1.26.0 mechanics — per-annotation-id run counters,
# gpu_graph_id "-1" skip semantics, capture-on-3rd-run. (1.26.0 needs
# Python >=3.11; the <3.11 branch exists only to keep universal resolution
# alive for torchwright's requires-python floor.)
gpu = [
"onnxruntime-gpu==1.26.0; python_version >= '3.11'",
"onnxruntime-gpu; python_version < '3.11'",
]
# Native HuggingFace surface for compiled token models (compiler/hf/):
# publishing a compiled artifact as a standard transformers causal LM.
# Opt-in — the core compiler does not need them.
hf = [
"transformers>=5.0",
"safetensors",
]
[dependency-groups]
dev = [
# Pinned exactly: select = ["ALL"] picks up new rules on upgrade, so a
# ruff bump is a deliberate act (bump pin + fix new violations together).
"ruff==0.15.22",
"modal",
"mypy",
"pytest",
"pytest-cov",
"pytest-xdist>=3.8.0",
"transformers>=5.0",
"safetensors",
]
# CPU onnxruntime for the ONNX-runtime and HF-parity tests (the OnnxTokenModule
# oracle in onnx_load.py, and everything that compares against it). This is a
# DEDICATED non-default group, deliberately NOT in `dev`: torchwright_doom
# carries `onnxruntime-gpu` (in its own opt-in `test-onnx` group), and the CPU
# and GPU builds collide on the same `onnxruntime` import path. Keeping it out
# of `dev` lets the local workspace use the GPU build while the Modal test image
# (modal_image.py) opts in explicitly via `--group test-onnx`. Pinned in
# lockstep with the gpu extra so the CPU
# oracle the parity tests compare against matches the 1.26.0 runtime contract;
# marker-split mirrors the gpu extra to keep universal resolution alive down to
# the requires-python floor.
test-onnx = [
"onnxruntime==1.26.0; python_version >= '3.11'",
"onnxruntime; python_version < '3.11'",
]
# Only the library ships: tests/, scripts/, examples/, docs/, and the
# modal_*.py launchers are repo infrastructure, not distribution content.
[tool.hatch.build.targets.wheel]
packages = ["torchwright"]
[tool.hatch.build.targets.sdist]
include = ["torchwright"]
[[tool.uv.index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true
[tool.uv.sources]
torch = [
{ index = "pytorch-cu128", marker = "sys_platform == 'linux'" },
]
[tool.pytest.ini_options]
[tool.coverage.run]
source = ["torchwright"]
[tool.coverage.report]
show_missing = true
[tool.mypy]
ignore_missing_imports = true
[tool.ruff]
# target-version is inferred from requires-python (>=3.10).
line-length = 88
[tool.ruff.lint]
select = ["ALL"]
# Every entry here defends a deliberate torchwright decision, not a backlog.
# Do not add entries to make a check pass — fix the code instead.
ignore = [
# Formatter conflicts (ruff's own recommendation when using its formatter)
"COM812", # missing-trailing-comma
"ISC001", # single-line-implicit-string-concatenation
# Docstring presence — deferred as a separate task; shape rules (D2xx) stay on
"D100", "D101", "D102", "D103", "D104", "D105", "D106", "D107",
# Exception-message style rules that fight the long, diagnostic messages
# this codebase deliberately writes
"TRY003", # long messages in exception constructors
"EM101", "EM102", # string literals / f-strings in exceptions
# Compiler invariants I1-I4 are runtime asserts by doctrine (CLAUDE.md,
# "Compiler Invariants"): AssertionError shape is pinned by negative tests
"S101", # use of assert
# The probe/watch debug tooling prints by contract ("prints, does not raise")
"T201", # print
# Math naming: Q/K/V/W matrices in a transformer compiler
"N802", "N803", "N806",
# Lazy imports of heavy deps (torch/onnx/modal) are deliberate
"PLC0415", # import-outside-top-level
# Wide keyword-only signatures are how this codebase does configuration:
# the compile entry points and ops library take many knobs by design,
# and much of that surface is called by torchwright_doom (2026-07 survey:
# 122 sites, tail to 26 args, all classified honest or public API)
"PLR0913", # too-many-arguments
# "token" in this codebase means vocabulary token (bos_token/eos_token/
# unk_token, format-version tags), never a credential
"S105", "S106", "S107",
# Advisory subprocess rules with no satisfying code change: the Modal
# launchers and git-provenance helpers build argv lists, never shell=True
"S603", # subprocess-without-shell-equals-true
"S607", # start-process-with-partial-path
]
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.ruff.lint.per-file-ignores]
"tests/**" = [
"PLR2004", # magic values allowed in tests
"ANN", # type annotations optional in tests
"SLF001", # private-member access allowed in tests
"E402", # pytest.importorskip must precede the imports it guards
"ARG001", # pytest fixtures/hooks are resolved by parameter name
]
# Complexity leaves (2026-07 wave-2 review): functions where helper
# extraction would move code across the I1-I4 assertion points, plus
# if/elif dispatch tables where splitting only relocates the table.
"torchwright/compiler/forward/add_placement.py" = ["C901"]
"torchwright/compiler/forward/compile.py" = ["C901", "PLR0912", "PLR0915"]
"torchwright/compiler/forward/cpsat_scheduler.py" = [
"C901", "PLR0912", "PLR0915",
"SLF001", # documented cache injection into Node._live_weight_row_ranges
]
"torchwright/compiler/forward/residual_map.py" = [
"C901", # _check_invariants IS the I1 assertion body
"ARG002", # free/hold's `mech` is a documented subclass interface slot
]
"torchwright/compiler/forward/scheduler.py" = ["C901", "PLR0912", "PLR0915"]
"torchwright/compiler/forward/weight_writer.py" = ["C901", "PLR0912", "PLR0915"]
"torchwright/graph/affine_rules.py" = [
"C901", # compute_affine_bound is a node-type dispatch table
"SLF001", # refresh_node_caches is the designated cache-write choke point
]
"scripts/measure_op_noise.py" = ["PLR0915"] # render_markdown doc-table pipeline
"tests/compile/forward/test_cpsat_intralayer.py" = ["C901"] # mirrors production warm-start loop
"tests/compile/test_graph_clone.py" = [
"C901", # per-field comparator dispatch table
"BLE001", # generic field comparator's deliberate fallback
]
# Interface slots and recorded design decisions
"torchwright/compiler/export.py" = [
"ARG002", # empty_past's max_len: call-site symmetry with ONNX runtime
"ANN401", # **attrs at ONNX make_node emission is genuinely dynamic
]
"torchwright/compiler/forward/cpsat_snapshot.py" = [
"BLE001", # _git_commit is best-effort provenance by contract
"ANN401", # SchedulingProblem._replace passthrough
]
"torchwright/compiler/hf/build.py" = ["PTH100"] # abspath: symlink semantics differ from resolve()
"torchwright/compiler/hf/modeling_torchwright_custom.py" = ["ARG002"] # HF forward() interface kwargs
"torchwright/compiler/hf/tokenization_torchwright_custom.py" = ["FBT001", "FBT002"] # transformers override signature
"torchwright/compiler/realization.py" = ["SLF001"] # live_weight_row_ranges owns its memo cache
"torchwright/compiler/transformer.py" = ["ARG002"] # past_len: accepted-and-ignored interface slot
"torchwright/debug/probe.py" = ["ANN401"] # past_kvs differs structurally per backend
"torchwright/graph/misc.py" = ["ARG002"] # Node.compute keyword contract on constant nodes
"torchwright/graph/node.py" = ["PLW0603"] # module-level node-id counter, reset by tests
# Op names deliberately mirror the builtins they implement for graph nodes
"torchwright/ops/relu/arithmetic_ops.py" = ["A001"]
"torchwright/ops/swiglu/arithmetic_ops.py" = ["A001"]
"torchwright/ops/swiglu/__init__.py" = ["A004"]
"tests/hf/test_calculator_parity.py" = ["S307"] # eval() of arithmetic expressions is the oracle
"scripts/arithmetic_scaling.py" = [
"SLF001", # recorded reach-in: scratchpad private ops for the viz panel
"FBT003", # matplotlib ax.grid(True)
]
"scripts/calculator_layer_table.py" = ["BLE001"] # records any build refusal as a data row
[tool.ruff.format]
docstring-code-format = true