Skip to content

Bind ifelse_branching to a CSE temporary while keeping branches lazy#966

Draft
ChrisRackauckas-Claude wants to merge 2 commits into
JuliaSymbolics:masterfrom
ChrisRackauckas-Claude:feat/cse-bind-expr
Draft

Bind ifelse_branching to a CSE temporary while keeping branches lazy#966
ChrisRackauckas-Claude wants to merge 2 commits into
JuliaSymbolics:masterfrom
ChrisRackauckas-Claude:feat/cse-bind-expr

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor

Please ignore until reviewed by @ChrisRackauckas. Opened as a draft.

Summary

Follow-up to #965 (this was developed on that PR's branch but GitHub dropped the push's synchronize event, so it never attached before the merge — re-landed here on current master).

Multiply-referenced ifelse_branching now shares a single if/else instead of re-emitting it per use site. Previously, cse_inside_expr = false conflated "do not descend into the arguments" with "do not bind this node": keeping the branches lazy also un-bound the conditional, so e.g. sin(z) + cos(z) with z = ifelse_branching(...) evaluated the taken branch twice.

Implementation

A second hook, Code.cse_bind_expr(sym, f) (default false), consulted only when cse_inside_expr is false. When true, _cse_compute binds the node as-is — arguments un-CSEd — to a CSE temporary; cse!'s id-cache makes every reference in the scope resolve to that one temporary. ifelse_branching opts in. Operator, getindex and any other opt-outs keep their exact prior fully-inline behaviour (their cse(ex) == ex identity tests are untouched and pass).

Generated code for the repro is now:

var"##cse#1" = if 0 < x
        f(x) ^ 2     # taken branch: runs once
    else
        g(x)         # untaken: never runs
    end
var"##cse#2" = sin(var"##cse#1")
var"##cse#3" = cos(var"##cse#1")

One semantic boundary (asserted with a comment in the tests): a conditional referenced inside both branches of an enclosing ifelse_branching is still emitted per branch — hoisting it above the conditional would evaluate it eagerly, which the laziness contract forbids. One-sided nesting is linear, matching ifelse (previously exponential in depth).

