feat: add the augmentation registry - #67
Open
Hendrik-code wants to merge 1 commit into
Open
Conversation
smauglab/registry.py, with no consumers yet -- reviewable on its own before anything depends on it. It answers four questions that are currently answered by reading an `if` ladder: what augmentations exist per backend, which class a config key maps to, what parameters that class accepts, and which backends implement a given concept. Accepted parameters come from inspect.signature, so there is no second schema to drift out of step with the constructors; registering a class whose __init__ ends in **kwargs without declaring forwards_to is an error, because signature-based validation would otherwise accept anything. The module is stdlib-only and imports nothing from smauglab.transforms at module scope. That keeps the import graph acyclic -- transform modules import register from here -- and lets a CLI answer "what exists?" without paying for torch. On pipeline order. Each augmentation's position is data the ladders held implicitly, so the registry has to hold it explicitly; config key order cannot decide it, because the two have never agreed and honouring the file would silently reorder every pipeline the moment someone tidied a config. It is one PIPELINE_ORDER tuple per backend rather than an `order=` integer on each @register. The question a reviewer needs to answer is "does the new pipeline run things in the same sequence as the old one?", and against a single list that is a diff against the ladder it was derived from. Against integers spread over eight files it is not. Each GPU entry carries the ladder key it came from as a comment, so the correspondence is checkable line by line. Registering a class absent from its backend's tuple is an error, so the table cannot fall out of date. RandomLaplaceGPU is the one GPU entry with no ladder key: the GPU Laplace kernel was reachable only by setting kernel_type="Laplace" on ScharrTransform, so its position is a new choice, placed next to its sibling. isolated() gains an `order` argument. Without one it turns the position check off for the block, which is what most tests want -- they register throwaway classes whose pipeline position is not the thing under test. With one, registration is checked against it, which is how the check itself is covered. Also: smauglab stops being a PEP 420 namespace package. Every directory gets an __init__.py, because the registry needs a deterministic import-time population point and because a namespace package lets a stray smauglab/ elsewhere on sys.path silently merge into this one. namespace_packages/explicit_package_bases come out of [tool.mypy] accordingly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #66.
smauglab/registry.py, with no consumers yet — reviewable on its own before anything depends on it.It answers four questions that today are answered by reading an
ifladder: what augmentations exist per backend, which class a config key maps to, what parameters that class accepts, and which backends implement a given concept.Accepted parameters come from
inspect.signature, so there is no second schema to drift out of step with the constructors. Registering a class whose__init__ends in**kwargswithout declaringforwards_tois an error — signature-based validation would otherwise accept anything.The module is stdlib-only and imports nothing from
smauglab.transformsat module scope. That keeps the import graph acyclic (transform modules importregisterfrom here) and lets a CLI answer "what exists?" without paying for torch.On pipeline order — the design question you asked about
Each augmentation's position is data the ladders held implicitly, so the registry has to hold it explicitly. Config key order cannot decide it: the two have never agreed, and honouring the file would silently reorder every pipeline the moment someone tidied a config. (A config will be able to opt into key order —
pipeline.order— whenconfig.pylands.)Per your call, it's one
PIPELINE_ORDERtuple per backend, not anorder=integer on each@register:The question a reviewer needs to answer is "does the new pipeline run things in the same sequence as the old one?" Against a single list that's a diff against the ladder it came from; against integers spread over eight files it isn't. Every GPU entry carries the ladder key it was derived from as a comment, so the correspondence is checkable line by line against
gpu/transforms.py.Registering a class absent from its backend's tuple is an error, so the table cannot fall out of date.
One entry needs a judgement call:
RandomLaplaceGPUhas no ladder key. The GPU Laplace kernel was reachable only by settingkernel_type="Laplace"onScharrTransform, so its position is a new choice — placed next to its sibling. Worth a look.isolated(order=...)isolated()without an argument turns the position check off for the block, which is what most tests want — they register throwaway classes whose pipeline position isn't under test. With an explicit table, registration is checked against it, which is how the check itself gets covered.Also in here
smauglabstops being a PEP 420 namespace package: every directory gets an__init__.py. The registry needs a deterministic import-time population point, and a namespace package lets a straysmauglab/elsewhere onsys.pathsilently merge into this one.namespace_packages/explicit_package_basescome out of[tool.mypy]accordingly.Testing
unit_tests/test_registry.py— 26 tests against synthetic transform classes, deliberately not the real ones (those get registered in the next PR; these are about the mechanism). Covers the registration invariants, signature-derived parameter validation, the "did you mean" suggestions, and the coverage matrix.Full suite: 131 passed, 237 subtests. The 24 seeded config digests are unchanged — nothing imports the registry yet.
ruffandmypyclean.