Skip to content

Coerce FNTYPE_SEED to UInt to unbreak 32-bit Julia precompile#895

Open
dpsanders wants to merge 1 commit into
JuliaSymbolics:masterfrom
dpsanders:fix-fntype-seed-32bit
Open

Coerce FNTYPE_SEED to UInt to unbreak 32-bit Julia precompile#895
dpsanders wants to merge 1 commit into
JuliaSymbolics:masterfrom
dpsanders:fix-fntype-seed-32bit

Conversation

@dpsanders
Copy link
Copy Markdown

@dpsanders dpsanders commented Apr 19, 2026

Summary

One-line fix for #894: FNTYPE_SEED (src/hashconsing.jl:310) was a bare UInt64 literal. Its only use site (hash(...)::UInt ⊻ FNTYPE_SEED at line 349) widens the XOR result to UInt64 on 32-bit Julia, which then fails to fit back into a ::UInt (= UInt32) hash field — so using SymbolicUtils errors out with InexactError: trunc(UInt32, 0x8b4142913acd1c23) during @compile_workload.

-const FNTYPE_SEED = 0x8b414291138f6c45
+const FNTYPE_SEED = 0x8b414291138f6c45 % UInt

Matches the style already used for SYM_SALT/DIV_SALT (lines 225-226). No-op on 64-bit, truncates the constant to UInt32 on 32-bit.

See #894 for the full diagnostic (XOR fingerprint, versions, downstream impact).

Closes #894.

CI note (not in this PR)

This slipped through because ci.yml runs only on ubuntu-latest × x64 (no arch key in the matrix). Adding arch: [x64, x86] (with a macOS-x86 exclude) would catch this class of 32-bit regressions. Not touching that here — happy to open a separate PR if the maintainers want it.

The bare `0x8b414291138f6c45` literal is a `UInt64`. Its only use
(`hash(...)::UInt ⊻ FNTYPE_SEED`, hashconsing.jl:349) widens the XOR
result to `UInt64` on 32-bit Julia, which then fails to fit back into a
`::UInt` (= `UInt32`) hash field — breaking `using SymbolicUtils` on
every 32-bit target.

Matches the style already used for `SYM_SALT`/`DIV_SALT` on lines
225-226. No-op on 64-bit, truncates to `UInt32` on 32-bit.

Fixes JuliaSymbolics#894.
@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Results (Julia vlts)

