From 881530dba2cc1062c6aa2ca69d34b064245d1ca6 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Thu, 25 Jun 2026 07:52:35 -0400 Subject: [PATCH] QA: run_qa v1.6 form + ExplicitImports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the hand-rolled test/qa/qa.jl (raw Aqua.test_* + per-function JET.report_call) to the SciMLTesting 1.6 `run_qa` form and enable the ExplicitImports checks. ExplicitImports findings (run vs released SciMLTesting 1.6.0): * no_stale_explicit_imports: removed the genuinely stale `ArrayInterface.allowed_getindex` import (never referenced; only `ismutable`/`allowed_setindex!` are used). * Made the `for i in 1:13 include("exp_generated/exp_$i.jl")` dynamic include in exp_noalloc.jl static (13 literal includes) so the module is analyzable — this unblocked no_implicit_imports and no_stale_explicit_imports (previously UnanalyzableModuleException). Verified Higham2005 matrix-exp still matches Base `exp` to ~6.7e-16. * all_qualified_accesses_via_owners / all_qualified_accesses_are_public / all_explicit_imports_are_public: ignore-listed other packages' non-public names (Base / LinearAlgebra(.BLAS/.LAPACK, incl. Stegr submodule) / ArrayInterface / libblastrampoline_jll); they go public as the base libs declare them. * no_implicit_imports: ~31 implicit names from `using LinearAlgebra, SparseArrays, Printf, PrecompileTools`. Making them explicit is a large refactor; marked ei_broken and tracked in #231 (auto-flags when fixed). Deps: test/qa/Project.toml SciMLTesting compat -> "1.6" (Aqua + ExplicitImports are transitive via SciMLTesting; Aqua kept a direct dep so the ambiguities sub-check's child process can resolve it; JET kept for the JET check). Root Project.toml SciMLTesting compat -> "1.6". QA group on Julia 1.10 (lts), released SciMLTesting 1.6.0: Quality Assurance | 17 Pass, 1 Broken, 0 Fail, 0 Error (no_implicit_imports broken per #231). On Julia 1.12 the JET typo check reports pre-existing "may be undefined" findings (kiops order/kest, Higham2005 ilo/ihi/scale/bal); master is already red there and the source fixes live in draft PR #229. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 2 +- src/ExponentialUtilities.jl | 2 +- src/exp_noalloc.jl | 16 +++++-- test/qa/Project.toml | 8 ++-- test/qa/qa.jl | 86 +++++++++++++++---------------------- 5 files changed, 53 insertions(+), 61 deletions(-) diff --git a/Project.toml b/Project.toml index 6cb2ce79..a1769161 100644 --- a/Project.toml +++ b/Project.toml @@ -33,7 +33,7 @@ PrecompileTools = "1" Printf = "1.10" Random = "1" SafeTestsets = "0.1, 1" -SciMLTesting = "1" +SciMLTesting = "1.6" SparseArrays = "1.10" StaticArrays = "1.9.8" Test = "1" diff --git a/src/ExponentialUtilities.jl b/src/ExponentialUtilities.jl index 9e89db38..dcfa0068 100644 --- a/src/ExponentialUtilities.jl +++ b/src/ExponentialUtilities.jl @@ -1,6 +1,6 @@ module ExponentialUtilities using LinearAlgebra, SparseArrays, Printf -using ArrayInterface: ismutable, allowed_getindex, allowed_setindex! +using ArrayInterface: ismutable, allowed_setindex! using PrecompileTools import GenericSchur import GPUArraysCore diff --git a/src/exp_noalloc.jl b/src/exp_noalloc.jl index d93d6304..7fd1cc92 100644 --- a/src/exp_noalloc.jl +++ b/src/exp_noalloc.jl @@ -18,9 +18,19 @@ function alloc_mem(A, ::ExpMethodHigham2005) end # Import the generated code -for i in 1:13 - include("exp_generated/exp_$i.jl") -end +include("exp_generated/exp_1.jl") +include("exp_generated/exp_2.jl") +include("exp_generated/exp_3.jl") +include("exp_generated/exp_4.jl") +include("exp_generated/exp_5.jl") +include("exp_generated/exp_6.jl") +include("exp_generated/exp_7.jl") +include("exp_generated/exp_8.jl") +include("exp_generated/exp_9.jl") +include("exp_generated/exp_10.jl") +include("exp_generated/exp_11.jl") +include("exp_generated/exp_12.jl") +include("exp_generated/exp_13.jl") function getmem(cache, k) # Called from generated code return cache[k - 1] diff --git a/test/qa/Project.toml b/test/qa/Project.toml index 1eb4dc29..2b51c79f 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -6,13 +6,13 @@ SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -[sources] -ExponentialUtilities = {path = "../.."} - [compat] Aqua = "0.8" JET = "0.9, 0.10, 0.11" SafeTestsets = "0.1, 1" -SciMLTesting = "1" +SciMLTesting = "1.6" Test = "1" julia = "1.10" + +[sources] +ExponentialUtilities = {path = "../.."} diff --git a/test/qa/qa.jl b/test/qa/qa.jl index dcc58f5c..9679ba6d 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -1,52 +1,34 @@ -using ExponentialUtilities, Aqua, JET, Test - -@testset "Aqua" begin - Aqua.find_persistent_tasks_deps(ExponentialUtilities) - Aqua.test_ambiguities(ExponentialUtilities, recursive = false) - Aqua.test_deps_compat( - ExponentialUtilities, - ignore = [:libblastrampoline_jll] - ) - Aqua.test_piracies(ExponentialUtilities) - Aqua.test_project_extras(ExponentialUtilities) - Aqua.test_stale_deps(ExponentialUtilities) - Aqua.test_unbound_args(ExponentialUtilities) - Aqua.test_undefined_exports(ExponentialUtilities) -end - -@testset "JET static analysis" begin - @testset "expv" begin - rep = JET.report_call(expv, (Float64, Matrix{Float64}, Vector{Float64})) - @test length(JET.get_reports(rep)) == 0 - end - - @testset "arnoldi" begin - rep = JET.report_call(arnoldi, (Matrix{Float64}, Vector{Float64})) - @test length(JET.get_reports(rep)) == 0 - end - - @testset "phi" begin - rep = JET.report_call(phi, (Matrix{Float64}, Int)) - @test length(JET.get_reports(rep)) == 0 - end - - @testset "exponential!" begin - rep = JET.report_call(ExponentialUtilities.exponential!, (Matrix{Float64},)) - @test length(JET.get_reports(rep)) == 0 - end - - @testset "phiv" begin - rep = JET.report_call(phiv, (Float64, Matrix{Float64}, Vector{Float64}, Int)) - @test length(JET.get_reports(rep)) == 0 - end - - @testset "kiops" begin - rep = JET.report_call(kiops, (Float64, Matrix{Float64}, Vector{Float64})) - @test length(JET.get_reports(rep)) == 0 - end - - @testset "expv_timestep" begin - rep = JET.report_call(expv_timestep, (Float64, Matrix{Float64}, Vector{Float64})) - @test length(JET.get_reports(rep)) == 0 - end -end +using SciMLTesting, ExponentialUtilities, JET, Test + +run_qa( + ExponentialUtilities; + explicit_imports = true, + aqua_kwargs = (; deps_compat = (; ignore = [:libblastrampoline_jll])), + ei_kwargs = (; + # Names owned elsewhere but reached through LinearAlgebra.BLAS. + all_qualified_accesses_via_owners = (; + ignore = (:BlasFloat, :chkstride1, :libblastrampoline), + ), + # Non-public names of Base / LinearAlgebra(.BLAS/.LAPACK) accessed qualified. + all_qualified_accesses_are_public = (; + ignore = ( + Symbol("@aliasscope"), Symbol("@assume_effects"), + Symbol("@blasfunc"), Symbol("@propagate_inbounds"), + :BlasFloat, :Cartesian, :Const, :Experimental, + :checksquare, :chkfinite, :chklapackerror, :chkstride1, + :gebal!, :gesv!, :libblastrampoline, :rcswap!, :stegr!, + ), + ), + # Non-public names explicitly imported from LinearAlgebra(.BLAS/.LAPACK, + # incl. the Stegr submodule) / ArrayInterface / Base. + all_explicit_imports_are_public = (; + ignore = ( + :BlasInt, :checksquare, :allowed_setindex!, :ismutable, :typename, + Symbol("@blasfunc"), :stegr!, + ), + ), + ), + # Heavy `using LinearAlgebra, SparseArrays, Printf, PrecompileTools` brings ~31 + # names implicitly; making them explicit is a large refactor tracked separately. + ei_broken = (:no_implicit_imports,) +) # SciML/ExponentialUtilities.jl#231