Repository navigation
v0.9.0
Algebra-guided training tooling lands as the headline 0.9.0 feature: a new quivers.analysis package walks any compiled QVR module and recommends saturation-free, algebra-aware initializers. The encoder rule-body sublanguage gains 86 PyTorch primitives and full user-callable dispatch, so encoder bodies can call top-level programs / morphisms / encoders / decoders by name. Contraction declarations infer their einsum from the typed signature.
Added
- Comprehensive PyTorch primitive surface for let-expression bodies. The let-expression compiler now resolves 86 named primitives drawn from
torch.nn.functionalandtorch: every standard activation (relu,gelu,silu/swish,mish,elu,selu,leaky_relu,prelu,rrelu,hardtanh,hardshrink,softplus,softshrink,softsign,hardsigmoid,hardswish,sigmoid,logsigmoid,tanh,tanhshrink,threshold,glu), simplex maps (softmax,log_softmax,softmin,normalize), pointwise transcendentals (exp,expm1,log,log1p,log2,log10,sqrt,rsqrt,square,abs,neg,sign,reciprocal,clamp), trig / hyperbolic (sin,cos,tan,asin,acos,atan,sinh,cosh,asinh,acosh,atanh), rounding (floor,ceil,round,trunc), special functions (erf,erfc,erfinv,lgamma,digamma),dim=-1reductions (sum,mean,var,std,min,max,argmin,argmax,prod,amax,amin,logsumexp,norm), cumulative / ordering ops (cumsum,cumprod,cummax,cummin,flip,sort), and training-mode primitives (dropout,alpha_dropout,layer_norm,rms_norm). Reductions takedim=-1by convention; reductions over a named axis go through the typedcontractionsurface. - User-defined programs callable from encoder bodies. Encoder / decoder / loss rule bodies (and any let-expression context) can now invoke top-level
programdeclarations,let-bound morphisms,encoders,decoders, anddeductions by name. The call formf(arg, ...)resolves first against the primitive table, then against the structural-globals dict, then against the user-declared constructor set. A deterministic program is a Dirac Kleisli arrow embedding Smooth into Kleisli(Giry); calling it from an encoder body composes the two Smooth pieces and stays in Smooth. - Compile-time arity checking on let-expression calls. For user-defined callables (
Morphism,MonadicProgram, plain Python callables) the compiler verifies the positional argument count at compile time and raisesCompileError("call to 'f': expected N positional argument(s), got M"). Variadic callables (*args) skip the check.Morphismis unary;MonadicProgramarity equalslen(params)when present, else 1. - Runtime tensor-shape errors wrapped at call sites. A
RuntimeErrororTypeErrorraised inside a user-defined callable surfaces asCompileError("call to 'f' failed: ..."), so shape mismatches name the call site instead of producing a bare PyTorch trace. - DSL
[init=auto]annotation on latent declarations.latent f : A -> B [init=auto]overrides the defaultrandn * scaleinit with the algebra's saturation-free recipe. ThroughLatentMorphism's sigmoid bijector (for ProductFuzzy / Boolean / Gödel / Łukasiewicz / Probability) the raw parameter is set vialogit(value); for other algebras the recipe is applied to the raw parameter directly. The annotation rides on the existingoption_blockgrammar; no new keywords. - Encoder factory form:
encoder NAME over SIG using FACTORY [k=v, ...]. An alternative to the explicit{ ... }body that invokes a shipped builder fromquivers.structural.shapes(rnn_encoder,transformer_encoder,bow_encoder,tree_lstm_encoder,gnn_encoder) with optional kwarg overrides. The two forms are mutually exclusive on one declaration and can coexist in the same module. The registry mapping factory name → import path lives inquivers.dsl.compiler.structural._ENCODER_FACTORY_REGISTRY. quivers.analysispackage with algebra-guided training tooling.ChainShape.from_module(module)walks a compiled QVRModuleand produces a per-step record (StepShape) with bound variable name, source line / col, chain depth (1-indexed at the first stochastic bind), governing algebra, and inferred intermediate axis size.Algebra.init_spec(depth, intermediate_size) -> InitSpecreturns the closed-form saturation-free init recipe per algebra (product-fuzzyp ≈ ln(2)/k, Łukasiewiczp ≈ 1/k, log-prob-ln k, Markov logits at 0, tropical / max-plus / real1/√k, Boolean / Gödel idempotent at 1/2, probability / counting1/k).recommend_initmaps every latent in a module to itsInitSpec;apply_init_specmaterialises the recipe onto a learnable tensor viatorch.nn.init.saturation_warnings(module)returns source-keyedSaturationWarningdiagnoses for every latent whose recipe differs materially (> 20% in location or scale) from a defaultNormal(0, 1).
- Type-driven contraction wiring.
contraction NAME(args) : DOM -> CODblocks no longer require a hand-written einsum string. The compiler infers the einsum from the typed signature: axes that appear in the output propagate; axes that appear in ≥ 2 inputs but not the output get contracted via the rule's join; axes that appear in exactly one input but not the output are flagged with a source-keyed error pointing at the disambiguators. Two opt-in clauses for the cases inference can't derive:share T1, T2, ...keeps the listed axes element-wise even when shared across inputs;wiring "<einsum>"remains as the explicit escape hatch (diagonal extraction, reorderings, etc.).
Full Changelog: v0.8.0...v0.9.0