Time benchmarks
master 8dd99ed... master / 8dd99ed...
arithmetic/2-arg mul 12.8 ± 0.28 μs 13.1 ± 0.35 μs 0.974 ± 0.034
arithmetic/addition 0.0856 ± 0.0057 ms 0.0818 ± 0.0079 ms 1.05 ± 0.12
arithmetic/division 26.9 ± 0.65 μs 26.5 ± 0.62 μs 1.02 ± 0.034
arithmetic/multiplication 0.0625 ± 0.0046 ms 0.0624 ± 0.0051 ms 1 ± 0.11
irstructure/substitute/IRSubstituter 8.88 ± 0.43 ms 9.71 ± 0.88 ms 0.914 ± 0.093
irstructure/substitute/reference 9.88 ± 0.55 ms 10.6 ± 0.78 ms 0.928 ± 0.085
irstructure/substitute/sparse IRSubstituter 1.35 ± 0.053 ms 1.36 ± 0.058 ms 0.987 ± 0.058
irstructure/substitute/sparse reference 2.15 ± 0.1 ms 2.2 ± 0.11 ms 0.977 ± 0.069
overhead/acrule/a+2 2.33 ± 0.04 μs 2.38 ± 0.039 μs 0.975 ± 0.023
overhead/acrule/a+2+b 0.06 ± 0.001 μs 0.06 ± 0 μs 1 ± 0.017
overhead/acrule/a+b 4.09 ± 0.091 μs 4.22 ± 0.1 μs 0.969 ± 0.032
overhead/acrule/noop:Int 0.041 ± 0.01 μs 0.041 ± 0.01 μs 1 ± 0.34
overhead/acrule/noop:Sym 0.05 ± 0.001 μs 0.05 ± 0.01 μs 1 ± 0.2
overhead/get_degrees/large_poly 0.08 ± 0.009 μs 0.07 ± 0.001 μs 1.14 ± 0.13
overhead/rule/noop:Int 0.06 ± 0 μs 0.06 ± 0 μs 1 ± 0
overhead/rule/noop:Sym 0.06 ± 0 μs 0.06 ± 0 μs 1 ± 0
overhead/rule/noop:Term 0.06 ± 0 μs 0.06 ± 0 μs 1 ± 0
overhead/ruleset/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/ruleset/noop:Sym 0.26 ± 0.001 μs 0.27 ± 0.01 μs 0.963 ± 0.036
overhead/ruleset/noop:Term 1.14 ± 0.011 μs 1.13 ± 0.02 μs 1.01 ± 0.02
overhead/simplify/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/simplify/noop:Sym 30 ± 10 ns 30 ± 10 ns 1 ± 0.47
overhead/simplify/noop:Term 27.5 ± 0.62 μs 28.7 ± 0.69 μs 0.96 ± 0.032
overhead/simplify/randterm (+, *):serial 0.264 ± 0.021 s 0.264 ± 0.02 s 1 ± 0.11
overhead/simplify/randterm (+, *):thread 0.278 ± 0.017 s 0.275 ± 0.026 s 1.01 ± 0.11
overhead/simplify/randterm (/, *):serial 0.164 ± 0.016 ms 0.165 ± 0.016 ms 0.992 ± 0.13
overhead/simplify/randterm (/, *):thread 0.168 ± 0.02 ms 0.171 ± 0.018 ms 0.985 ± 0.16
overhead/substitute/a 0.0409 ± 0.0011 ms 0.0428 ± 0.0011 ms 0.956 ± 0.035
overhead/substitute/a,b 0.0492 ± 0.0012 ms 0.0522 ± 0.0012 ms 0.943 ± 0.031
overhead/substitute/a,b,c 0.0444 ± 0.001 ms 0.0467 ± 0.0012 ms 0.951 ± 0.032
polyform/easy_iszero 23 ± 0.76 μs 23.4 ± 0.8 μs 0.982 ± 0.047
polyform/isone 1.12 ± 0.089 ms 1.09 ± 0.023 ms 1.03 ± 0.084
polyform/isone:noop 0.08 ± 0.01 μs 0.08 ± 0.01 μs 1 ± 0.18
polyform/iszero 0.947 ± 0.071 ms 0.926 ± 0.02 ms 1.02 ± 0.08
polyform/iszero:noop 0.08 ± 0.009 μs 0.08 ± 0.01 μs 1 ± 0.17
polyform/simplify_fractions 1.24 ± 0.091 ms 1.2 ± 0.08 ms 1.03 ± 0.1
printing/large_poly 0.212 ± 0.0017 s 0.212 ± 0.0011 s 1 ± 0.0097
time_to_load 1.58 ± 0.013 s 1.6 ± 0.0033 s 0.987 ± 0.0086
Memory benchmarks
master 8dd99ed... master / 8dd99ed...
arithmetic/2-arg mul 0.077 k allocs: 2.69 kB 0.078 k allocs: 2.72 kB 0.989
arithmetic/addition 0.468 k allocs: 16.9 kB 0.468 k allocs: 16.9 kB 1
arithmetic/division 0.141 k allocs: 5.44 kB 0.142 k allocs: 5.47 kB 0.994
arithmetic/multiplication 0.356 k allocs: 11.7 kB 0.356 k allocs: 11.7 kB 1
irstructure/substitute/IRSubstituter 0.0438 M allocs: 1.61 MB 0.0438 M allocs: 1.61 MB 1
irstructure/substitute/reference 0.0425 M allocs: 1.62 MB 0.0452 M allocs: 1.66 MB 0.976
irstructure/substitute/sparse IRSubstituter 5.17 k allocs: 0.192 MB 5.17 k allocs: 0.192 MB 1
irstructure/substitute/sparse reference 7.37 k allocs: 0.341 MB 10 k allocs: 0.381 MB 0.894
overhead/acrule/a+2 0.033 k allocs: 1.23 kB 0.034 k allocs: 1.25 kB 0.988
overhead/acrule/a+2+b 0 allocs: 0 B 0 allocs: 0 B
overhead/acrule/a+b 0.045 k allocs: 1.77 kB 0.047 k allocs: 1.8 kB 0.983
overhead/acrule/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/acrule/noop:Sym 0 allocs: 0 B 0 allocs: 0 B
overhead/get_degrees/large_poly 2 allocs: 32 B 2 allocs: 32 B 1
overhead/rule/noop:Int 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/rule/noop:Sym 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/rule/noop:Term 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/ruleset/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/ruleset/noop:Sym 3 allocs: 0.109 kB 3 allocs: 0.109 kB 1
overhead/ruleset/noop:Term 12 allocs: 0.391 kB 12 allocs: 0.391 kB 1
overhead/simplify/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/simplify/noop:Sym 0 allocs: 0 B 0 allocs: 0 B
overhead/simplify/noop:Term 0.282 k allocs: 11.3 kB 0.298 k allocs: 11.5 kB 0.978
overhead/simplify/randterm (+, *):serial 2.43 M allocs: 0.0957 GB 2.53 M allocs: 0.0972 GB 0.984
overhead/simplify/randterm (+, *):thread 2.48 M allocs: 0.253 GB 2.59 M allocs: 0.255 GB 0.994
overhead/simplify/randterm (/, *):serial 1.91 k allocs: 0.0713 MB 2.04 k allocs: 0.0733 MB 0.974
overhead/simplify/randterm (/, *):thread 1.95 k allocs: 0.0724 MB 2.07 k allocs: 0.0743 MB 0.974
overhead/substitute/a 0.22 k allocs: 8.42 kB 0.22 k allocs: 8.42 kB 1
overhead/substitute/a,b 0.267 k allocs: 10.1 kB 0.267 k allocs: 10.1 kB 1
overhead/substitute/a,b,c 0.238 k allocs: 8.62 kB 0.238 k allocs: 8.62 kB 1
polyform/easy_iszero 0.127 k allocs: 4.48 kB 0.133 k allocs: 4.58 kB 0.98
polyform/isone 7.99 k allocs: 0.568 MB 8.33 k allocs: 0.573 MB 0.99
polyform/isone:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/iszero 6.7 k allocs: 0.471 MB 6.86 k allocs: 0.474 MB 0.994
polyform/iszero:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/simplify_fractions 8.64 k allocs: 0.593 MB 8.81 k allocs: 0.596 MB 0.995
printing/large_poly 1.86 M allocs: 0.082 GB 1.86 M allocs: 0.082 GB 1
time_to_load 0.153 k allocs: 14.5 kB 0.153 k allocs: 14.5 kB 1

