Repository navigation
Refactor Remez exchange into structured Julia and reduce allocations - #667
thimotedupuch wants to merge 1 commit into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #667 +/- ##
==========================================
+ Coverage 97.98% 98.65% +0.66%
==========================================
Files 19 20 +1
Lines 3332 3335 +3
==========================================
+ Hits 3265 3290 +25
+ Misses 67 45 -22 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Hm, had always thought that chunk of code was a bit unsightly, but still, wary of changing it because I don't fully understand Remez, and it's pesky to verify the behaviour of the gotos are fully replicated when one changes the code. What does this do to code size (does LLVM IR look nicer? shorter?)? Are there any numerical gotchas? |
|
Thanks. I also see that it passes all platforms on the CI. I am not a compiler engineer myself and I don't know much about LLVM IR. So I asked the agent about it, that answered : "For a concrete 31-tap, two-band design on Julia 1.12.6, the legacy implementation compiles the whole algorithm into one very large method: about 6,456 lines / 451 kB of textual LLVM IR (8,388 lines / 292 kB of textual assembly). The refactor’s top-level algorithm method is about 208 lines / 15 kB of LLVM IR (270 lines / 7.6 kB assembly)." If I understand correctly, the new algorithm generates many small compiled helpers instead of a large one. (I don't know if it's trivial to get the sum of sizes of all helpers) I don't really have the technical knowledge to give you better information. |
|
Still, I think it is extremely non-obvious that this rewrite is equivalent to the previous, and I wouldn't like to silently corrupt downstream consumers. Tests are good but not enough, there could always be an edge case that your rewrite handles incorrectly that they simply don't hit. Could you show that the state machines are equivalent? |
|
Yes that is true. I don't see a trivial or non convoluted way to prove that the rewrite is precisely equivalent to the goto state machine. Do you know why julia added goto and label to the language, knowing this would result in very unreadable code ? I understand the importance of having correct algorithms for downstream users. You can do whatever you want with this PR. This can be a reference of what an implementation of the algorithm would look like without these macros. Thanks, have a nice day. |
|
If this PR was squashed from a series of PRs that gradually transformed the original code, one might be able to verify the final output by going through them.
sometimes you just need IDK, since you're using GPT6-Astra, you might as well pull the jackpot machine's lever and maybe it can generate two images of the old and new state machines (or CFGs à la Godbolt's); easier to see that way. |
Disclaimer : The following was written by AI agent (specifically GPT6-Astra)
I noticed a few months ago the legacy remez implementation and I thought a proper Julia rewrite would be interesting.
Thank you very much,
Thimoté D.
This draft proposes a structured Julia implementation of the Remez exchange step, with the aim of making the algorithm easier to follow while preserving both public
remezAPIs and improving runtime and allocations.The exchange search uses loops and small helpers in place of labels and jumps. It retains the original search order, endpoint margin, tie handling, and stopping rules, including the warning and returned approximation when
maxiteris reached. Grid construction fills its arrays directly, coefficient recovery reuses interpolation workspace, and the barycentric evaluator groups independent divisions while retaining accumulation order with fused operations. The existing attribution and license notice are retained; no package dependencies are added.Validation performed locally on Julia 1.12.7:
--check-bounds=yes: 12,079 passing assertions and 7 existingbrokentests, including 95 passing Remez assertions.7c798756cca39251da14bb5d38146feb2cdd1717. Coefficients match bit for bit in these tests, as do warning messages and exception types/messages.Across 18 benchmark cases covering both APIs, local measurements show approximately 9–31% less execution time and 24–27% fewer allocated bytes. These are measurements on one
znver3machine using Julia 1.12.7 and one Julia thread, not a claim about every platform. The scripts warm up both implementations and alternate their measurement order; compilation time and process resident memory are not measured. Commands, methodology, and the complete results are inbenchmark/README.md.I am opening this as a draft because Julia 1.10 and the other supported platforms still need validation. In particular, the fused operations deserve review across architectures. The exact comparisons above describe the tested environment and do not establish bitwise equivalence on all systems.