libmath: add jets for Chebyshev variants of libmath#63
Open
sigilante wants to merge 28 commits into
Open
Conversation
Wrap math.hoon's width doors in a %math engine DOOR under the shared %non chapter (=< math preserves the /+ math + rd:math API), mirroring /lib/lagoon's %non/%lagoon jet structure, with ~/ hints on the rd door and exp arm. The engine MUST be a door (^| =+ [rnd] ~/ %math |%): a sample-less ~/-core anchors its parent to the dashboard root, so the jet never attaches (found by tracing _cj_hot_mean in the runtime). Mirror the vere-side C jet into libmath/vere/ (jets/i/math.c + tree-registration.snippet.c + README) for hand-maintained cross-repo sync -- the runtime jets live in urbit/vere (PR to follow). Add libmath/tools/rd_exp_check.c, the SoftFloat-f64 reference proving the jet is bit-exact to the Hoon. @rd exp verified jetted (34us vs ~970us interpreted), bit-exact 0x4005.bf0a.8b14.576a. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add @rd log as the second jetted transcendental, and refactor the vere master (libmath/vere/jets/i/math.c) so the SoftFloat algorithm cores (_rd_exp, _rd_log) are shared between the runtime jet and a standalone bit-exact harness (libmath/vere/test/, via -DMATH_JET_HARNESS) -- the C the test runs is byte-for-byte the C the jet runs, so they can't drift. log transcribes math.hoon ++rd ++log (2^e*m reduction + degree-9 atanh Horner); ~/ %log hint added. Verified bit-exact to the Hoon incl the subnormal and sqrt(2)-boundary branches, and jetted on-ship (log:rd:math .~2 = 0x3fe6.2e42.fefa.39ef). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-ship) Finish the @rd jet port begun with exp/log: add faithful softfloat cores + u3 wrappers for sin/cos/tan/atan/atan2/asin/acos/sqt/cbt/pow/pow-n/log-2/log-10, each transcribing its Hoon arm's exact reduction/coefficients/Horner order so jet output is bit-identical to the pure-Hoon reference, not merely faithful. - math.hoon: ~/ hints on all 15 @rd arms under the %math door anchor. - jets/i/math.c: 15 algorithm cores shared with the harness via -DMATH_JET_HARNESS, plus u3 ABI wrappers. Fix the 2-arg wrappers (atan2/pow/pow-n) to use brace-enclosed u3r_mean pairs {axis,&ptr} — the flat form failed -Werror=missing-braces and never compiled. - test/rd_check.c: add emit2() + atan2/pow/pow-n vectors. - test/verify_clean.sh: one-query-at-a-time on-ship diff, NO C-c. (SIGINT mid-event corrupts the loom; the old verify.sh's C-c spam was crashing the serf and masquerading as a jet bug.) Verified bit-exact on a fresh fakeship: 234/234 vectors, 0 DIFF (198 single-arg via verify_clean.sh, 36 two-arg via gen/m2.hoon in one event). sin x 200k under %bout = 431ms (~2.1us/call) confirms jetting. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mirror /lib/lagoon's layout: maintain both runtimes' vendored jet files under
libmath/, in noun/jets/ form. The two math.c copies differ by exactly two lines
-- the two-arg u3r_mean form (brace-pair {axis,&p} on 64-bit vere-ml64 vs flat
varargs on 32-bit vere), because that macro's API diverged between the runtimes.
Everything else (15 algorithm cores, 12 single-arg wrappers, helpers) is
byte-identical: marshalling is chub-based and word-size-agnostic.
- libmath/vere/ noun/jets/{i/math.c,135/tree.c,q.h,w.h} -- 32-bit
- libmath/vere64/ noun/jets/{i/math.c,135/tree.c,q.h,w.h} -- 64-bit (+ test/)
Both built and verified bit-exact: full -test suite (math-exp/log/sqrt/ainv/
atan/tan/trig/derived) passes ok=%.y on a jetted 32-bit AND 64-bit fakeship,
plus the standalone harness's 234 single+two-arg vectors. Vendor 135 only (the
stock test ships' hoon-version; apply to 136/137 only if a target needs them).
Drop the now-redundant tree-registration.snippet.c (the full vendored tree.c
plus the rewritten README supersede it). README documents the 2-line divergence,
per-word-size apply steps, the door-anchor gotcha, -test verification, and the
SIGINT-corrupts-the-loom warning.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add all 15 @rs (single-precision) transcendental jets, single-precision twins of the @rd cores (same reductions/coeffs, SoftFloat f32, chub marshalling so they stay word-size-agnostic). Registered under non/math/rs in 135/tree.c, q.h/w.h decls, and ~/ hints on the rs door arms. 74 harness vectors bit-exact; full -test %/tests/lib passes ok=%.y on both the 32- and 64-bit jetted runtimes. Also fix a latent rounding-mode bug (affected @rd atan2/pow/pow-n from #63, and the new @rs atan2/pow/pow-n/tan): the math doors carry r=?(%n %u %d %z) whose bunt is %z, and the composite arms used bare door ops (mul:^rd, (div y x)) that silently bound that %z bunt instead of honoring r. The transcendental KERNELS correctly hardcode ~(mul ^rd %n); only the composite assembly was wrong. - Hoon: thread r into the door helper arms (sun/san/toi/drg/grd/add/sub/mul/ div/fma -> ~(op ^rd r)) for the rd and rs doors, so pow/atan2/tan/pow-n honor the door's rounding mode. Kernels keep their explicit %n. - Jets: a file-static _math_rnd, set from the door's r (gate axis 60, mapping 'n'/'u'/'d'/'z' -> SoftFloat near_even/max/min/minMag), brackets the bare ops in the composite cores; kernel calls run at near_even. - test-pow-3-2h's expected was baked from the old %z behavior (its pd door is %n); corrected to the near-even value (exact arithmetic: 2.5*log3 -> ...43ce -> exp -> ...5643). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add all 15 @rh jets. Every @rh arm is narrow-sh(rs_fn(widen-hs(x))): widen f16->f32 (exact = f16_to_f32), compute in the @rs cores, narrow f32->f16 (= f32_to_f16). No new algorithm cores -- the @rs cores are reused. 16-bit chub marshalling keeps them word-size-agnostic. Per the refinement, @rh now inherits the door's rounding mode r instead of pinning %n (consistent with @rd/@rs): - Hoon: the arms thread r into the @rs delegation (~(exp rs [r ...])), so the @rs composites honor r; and narrow-sh, formerly a hardcoded round-half-to-even, now does directed rounding per r (overflow -> inf/max-finite, underflow -> 0/min-subnormal, with an exact-zero guard). - Jets: the wrapper sets _math_rnd from the door's r (axis 60); the cores run the rs kernels at near-even and narrow via f32_to_f16 at r. A harness spike (rd_check.c emit_narrow) confirmed the hand-rolled narrow-sh is bit-exact to SoftFloat f32_to_f16 across all four rounding modes and the edge cases (subnormals, the e>=143 overflow, the 0x7e00 NaN) -- it caught exactly one bug (directed rounding of exact zero), now fixed. Registered rh under non/math in 135/tree.c, q.h/w.h decls, ~/ hints on the @rh door. Full -test %/tests/lib (incl math-rh) passes ok=%.y on both the 32- and 64-bit jetted runtimes; jets fire (us) and honor r. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Establish the @rq (quad, 128-bit) jet pipeline, proven bit-exact on exp: - Two-chub float128_t marshalling (read u3r_chub(0/1) into v[0..1]); stays word-size-agnostic, sidestepping the c3_w*[n=2|4] divergence of rq.c. - This SoftFloat build has only pointer-based f128M_*; thin by-value wrapper inlines (_rqm/_rqa/_rqs/_rqd/_rqq/_rqeq/...) keep the cores as readable as the @rd ones. - _rq_exp: Cody-Waite + degree-24 minimax (25 f128 coeffs, extracted from the Hoon programmatically), bias 16383. Bit-exact to (exp:rq:math ...) for 1/2/-1/0.1 (verified on-ship + harness emit exp-q). - Rounding dispatch: thread r into the @rq door helper arms (sun/san/toi/drg/ grd/add/sub/mul/div/fma -> ~(op ^rq r)) so the composite arms honor r, as in @rd/@rs. -test %/tests/lib still ok=%.y (no regression). Remaining: the other 14 @rq cores (log/trig/atan/ainv/sqt/cbt/derived) + the rq wrappers, registration, and ~/ hints -- mechanical, same pattern. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fix the @rq pow/pow-n/atan2 arms to use the bare door ops (mul/div/add/sub/toi/ san) instead of hardcoded ~(op ^rq %n), so they honor the door's r like the @rd/@rs composites do (tan already used a bare div). The transcendental kernels and log-2/log-10/lr keep their explicit %n, matching @rd/@rs. Verified: @rq div(1,3) gives ...5556 at %u vs ...5555 at %d/%n (honors r); full -test %/tests/lib still ok=%.y (the math-rq tests use %n doors, where bare ops == the old explicit %n, so no regression). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nd-nearest Explain why a correct/faithful transcendental fixes its internal arithmetic to round-nearest-even and takes no rounding-mode axis (the faithfulness bound is defined w.r.t. nearest; directed-rounding the true result is the Table-Maker's Dilemma), while the door's r governs only the composite arithmetic that assembles already-rounded kernel outputs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- @rq pow-n was missing the `?> &((gth n .0) (is-int n))` guard that @rd/@rs have, so e.g. pow-n(2,-2) returned garbage (8.0) via its @s counter loop. Give it the same guard + float-countdown structure as @rd/@rs; negatives/non-integers now crash loudly instead of returning nonsense. - @rh pow-n was delegating to @rs (widen->rs pow-n->narrow) -- a cross-door call. Make it native @rh repeated-multiply (it's exact integer multiplication, no polynomial, so no need for @rs). Threads the @rh door helpers for this. pow-n stays public (Saloon's %pow-n array op dispatches to pow-n:rX:math). Verified on-ship: pow-n(2,3)=8 (@rq and @rh), pow-n(2,-2) now rejects; -test ok=%.y. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Begin the @rh-native rewrite (no cross-door @rs calls). exp and log now compute natively in f16 with derived half-precision minimax (cheb_check.py retargeted to f16, mpmath-designed, exhaustively verified <=1 ULP): - exp: Cody-Waite + deg-4 minimax. LOG2E=0x3dc5 LN2HI=0x3980 LN2LO=0x1dc8, c0..c4=0x3c00 0x3c00 0x3800 0x3160 0x295c. Two-branch scale2 (overflow split k>=16, subnormal split k<-14; f16 can't use 2^24 like @rs -- uses 2^11/2^10), overflow k>=17, underflow k<=-25. - log: 2^e*m reduction + deg-1 atanh [0x3555,0x3266]. SQRT2=0x3da8, subnormal pre-mul 2^10 (not 2^24). Both explicit %n throughout (kernels take no rounding axis) -- which fixes a real bug the old delegating arms had: narrow-sh honored the door's r, so the default %z bunt leaked into exp/log (e.g. exp(1) gave 0x416f toward-zero instead of the correct nearest 0x4170). -test %/tests/lib/math-rh ok=%.y. (Native @rh jets + remaining 11 arms still to come; binary still has the old delegating jets, so jetted exp:rh/log:rh lag the Hoon until rebuilt.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Native f16 sin/cos via fdlibm ksin/kcos kernels (2 coeffs each: sc=[0xb155, 0x2044] cc=[0x2955,0x95b0]) + 3-part pi/2 reduction (INVPIO2=0x3918, P=0x3e00/ 0x2c80/0x0fed). All explicit %n. Replaces the @rs delegation. -test math-rh ok=%.y. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…terals Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Completes the native f16 @rh door -- no cross-door delegation remains (only widen-hs/narrow-sh conversions). tan is the sin/cos ratio; atan2/pow honor the door r via bare composite ops; cbt/log-2/log-10 reuse the native exp/log kernels; sqt is the stdlib f16 root; lr is the f16 log reduction. Updated test-tan-1 vector 0x3e3b->0x3e3a (native sin/cos ratio, 0.79 ULP, faithful). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The 15 _rh_* cores now compute entirely in half-precision (SoftFloat f16 ops), mirroring the native Hoon arms op-for-op -- f16 minimax coeffs, lower poly degrees (sin/cos/atan/ainv shorter, ainv no denominator, acos no tiny branch). Verified bit-exact to all 20 math-rh.hoon vectors (test/rh_check.c) and faithful (<=1.01 ULP) across all 64k finite f16 inputs for exp/log/atan/asin/acos/sqt; sin/cos faithful for small |x|, lossy for large |x| exactly as the Hoon reduction intends (test/rh_sweep.c). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Identical to vere64 except the 4 two-arg u3r_mean lines (flat varargs vs brace pairs), preserving the documented 32/64-bit invariant. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The native f16 kernels read the global softfloat_roundingMode (via f16_mul/add etc.), but the @rh wrappers only set _math_rnd -- so a kernel called after a %z door op ran under round-toward-zero, corrupting sin/cos (exp/atan survived by luck). Mirror the @rd/@rs wrappers: _rh_jet/_rh_jet2 and the 15 u3qi_rh_* softpaths now set softfloat_roundingMode = near_even (kernels) and _math_rnd = door r (composites). Verified on a fresh fakeship (clean jet dashboard): sin 0x3abb, cos 0x3853, exp 0x4170, tan 0x3e3a(%n)/0x3e39(%z), -test ok=%.y. Hardened rh_check.c to pre-dirty the global mode so it catches this class. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The full-Horner exp was ~1.10 ULP (not faithful) -- finely sampled vs MPFR it rounds the dominant ~1.0 result through the whole Horner chain. Replace with fdlibm's compensated form exp(r) = 1 - ((lo - r*c/(2-c)) - hi), c = r - t*P(t), keeping the leading 1+r out of the rounded sum. P is a deg-10 even minimax in t=r^2 (11 coeffs, fewer than the 25-term Taylor it replaces). Result: 0.87 ULP (faithful), validated against MPFR (tools/rq_check.c). cbt(-27) now lands on exactly -3 (was 1 ULP short); test vector updated. Derivation + the exact reduction constants live in tools/cheb_check.py exp-rq. All math-rq tests pass on a fresh fakeship. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fine-sampled audit completes the @rq kernel surface (rq_check.c covers exp/log/ sin/cos/sqrt vs MPFR; this covers atan/asin/acos via a 113-bit mpmath model, parsing the coeff lists straight out of math.hoon). Full @rq audit result -- every kernel faithful (<=1 ULP): exp 0.836 log 0.854 sin 0.752 cos 0.763 sqrt 0.500 atan 0.812 asin 0.975 acos 0.853 exp was the lone arm that needed fixing (the fdlibm reconstruction, prior commit); nothing else flagged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brings the @rq exp jet core in line with the new Hoon arm (fdlibm rational form, deg-10 even minimax P). Verified via tools harness: exp(1) = the correctly- rounded e, exp(2)=e^2, exp(0)=1.0. (First core of the @rq jet port; the remaining 13 + wrappers + registration follow, modeled on the vere32 @rd jet -- f128/2-chub is the structural twin of f64/2-word on a 32-bit runtime.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
log/lr/log-2/log-10, sin/cos/trig kernels, tan (=div sin/cos), atan/atan2, asin/acos/ainv, sqt/cbt, pow/pow-n -- native f128, mirroring the @rd cores with the f128 minimax coeffs read from the Hoon (no cross-door calls; composites call the internal _rq_* C functions directly). Coeff arrays generated straight from math.hoon to avoid transcription error. Verified bit-exact to the math-rq.hoon vectors via test/rq_cores.c (13/13): log/log2/sin/cos/atan/asin/acos/sqt/cbt/pow/tan all match; tan confirmed against the live Hoon under the %n door. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
_rq_in/_rq_out (2-chub f128 I/O), _rq_jet/_rq_jet2 (1- and 2-arg, set softfloat_roundingMode=near-even + _math_rnd from axis 60), and u3qi/u3wi for all 15 @rq fns. Models the @rh wrappers (kernels near-even, composites honor door r) -- carries the softfloat_roundingMode-not-_math_rnd fix from the start. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
15 harms + the _135_non__math_rq_d core + the rq entry in _135_non__math_d, mirroring @rh; q.h/w.h declare the 15 u3qi_rq_*/u3wi_rq_*. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Identical to vere64 except the 5 two-arg u3r_mean lines (flat varargs). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds the 16 ~/ hints for the @rq door (engine %rq + 15 arm hints), completing the hint set across all four math doors. Documents (vere64/README) that the math transcendental jets do NOT currently attach on-ship -- a structural issue, not kelvin. A lagoon control (mmul, the sibling userspace jet in the same `non` chapter) fires on the same hoon-version-136 ship; math does not. Cause: the `math` engine core makes the width doors grandchildren of the `non` chapter (chapter->engine->door->arm, 3-deep) vs the standard chapter->door->arm (lagoon's `la`, kernel two->by/two->in). The jet C code itself is correct (test/rq_cores.c harness 13/13); only on-ship attachment is blocked. Fix direction pending core-dev review. Co-Authored-By: Claude Opus 4.8 <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.
First slice of the transcendental jetting effort: wire the first jetted
math.hoonarm (@rd exp) and establish the structure + cross-repo mirror therest will follow.
The Hoon transcendentals themselves already merged; this PR adds only the
jet-anchoring structure and the vere-side mirror. (math.hoon's large diff
is almost entirely the
++ mathre-indent — review with whitespace hidden; thesubstantive change is ~18 lines.)
What changed
libmath/desk/lib/math.hoon— wrap the width doors in a%mathenginedoor under the shared
%nonchapter, mirroring/lib/lagoon's%non/%lagoonjet structure.=< mathkeeps the/+ math+rd:math/~(exp rd:math [%n rtol])API unchanged.~/hints on therddoor andexparm.
libmath/vere/(new) — hand-maintained mirror of the runtime jet code(
jets/i/math.c, thetree.cregistration snippet, README). The jets live inurbit/verepkg/noun; a matching PR there will follow.libmath/tools/rd_exp_check.c(new) — SoftFloat-f64 reference that provesthe jet is bit-exact to the Hoon (not merely faithful).
The gotcha (documented in the README)
A
~/-hinted engine core must be a door (^| =+ [rnd] ~/ %math |%), not abare
|%: a sample-less~/-core anchors its parent to the dashboard root,so
%mathand everything under it miss the hot dashboard — the core registersbut no C jet ever attaches. Found by tracing
_cj_hot_meanin the runtime(
math par=0 MISS→math par=non FOUNDonce it's a door).Verified
exp:rd:math .~1→0x4005.bf0a.8b14.576a(bit-exact), 34 µs jetted vs~970 µs interpreted; the rest of math.hoon (other fns/widths, the rounding-mode
door idiom) unchanged.
Follow-on
The remaining 14 fns × 4 widths follow this exact mold (one
u3wi_body + tree.centry + bit-exact harness each), plus the matching
urbit/vereruntime PR.🤖 Generated with Claude Code