Skip to content

Commit 64e166f

Browse files
authored
1.10: Backport CI test time improvements (#744)
1 parent 60273e7 commit 64e166f

6 files changed

Lines changed: 87 additions & 48 deletions

File tree

.github/workflows/ci.yml

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,34 @@ jobs:
4646
- run: julia --color=yes .ci/test_and_change_uuid.jl
4747
- uses: julia-actions/julia-buildpkg@v1
4848
- uses: julia-actions/julia-runtest@v1
49-
env:
50-
SPARSEARRAYS_AQUA_TEST: true
5149
- uses: julia-actions/julia-processcoverage@v1
5250
- uses: codecov/codecov-action@v4
5351
with:
5452
file: lcov.info
5553
token: ${{ secrets.CODECOV_TOKEN }}
5654

55+
aqua-test:
56+
runs-on: ${{ matrix.os }}
57+
timeout-minutes: 60
58+
strategy:
59+
matrix:
60+
version:
61+
- '1.10'
62+
os:
63+
- ubuntu-latest
64+
arch:
65+
- x64
66+
steps:
67+
- uses: actions/checkout@v4
68+
- uses: julia-actions/setup-julia@v2
69+
with:
70+
version: ${{ matrix.version }}
71+
arch: ${{ matrix.arch }}
72+
- uses: julia-actions/cache@v2
73+
- run: julia --color=yes .ci/test_and_change_uuid.jl
74+
- name: Run Aqua and ambiguity tests
75+
run: |
76+
julia --color=yes -e 'using Pkg; Pkg.activate(temp=true); Pkg.develop(path=pwd()); Pkg.add(name="Aqua", version="0.8"); include(joinpath(pwd(), "test", "ambiguous.jl"))'
5777
docs:
5878
runs-on: ubuntu-latest
5979
steps:

Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Dates = "<0.0.1, 1"
1515
InteractiveUtils = "<0.0.1, 1"
1616
Libdl = "<0.0.1, 1"
1717
LinearAlgebra = "<0.0.1, 1"
18+
ParallelTestRunner = "2"
1819
Pkg = "<0.0.1, 1"
1920
Printf = "<0.0.1, 1"
2021
Random = "<0.0.1, 1"
@@ -27,9 +28,10 @@ julia = "1.10"
2728
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
2829
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
2930
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
31+
ParallelTestRunner = "d3525ed8-44d0-4b2c-a655-542cee43accc"
3032
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
3133
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
3234
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3335

3436
[targets]
35-
test = ["Aqua", "Dates", "InteractiveUtils", "Pkg", "Printf", "Test"]
37+
test = ["Aqua", "Dates", "InteractiveUtils", "ParallelTestRunner", "Pkg", "Printf", "Test"]

test/runtests.jl

Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,22 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
2-
using Test, LinearAlgebra, SparseArrays
32

4-
if Base.get_bool_env("SPARSEARRAYS_AQUA_TEST", false)
5-
include("ambiguous.jl")
6-
end
3+
using Test, LinearAlgebra, SparseArrays
74

8-
for file in readlines(joinpath(@__DIR__, "testgroups"))
9-
file == "" && continue # skip empty lines
10-
include(file * ".jl")
11-
end
5+
testfiles = [file * ".jl" for file in readlines(joinpath(@__DIR__, "testgroups")) if file != ""]
126

137
if Base.USE_GPL_LIBS
8+
push!(testfiles, "threads_suite.jl")
9+
end
1410

15-
nt = @static if isdefined(Threads, :maxthreadid)
16-
Threads.maxthreadid()
17-
else
18-
Threads.nthreads()
19-
end
20-
21-
# Test multithreaded execution
22-
@testset "threaded SuiteSparse tests" verbose = true begin
23-
@testset "threads = $nt" begin
24-
include("threads.jl")
25-
end
26-
# test both nthreads==1 and nthreads>1. spawn a process to test whichever
27-
# case we are not running currently.
28-
other_nthreads = nt == 1 ? 4 : 1
29-
@testset "threads = $other_nthreads" begin
30-
let p, cmd = `$(Base.julia_cmd()) --depwarn=error --startup-file=no threads.jl`
31-
p = run(
32-
pipeline(
33-
setenv(
34-
cmd,
35-
"JULIA_NUM_THREADS" => other_nthreads,
36-
dir=@__DIR__()),
37-
stdout = stdout,
38-
stderr = stderr),
39-
wait = false)
40-
if !success(p)
41-
error("SuiteSparse threads test failed with nthreads == $other_nthreads")
42-
else
43-
@test true # mimic the one @test in threads.jl
44-
end
45-
end
46-
end
47-
end
48-
11+
# ParallelTestRunner comes from the Pkg.test target; Julia base CI runs this
12+
# file without it and falls back to the serial path.
13+
if Base.find_package("ParallelTestRunner") !== nothing
14+
using ParallelTestRunner
15+
# Auto CPU thread count detection in ParallelTestRunner is bad
16+
push!(ARGS, "--jobs=$(Sys.CPU_THREADS)")
17+
testsuite = Dict{String,Expr}(splitext(f)[1] => :(include($(joinpath(@__DIR__, f))))
18+
for f in testfiles)
19+
runtests(SparseArrays, ARGS; testsuite)
20+
else
21+
foreach(include, testfiles)
4922
end

test/sparsematrix_constructors_indexing.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,9 @@ end
821821
times = Float64[0,0,0]
822822
best = [typemax(Float64), 0]
823823
for searchtype in [0, 1, 2]
824-
GC.gc()
824+
# stabilizes the debug timings below, but forces 180 full
825+
# collections across these loops which dominates the file's GC time
826+
# GC.gc()
825827
tres = @timed test_getindex_algs(S, I, J, searchtype)
826828
res[searchtype+1] = tres[1]
827829
times[searchtype+1] = tres[2]
@@ -877,9 +879,9 @@ end
877879
for I in IA
878880
Isorted = sort(I)
879881
for S in SA
880-
GC.gc()
882+
# GC.gc() # see comment above
881883
ru = @timed S[I, J]
882-
GC.gc()
884+
# GC.gc()
883885
rs = @timed S[Isorted, Jsorted]
884886
if debug
885887
@printf(" %7d | %7d | %7d | %4.2e | %4.2e | %4.2e | %4.2e |\n", round(Int,nnz(S)/size(S, 2)), length(I), length(J), rs[2], ru[2], rs[3], ru[3])

test/sparsevector.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,10 @@ end
12811281
floattypes = (Float32, Float64, BigFloat)
12821282
complextypes = (ComplexF32, ComplexF64)
12831283
eltypes = (inttypes..., floattypes..., complextypes...)
1284+
# The full eltype cross product compiles thousands of specializations
1285+
# (several CI minutes); do it only for the core types and pair the
1286+
# remaining eltypes with Float64.
1287+
coretypes = (Int64, Float64, ComplexF64)
12841288

12851289
for eltypemat in eltypes
12861290
(densemat, sparsemat) = eltypemat in inttypes ? (denseintmat, sparseintmat) :
@@ -1294,6 +1298,8 @@ end
12941298
LinearAlgebra.UnitLowerTriangular(sparsemat), LinearAlgebra.UnitUpperTriangular(sparsemat) )
12951299

