diff --git a/Project.toml b/Project.toml index 39fa940d9..101fc76ea 100644 --- a/Project.toml +++ b/Project.toml @@ -71,7 +71,8 @@ julia = "1.6" [extras] SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [targets] -test = ["Test", "Unitful", "SpecialFunctions"] +test = ["Test", "Unitful", "SpecialFunctions", "TimerOutputs"] diff --git a/test/runtests.jl b/test/runtests.jl index 9a8669e6a..581fe9b33 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -9,33 +9,88 @@ using StaticArrays using StatsBase using Tables, TypedTables using Unitful +using TimerOutputs + @info "Running tests with $(Base.Threads.nthreads()) Julia threads active." T = Float32 device_array_type = (@isdefined CUDAKernels) ? CUDAKernels.CUDA.CuArray : Array -@testset "Comparison to analytic solutions" begin + +testtimer() = get_timer("_default_testtimer_") + +macro timed_testset(title, body) + quote + tmr = testtimer() + _title = $(esc(title)) + @timeit tmr "$_title" begin + @testset "$_title" begin + $(esc(body)) + end + end + end +end + + +function timed_calculate_electric_potential!(args...; kwargs...) + @timeit testtimer() "calculate_electric_potential!" begin + calculate_electric_potential!(args...; kwargs...) + end +end + +function timed_calculate_electric_field!(args...; kwargs...) + @timeit testtimer() "calculate_electric_field!" begin + calculate_electric_field!(args...; kwargs...) + end +end + +function timed_calculate_weighting_potential!(args...; kwargs...) + @timeit testtimer() "calculate_weighting_potential!" begin + calculate_weighting_potential!(args...; kwargs...) + end +end + +function timed_simulate_waveforms(args...; kwargs...) + @timeit testtimer() "simulate_waveforms" begin + simulate_waveforms(args...; kwargs...) + end +end + +function timed_simulate!(args...; kwargs...) + @timeit testtimer() "simulate!" begin + simulate!(args...; kwargs...) + end +end + +function timed_estimate_depletion_voltage(args...; kwargs...) + @timeit testtimer() "estimate_depletion_voltage" begin + estimate_depletion_voltage(args...; kwargs...) + end +end + + +@timed_testset "Comparison to analytic solutions" begin include("comparison_to_analytic_solutions.jl") end -@testset "SOR GPU Backend" begin +@timed_testset "SOR GPU Backend" begin include("SOR_GPU_Backend.jl") end -@testset "ConstructiveSolidGeometry" begin +@timed_testset "ConstructiveSolidGeometry" begin include("ConstructiveSolidGeometry/CSG_IO.jl") include("ConstructiveSolidGeometry/CSG_primitives.jl") end T = Float32 -@testset "Test real detectors" begin - @testset "Simulate example detector: Inverted Coax" begin +@timed_testset "Test real detectors" begin + @timed_testset "Simulate example detector: Inverted Coax" begin sim = Simulation{T}(SSD_examples[:InvertedCoax]) - simulate!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) + timed_simulate!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) evt = Event(CartesianPoint.([CylindricalPoint{T}(20e-3, deg2rad(10), 10e-3 )])) - simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) + timed_simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) signalsum = T(0) for i in 1:length(evt.waveforms) signalsum += abs(ustrip(evt.waveforms[i].signal[end])) @@ -45,23 +100,23 @@ T = Float32 @test isapprox( signalsum, T(2), atol = 5e-3 ) nt = NamedTuple(sim) @test sim == Simulation(nt) - deplV = estimate_depletion_voltage(sim, (verbose = false,)) + deplV = timed_estimate_depletion_voltage(sim, (verbose = false,)) @test isapprox(deplV, 1870*u"V", atol = 5.0*u"V") id = SolidStateDetectors.determine_bias_voltage_contact_id(sim.detector) # Check wether detector is undepleted, 10V below the previously calculated depletion voltage sim.detector = SolidStateDetector(sim.detector, contact_id = id, contact_potential = ustrip(deplV - deplV*0.005)) - calculate_electric_potential!(sim, depletion_handling = true) + timed_calculate_electric_potential!(sim, depletion_handling = true) @test !is_depleted(sim.point_types) # Check wether detector is depleted, 10V above the previously calculated depletion voltage sim.detector = SolidStateDetector(sim.detector, contact_id = id, contact_potential = ustrip(deplV + deplV*0.005)) - calculate_electric_potential!(sim, depletion_handling = true) + timed_calculate_electric_potential!(sim, depletion_handling = true) @test is_depleted(sim.point_types) end - @testset "Simulate example detector: Inverted Coax (in cryostat)" begin + @timed_testset "Simulate example detector: Inverted Coax (in cryostat)" begin sim = Simulation{T}(SSD_examples[:InvertedCoaxInCryostat]) - simulate!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) + timed_simulate!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) evt = Event(CartesianPoint.([CylindricalPoint{T}(20e-3, deg2rad(10), 10e-3 )])) - simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) + timed_simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) signalsum = T(0) for i in 1:length(evt.waveforms) signalsum += abs(ustrip(evt.waveforms[i].signal[end])) @@ -70,17 +125,17 @@ T = Float32 @info signalsum @test isapprox( signalsum, T(2), atol = 5e-3 ) end - # @testset "Simulate example detector: Coax" begin + # @timed_testset "Simulate example detector: Coax" begin # sim = Simulation{T}(SSD_examples[:Coax]) - # calculate_electric_potential!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) - # calculate_electric_field!(sim) - # calculate_weighting_potential!(sim, 1, convergence_limit = 1e-6, refinement_limits = [0.2, 0.1], verbose = false) - # calculate_weighting_potential!(sim, 2, convergence_limit = 1e-6, refinement_limits = [0.2, 0.1], verbose = false) + # timed_calculate_electric_potential!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) + # timed_calculate_electric_field!(sim) + # timed_calculate_weighting_potential!(sim, 1, convergence_limit = 1e-6, refinement_limits = [0.2, 0.1], verbose = false) + # timed_calculate_weighting_potential!(sim, 2, convergence_limit = 1e-6, refinement_limits = [0.2, 0.1], verbose = false) # for i in 3:19 - # calculate_weighting_potential!(sim, i, convergence_limit = 5e-6, refinement_limits = [0.2], verbose = false) + # timed_calculate_weighting_potential!(sim, i, convergence_limit = 5e-6, refinement_limits = [0.2], verbose = false) # end # evt = Event(CartesianPoint.([CylindricalPoint{T}(20e-3, deg2rad(30), 12e-3 )])) - # simulate!(evt, sim, Δt = 5e-10, max_nsteps = 10000) + # timed_simulate!(evt, sim, Δt = 5e-10, max_nsteps = 10000) # signalsum = T(0) # for i in 1:length(evt.waveforms) # signalsum += abs(ustrip(evt.waveforms[i].signal[end])) @@ -89,16 +144,16 @@ T = Float32 # @info signalsum # @test isapprox( signalsum, T(2), atol = 5e-3 ) # end - @testset "Simulate example detector: BEGe" begin + @timed_testset "Simulate example detector: BEGe" begin sim = Simulation{T}(SSD_examples[:BEGe]) - calculate_electric_potential!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) - calculate_electric_field!(sim) - calculate_weighting_potential!(sim, 1, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) + timed_calculate_electric_potential!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) + timed_calculate_electric_field!(sim) + timed_calculate_weighting_potential!(sim, 1, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) for i in 2:5 - calculate_weighting_potential!(sim, i, convergence_limit = 5e-6, device_array_type = device_array_type, refinement_limits = [0.2], verbose = false) + timed_calculate_weighting_potential!(sim, i, convergence_limit = 5e-6, device_array_type = device_array_type, refinement_limits = [0.2], verbose = false) end evt = Event(CartesianPoint.([CylindricalPoint{T}(20e-3, deg2rad(10), 20e-3 )])) - simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) + timed_simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) signalsum = T(0) for i in 1:length(evt.waveforms) signalsum += abs(ustrip(evt.waveforms[i].signal[end])) @@ -109,8 +164,8 @@ T = Float32 nt = NamedTuple(sim) @test sim == Simulation(nt) # test handling at r = 0 (see PR #322) - calculate_weighting_potential!(sim, 4, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1, 0.05], verbose = false) - let wp = sim.weighting_potentials[4] + timed_calculate_weighting_potential!(sim, 4, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1, 0.05], verbose = false) + @timed_testset "monotonous decrease of WP" let wp = sim.weighting_potentials[4] φidx1 = SolidStateDetectors.searchsortednearest(wp.grid.φ, T(deg2rad(30))) φidx2 = SolidStateDetectors.searchsortednearest(wp.grid.φ, T(deg2rad(210))) rmin = SolidStateDetectors.searchsortednearest(wp.grid.r, T(0.01)) @@ -119,13 +174,13 @@ T = Float32 l = vcat(wp.data[rmin:-1:2,φidx2,zidx], wp.data[1:rmax,φidx1,zidx]) @test all(diff(l) .< 0) # the weighting potential should monotonously decrease from rmin to rmax end - @test isapprox(estimate_depletion_voltage(sim, (verbose = false,)), 0u"V", atol = 0.2u"V") # This detector has no impurity profile + @test isapprox(timed_estimate_depletion_voltage(sim, (verbose = false,)), 0u"V", atol = 0.2u"V") # This detector has no impurity profile end - @testset "Simulate example detector: HexagonalPrism" begin + @timed_testset "Simulate example detector: HexagonalPrism" begin sim = Simulation{T}(SSD_examples[:Hexagon]) - simulate!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) + timed_simulate!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) evt = Event([CartesianPoint{T}(0, 5e-4, 1e-3)]) - simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) + timed_simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) signalsum = T(0) for i in 1:length(evt.waveforms) signalsum += abs(ustrip(evt.waveforms[i].signal[end])) @@ -133,13 +188,13 @@ T = Float32 signalsum *= inv(ustrip(SolidStateDetectors._convert_internal_energy_to_external_charge(sim.detector.semiconductor.material))) @info signalsum @test isapprox( signalsum, T(2), atol = 5e-3 ) - @test isapprox(estimate_depletion_voltage(sim, (verbose = false,)), T(-13.15)*u"V", atol = 1.0u"V") + @test isapprox(timed_estimate_depletion_voltage(sim, (verbose = false,)), T(-13.15)*u"V", atol = 1.0u"V") end - @testset "Simulate example detector: CGD" begin + @timed_testset "Simulate example detector: CGD" begin sim = Simulation{T}(SSD_examples[:CGD]) - simulate!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) + timed_simulate!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) evt = Event([CartesianPoint{T}(0,2e-3,0)]) - simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) + timed_simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) signalsum = T(0) for i in 1:length(evt.waveforms) signalsum += abs(ustrip(evt.waveforms[i].signal[end])) @@ -150,11 +205,11 @@ T = Float32 nt = NamedTuple(sim) @test sim == Simulation(nt) end - @testset "Simulate example detector: Spherical" begin + @timed_testset "Simulate example detector: Spherical" begin sim = Simulation{T}(SSD_examples[:Spherical]) - simulate!(sim, convergence_limit = 1e-5, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) + timed_simulate!(sim, convergence_limit = 1e-5, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) evt = Event([CartesianPoint{T}(0,0,0)]) - simulate!(evt, sim) + timed_simulate!(evt, sim) signalsum = T(0) for i in 1:length(evt.waveforms) signalsum += abs(ustrip(evt.waveforms[i].signal[end])) @@ -163,13 +218,13 @@ T = Float32 @info signalsum @test isapprox( signalsum, T(2), atol = 5e-3 ) end - @testset "Simulate example detector: Toroidal" begin + @timed_testset "Simulate example detector: Toroidal" begin sim = Simulation{T}(SSD_examples[:CoaxialTorus]) SolidStateDetectors.apply_initial_state!(sim, ElectricPotential) - simulate!(sim, convergence_limit = 1e-5, device_array_type = device_array_type, refinement_limits = [0.2, 0.1, 0.05, 0.02, 0.01], + timed_simulate!(sim, convergence_limit = 1e-5, device_array_type = device_array_type, refinement_limits = [0.2, 0.1, 0.05, 0.02, 0.01], max_tick_distance = 0.5u"mm", verbose = false) evt = Event([CartesianPoint{T}(0.0075,0,0)]) - simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) + timed_simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) signalsum = T(0) for i in 1:length(evt.waveforms) signalsum += abs(ustrip(evt.waveforms[i].signal[end])) @@ -178,12 +233,12 @@ T = Float32 @info signalsum @test isapprox( signalsum, T(2), atol = 5e-3 ) end - @testset "Simulate example detector: Coaxial for partial phi range" begin + @timed_testset "Simulate example detector: Coaxial for partial phi range" begin sim = Simulation{T}(SSD_examples[:Cone2D]) - calculate_electric_potential!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = missing, verbose = false) + timed_calculate_electric_potential!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = missing, verbose = false) sim_alt = Simulation{T}(SSD_examples[:Cone2D]) - calculate_electric_potential!(sim_alt, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = missing, verbose = false) + timed_calculate_electric_potential!(sim_alt, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = missing, verbose = false) # Test equal initial grid spacing in r and z, no matter the phi range @test sim.electric_potential.grid.r == sim_alt.electric_potential.grid.r @@ -192,11 +247,11 @@ T = Float32 idx = findall(pt -> SolidStateDetectors.is_pn_junction_point_type(pt), sim.point_types.data) @test maximum(abs.(sim_alt.electric_potential.data[idx] .- sim.electric_potential.data[idx])) .< T(0.2) end - @testset "Simulate example detector: SigGen PPC" begin + @timed_testset "Simulate example detector: SigGen PPC" begin sim = Simulation{T}(SSD_examples[:SigGen]) - simulate!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) + timed_simulate!(sim, convergence_limit = 1e-6, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) evt = Event(CartesianPoint.([CylindricalPoint{T}(20e-3, deg2rad(10), 10e-3 )])) - simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) + timed_simulate!(evt, sim, Δt = 1e-9, max_nsteps = 10000) signalsum = T(0) for i in 1:length(evt.waveforms) signalsum += abs(ustrip(evt.waveforms[i].signal[end])) @@ -207,15 +262,15 @@ T = Float32 end end -@testset "Diffusion and Self-Repulsion" begin +@timed_testset "Diffusion and Self-Repulsion" begin sim = Simulation{T}(SSD_examples[:InvertedCoax]) - simulate!(sim, convergence_limit = 1e-5, device_array_type = device_array_type, refinement_limits = [0.2, 0.1, 0.05], verbose = false) + timed_simulate!(sim, convergence_limit = 1e-5, device_array_type = device_array_type, refinement_limits = [0.2, 0.1, 0.05], verbose = false) pos = CartesianPoint{T}(0.02,0,0.05); Edep = 1u"eV" nbcc = NBodyChargeCloud(pos, Edep, 40, radius = T(0.0005), number_of_shells = 2) evt = Event(nbcc) - simulate!(evt, sim, self_repulsion = true, diffusion = true) + timed_simulate!(evt, sim, self_repulsion = true, diffusion = true) signalsum = T(0) for i in 1:length(evt.waveforms) signalsum += abs(ustrip(evt.waveforms[i].signal[end])) @@ -225,9 +280,9 @@ end @test isapprox( signalsum, T(2), atol = 5e-3 ) end -@testset "Table Simulation" begin +@timed_testset "Table Simulation" begin sim = Simulation{T}(SSD_examples[:InvertedCoax]) - simulate!(sim, convergence_limit = 1e-5, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) + timed_simulate!(sim, convergence_limit = 1e-5, device_array_type = device_array_type, refinement_limits = [0.2, 0.1], verbose = false) evt_table = Table( evtno = Int32[1], @@ -236,7 +291,7 @@ end edep = [T[1] * u"eV"], pos = [[SVector{3, T}.(0.01, 0.01, 0.01) * u"m"]] ) - contact_charge_signals = simulate_waveforms( + contact_charge_signals = timed_simulate_waveforms( evt_table, sim, max_nsteps = 4000, @@ -252,12 +307,12 @@ end @test isapprox( signalsum, T(2), atol = 5e-3 ) end -@testset "Isochrone" begin +@timed_testset "Isochrone" begin T = Float64 # to prevent rounding errors that might cause the final test to fail sim = Simulation{T}(SSD_examples[:IsochroneTest]) - simulate!(sim, device_array_type = device_array_type) - calculate_electric_potential!(sim, device_array_type = device_array_type, refinement_limits = [0.2, 0.1, 0.05, 0.01]) - calculate_electric_field!(sim, n_points_in_φ = 72) + timed_simulate!(sim, device_array_type = device_array_type) + timed_calculate_electric_potential!(sim, device_array_type = device_array_type, refinement_limits = [0.2, 0.1, 0.05, 0.01]) + timed_calculate_electric_field!(sim, n_points_in_φ = 72) sim.detector = SolidStateDetector(sim.detector, ADLChargeDriftModel{T}()); spawn_positions = CartesianPoint{T}[] @@ -298,28 +353,28 @@ end @test all(broadcast(dp -> dp.e_path[end] in sim.detector.contacts[2], ev.drift_paths)) end -@testset "ADLChargeDriftModel" begin +@timed_testset "ADLChargeDriftModel" begin include("ADLChargeDriftModel.jl") end -@testset "IO" begin +@timed_testset "IO" begin sim = Simulation(SSD_examples[:InvertedCoax]) - calculate_electric_potential!(sim, verbose = false, device_array_type = device_array_type) + timed_calculate_electric_potential!(sim, verbose = false, device_array_type = device_array_type) nt = NamedTuple(sim) @test sim == Simulation(nt) - calculate_electric_field!(sim) + timed_calculate_electric_field!(sim) nt = NamedTuple(sim) @test sim == Simulation(nt) - calculate_weighting_potential!(sim, 1, verbose = false, device_array_type = device_array_type) + timed_calculate_weighting_potential!(sim, 1, verbose = false, device_array_type = device_array_type) nt = NamedTuple(sim) @test sim == Simulation(nt) - for i in findall(ismissing.(sim.weighting_potentials)) calculate_weighting_potential!(sim, i, verbose = false, device_array_type = device_array_type) end + for i in findall(ismissing.(sim.weighting_potentials)) timed_calculate_weighting_potential!(sim, i, verbose = false, device_array_type = device_array_type) end nt = NamedTuple(sim) @test sim == Simulation(nt) end - +display(testtimer())