@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Results (Julia v1)

Time benchmarks
master 8dd99ed... master / 8dd99ed...
arithmetic/2-arg mul 9.9 ± 0.25 μs 9.86 ± 0.29 μs 1.01 ± 0.039
arithmetic/addition 0.0673 ± 0.001 ms 0.0689 ± 0.00091 ms 0.976 ± 0.02
arithmetic/division 21.8 ± 0.46 μs 21.9 ± 0.45 μs 0.996 ± 0.029
arithmetic/multiplication 0.0503 ± 0.0016 ms 0.0511 ± 0.0021 ms 0.983 ± 0.052
irstructure/substitute/IRSubstituter 7.25 ± 0.15 ms 7.33 ± 0.27 ms 0.988 ± 0.042
irstructure/substitute/reference 7.68 ± 0.42 ms 8.12 ± 0.59 ms 0.945 ± 0.086
irstructure/substitute/sparse IRSubstituter 1.09 ± 0.027 ms 1.12 ± 0.04 ms 0.975 ± 0.042
irstructure/substitute/sparse reference 1.66 ± 0.12 ms 1.68 ± 0.1 ms 0.989 ± 0.092
overhead/acrule/a+2 2.18 ± 0.1 μs 2.18 ± 0.1 μs 1 ± 0.065
overhead/acrule/a+2+b 0.09 ± 0 μs 0.08 ± 0 μs 1.12 ± 0
overhead/acrule/a+b 3.7 ± 0.17 μs 3.81 ± 0.15 μs 0.971 ± 0.059
overhead/acrule/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/acrule/noop:Sym 0.07 ± 0 μs 0.06 ± 0.001 μs 1.17 ± 0.019
overhead/get_degrees/large_poly 0.08 ± 0.01 μs 0.08 ± 0.01 μs 1 ± 0.18
overhead/rule/noop:Int 0.07 ± 0 μs 0.07 ± 0.01 μs 1 ± 0.14
overhead/rule/noop:Sym 0.07 ± 0.01 μs 0.07 ± 0.01 μs 1 ± 0.2
overhead/rule/noop:Term 0.07 ± 0.01 μs 0.07 ± 0.01 μs 1 ± 0.2
overhead/ruleset/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/ruleset/noop:Sym 0.271 ± 0.01 μs 0.261 ± 0.01 μs 1.04 ± 0.055
overhead/ruleset/noop:Term 1.03 ± 0.04 μs 1.06 ± 0.04 μs 0.971 ± 0.052
overhead/simplify/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/simplify/noop:Sym 0.04 ± 0.01 μs 0.04 ± 0.01 μs 1 ± 0.35
overhead/simplify/noop:Term 25 ± 0.52 μs 24.9 ± 0.57 μs 1.01 ± 0.031
overhead/simplify/randterm (+, *):serial 0.236 ± 0.032 s 0.234 ± 0.032 s 1.01 ± 0.2
overhead/simplify/randterm (+, *):thread 0.265 ± 0.075 s 0.272 ± 0.063 s 0.976 ± 0.36
overhead/simplify/randterm (/, *):serial 0.158 ± 0.024 ms 0.158 ± 0.024 ms 0.999 ± 0.22
overhead/simplify/randterm (/, *):thread 0.177 ± 0.038 ms 0.176 ± 0.039 ms 1 ± 0.31
overhead/substitute/a 30.9 ± 0.58 μs 30.8 ± 0.55 μs 1 ± 0.026
overhead/substitute/a,b 0.038 ± 0.00065 ms 0.0379 ± 0.00064 ms 1 ± 0.024
overhead/substitute/a,b,c 0.0369 ± 0.00073 ms 0.037 ± 0.0007 ms 0.996 ± 0.027
polyform/easy_iszero 17.7 ± 0.38 μs 17.9 ± 0.38 μs 0.987 ± 0.03
polyform/isone 0.866 ± 0.025 ms 0.891 ± 0.033 ms 0.972 ± 0.045
polyform/isone:noop 0.08 ± 0.01 μs 0.08 ± 0 μs 1 ± 0.12
polyform/iszero 0.738 ± 0.02 ms 0.758 ± 0.022 ms 0.973 ± 0.039
polyform/iszero:noop 0.08 ± 0.001 μs 0.08 ± 0 μs 1 ± 0.013
polyform/simplify_fractions 0.935 ± 0.029 ms 0.958 ± 0.033 ms 0.976 ± 0.046
printing/large_poly 0.205 ± 0.022 s 0.209 ± 0.021 s 0.98 ± 0.14
time_to_load 1.63 ± 0.021 s 1.65 ± 0.012 s 0.992 ± 0.014
Memory benchmarks
master 8dd99ed... master / 8dd99ed...
arithmetic/2-arg mul 0.056 k allocs: 1.78 kB 0.056 k allocs: 1.78 kB 1
arithmetic/addition 0.33 k allocs: 11.3 kB 0.33 k allocs: 11.3 kB 1
arithmetic/division 0.132 k allocs: 4.77 kB 0.132 k allocs: 4.77 kB 1
arithmetic/multiplication 0.252 k allocs: 6.5 kB 0.252 k allocs: 6.5 kB 1
irstructure/substitute/IRSubstituter 0.0326 M allocs: 1.06 MB 0.0326 M allocs: 1.06 MB 1
irstructure/substitute/reference 0.0353 M allocs: 1.23 MB 0.0353 M allocs: 1.23 MB 1
irstructure/substitute/sparse IRSubstituter 3.81 k allocs: 0.125 MB 3.81 k allocs: 0.125 MB 1
irstructure/substitute/sparse reference 6.49 k allocs: 0.293 MB 6.49 k allocs: 0.293 MB 1
overhead/acrule/a+2 0.034 k allocs: 1.12 kB 0.034 k allocs: 1.12 kB 1
overhead/acrule/a+2+b 0 allocs: 0 B 0 allocs: 0 B
overhead/acrule/a+b 0.046 k allocs: 1.55 kB 0.046 k allocs: 1.55 kB 1
overhead/acrule/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/acrule/noop:Sym 0 allocs: 0 B 0 allocs: 0 B
overhead/get_degrees/large_poly 2 allocs: 32 B 2 allocs: 32 B 1
overhead/rule/noop:Int 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/rule/noop:Sym 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/rule/noop:Term 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/ruleset/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/ruleset/noop:Sym 3 allocs: 0.109 kB 3 allocs: 0.109 kB 1
overhead/ruleset/noop:Term 12 allocs: 0.391 kB 12 allocs: 0.391 kB 1
overhead/simplify/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/simplify/noop:Sym 0 allocs: 0 B 0 allocs: 0 B
overhead/simplify/noop:Term 0.284 k allocs: 9.91 kB 0.284 k allocs: 9.91 kB 1
overhead/simplify/randterm (+, *):serial 2.39 M allocs: 0.0829 GB 2.39 M allocs: 0.0829 GB 1
overhead/simplify/randterm (+, *):thread 2.55 M allocs: 0.245 GB 2.55 M allocs: 0.245 GB 1
overhead/simplify/randterm (/, *):serial 1.91 k allocs: 0.0655 MB 1.91 k allocs: 0.0655 MB 1
overhead/simplify/randterm (/, *):thread 2.05 k allocs: 0.0704 MB 2.05 k allocs: 0.0704 MB 1
overhead/substitute/a 0.172 k allocs: 6.05 kB 0.172 k allocs: 6.05 kB 1
overhead/substitute/a,b 0.223 k allocs: 7.69 kB 0.223 k allocs: 7.69 kB 1
overhead/substitute/a,b,c 0.229 k allocs: 7.81 kB 0.229 k allocs: 7.81 kB 1
polyform/easy_iszero 0.092 k allocs: 2.94 kB 0.092 k allocs: 2.94 kB 1
polyform/isone 10.9 k allocs: 0.578 MB 10.9 k allocs: 0.57 MB 1.01
polyform/isone:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/iszero 8.96 k allocs: 0.48 MB 8.95 k allocs: 0.472 MB 1.02
polyform/iszero:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/simplify_fractions 11.4 k allocs: 0.595 MB 11.4 k allocs: 0.588 MB 1.01
printing/large_poly 2.15 M allocs: 0.079 GB 2.15 M allocs: 0.079 GB 1
time_to_load 0.145 k allocs: 11 kB 0.145 k allocs: 11 kB 1

@ChrisRackauckas
Copy link
Copy Markdown
Member

open a PR to add 32-bit as well, that would be helpful, or just add here

@dpsanders
Copy link
Copy Markdown
Author

You mean to add it to CI?

@ChrisRackauckas
Copy link
Copy Markdown
Member

yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Precompile fails on 32-bit Julia: FNTYPE_SEED is a raw UInt64 literal, truncates to UInt when stored in hash::UInt

2 participants