Verification

  • New testsets in test/conditionals.jl: side-effect counting shows the taken branch fires once (was twice) and the untaken branch never; the CSE structure contains exactly one bound ifelse_branching; one-sided nesting emits the same number of ifs as ifelse; values match ifelse throughout.
  • Full local Pkg.test() on this branch (on top of the add some more specialized hashing functions #963 hashing changes): 17771 pass, 3 broken (pre-existing), 0 fail.
  • cse_bind_expr documented and added to the codegen manual alongside cse_inside_expr, plus docs entries for the two operators.

Version bumped to 4.36.0. Companion test on the Symbolics side: JuliaSymbolics/Symbolics.jl#1892 (blocked on this releasing).

🤖 Generated with Claude Code

`cse_inside_expr = false` previously conflated "do not descend into the
arguments" with "do not bind this node", so an `ifelse_branching` referenced at
multiple sites re-emitted its entire `if`/`else` per use. Add a second hook,
`cse_bind_expr`, consulted only when `cse_inside_expr` is `false`: when it
returns `true`, CSE binds the node as-is (arguments un-CSEd) to a temporary, so
all references share one computation. `ifelse_branching` opts in; the default
`false` preserves the existing fully-inline behaviour for `Operator`, `getindex`
and any other opt-outs.

The branches remain lazy (a conditional inside a branch is still emitted within
that branch), and one-sided nesting now stays linear, matching `ifelse`.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@github-actions

Copy link
Copy Markdown
Contributor

Benchmark Results (Julia vlts)

Time benchmarks
master 22d0a15... master / 22d0a15...
arithmetic/2-arg mul 11.2 ± 0.56 μs 11.2 ± 0.88 μs 0.998 ± 0.093
arithmetic/addition 0.0669 ± 0.0042 ms 0.0676 ± 0.004 ms 0.99 ± 0.084
arithmetic/division 22.8 ± 0.61 μs 22.8 ± 0.64 μs 1 ± 0.039
arithmetic/multiplication 0.0334 ± 0.0024 ms 0.0341 ± 0.0011 ms 0.981 ± 0.075
codegen/arrayop_nested/fast_toexpr 10.5 ± 1.5 μs 11.4 ± 1.6 μs 0.918 ± 0.18
codegen/arrayop_nested/toexpr 0.0535 ± 0.0028 ms 0.0545 ± 0.003 ms 0.982 ± 0.075
codegen/deep_poly/deg=10:fast_toexpr 0.0744 ± 0.0069 ms 0.0743 ± 0.0069 ms 1 ± 0.13
codegen/deep_poly/deg=10:toexpr 0.074 ± 0.0037 ms 0.0759 ± 0.005 ms 0.974 ± 0.081
codegen/deep_poly/deg=14:fast_toexpr 0.137 ± 0.014 ms 0.136 ± 0.012 ms 1 ± 0.14
codegen/deep_poly/deg=14:toexpr 0.136 ± 0.011 ms 0.137 ± 0.012 ms 0.996 ± 0.12
codegen/deep_poly/deg=6:fast_toexpr 0.0342 ± 0.0028 ms 0.0342 ± 0.0029 ms 1 ± 0.12
codegen/deep_poly/deg=6:toexpr 0.0322 ± 0.0024 ms 0.0332 ± 0.0026 ms 0.972 ± 0.11
codegen/makearray/n=100:fast_toexpr 0.0815 ± 0.01 ms 0.0809 ± 0.0077 ms 1.01 ± 0.16
codegen/makearray/n=100:toexpr 0.556 ± 0.023 ms 0.547 ± 0.019 ms 1.02 ± 0.055
codegen/makearray/n=200:fast_toexpr 0.15 ± 0.015 ms 0.149 ± 0.014 ms 1.01 ± 0.14
codegen/makearray/n=200:toexpr 0.797 ± 0.03 ms 0.787 ± 0.025 ms 1.01 ± 0.049
codegen/makearray/n=400:fast_toexpr 0.305 ± 0.026 ms 0.301 ± 0.024 ms 1.01 ± 0.12
codegen/makearray/n=400:toexpr 1.29 ± 0.05 ms 1.27 ± 0.039 ms 1.01 ± 0.05
codegen/wide_deep_poly/fast_toexpr 0.548 ± 0.037 ms 0.544 ± 0.029 ms 1.01 ± 0.087
codegen/wide_deep_poly/toexpr 0.488 ± 0.016 ms 0.494 ± 0.024 ms 0.989 ± 0.057
codegen/wide_poly/n=100:fast_toexpr 0.239 ± 0.024 ms 0.236 ± 0.021 ms 1.01 ± 0.14
codegen/wide_poly/n=100:toexpr 0.278 ± 0.02 ms 0.285 ± 0.018 ms 0.975 ± 0.093
codegen/wide_poly/n=25:fast_toexpr 0.0525 ± 0.0049 ms 0.0524 ± 0.0046 ms 1 ± 0.13
codegen/wide_poly/n=25:toexpr 0.0683 ± 0.0056 ms 0.0703 ± 0.0049 ms 0.972 ± 0.11
codegen/wide_poly/n=50:fast_toexpr 0.109 ± 0.012 ms 0.109 ± 0.011 ms 1.01 ± 0.15
codegen/wide_poly/n=50:toexpr 0.137 ± 0.012 ms 0.142 ± 0.011 ms 0.967 ± 0.11
irstructure/search_variables/common:IRStructure 0.243 ± 0.007 ms 0.247 ± 0.0068 ms 0.983 ± 0.039
irstructure/search_variables/common:reference 0.434 ± 0.12 ms 0.513 ± 0.013 ms 0.845 ± 0.23
irstructure/search_variables/dissimilar:IRStructure 0.0604 ± 0.0025 ms 0.0607 ± 0.0026 ms 0.995 ± 0.059
irstructure/search_variables/dissimilar:reference 0.135 ± 0.0049 ms 0.141 ± 0.069 ms 0.955 ± 0.47
irstructure/subset_ir/large 3.02 ± 0.056 ms 3.04 ± 0.053 ms 0.993 ± 0.025
irstructure/subset_ir/small 0.207 ± 0.0096 ms 0.211 ± 0.0095 ms 0.978 ± 0.063
irstructure/substitute/IRSubstituter 7.94 ± 0.12 ms 7.84 ± 0.098 ms 1.01 ± 0.02
irstructure/substitute/reference 8.53 ± 0.1 ms 8.41 ± 0.1 ms 1.01 ± 0.017
irstructure/substitute/sparse IRSubstituter 1.37 ± 0.028 ms 1.35 ± 0.03 ms 1.01 ± 0.03
irstructure/substitute/sparse reference 1.99 ± 0.022 ms 1.95 ± 0.026 ms 1.02 ± 0.018
overhead/acrule/a+2 2.24 ± 0.13 μs 2.15 ± 0.11 μs 1.04 ± 0.081
overhead/acrule/a+2+b 0.06 ± 0.01 μs 0.06 ± 0.01 μs 1 ± 0.24
overhead/acrule/a+b 4 ± 0.25 μs 3.79 ± 0.26 μs 1.06 ± 0.098
overhead/acrule/noop:Int 0.05 ± 0.009 μs 0.05 ± 0.01 μs 1 ± 0.27
overhead/acrule/noop:Sym 0.05 ± 0.01 μs 0.051 ± 0.01 μs 0.98 ± 0.27
overhead/get_degrees/large_poly 0.09 ± 0 μs 0.08 ± 0 μs 1.12 ± 0
overhead/rule/noop:Int 0.06 ± 0.01 μs 0.061 ± 0.01 μs 0.984 ± 0.23
overhead/rule/noop:Sym 0.06 ± 0.01 μs 0.06 ± 0.01 μs 1 ± 0.24
overhead/rule/noop:Term 0.06 ± 0.001 μs 0.06 ± 0.01 μs 1 ± 0.17
overhead/ruleset/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/ruleset/noop:Sym 0.26 ± 0.011 μs 0.251 ± 0.01 μs 1.04 ± 0.06
overhead/ruleset/noop:Term 1.1 ± 0.031 μs 1.1 ± 0.03 μs 1 ± 0.039
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 29.7 ± 2.6 μs 28.5 ± 1.5 μs 1.04 ± 0.1
overhead/simplify/randterm (+, *):serial 0.234 ± 0.0098 s 0.234 ± 0.012 s 1 ± 0.066
overhead/simplify/randterm (+, *):thread 0.272 ± 0.0095 s 0.263 ± 0.015 s 1.03 ± 0.068
overhead/simplify/randterm (/, *):serial 0.181 ± 0.011 ms 0.181 ± 0.011 ms 0.998 ± 0.088
overhead/simplify/randterm (/, *):thread 0.183 ± 0.012 ms 0.184 ± 0.011 ms 0.995 ± 0.086
overhead/substitute/a 0.0337 ± 0.0008 ms 0.0329 ± 0.00095 ms 1.03 ± 0.038
overhead/substitute/a,b 0.0417 ± 0.00095 ms 0.0407 ± 0.00088 ms 1.02 ± 0.032
overhead/substitute/a,b,c 0.0395 ± 0.00086 ms 0.039 ± 0.00083 ms 1.01 ± 0.031
polyform/easy_iszero 18.1 ± 0.53 μs 18.2 ± 0.53 μs 0.995 ± 0.041
polyform/isone 0.947 ± 0.034 ms 0.938 ± 0.027 ms 1.01 ± 0.047
polyform/isone:noop 0.08 ± 0 μs 0.08 ± 0.01 μs 1 ± 0.12
polyform/iszero 0.799 ± 0.029 ms 0.778 ± 0.022 ms 1.03 ± 0.048
polyform/iszero:noop 0.08 ± 0.01 μs 0.081 ± 0.011 μs 0.988 ± 0.18
polyform/simplify_fractions 1.02 ± 0.037 ms 1.01 ± 0.031 ms 1.01 ± 0.047
printing/large_poly 0.233 ± 0.0045 s 0.23 ± 0.0047 s 1.01 ± 0.028
time_to_load 1.36 ± 0.0053 s 1.36 ± 0.017 s 1 ± 0.013
Memory benchmarks
master 22d0a15... master / 22d0a15...
arithmetic/2-arg mul 0.086 k allocs: 3.39 kB 0.084 k allocs: 3.33 kB 1.02
arithmetic/addition 0.267 k allocs: 9 kB 0.267 k allocs: 9 kB 1
arithmetic/division 0.144 k allocs: 5.56 kB 0.141 k allocs: 5.47 kB 1.02
arithmetic/multiplication 0.287 k allocs: 8.23 kB 0.287 k allocs: 8.23 kB 1
codegen/arrayop_nested/fast_toexpr 0.189 k allocs: 11 kB 0.183 k allocs: 10.9 kB 1.01
codegen/arrayop_nested/toexpr 0.474 k allocs: 20.3 kB 0.468 k allocs: 20.2 kB 1
codegen/deep_poly/deg=10:fast_toexpr 0.973 k allocs: 0.0539 MB 0.973 k allocs: 0.0539 MB 1
codegen/deep_poly/deg=10:toexpr 1.05 k allocs: 0.0497 MB 1.05 k allocs: 0.0497 MB 1
codegen/deep_poly/deg=14:fast_toexpr 1.71 k allocs: 0.109 MB 1.71 k allocs: 0.109 MB 1
codegen/deep_poly/deg=14:toexpr 1.89 k allocs: 0.093 MB 1.89 k allocs: 0.093 MB 1
codegen/deep_poly/deg=6:fast_toexpr 0.445 k allocs: 28.9 kB 0.445 k allocs: 28.9 kB 1
codegen/deep_poly/deg=6:toexpr 0.449 k allocs: 22.9 kB 0.449 k allocs: 22.9 kB 1
codegen/makearray/n=100:fast_toexpr 1.35 k allocs: 0.066 MB 1.34 k allocs: 0.0658 MB 1
codegen/makearray/n=100:toexpr 4.44 k allocs: 0.171 MB 4.42 k allocs: 0.171 MB 1
codegen/makearray/n=200:fast_toexpr 2.52 k allocs: 0.116 MB 2.5 k allocs: 0.116 MB 1
codegen/makearray/n=200:toexpr 6.37 k allocs: 0.243 MB 6.35 k allocs: 0.243 MB 1
codegen/makearray/n=400:fast_toexpr 4.71 k allocs: 0.227 MB 4.67 k allocs: 0.227 MB 1
codegen/makearray/n=400:toexpr 10.2 k allocs: 0.388 MB 10.1 k allocs: 0.388 MB 1
codegen/wide_deep_poly/fast_toexpr 5.56 k allocs: 0.292 MB 5.56 k allocs: 0.292 MB 1
codegen/wide_deep_poly/toexpr 6.88 k allocs: 0.319 MB 6.88 k allocs: 0.319 MB 1
codegen/wide_poly/n=100:fast_toexpr 2.98 k allocs: 0.17 MB 2.98 k allocs: 0.17 MB 1
codegen/wide_poly/n=100:toexpr 3.92 k allocs: 0.168 MB 3.92 k allocs: 0.168 MB 1
codegen/wide_poly/n=25:fast_toexpr 0.777 k allocs: 0.0439 MB 0.777 k allocs: 0.0439 MB 1
codegen/wide_poly/n=25:toexpr 0.993 k allocs: 0.0428 MB 0.993 k allocs: 0.0428 MB 1
codegen/wide_poly/n=50:fast_toexpr 1.52 k allocs: 0.101 MB 1.52 k allocs: 0.101 MB 1
codegen/wide_poly/n=50:toexpr 1.97 k allocs: 0.0883 MB 1.97 k allocs: 0.0883 MB 1
irstructure/search_variables/common:IRStructure 0.04 k allocs: 5.31 kB 0.04 k allocs: 5.31 kB 1
irstructure/search_variables/common:reference 0.08 k allocs: 0.238 MB 0.1 k allocs: 0.863 MB 0.275
irstructure/search_variables/dissimilar:IRStructure 29 allocs: 3.22 kB 29 allocs: 3.22 kB 1
irstructure/search_variables/dissimilar:reference 0.07 k allocs: 0.115 MB 0.073 k allocs: 0.139 MB 0.829
irstructure/subset_ir/large 0.0425 M allocs: 1.95 MB 0.0425 M allocs: 1.95 MB 1
irstructure/subset_ir/small 2.65 k allocs: 0.175 MB 2.65 k allocs: 0.175 MB 1
irstructure/substitute/IRSubstituter 0.0317 M allocs: 1.13 MB 0.0317 M allocs: 1.13 MB 1
irstructure/substitute/reference 0.0371 M allocs: 1.33 MB 0.0344 M allocs: 1.29 MB 1.03
irstructure/substitute/sparse IRSubstituter 3.68 k allocs: 0.132 MB 3.68 k allocs: 0.132 MB 1
irstructure/substitute/sparse reference 9.01 k allocs: 0.34 MB 6.35 k allocs: 0.3 MB 1.14
overhead/acrule/a+2 0.033 k allocs: 1.2 kB 0.032 k allocs: 1.19 kB 1.01
overhead/acrule/a+2+b 0 allocs: 0 B 0 allocs: 0 B
overhead/acrule/a+b 0.045 k allocs: 1.7 kB 0.043 k allocs: 1.67 kB 1.02
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.304 k allocs: 11.7 kB 0.288 k allocs: 11.5 kB 1.02
overhead/simplify/randterm (+, *):serial 2.42 M allocs: 0.0915 GB 2.32 M allocs: 0.09 GB 1.02
overhead/simplify/randterm (+, *):thread 2.48 M allocs: 0.249 GB 2.37 M allocs: 0.248 GB 1.01
overhead/simplify/randterm (/, *):serial 2.11 k allocs: 0.0759 MB 1.99 k allocs: 0.074 MB 1.03
overhead/simplify/randterm (/, *):thread 2.15 k allocs: 0.0769 MB 2.02 k allocs: 0.075 MB 1.03
overhead/substitute/a 0.171 k allocs: 6.39 kB 0.171 k allocs: 6.39 kB 1
overhead/substitute/a,b 0.215 k allocs: 7.91 kB 0.215 k allocs: 7.91 kB 1
overhead/substitute/a,b,c 0.218 k allocs: 7.88 kB 0.218 k allocs: 7.88 kB 1
polyform/easy_iszero 0.117 k allocs: 4 kB 0.111 k allocs: 3.91 kB 1.02
polyform/isone 7.94 k allocs: 0.56 MB 7.57 k allocs: 0.554 MB 1.01
polyform/isone:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/iszero 6.52 k allocs: 0.464 MB 6.34 k allocs: 0.461 MB 1.01
polyform/iszero:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/simplify_fractions 8.38 k allocs: 0.582 MB 8.19 k allocs: 0.578 MB 1.01
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 22d0a15... master / 22d0a15...
arithmetic/2-arg mul 9.09 ± 0.17 μs 9.41 ± 0.25 μs 0.966 ± 0.031
arithmetic/addition 0.0533 ± 0.00051 ms 0.0552 ± 0.00067 ms 0.967 ± 0.015
arithmetic/division 22.2 ± 0.28 μs 22.7 ± 0.4 μs 0.977 ± 0.021
arithmetic/multiplication 0.0346 ± 0.0019 ms 0.0333 ± 0.00059 ms 1.04 ± 0.061
codegen/arrayop_nested/fast_toexpr 8.5 ± 0.37 μs 8.79 ± 0.45 μs 0.967 ± 0.065
codegen/arrayop_nested/toexpr 0.0488 ± 0.0012 ms 0.0476 ± 0.0012 ms 1.02 ± 0.036
codegen/deep_poly/deg=10:fast_toexpr 0.0642 ± 0.013 ms 0.0646 ± 0.013 ms 0.995 ± 0.29
codegen/deep_poly/deg=10:toexpr 0.0696 ± 0.015 ms 0.0692 ± 0.014 ms 1 ± 0.3
codegen/deep_poly/deg=14:fast_toexpr 0.126 ± 0.016 ms 0.121 ± 0.016 ms 1.04 ± 0.19
codegen/deep_poly/deg=14:toexpr 0.127 ± 0.029 ms 0.126 ± 0.027 ms 1.01 ± 0.32
codegen/deep_poly/deg=6:fast_toexpr 29.1 ± 1.6 μs 29 ± 1.7 μs 1 ± 0.079
codegen/deep_poly/deg=6:toexpr 30.2 ± 0.94 μs 30 ± 1.2 μs 1.01 ± 0.051
codegen/makearray/n=100:fast_toexpr 0.105 ± 0.026 ms 0.1 ± 0.027 ms 1.05 ± 0.38
codegen/makearray/n=100:toexpr 0.506 ± 0.06 ms 0.496 ± 0.057 ms 1.02 ± 0.17
codegen/makearray/n=200:fast_toexpr 0.168 ± 0.043 ms 0.158 ± 0.043 ms 1.06 ± 0.4
codegen/makearray/n=200:toexpr 0.882 ± 0.098 ms 0.862 ± 0.098 ms 1.02 ± 0.16
codegen/makearray/n=400:fast_toexpr 0.351 ± 0.026 ms 0.343 ± 0.025 ms 1.02 ± 0.11
codegen/makearray/n=400:toexpr 1.48 ± 0.14 ms 1.46 ± 0.15 ms 1.01 ± 0.14
codegen/wide_deep_poly/fast_toexpr 0.573 ± 0.029 ms 0.565 ± 0.029 ms 1.01 ± 0.073
codegen/wide_deep_poly/toexpr 0.456 ± 0.019 ms 0.452 ± 0.018 ms 1.01 ± 0.058
codegen/wide_poly/n=100:fast_toexpr 0.203 ± 0.017 ms 0.2 ± 0.018 ms 1.01 ± 0.12
codegen/wide_poly/n=100:toexpr 0.296 ± 0.034 ms 0.41 ± 0.025 ms 0.722 ± 0.095
codegen/wide_poly/n=25:fast_toexpr 0.044 ± 0.011 ms 0.0437 ± 0.011 ms 1.01 ± 0.37
codegen/wide_poly/n=25:toexpr 0.078 ± 0.014 ms 0.101 ± 0.014 ms 0.77 ± 0.17
codegen/wide_poly/n=50:fast_toexpr 0.0927 ± 0.011 ms 0.0911 ± 0.0076 ms 1.02 ± 0.14
codegen/wide_poly/n=50:toexpr 0.151 ± 0.026 ms 0.207 ± 0.025 ms 0.731 ± 0.15
irstructure/search_variables/common:IRStructure 0.188 ± 0.00092 ms 0.193 ± 0.0013 ms 0.972 ± 0.0082
irstructure/search_variables/common:reference 0.691 ± 0.0088 ms 0.728 ± 0.01 ms 0.948 ± 0.018
irstructure/search_variables/dissimilar:IRStructure 0.048 ± 0.00055 ms 0.052 ± 0.00045 ms 0.925 ± 0.013
irstructure/search_variables/dissimilar:reference 0.205 ± 0.011 ms 0.214 ± 0.013 ms 0.957 ± 0.077
irstructure/subset_ir/large 2.31 ± 0.064 ms 2.31 ± 0.056 ms 1 ± 0.037
irstructure/subset_ir/small 0.156 ± 0.0088 ms 0.165 ± 0.0088 ms 0.946 ± 0.073
irstructure/substitute/IRSubstituter 6.75 ± 0.08 ms 7.01 ± 0.065 ms 0.963 ± 0.015
irstructure/substitute/reference 7.05 ± 0.16 ms 7.29 ± 0.16 ms 0.968 ± 0.03
irstructure/substitute/sparse IRSubstituter 1.22 ± 0.1 ms 1.25 ± 0.093 ms 0.98 ± 0.11
irstructure/substitute/sparse reference 1.68 ± 0.072 ms 1.73 ± 0.068 ms 0.974 ± 0.057
overhead/acrule/a+2 1.66 ± 0.13 μs 1.82 ± 0.054 μs 0.911 ± 0.075
overhead/acrule/a+2+b 0.056 ± 0.001 μs 0.056 ± 0.001 μs 1 ± 0.025
overhead/acrule/a+b 2.75 ± 0.13 μs 3.12 ± 0.064 μs 0.883 ± 0.046
overhead/acrule/noop:Int 19 ± 1 ns 19 ± 0 ns 1 ± 0.053
overhead/acrule/noop:Sym 0.038 ± 0.001 μs 0.039 ± 0.001 μs 0.974 ± 0.036
overhead/get_degrees/large_poly 0.086 ± 0.003 μs 0.09 ± 0.005 μs 0.956 ± 0.063
overhead/rule/noop:Int 0.047 ± 0.002 μs 0.046 ± 0.001 μs 1.02 ± 0.049
overhead/rule/noop:Sym 0.052 ± 0.003 μs 0.048 ± 0.002 μs 1.08 ± 0.077
overhead/rule/noop:Term 0.052 ± 0.003 μs 0.048 ± 0.002 μs 1.08 ± 0.077
overhead/ruleset/noop:Int 19 ± 1 ns 19 ± 0 ns 1 ± 0.053
overhead/ruleset/noop:Sym 0.271 ± 0.008 μs 0.265 ± 0.008 μs 1.02 ± 0.043
overhead/ruleset/noop:Term 1.17 ± 0.021 μs 1.43 ± 0.026 μs 0.819 ± 0.021
overhead/simplify/noop:Int 19 ± 1 ns 19 ± 1 ns 1 ± 0.074
overhead/simplify/noop:Sym 23 ± 0 ns 23 ± 0 ns 1 ± 0
overhead/simplify/noop:Term 24 ± 0.48 μs 25.1 ± 0.5 μs 0.959 ± 0.027
overhead/simplify/randterm (+, *):serial 0.171 ± 0.019 s 0.184 ± 0.018 s 0.928 ± 0.14
overhead/simplify/randterm (+, *):thread 0.251 ± 0.1 s 0.248 ± 0.041 s 1.01 ± 0.45
overhead/simplify/randterm (/, *):serial 0.156 ± 0.012 ms 0.165 ± 0.013 ms 0.94 ± 0.1
overhead/simplify/randterm (/, *):thread 0.164 ± 0.015 ms 0.174 ± 0.016 ms 0.945 ± 0.12
overhead/substitute/a 26.9 ± 0.37 μs 28.8 ± 0.44 μs 0.936 ± 0.019
overhead/substitute/a,b 0.0335 ± 0.00044 ms 0.0359 ± 0.00051 ms 0.934 ± 0.018
overhead/substitute/a,b,c 0.0332 ± 0.00048 ms 0.0349 ± 0.00056 ms 0.951 ± 0.021
polyform/easy_iszero 14.7 ± 0.18 μs 14.8 ± 0.23 μs 0.988 ± 0.019
polyform/isone 0.778 ± 0.017 ms 0.807 ± 0.02 ms 0.963 ± 0.032
polyform/isone:noop 0.071 ± 0.004 μs 0.071 ± 0.003 μs 1 ± 0.07
polyform/iszero 0.66 ± 0.013 ms 0.685 ± 0.017 ms 0.964 ± 0.031
polyform/iszero:noop 0.071 ± 0.002 μs 0.072 ± 0.003 μs 0.986 ± 0.05
polyform/simplify_fractions 0.842 ± 0.015 ms 0.875 ± 0.019 ms 0.962 ± 0.027
printing/large_poly 0.218 ± 0.024 s 0.22 ± 0.02 s 0.991 ± 0.14
time_to_load 1.29 ± 0.011 s 1.29 ± 0.0028 s 1 ± 0.0085
Memory benchmarks
master 22d0a15... master / 22d0a15...
arithmetic/2-arg mul 0.076 k allocs: 2.59 kB 0.076 k allocs: 2.59 kB 1
arithmetic/addition 0.226 k allocs: 7.38 kB 0.226 k allocs: 7.38 kB 1
arithmetic/division 0.149 k allocs: 5.16 kB 0.149 k allocs: 5.16 kB 1
arithmetic/multiplication 0.252 k allocs: 7.05 kB 0.252 k allocs: 7.05 kB 1
codegen/arrayop_nested/fast_toexpr 0.207 k allocs: 9.48 kB 0.207 k allocs: 9.48 kB 1
codegen/arrayop_nested/toexpr 0.528 k allocs: 19.7 kB 0.528 k allocs: 19.7 kB 1
codegen/deep_poly/deg=10:fast_toexpr 1.25 k allocs: 0.0553 MB 1.25 k allocs: 0.0553 MB 1
codegen/deep_poly/deg=10:toexpr 1.41 k allocs: 0.0488 MB 1.41 k allocs: 0.0488 MB 1
codegen/deep_poly/deg=14:fast_toexpr 2.22 k allocs: 0.115 MB 2.22 k allocs: 0.115 MB 1
codegen/deep_poly/deg=14:toexpr 2.55 k allocs: 0.0908 MB 2.55 k allocs: 0.0908 MB 1
codegen/deep_poly/deg=6:fast_toexpr 0.559 k allocs: 27.8 kB 0.559 k allocs: 27.8 kB 1
codegen/deep_poly/deg=6:toexpr 0.601 k allocs: 22.2 kB 0.601 k allocs: 22.2 kB 1
codegen/makearray/n=100:fast_toexpr 2.07 k allocs: 0.0833 MB 2.07 k allocs: 0.0833 MB 1
codegen/makearray/n=100:toexpr 4.88 k allocs: 0.166 MB 4.88 k allocs: 0.166 MB 1
codegen/makearray/n=200:fast_toexpr 3.56 k allocs: 0.141 MB 3.56 k allocs: 0.141 MB 1
codegen/makearray/n=200:toexpr 8.41 k allocs: 0.286 MB 8.41 k allocs: 0.286 MB 1
codegen/makearray/n=400:fast_toexpr 7.36 k allocs: 0.289 MB 7.36 k allocs: 0.289 MB 1
codegen/makearray/n=400:toexpr 13.9 k allocs: 0.466 MB 13.9 k allocs: 0.466 MB 1
codegen/wide_deep_poly/fast_toexpr 7.42 k allocs: 0.348 MB 7.42 k allocs: 0.348 MB 1
codegen/wide_deep_poly/toexpr 9.37 k allocs: 0.327 MB 9.37 k allocs: 0.327 MB 1
codegen/wide_poly/n=100:fast_toexpr 3.5 k allocs: 0.151 MB 3.5 k allocs: 0.151 MB 1
codegen/wide_poly/n=100:toexpr 4.92 k allocs: 0.166 MB 4.92 k allocs: 0.166 MB 1
codegen/wide_poly/n=25:fast_toexpr 0.909 k allocs: 0.0377 MB 0.909 k allocs: 0.0377 MB 1
codegen/wide_poly/n=25:toexpr 1.24 k allocs: 0.0421 MB 1.24 k allocs: 0.0421 MB 1
codegen/wide_poly/n=50:fast_toexpr 1.78 k allocs: 0.0884 MB 1.78 k allocs: 0.0884 MB 1
codegen/wide_poly/n=50:toexpr 2.47 k allocs: 0.0862 MB 2.47 k allocs: 0.0862 MB 1
irstructure/search_variables/common:IRStructure 0.06 k allocs: 4.53 kB 0.06 k allocs: 4.53 kB 1
irstructure/search_variables/common:reference 0.26 k allocs: 0.23 MB 0.262 k allocs: 0.232 MB 0.992
irstructure/search_variables/dissimilar:IRStructure 0.044 k allocs: 3.28 kB 0.044 k allocs: 3.28 kB 1
irstructure/search_variables/dissimilar:reference 0.151 k allocs: 0.047 MB 0.155 k allocs: 0.0486 MB 0.967
irstructure/subset_ir/large 0.0369 M allocs: 1.61 MB 0.0369 M allocs: 1.61 MB 1
irstructure/subset_ir/small 2.66 k allocs: 0.155 MB 2.66 k allocs: 0.155 MB 1
irstructure/substitute/IRSubstituter 31.3 k allocs: 1.03 MB 31.3 k allocs: 1.03 MB 1
irstructure/substitute/reference 0.0339 M allocs: 1.19 MB 0.0339 M allocs: 1.19 MB 1
irstructure/substitute/sparse IRSubstituter 3.64 k allocs: 0.121 MB 3.64 k allocs: 0.121 MB 1
irstructure/substitute/sparse reference 6.31 k allocs: 0.288 MB 6.31 k allocs: 0.288 MB 1
overhead/acrule/a+2 30 allocs: 1.03 kB 30 allocs: 1.03 kB 1
overhead/acrule/a+2+b 0 allocs: 0 B 0 allocs: 0 B
overhead/acrule/a+b 0.038 k allocs: 1.36 kB 0.038 k allocs: 1.36 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.27 k allocs: 9.92 kB 0.266 k allocs: 9.73 kB 1.02
overhead/simplify/randterm (+, *):serial 2.13 M allocs: 0.0778 GB 2.12 M allocs: 0.0773 GB 1.01
overhead/simplify/randterm (+, *):thread 2.29 M allocs: 0.24 GB 2.28 M allocs: 0.239 GB 1
overhead/simplify/randterm (/, *):serial 1.89 k allocs: 0.0668 MB 1.89 k allocs: 0.0665 MB 1
overhead/simplify/randterm (/, *):thread 2.03 k allocs: 0.0717 MB 2.02 k allocs: 0.0714 MB 1
overhead/substitute/a 0.165 k allocs: 5.81 kB 0.165 k allocs: 5.81 kB 1
overhead/substitute/a,b 0.213 k allocs: 7.38 kB 0.213 k allocs: 7.38 kB 1
overhead/substitute/a,b,c 0.219 k allocs: 7.5 kB 0.219 k allocs: 7.5 kB 1
polyform/easy_iszero 0.097 k allocs: 3.11 kB 0.097 k allocs: 3.11 kB 1
polyform/isone 11.1 k allocs: 0.583 MB 11.1 k allocs: 0.583 MB 1
polyform/isone:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/iszero 9.15 k allocs: 0.487 MB 9.15 k allocs: 0.487 MB 1
polyform/iszero:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/simplify_fractions 11.6 k allocs: 0.601 MB 11.6 k allocs: 0.601 MB 1
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-Claude

Copy link
Copy Markdown
Contributor Author

CI triage — 26/29 green (all SymbolicUtils own-test matrices, Symbolics.jl/Core, and Symbolics.jl/GroebnerExt now that JuliaSymbolics/Symbolics.jl#1889 is merged). The 3 failures, each investigated and none caused by this PR:

  1. ModelingToolkit.jl/InterfaceI — 1 failure of 1386: test/structural_transformation/tearing.jl:111 gets a permuted (same-nnz) incidence matrix. Bisected locally with a minimal repro of exactly that assertion against three SymbolicUtils commits:

    SymbolicUtils commit contains result
    abcbea0c (Add ifelse_eager and ifelse_branching conditional operators #965 merge = released v4.35.0) operators, no hashing change ✅ pass
    79d748b7 (master = + add some more specialized hashing functions #963 hashing) no commits from this PR ❌ fail, identical pattern
    22d0a15b (this PR head) + cse_bind_expr ❌ fail, identical pattern

    ⇒ caused by add some more specialized hashing functions #963 (kc/hashing) changing Term hashes → hash-order-dependent variable ordering in MTK's tearing. Note: v4.35.0 was tagged before add some more specialized hashing functions #963 merged, so the breakage is latent on master and will surface downstream with the next SymbolicUtils release (including the 4.36.0 proposed here). Filed on the MTK side with the repro (issue link to follow).

  2. Symbolics.jl/Downstream — JET fails to precompile on Julia 1.12.6 (MethodError: add_active_gotos! in Compiler internals); the job's DI Test dies loading JET. A JET↔Julia-patch incompatibility, unrelated to SymbolicUtils content.

  3. ModelOrderReduction.jl/All — long-standing pre-existing failure (red on Add ifelse_eager and ifelse_branching conditional operators #965, Symbolics#1887, and master IntegrationTest alike).

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor Author

The ModelingToolkit.jl/InterfaceI failure now has a ready fix: SciML/ModelingToolkit.jl#4620 (makes the tearing matrix assertion accept both valid maximal matchings, mirroring the || pattern the same file already uses; mechanism + bisect in SciML/ModelingToolkit.jl#4619). Once that merges, this downstream check goes green for any SymbolicUtils release that includes #963.

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.

3 participants