12961300
for eltypevec in eltypes
1301+
(eltypemat in coretypes && eltypevec in coretypes) ||
1302+
eltypemat == Float64 || eltypevec == Float64 || continue
12971303
spvecs = eltypevec in inttypes ? sparseintvecs :
12981304
eltypevec in floattypes ? sparsefloatvecs :
12991305
eltypevec in complextypes && sparsecomplexvecs

test/threads_suite.jl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
using Test, SparseArrays
4+
5+
nt = @static if isdefined(Threads, :maxthreadid)
6+
Threads.maxthreadid()
7+
else
8+
Threads.nthreads()
9+
end
10+
11+
@testset "threaded SuiteSparse tests" verbose = true begin
12+
@testset "threads = $nt" begin
13+
include("threads.jl")
14+
end
15+
# test both nthreads==1 and nthreads>1. spawn a process to test whichever
16+
# case we are not running currently.
17+
other_nthreads = nt == 1 ? 4 : 1
18+
@testset "threads = $other_nthreads" begin
19+
let p, cmd = `$(Base.julia_cmd()) --depwarn=error --startup-file=no threads.jl`
20+
p = run(
21+
pipeline(
22+
setenv(
23+
cmd,
24+
"JULIA_NUM_THREADS" => other_nthreads,
25+
dir=@__DIR__()),
26+
stdout = stdout,
27+
stderr = stderr),
28+
wait = false)
29+
if !success(p)
30+
error("SuiteSparse threads test failed with nthreads == $other_nthreads")
31+
else
32+
@test true # mimic the one @test in threads.jl
33+
end
34+
end
35+
end
36+
end

0 commit comments

Comments
 (0)