From 152208e4815590b5bf5e314f2008c7db35faa037 Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 15:16:52 -0700 Subject: [PATCH 01/19] Start implementing trimming test We introduce `SafeTestsets` as part of this, inspired by the way the downstream tests are set up in the `SciMLBase` repo. --- Project.toml | 4 +-- test/runtests.jl | 41 +++++++++++++++++++++++------ test/trim/Project.toml | 27 +++++++++++++++++++ test/trim/clean_optimization.jl | 32 ++++++++++++++++++++++ test/trim/trimmable_optimization.jl | 35 ++++++++++++++++++++++++ 5 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 test/trim/Project.toml create mode 100644 test/trim/clean_optimization.jl create mode 100644 test/trim/trimmable_optimization.jl diff --git a/Project.toml b/Project.toml index 1be25a8b7..a8dbaa9f6 100644 --- a/Project.toml +++ b/Project.toml @@ -143,6 +143,7 @@ PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" ReTestItems = "817f1d60-ba6b-4fd5-9520-3cf149f6a823" SIAMFANLEquations = "084e46ad-d928-497d-ad5e-07fa361a48c4" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" SpeedMapping = "f1835b91-879b-4a3f-a438-e4baacf14412" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" @@ -170,5 +171,4 @@ path = "lib/NonlinearSolveSpectralMethods" path = "lib/SimpleNonlinearSolve" [targets] -test = ["Aqua", "BandedMatrices", "BenchmarkTools", "CUDA", "Enzyme", "ExplicitImports", "FastLevenbergMarquardt", "FixedPointAcceleration", "Hwloc", "InteractiveUtils", "LeastSquaresOptim", "LineSearches", "MINPACK", "NLSolvers", "NLsolve", "NaNMath", "NonlinearProblemLibrary", "OrdinaryDiffEqTsit5", "PETSc", "Pkg", "PolyesterForwardDiff", "Random", "ReTestItems", "SIAMFANLEquations", "SparseConnectivityTracer", "SpeedMapping", "StableRNGs", "StaticArrays", "Sundials", "Test", "Zygote"] - +test = ["Aqua", "BandedMatrices", "BenchmarkTools", "CUDA", "Enzyme", "ExplicitImports", "FastLevenbergMarquardt", "FixedPointAcceleration", "Hwloc", "InteractiveUtils", "LeastSquaresOptim", "LineSearches", "MINPACK", "NLSolvers", "NLsolve", "NaNMath", "NonlinearProblemLibrary", "OrdinaryDiffEqTsit5", "PETSc", "Pkg", "PolyesterForwardDiff", "Random", "ReTestItems", "SafeTestsets", "SIAMFANLEquations", "SparseConnectivityTracer", "SpeedMapping", "StableRNGs", "StaticArrays", "Sundials", "Test", "Zygote"] diff --git a/test/runtests.jl b/test/runtests.jl index bfdd07b35..e1a928ae2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,9 +1,18 @@ -using ReTestItems, NonlinearSolve, Hwloc, InteractiveUtils, Pkg +using NonlinearSolve, Hwloc, InteractiveUtils, Pkg +using SafeTestsets +using ReTestItems @info sprint(InteractiveUtils.versioninfo) const GROUP = lowercase(get(ENV, "GROUP", "All")) +function activate_trim_env!() + Pkg.activate(abspath(joinpath(dirname(@__FILE__), "trim"))) + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() + return nothing +end + const EXTRA_PKGS = Pkg.PackageSpec[] if GROUP == "all" || GROUP == "downstream" push!(EXTRA_PKGS, Pkg.PackageSpec("ModelingToolkit")) @@ -12,11 +21,13 @@ end length(EXTRA_PKGS) ≥ 1 && Pkg.add(EXTRA_PKGS) const RETESTITEMS_NWORKERS = parse( - Int, get(ENV, "RETESTITEMS_NWORKERS", + Int, get( + ENV, "RETESTITEMS_NWORKERS", string(min(ifelse(Sys.iswindows(), 0, Hwloc.num_physical_cores()), 4)) ) ) -const RETESTITEMS_NWORKER_THREADS = parse(Int, +const RETESTITEMS_NWORKER_THREADS = parse( + Int, get( ENV, "RETESTITEMS_NWORKER_THREADS", string(max(Hwloc.num_virtual_cores() ÷ max(RETESTITEMS_NWORKERS, 1), 1)) @@ -25,8 +36,22 @@ const RETESTITEMS_NWORKER_THREADS = parse(Int, @info "Running tests for group: $(GROUP) with $(RETESTITEMS_NWORKERS) workers" -ReTestItems.runtests( - NonlinearSolve; tags = (GROUP == "all" ? nothing : [Symbol(GROUP)]), - nworkers = RETESTITEMS_NWORKERS, nworker_threads = RETESTITEMS_NWORKER_THREADS, - testitem_timeout = 3600 -) +if GROUP != "trim" + ReTestItems.runtests( + NonlinearSolve; tags = (GROUP == "all" ? nothing : [Symbol(GROUP)]), + nworkers = RETESTITEMS_NWORKERS, nworker_threads = RETESTITEMS_NWORKER_THREADS, + testitem_timeout = 3600 + ) +elseif GROUP == "trim" && VERSION >= v"1.12.0-rc1" # trimming has been introduced in julia 1.12 + activate_trim_env!() + @safetestset "Clean implementation (non-trimmable)" begin + using SciMLBase: successful_retcode + include("trim/clean_optimization.jl") + @test successful_retcode(minimize(1.0).retcode) + end + @safetestset "Trimmable implementation" begin + using SciMLBase: successful_retcode + include("trim/trimmable_optimization.jl") + @test successful_retcode(minimize(1.0).retcode) + end +end diff --git a/test/trim/Project.toml b/test/trim/Project.toml new file mode 100644 index 000000000..018357746 --- /dev/null +++ b/test/trim/Project.toml @@ -0,0 +1,27 @@ +[deps] +ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" +DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" +NonlinearSolveFirstOrder = "5959db7a-ea39-4486-b5fe-2dd0bf03d60d" +Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" +PolyesterWeave = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[sources] +ForwardDiff = {rev = "rv/remove-quote-assert-string-interpolation", url = "https://github.com/RomeoV/ForwardDiff.jl"} +LinearSolve = {rev = "rv/remove-linsolve-forwarddiff-special-path", url = "https://github.com/RomeoV/LinearSolve.jl"} +NonlinearSolveFirstOrder = {path = "../../lib/NonlinearSolveFirstOrder"} +Polyester = {rev = "master", url = "https://github.com/RomeoV/Polyester.jl"} +PolyesterWeave = {rev = "main", url = "https://github.com/RomeoV/PolyesterWeave.jl"} +SciMLBase = {rev = "as/fix-jet-opt", url = "https://github.com/AayushSabharwal/SciMLBase.jl"} + +[compat] +ADTypes = "1.15.0" +DiffEqBase = "6.179.0" +LinearAlgebra = "1.12.0" +NonlinearSolveFirstOrder = "1.6.0" +StaticArrays = "1.9.0" diff --git a/test/trim/clean_optimization.jl b/test/trim/clean_optimization.jl new file mode 100644 index 000000000..338fe3544 --- /dev/null +++ b/test/trim/clean_optimization.jl @@ -0,0 +1,32 @@ +using NonlinearSolveFirstOrder +using ADTypes: AutoForwardDiff +using ForwardDiff +using LinearAlgebra +using StaticArrays +using LinearSolve +const LS = LinearSolve + +function f(u, p) + L, U = cholesky(p.Σ) + rhs = (u .* u .- p.λ) + # there are some issues currently with LinearSolve and triangular matrices, + # so we just make `L` dense here. + linprob = LinearProblem(Matrix(L), rhs) + alg = LS.GenericLUFactorization() + sol = LinearSolve.solve(linprob, alg) + return sol.u +end + +struct MyParams{T, M} + λ::T + Σ::M +end + +function minimize(x) + autodiff = AutoForwardDiff(; chunksize=1) + alg = TrustRegion(; autodiff, linsolve=LS.CholeskyFactorization()) + ps = MyParams(rand(), hermitianpart(rand(2,2)+2I)) + prob = NonlinearLeastSquaresProblem{false}(f, rand(2), ps) + sol = solve(prob, alg) + return sol +end diff --git a/test/trim/trimmable_optimization.jl b/test/trim/trimmable_optimization.jl new file mode 100644 index 000000000..51aa6ee72 --- /dev/null +++ b/test/trim/trimmable_optimization.jl @@ -0,0 +1,35 @@ +using NonlinearSolveFirstOrder +using ADTypes: AutoForwardDiff +using ForwardDiff +using LinearAlgebra +using StaticArrays +using LinearSolve +const LS = LinearSolve + +function f(u, p) + L, U = cholesky(p.Σ) + rhs = (u .* u .- p.λ) + # there are some issues currently with LinearSolve and triangular matrices, + # so we just make `L` dense here. + linprob = LinearProblem(Matrix(L), rhs) + alg = LS.GenericLUFactorization() + sol = LinearSolve.solve(linprob, alg) + return sol.u +end + +struct MyParams{T, M} + λ::T + Σ::M +end + +const autodiff = AutoForwardDiff(; chunksize = 1) +const alg = TrustRegion(; autodiff, linsolve = LS.CholeskyFactorization()) +const prob = NonlinearLeastSquaresProblem{false}(f, rand(2), MyParams(rand(), hermitianpart(rand(2, 2) + 2I))) +const cache = init(prob, alg) + +function minimize(x) + ps = MyParams(x, hermitianpart(rand(2, 2) + 2I)) + reinit!(cache, rand(2); p = ps) + solve!(cache) + return cache +end From e728e55d2c07c57d5473820068399f167b01e65c Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 15:38:49 -0700 Subject: [PATCH 02/19] Add JET tests for now --- test/runtests.jl | 5 +---- test/trim/Project.toml | 1 + test/trim/clean_optimization.jl | 5 +++++ test/trim/trimmable_optimization.jl | 5 +++++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index e1a928ae2..4ea08a2da 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,4 @@ -using NonlinearSolve, Hwloc, InteractiveUtils, Pkg -using SafeTestsets -using ReTestItems +using ReTestItems, NonlinearSolve, Hwloc, InteractiveUtils, Pkg @info sprint(InteractiveUtils.versioninfo) @@ -8,7 +6,6 @@ const GROUP = lowercase(get(ENV, "GROUP", "All")) function activate_trim_env!() Pkg.activate(abspath(joinpath(dirname(@__FILE__), "trim"))) - Pkg.develop(PackageSpec(path = dirname(@__DIR__))) Pkg.instantiate() return nothing end diff --git a/test/trim/Project.toml b/test/trim/Project.toml index 018357746..d0afc466c 100644 --- a/test/trim/Project.toml +++ b/test/trim/Project.toml @@ -2,6 +2,7 @@ ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" NonlinearSolveFirstOrder = "5959db7a-ea39-4486-b5fe-2dd0bf03d60d" diff --git a/test/trim/clean_optimization.jl b/test/trim/clean_optimization.jl index 338fe3544..b6f3875a1 100644 --- a/test/trim/clean_optimization.jl +++ b/test/trim/clean_optimization.jl @@ -5,6 +5,8 @@ using LinearAlgebra using StaticArrays using LinearSolve const LS = LinearSolve +using SciMLBase: successful_retcode +using JET function f(u, p) L, U = cholesky(p.Σ) @@ -30,3 +32,6 @@ function minimize(x) sol = solve(prob, alg) return sol end + +@test successful_retcode(minimize(1.0).retcode) +@test_opt minimize(1.0) broken=true diff --git a/test/trim/trimmable_optimization.jl b/test/trim/trimmable_optimization.jl index 51aa6ee72..9bdc12b33 100644 --- a/test/trim/trimmable_optimization.jl +++ b/test/trim/trimmable_optimization.jl @@ -5,6 +5,8 @@ using LinearAlgebra using StaticArrays using LinearSolve const LS = LinearSolve +using SciMLBase: successful_retcode +using JET function f(u, p) L, U = cholesky(p.Σ) @@ -33,3 +35,6 @@ function minimize(x) solve!(cache) return cache end + +@test successful_retcode(minimize(1.0).retcode) +@test_opt minimize(1.0) broken=true From a6357dde29c79b4ad8dc177a7168b109892fb20b Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 15:41:00 -0700 Subject: [PATCH 03/19] Move all the trimming tests into their own file --- test/runtests.jl | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 4ea08a2da..c4cdaaee7 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -41,14 +41,5 @@ if GROUP != "trim" ) elseif GROUP == "trim" && VERSION >= v"1.12.0-rc1" # trimming has been introduced in julia 1.12 activate_trim_env!() - @safetestset "Clean implementation (non-trimmable)" begin - using SciMLBase: successful_retcode - include("trim/clean_optimization.jl") - @test successful_retcode(minimize(1.0).retcode) - end - @safetestset "Trimmable implementation" begin - using SciMLBase: successful_retcode - include("trim/trimmable_optimization.jl") - @test successful_retcode(minimize(1.0).retcode) - end + include("trim/runtests.jl") end From a6c2ba34f32121bf2269acea405aaeafb25b113a Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 15:42:10 -0700 Subject: [PATCH 04/19] Add comments to `Project.toml` explaining PRd repos. --- test/trim/Project.toml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/test/trim/Project.toml b/test/trim/Project.toml index d0afc466c..09321c042 100644 --- a/test/trim/Project.toml +++ b/test/trim/Project.toml @@ -13,12 +13,19 @@ SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [sources] -ForwardDiff = {rev = "rv/remove-quote-assert-string-interpolation", url = "https://github.com/RomeoV/ForwardDiff.jl"} -LinearSolve = {rev = "rv/remove-linsolve-forwarddiff-special-path", url = "https://github.com/RomeoV/LinearSolve.jl"} +# Remove assert that triggers false positive for JET. Tracked at https://github.com/aviatesk/JET.jl/issues/736. +ForwardDiff = {url = "https://github.com/RomeoV/ForwardDiff.jl", rev="rv/remove-quote-assert-string-interpolation"} +# Remove special path code path for ForwarDiff of LinearSolve, which uses untrimmable `deepcopy`. +# Use of `deepcopy` is tracked at https://github.com/SciML/LinearSolve.jl/issues/648. +LinearSolve = {url = "https://github.com/RomeoV/LinearSolve.jl", rev="rv/remove-linsolve-forwarddiff-special-path"} NonlinearSolveFirstOrder = {path = "../../lib/NonlinearSolveFirstOrder"} -Polyester = {rev = "master", url = "https://github.com/RomeoV/Polyester.jl"} -PolyesterWeave = {rev = "main", url = "https://github.com/RomeoV/PolyesterWeave.jl"} -SciMLBase = {rev = "as/fix-jet-opt", url = "https://github.com/AayushSabharwal/SciMLBase.jl"} +# Remove use of CPUSummary which segfaults trimmed binary. Tracked at https://github.com/JuliaSIMD/Polyester.jl/pull/163. +Polyester = {url = "https://github.com/RomeoV/Polyester.jl", rev="master"} +# Remove use of CPUSummary which segfaults trimmed binary. Tracked at https://github.com/JuliaSIMD/PolyesterWeave.jl/pull/28 +PolyesterWeave = {url = "https://github.com/RomeoV/PolyesterWeave.jl", rev="main"} +# Fix a type instability. Tracked at https://github.com/SciML/SciMLBase.jl/pull/1074. +SciMLBase = {url = "https://github.com/AayushSabharwal/SciMLBase.jl", rev="as/fix-jet-opt"} + [compat] ADTypes = "1.15.0" From a5d4b8eec191b1e58b39eed45758252c706a125c Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 15:42:52 -0700 Subject: [PATCH 05/19] fixup! Add JET tests for now --- test/trim/trimmable_optimization.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trim/trimmable_optimization.jl b/test/trim/trimmable_optimization.jl index 9bdc12b33..ae46caa19 100644 --- a/test/trim/trimmable_optimization.jl +++ b/test/trim/trimmable_optimization.jl @@ -37,4 +37,4 @@ function minimize(x) end @test successful_retcode(minimize(1.0).retcode) -@test_opt minimize(1.0) broken=true +@test_opt minimize(1.0) From 7462b077dbd4ba42abe367c8b0e3639ba1698a7b Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 15:51:43 -0700 Subject: [PATCH 06/19] Fix JET tests --- test/trim/clean_optimization.jl | 2 +- test/trim/trimmable_optimization.jl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/trim/clean_optimization.jl b/test/trim/clean_optimization.jl index b6f3875a1..62d4c5303 100644 --- a/test/trim/clean_optimization.jl +++ b/test/trim/clean_optimization.jl @@ -34,4 +34,4 @@ function minimize(x) end @test successful_retcode(minimize(1.0).retcode) -@test_opt minimize(1.0) broken=true +@test_opt minimize(1.0) diff --git a/test/trim/trimmable_optimization.jl b/test/trim/trimmable_optimization.jl index ae46caa19..3ff388fdc 100644 --- a/test/trim/trimmable_optimization.jl +++ b/test/trim/trimmable_optimization.jl @@ -1,5 +1,6 @@ using NonlinearSolveFirstOrder using ADTypes: AutoForwardDiff +using DiffEqBase using ForwardDiff using LinearAlgebra using StaticArrays @@ -23,6 +24,7 @@ struct MyParams{T, M} λ::T Σ::M end +DiffEqBase.anyeltypedual(::MyParams) = Any const autodiff = AutoForwardDiff(; chunksize = 1) const alg = TrustRegion(; autodiff, linsolve = LS.CholeskyFactorization()) From 360da41bf8bf4dda455064956c34d26312ec865c Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 16:22:49 -0700 Subject: [PATCH 07/19] refactor: main runtests.jl file --- test/runtests.jl | 49 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index c4cdaaee7..3f187a9db 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,45 +1,42 @@ -using ReTestItems, NonlinearSolve, Hwloc, InteractiveUtils, Pkg +using ReTestItems, Hwloc, InteractiveUtils, Pkg @info sprint(InteractiveUtils.versioninfo) const GROUP = lowercase(get(ENV, "GROUP", "All")) -function activate_trim_env!() - Pkg.activate(abspath(joinpath(dirname(@__FILE__), "trim"))) - Pkg.instantiate() - return nothing -end +if GROUP != "trim" + using NonlinearSolve # trimming uses a NonlinearSolve from a custom environment -const EXTRA_PKGS = Pkg.PackageSpec[] -if GROUP == "all" || GROUP == "downstream" - push!(EXTRA_PKGS, Pkg.PackageSpec("ModelingToolkit")) - push!(EXTRA_PKGS, Pkg.PackageSpec("SymbolicIndexingInterface")) -end -length(EXTRA_PKGS) ≥ 1 && Pkg.add(EXTRA_PKGS) + const EXTRA_PKGS = Pkg.PackageSpec[] + if GROUP == "all" || GROUP == "downstream" + push!(EXTRA_PKGS, Pkg.PackageSpec("ModelingToolkit")) + push!(EXTRA_PKGS, Pkg.PackageSpec("SymbolicIndexingInterface")) + end + length(EXTRA_PKGS) ≥ 1 && Pkg.add(EXTRA_PKGS) -const RETESTITEMS_NWORKERS = parse( - Int, get( - ENV, "RETESTITEMS_NWORKERS", - string(min(ifelse(Sys.iswindows(), 0, Hwloc.num_physical_cores()), 4)) + const RETESTITEMS_NWORKERS = parse( + Int, get( + ENV, "RETESTITEMS_NWORKERS", + string(min(ifelse(Sys.iswindows(), 0, Hwloc.num_physical_cores()), 4)) + ) ) -) -const RETESTITEMS_NWORKER_THREADS = parse( - Int, - get( - ENV, "RETESTITEMS_NWORKER_THREADS", - string(max(Hwloc.num_virtual_cores() ÷ max(RETESTITEMS_NWORKERS, 1), 1)) + const RETESTITEMS_NWORKER_THREADS = parse( + Int, + get( + ENV, "RETESTITEMS_NWORKER_THREADS", + string(max(Hwloc.num_virtual_cores() ÷ max(RETESTITEMS_NWORKERS, 1), 1)) + ) ) -) -@info "Running tests for group: $(GROUP) with $(RETESTITEMS_NWORKERS) workers" + @info "Running tests for group: $(GROUP) with $(RETESTITEMS_NWORKERS) workers" -if GROUP != "trim" ReTestItems.runtests( NonlinearSolve; tags = (GROUP == "all" ? nothing : [Symbol(GROUP)]), nworkers = RETESTITEMS_NWORKERS, nworker_threads = RETESTITEMS_NWORKER_THREADS, testitem_timeout = 3600 ) elseif GROUP == "trim" && VERSION >= v"1.12.0-rc1" # trimming has been introduced in julia 1.12 - activate_trim_env!() + Pkg.activate(joinpath(dirname(@__FILE__), "trim")) + Pkg.instantiate() include("trim/runtests.jl") end From c23f977db9d7b9636d488d07940c7b736141e067 Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 16:23:10 -0700 Subject: [PATCH 08/19] Add compat entries --- test/trim/Project.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/trim/Project.toml b/test/trim/Project.toml index 09321c042..c19f8ac65 100644 --- a/test/trim/Project.toml +++ b/test/trim/Project.toml @@ -30,6 +30,9 @@ SciMLBase = {url = "https://github.com/AayushSabharwal/SciMLBase.jl", rev="as/fi [compat] ADTypes = "1.15.0" DiffEqBase = "6.179.0" +ForwardDiff = "1.0.1" LinearAlgebra = "1.12.0" NonlinearSolveFirstOrder = "1.6.0" +Polyester = "0.7.18" +PolyesterWeave = "0.2.2" StaticArrays = "1.9.0" From 69b54a1bdb771fbd4dd4cfcc3184841cd082a04d Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 16:24:18 -0700 Subject: [PATCH 09/19] fixup! Start implementing trimming test --- Project.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index a8dbaa9f6..49a32dc64 100644 --- a/Project.toml +++ b/Project.toml @@ -143,7 +143,6 @@ PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" ReTestItems = "817f1d60-ba6b-4fd5-9520-3cf149f6a823" SIAMFANLEquations = "084e46ad-d928-497d-ad5e-07fa361a48c4" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" SpeedMapping = "f1835b91-879b-4a3f-a438-e4baacf14412" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" @@ -171,4 +170,4 @@ path = "lib/NonlinearSolveSpectralMethods" path = "lib/SimpleNonlinearSolve" [targets] -test = ["Aqua", "BandedMatrices", "BenchmarkTools", "CUDA", "Enzyme", "ExplicitImports", "FastLevenbergMarquardt", "FixedPointAcceleration", "Hwloc", "InteractiveUtils", "LeastSquaresOptim", "LineSearches", "MINPACK", "NLSolvers", "NLsolve", "NaNMath", "NonlinearProblemLibrary", "OrdinaryDiffEqTsit5", "PETSc", "Pkg", "PolyesterForwardDiff", "Random", "ReTestItems", "SafeTestsets", "SIAMFANLEquations", "SparseConnectivityTracer", "SpeedMapping", "StableRNGs", "StaticArrays", "Sundials", "Test", "Zygote"] +test = ["Aqua", "BandedMatrices", "BenchmarkTools", "CUDA", "Enzyme", "ExplicitImports", "FastLevenbergMarquardt", "FixedPointAcceleration", "Hwloc", "InteractiveUtils", "LeastSquaresOptim", "LineSearches", "MINPACK", "NLSolvers", "NLsolve", "NaNMath", "NonlinearProblemLibrary", "OrdinaryDiffEqTsit5", "PETSc", "Pkg", "PolyesterForwardDiff", "Random", "ReTestItems", "SIAMFANLEquations", "SparseConnectivityTracer", "SpeedMapping", "StableRNGs", "StaticArrays", "Sundials", "Test", "Zygote"] From 8c45ab348bfc4bc4de9b5984db7e54fe6905c9c2 Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 18:38:00 -0700 Subject: [PATCH 10/19] Add trimming test --- test/trim/main.jl | 12 ++++++++ test/trim/runtests.jl | 65 +++++++++++++++++++++++++++++++++++++++ test/trim/src/TrimTest.jl | 3 ++ 3 files changed, 80 insertions(+) create mode 100644 test/trim/main.jl create mode 100644 test/trim/runtests.jl create mode 100644 test/trim/src/TrimTest.jl diff --git a/test/trim/main.jl b/test/trim/main.jl new file mode 100644 index 000000000..dd85aca84 --- /dev/null +++ b/test/trim/main.jl @@ -0,0 +1,12 @@ +using TrimTest + +function (@main)(argv::Vector{String})::Cint + λ = try + parse(Float64, argv[2]) + catch + parse(Float64, argv[1]) + end + sol = TrimTest.minimize(λ) + println(Core.stdout, sum(sol.u)) + return 0 +end diff --git a/test/trim/runtests.jl b/test/trim/runtests.jl new file mode 100644 index 000000000..2ef26457a --- /dev/null +++ b/test/trim/runtests.jl @@ -0,0 +1,65 @@ +using SafeTestsets + +@safetestset "Clean implementation (non-trimmable)" begin + using JET + using SciMLBase: successful_retcode + include("clean_optimization.jl") + @test successful_retcode(minimize(1.0).retcode) + # can't use `@test_opt` macro here because it would eval before `using JET` + # is processed + test_opt(minimize, (typeof(1.0),)) +end + +@safetestset "Trimmable implementation" begin + using JET + using SciMLBase: successful_retcode + include("trimmable_optimization.jl") + @test successful_retcode(minimize(1.0).retcode) + # can't use `@test_opt` macro here because it would eval before `using JET` + # is processed + test_opt(minimize, (typeof(1.0),)) +end + +@safetestset "Run trim" begin + # https://discourse.julialang.org/t/capture-stdout-and-stderr-in-case-a-command-fails/101772/3?u=romeov + "Run a Cmd object, returning the stdout & stderr contents plus the exit code" + function _execute(cmd::Cmd) + out = Pipe() + err = Pipe() + process = run(pipeline(ignorestatus(cmd); stdout = out, stderr = err)) + close(out.in) + close(err.in) + out = ( + stdout = String(read(out)), stderr = String(read(err)), + exitcode = process.exitcode, + ) + return out + end + + JULIAC = normpath( + joinpath( + Sys.BINDIR, Base.DATAROOTDIR, "julia", "juliac", + "juliac.jl" + ) + ) + @test isfile(JULIAC) + binpath = tempname() + cmd = `$(Base.julia_cmd()) --project=. --depwarn=error $(JULIAC) --experimental --trim=unsafe-warn --output-exe $(binpath) main.jl` + + # since we are calling Julia from Julia, we first need to clean some + # environment variables + clean_env = copy(ENV) + delete!(clean_env, "JULIA_PROJECT") + delete!(clean_env, "JULIA_LOAD_PATH") + # We could just check for success, but then failures are hard to debug. + # Instead we use `_execute` to also capture `stdout` and `stderr`. + # @test success(setenv(cmd, clean_env)) + trimcall = _execute(setenv(cmd, clean_env; dir = @__DIR__)) + if trimcall.exitcode != 0 + @show trimcall.stdout + @show trimcall.stderr + end + @test trimcall.exitcode == 0 + @test isfile(binpath) + @test success(`$(binpath) 1.0`) +end diff --git a/test/trim/src/TrimTest.jl b/test/trim/src/TrimTest.jl new file mode 100644 index 000000000..6862439be --- /dev/null +++ b/test/trim/src/TrimTest.jl @@ -0,0 +1,3 @@ +module TrimTest +include("../trimmable_optimization.jl") +end From bd68b9d6da163a28171cfc3881b0a2ac396a6d3c Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 18:52:07 -0700 Subject: [PATCH 11/19] Put trimmable code into package See TrimTest.jl comment for rationale. --- test/trim/Project.toml | 3 +++ test/trim/clean_optimization.jl | 5 ----- test/trim/main.jl | 6 +----- test/trim/src/TrimTest.jl | 23 +++++++++++++++++++++++ test/trim/trimmable_optimization.jl | 9 ++------- 5 files changed, 29 insertions(+), 17 deletions(-) diff --git a/test/trim/Project.toml b/test/trim/Project.toml index c19f8ac65..88a8ac1b3 100644 --- a/test/trim/Project.toml +++ b/test/trim/Project.toml @@ -1,3 +1,6 @@ +name = "TrimTest" +uuid = "7e54ada7-ece5-4046-aa01-512d530850d8" + [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" diff --git a/test/trim/clean_optimization.jl b/test/trim/clean_optimization.jl index 62d4c5303..338fe3544 100644 --- a/test/trim/clean_optimization.jl +++ b/test/trim/clean_optimization.jl @@ -5,8 +5,6 @@ using LinearAlgebra using StaticArrays using LinearSolve const LS = LinearSolve -using SciMLBase: successful_retcode -using JET function f(u, p) L, U = cholesky(p.Σ) @@ -32,6 +30,3 @@ function minimize(x) sol = solve(prob, alg) return sol end - -@test successful_retcode(minimize(1.0).retcode) -@test_opt minimize(1.0) diff --git a/test/trim/main.jl b/test/trim/main.jl index dd85aca84..4c3c27377 100644 --- a/test/trim/main.jl +++ b/test/trim/main.jl @@ -1,11 +1,7 @@ using TrimTest function (@main)(argv::Vector{String})::Cint - λ = try - parse(Float64, argv[2]) - catch - parse(Float64, argv[1]) - end + λ = parse(Float64, argv[2]) sol = TrimTest.minimize(λ) println(Core.stdout, sum(sol.u)) return 0 diff --git a/test/trim/src/TrimTest.jl b/test/trim/src/TrimTest.jl index 6862439be..f1955c4c2 100644 --- a/test/trim/src/TrimTest.jl +++ b/test/trim/src/TrimTest.jl @@ -1,3 +1,26 @@ module TrimTest +#= +Currently, trimming only works if the target code is in a package. I.e., trying to trim +```julia +include("trimmable_optimization.jl") +function (@main)(argv::Vector{String})::Cint + minimize(1.0) + return 0 +end +``` +or even +```julia +mod MyMod + include("trimmable_optimization.jl") +end +function (@main)(argv::Vector{String})::Cint + MyMod.minimize(1.0) + return 0 +end +``` +segfaults `juliac`. Looking at the segfault stacktrace it seems the culprit is +`const cache = init(...)`. Either way, we circumvent the segfault by putting +this below code into a package definition. +=# include("../trimmable_optimization.jl") end diff --git a/test/trim/trimmable_optimization.jl b/test/trim/trimmable_optimization.jl index 3ff388fdc..5a7b7641b 100644 --- a/test/trim/trimmable_optimization.jl +++ b/test/trim/trimmable_optimization.jl @@ -1,13 +1,12 @@ using NonlinearSolveFirstOrder -using ADTypes: AutoForwardDiff using DiffEqBase +using ADTypes: AutoForwardDiff using ForwardDiff using LinearAlgebra using StaticArrays using LinearSolve +import SciMLBase const LS = LinearSolve -using SciMLBase: successful_retcode -using JET function f(u, p) L, U = cholesky(p.Σ) @@ -24,7 +23,6 @@ struct MyParams{T, M} λ::T Σ::M end -DiffEqBase.anyeltypedual(::MyParams) = Any const autodiff = AutoForwardDiff(; chunksize = 1) const alg = TrustRegion(; autodiff, linsolve = LS.CholeskyFactorization()) @@ -37,6 +35,3 @@ function minimize(x) solve!(cache) return cache end - -@test successful_retcode(minimize(1.0).retcode) -@test_opt minimize(1.0) From 1fc1c1881a3181db0a36ebdbd85836f10aa9856c Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 19:02:50 -0700 Subject: [PATCH 12/19] nit: grammar --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 3f187a9db..997d87b0a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,7 +5,7 @@ using ReTestItems, Hwloc, InteractiveUtils, Pkg const GROUP = lowercase(get(ENV, "GROUP", "All")) if GROUP != "trim" - using NonlinearSolve # trimming uses a NonlinearSolve from a custom environment + using NonlinearSolve # trimming uses NonlinearSolve from a custom environment const EXTRA_PKGS = Pkg.PackageSpec[] if GROUP == "all" || GROUP == "downstream" From 8ec2de04fe724258aed0994f3c1d4f36c2b647e0 Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 19:08:40 -0700 Subject: [PATCH 13/19] Add "trim" group to CI --- .github/workflows/CI_NonlinearSolve.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/CI_NonlinearSolve.yml b/.github/workflows/CI_NonlinearSolve.yml index 84aa7a2ba..0a137a8ac 100644 --- a/.github/workflows/CI_NonlinearSolve.yml +++ b/.github/workflows/CI_NonlinearSolve.yml @@ -36,6 +36,7 @@ jobs: - downstream - wrappers - misc + - trim version: - "1" - "lts" From 076b9f0868351c557031b346959069b9a5a08671 Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 19:21:11 -0700 Subject: [PATCH 14/19] Add test that `optimization_clean` doesn't trim, marked `broken` --- test/trim/{main.jl => main_clean.jl} | 2 +- test/trim/main_trimmable.jl | 8 +++ ..._optimization.jl => optimization_clean.jl} | 8 ++- ...imization.jl => optimization_trimmable.jl} | 2 + test/trim/runtests.jl | 58 ++++++++++--------- test/trim/src/TrimTest.jl | 7 ++- 6 files changed, 51 insertions(+), 34 deletions(-) rename test/trim/{main.jl => main_clean.jl} (75%) create mode 100644 test/trim/main_trimmable.jl rename test/trim/{clean_optimization.jl => optimization_clean.jl} (76%) rename test/trim/{trimmable_optimization.jl => optimization_trimmable.jl} (96%) diff --git a/test/trim/main.jl b/test/trim/main_clean.jl similarity index 75% rename from test/trim/main.jl rename to test/trim/main_clean.jl index 4c3c27377..be60b697a 100644 --- a/test/trim/main.jl +++ b/test/trim/main_clean.jl @@ -2,7 +2,7 @@ using TrimTest function (@main)(argv::Vector{String})::Cint λ = parse(Float64, argv[2]) - sol = TrimTest.minimize(λ) + sol = TrimTest.TestModuleClean.minimize(λ) println(Core.stdout, sum(sol.u)) return 0 end diff --git a/test/trim/main_trimmable.jl b/test/trim/main_trimmable.jl new file mode 100644 index 000000000..b25e20fe0 --- /dev/null +++ b/test/trim/main_trimmable.jl @@ -0,0 +1,8 @@ +using TrimTest + +function (@main)(argv::Vector{String})::Cint + λ = parse(Float64, argv[2]) + sol = TrimTest.TestModuleTrimmable.minimize(λ) + println(Core.stdout, sum(sol.u)) + return 0 +end diff --git a/test/trim/clean_optimization.jl b/test/trim/optimization_clean.jl similarity index 76% rename from test/trim/clean_optimization.jl rename to test/trim/optimization_clean.jl index 338fe3544..ca6de20e3 100644 --- a/test/trim/clean_optimization.jl +++ b/test/trim/optimization_clean.jl @@ -1,3 +1,4 @@ +module TestModuleClean using NonlinearSolveFirstOrder using ADTypes: AutoForwardDiff using ForwardDiff @@ -23,10 +24,11 @@ struct MyParams{T, M} end function minimize(x) - autodiff = AutoForwardDiff(; chunksize=1) - alg = TrustRegion(; autodiff, linsolve=LS.CholeskyFactorization()) - ps = MyParams(rand(), hermitianpart(rand(2,2)+2I)) + autodiff = AutoForwardDiff(; chunksize = 1) + alg = TrustRegion(; autodiff, linsolve = LS.CholeskyFactorization()) + ps = MyParams(rand(), hermitianpart(rand(2, 2) + 2I)) prob = NonlinearLeastSquaresProblem{false}(f, rand(2), ps) sol = solve(prob, alg) return sol end +end diff --git a/test/trim/trimmable_optimization.jl b/test/trim/optimization_trimmable.jl similarity index 96% rename from test/trim/trimmable_optimization.jl rename to test/trim/optimization_trimmable.jl index 5a7b7641b..c651d7329 100644 --- a/test/trim/trimmable_optimization.jl +++ b/test/trim/optimization_trimmable.jl @@ -1,3 +1,4 @@ +module TestModuleTrimmable using NonlinearSolveFirstOrder using DiffEqBase using ADTypes: AutoForwardDiff @@ -35,3 +36,4 @@ function minimize(x) solve!(cache) return cache end +end diff --git a/test/trim/runtests.jl b/test/trim/runtests.jl index 2ef26457a..8146b2468 100644 --- a/test/trim/runtests.jl +++ b/test/trim/runtests.jl @@ -3,21 +3,21 @@ using SafeTestsets @safetestset "Clean implementation (non-trimmable)" begin using JET using SciMLBase: successful_retcode - include("clean_optimization.jl") - @test successful_retcode(minimize(1.0).retcode) - # can't use `@test_opt` macro here because it would eval before `using JET` - # is processed - test_opt(minimize, (typeof(1.0),)) + include("optimization_clean.jl") + @test successful_retcode(TestModuleClean.minimize(1.0).retcode) + # can't use `@test_opt` macro here because it would try to eval before + # `using JET` is processed + test_opt(TestModuleClean.minimize, (typeof(1.0),)) end @safetestset "Trimmable implementation" begin using JET using SciMLBase: successful_retcode - include("trimmable_optimization.jl") - @test successful_retcode(minimize(1.0).retcode) - # can't use `@test_opt` macro here because it would eval before `using JET` - # is processed - test_opt(minimize, (typeof(1.0),)) + include("optimization_trimmable.jl") + @test successful_retcode(TestModuleClean.minimize(1.0).retcode) + # can't use `@test_opt` macro here because it would try to eval before + # `using JET` is processed + test_opt(TestModuleTrimmable.minimize, (typeof(1.0),)) end @safetestset "Run trim" begin @@ -43,23 +43,27 @@ end ) ) @test isfile(JULIAC) - binpath = tempname() - cmd = `$(Base.julia_cmd()) --project=. --depwarn=error $(JULIAC) --experimental --trim=unsafe-warn --output-exe $(binpath) main.jl` - # since we are calling Julia from Julia, we first need to clean some - # environment variables - clean_env = copy(ENV) - delete!(clean_env, "JULIA_PROJECT") - delete!(clean_env, "JULIA_LOAD_PATH") - # We could just check for success, but then failures are hard to debug. - # Instead we use `_execute` to also capture `stdout` and `stderr`. - # @test success(setenv(cmd, clean_env)) - trimcall = _execute(setenv(cmd, clean_env; dir = @__DIR__)) - if trimcall.exitcode != 0 - @show trimcall.stdout - @show trimcall.stderr + for (mainfile, shouldpass) in [("main_trimmable.jl", true), + ("main_clean.jl", false)] + binpath = tempname() + cmd = `$(Base.julia_cmd()) --project=. --depwarn=error $(JULIAC) --experimental --trim=unsafe-warn --output-exe $(binpath) $(mainfile)` + + # since we are calling Julia from Julia, we first need to clean some + # environment variables + clean_env = copy(ENV) + delete!(clean_env, "JULIA_PROJECT") + delete!(clean_env, "JULIA_LOAD_PATH") + # We could just check for success, but then failures are hard to debug. + # Instead we use `_execute` to also capture `stdout` and `stderr`. + # @test success(setenv(cmd, clean_env)) + trimcall = _execute(setenv(cmd, clean_env; dir = @__DIR__)) + if trimcall.exitcode != 0 && shouldpass + @show trimcall.stdout + @show trimcall.stderr + end + @test trimcall.exitcode == 0 broken=!shouldpass + @test isfile(binpath) broken=!shouldpass + @test success(`$(binpath) 1.0`) broken=!shouldpass end - @test trimcall.exitcode == 0 - @test isfile(binpath) - @test success(`$(binpath) 1.0`) end diff --git a/test/trim/src/TrimTest.jl b/test/trim/src/TrimTest.jl index f1955c4c2..85d0f78fe 100644 --- a/test/trim/src/TrimTest.jl +++ b/test/trim/src/TrimTest.jl @@ -2,7 +2,7 @@ module TrimTest #= Currently, trimming only works if the target code is in a package. I.e., trying to trim ```julia -include("trimmable_optimization.jl") +include("optimization_trimmable.jl") function (@main)(argv::Vector{String})::Cint minimize(1.0) return 0 @@ -11,7 +11,7 @@ end or even ```julia mod MyMod - include("trimmable_optimization.jl") + include("optimization_trimmable.jl") end function (@main)(argv::Vector{String})::Cint MyMod.minimize(1.0) @@ -22,5 +22,6 @@ segfaults `juliac`. Looking at the segfault stacktrace it seems the culprit is `const cache = init(...)`. Either way, we circumvent the segfault by putting this below code into a package definition. =# -include("../trimmable_optimization.jl") +include("../optimization_trimmable.jl") +include("../optimization_clean.jl") end From ff3ef269b325b0872fede84ad16c0e463f044122 Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 19:24:29 -0700 Subject: [PATCH 15/19] fixup! Add test that `optimization_clean` doesn't trim, marked `broken` --- test/trim/runtests.jl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/trim/runtests.jl b/test/trim/runtests.jl index 8146b2468..79c3d3b7c 100644 --- a/test/trim/runtests.jl +++ b/test/trim/runtests.jl @@ -14,7 +14,7 @@ end using JET using SciMLBase: successful_retcode include("optimization_trimmable.jl") - @test successful_retcode(TestModuleClean.minimize(1.0).retcode) + @test successful_retcode(TestModuleTrimmable.minimize(1.0).retcode) # can't use `@test_opt` macro here because it would try to eval before # `using JET` is processed test_opt(TestModuleTrimmable.minimize, (typeof(1.0),)) @@ -44,8 +44,10 @@ end ) @test isfile(JULIAC) - for (mainfile, shouldpass) in [("main_trimmable.jl", true), - ("main_clean.jl", false)] + for (mainfile, expectedtopass) in [ + ("main_trimmable.jl", true), + ("main_clean.jl", false), + ] binpath = tempname() cmd = `$(Base.julia_cmd()) --project=. --depwarn=error $(JULIAC) --experimental --trim=unsafe-warn --output-exe $(binpath) $(mainfile)` @@ -58,12 +60,12 @@ end # Instead we use `_execute` to also capture `stdout` and `stderr`. # @test success(setenv(cmd, clean_env)) trimcall = _execute(setenv(cmd, clean_env; dir = @__DIR__)) - if trimcall.exitcode != 0 && shouldpass + if trimcall.exitcode != 0 && expectedtopass @show trimcall.stdout @show trimcall.stderr end - @test trimcall.exitcode == 0 broken=!shouldpass - @test isfile(binpath) broken=!shouldpass - @test success(`$(binpath) 1.0`) broken=!shouldpass + @test trimcall.exitcode == 0 broken = !expectedtopass + @test isfile(binpath) broken = !expectedtopass + @test success(`$(binpath) 1.0`) broken = !expectedtopass end end From 4bd419c8f10cf6f0333d3c741e12bd2e7aeac8b1 Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Fri, 1 Aug 2025 19:50:02 -0700 Subject: [PATCH 16/19] Unfortunately, broken test also hangs. So comment out. The rational in code comment. --- test/trim/runtests.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/trim/runtests.jl b/test/trim/runtests.jl index 79c3d3b7c..3810b2dd4 100644 --- a/test/trim/runtests.jl +++ b/test/trim/runtests.jl @@ -46,7 +46,11 @@ end for (mainfile, expectedtopass) in [ ("main_trimmable.jl", true), - ("main_clean.jl", false), + #= The test below should verify that we indeed can't get a trimmed binary + # for the "clean" implementation, but will trigger in the future if + # it does start working. Unfortunately, right now it hangs indefinitely + # so we are commenting it out. =# + # ("main_clean.jl", false), ] binpath = tempname() cmd = `$(Base.julia_cmd()) --project=. --depwarn=error $(JULIAC) --experimental --trim=unsafe-warn --output-exe $(binpath) $(mainfile)` From 3c332634bbac591aabadaedf2397b1d8f2304509 Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Sat, 2 Aug 2025 16:24:20 -0700 Subject: [PATCH 17/19] Appease JuliaFormatter --- test/trim/optimization_trimmable.jl | 6 +++++- test/trim/runtests.jl | 26 ++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/test/trim/optimization_trimmable.jl b/test/trim/optimization_trimmable.jl index c651d7329..e1ee111d7 100644 --- a/test/trim/optimization_trimmable.jl +++ b/test/trim/optimization_trimmable.jl @@ -27,7 +27,11 @@ end const autodiff = AutoForwardDiff(; chunksize = 1) const alg = TrustRegion(; autodiff, linsolve = LS.CholeskyFactorization()) -const prob = NonlinearLeastSquaresProblem{false}(f, rand(2), MyParams(rand(), hermitianpart(rand(2, 2) + 2I))) +const prob = NonlinearLeastSquaresProblem{false}( + f, + rand(2), + MyParams(rand(), hermitianpart(rand(2, 2) + 2I)) +) const cache = init(prob, alg) function minimize(x) diff --git a/test/trim/runtests.jl b/test/trim/runtests.jl index 3810b2dd4..a53aa77e0 100644 --- a/test/trim/runtests.jl +++ b/test/trim/runtests.jl @@ -22,7 +22,9 @@ end @safetestset "Run trim" begin # https://discourse.julialang.org/t/capture-stdout-and-stderr-in-case-a-command-fails/101772/3?u=romeov - "Run a Cmd object, returning the stdout & stderr contents plus the exit code" + """ + Run a Cmd object, returning the stdout & stderr contents plus the exit code + """ function _execute(cmd::Cmd) out = Pipe() err = Pipe() @@ -31,27 +33,27 @@ end close(err.in) out = ( stdout = String(read(out)), stderr = String(read(err)), - exitcode = process.exitcode, + exitcode = process.exitcode ) return out end JULIAC = normpath( joinpath( - Sys.BINDIR, Base.DATAROOTDIR, "julia", "juliac", - "juliac.jl" - ) + Sys.BINDIR, Base.DATAROOTDIR, "julia", "juliac", + "juliac.jl" + ) ) @test isfile(JULIAC) for (mainfile, expectedtopass) in [ - ("main_trimmable.jl", true), - #= The test below should verify that we indeed can't get a trimmed binary - # for the "clean" implementation, but will trigger in the future if - # it does start working. Unfortunately, right now it hangs indefinitely - # so we are commenting it out. =# - # ("main_clean.jl", false), - ] + ("main_trimmable.jl", true), + #= The test below should verify that we indeed can't get a trimmed binary + # for the "clean" implementation, but will trigger in the future if + # it does start working. Unfortunately, right now it hangs indefinitely + # so we are commenting it out. =# + # ("main_clean.jl", false), + ] binpath = tempname() cmd = `$(Base.julia_cmd()) --project=. --depwarn=error $(JULIAC) --experimental --trim=unsafe-warn --output-exe $(binpath) $(mainfile)` From ca0d0f2a8cf752a68c48ab88cf4c850bb1acbc49 Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Tue, 5 Aug 2025 13:17:59 -0700 Subject: [PATCH 18/19] Add segfault case [skip ci] --- test/trim/main_segfault.jl | 10 ++++++++++ test/trim/runtests.jl | 1 + 2 files changed, 11 insertions(+) create mode 100644 test/trim/main_segfault.jl diff --git a/test/trim/main_segfault.jl b/test/trim/main_segfault.jl new file mode 100644 index 000000000..91ef5ef47 --- /dev/null +++ b/test/trim/main_segfault.jl @@ -0,0 +1,10 @@ +module MyModule +include("./optimization_trimmable.jl") +end + +function (@main)(argv::Vector{String})::Cint + λ = parse(Float64, argv[2]) + sol = MyModule.TestModuleTrimmable.minimize(λ) + println(Core.stdout, sum(sol.u)) + return 0 +end diff --git a/test/trim/runtests.jl b/test/trim/runtests.jl index a53aa77e0..5af443581 100644 --- a/test/trim/runtests.jl +++ b/test/trim/runtests.jl @@ -53,6 +53,7 @@ end # it does start working. Unfortunately, right now it hangs indefinitely # so we are commenting it out. =# # ("main_clean.jl", false), + ("main_segfault.jl", false), ] binpath = tempname() cmd = `$(Base.julia_cmd()) --project=. --depwarn=error $(JULIAC) --experimental --trim=unsafe-warn --output-exe $(binpath) $(mainfile)` From 6eca9581849f825f4f8e58bb1c94c96a4b103100 Mon Sep 17 00:00:00 2001 From: Romeo Valentin Date: Thu, 7 Aug 2025 11:10:52 -0700 Subject: [PATCH 19/19] Bump CPUSummary, use upstream Polyester See https://github.com/SciML/NonlinearSolve.jl/pull/665#issuecomment-3165081370 --- test/trim/Project.toml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/trim/Project.toml b/test/trim/Project.toml index 88a8ac1b3..a30f60ae2 100644 --- a/test/trim/Project.toml +++ b/test/trim/Project.toml @@ -3,6 +3,7 @@ uuid = "7e54ada7-ece5-4046-aa01-512d530850d8" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" +CPUSummary = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" @@ -22,16 +23,13 @@ ForwardDiff = {url = "https://github.com/RomeoV/ForwardDiff.jl", rev="rv/remove- # Use of `deepcopy` is tracked at https://github.com/SciML/LinearSolve.jl/issues/648. LinearSolve = {url = "https://github.com/RomeoV/LinearSolve.jl", rev="rv/remove-linsolve-forwarddiff-special-path"} NonlinearSolveFirstOrder = {path = "../../lib/NonlinearSolveFirstOrder"} -# Remove use of CPUSummary which segfaults trimmed binary. Tracked at https://github.com/JuliaSIMD/Polyester.jl/pull/163. -Polyester = {url = "https://github.com/RomeoV/Polyester.jl", rev="master"} -# Remove use of CPUSummary which segfaults trimmed binary. Tracked at https://github.com/JuliaSIMD/PolyesterWeave.jl/pull/28 -PolyesterWeave = {url = "https://github.com/RomeoV/PolyesterWeave.jl", rev="main"} # Fix a type instability. Tracked at https://github.com/SciML/SciMLBase.jl/pull/1074. SciMLBase = {url = "https://github.com/AayushSabharwal/SciMLBase.jl", rev="as/fix-jet-opt"} [compat] ADTypes = "1.15.0" +CPUSummary = "0.2.7" DiffEqBase = "6.179.0" ForwardDiff = "1.0.1" LinearAlgebra = "1.12.0"