Skip to content

Commit

Permalink
Fixups for 32-bit (#143)
Browse files Browse the repository at this point in the history
- Allow calibration to request a number of evals up to and exceeding typemax(Int)
- round down to typemax(Int) instead of erroring 
- Add tests for long runtime

Note that CI does not currently run on 32-bit
  • Loading branch information
LilithHafner authored Nov 25, 2024
1 parent 9d369ca commit ec00541
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
7 changes: 4 additions & 3 deletions src/benchmarking.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ maybecall(::Nothing, x::Tuple{}) = x
maybecall(f, x::Tuple{Any}) = (f(only(x)),)
maybecall(f::Function, ::Tuple{}) = (f(),)
maybecall(x, ::Tuple{}) = (x,)
floor_to_Int(x::Float64) = x >= Float64(typemax(Int)) ? typemax(Int) : floor(Int, x)
function benchmark(init, setup, fs::Tuple{Vararg{Any, N}}, teardown;
evals::Union{Int, Nothing}=nothing,
samples::Union{Int, Nothing}=nothing,
Expand Down Expand Up @@ -67,12 +68,12 @@ function _benchmark_1(init, setup, teardown, evals::Union{Int, Nothing}, samples
if calibration1time < .00015seconds # This branch protects us against cases where runtime is dominated by the reduction.
calibration2, time = _benchmark_2(args1, setup, teardown, gc, 10, true, fs...)
calibration2time = sum(s.time for s in calibration2)
trials = floor(Int, .05seconds/(calibration2time+1e-9))
trials = floor_to_Int(.05seconds/(calibration2time+1e-9))
if trials > 20
calibration2, time = _benchmark_2(args1, setup, teardown, gc, trials, true, fs...)
end
elseif calibration1time < .01seconds
calibration2, time = _benchmark_2(args1, setup, teardown, gc, floor(Int, .05seconds/(calibration1time+1e-9)), true, fs...)
calibration2, time = _benchmark_2(args1, setup, teardown, gc, floor_to_Int(.05seconds/(calibration1time+1e-9)), true, fs...)
end
if calibration2 !== nothing
calibration2time = sum(s.time for s in calibration2)
Expand All @@ -90,7 +91,7 @@ function _benchmark_1(init, setup, teardown, evals::Union{Int, Nothing}, samples
# exp(evalpoly(log(seconds), (-log(30e-9)^2/4log(1000),1+(2log(30e-9)/4log(1000)),-1/4log(1000))))
end

max(1, floor(Int, target_sample_time/(something(calibration2time, calibration1time)+1e-9)))
max(1, floor_to_Int(target_sample_time/(something(calibration2time, calibration1time)+1e-9)))
else
evals
end
Expand Down
28 changes: 27 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,12 @@ using Random: rand!
@testset "errors" begin
@test_throws UndefKeywordError Sample(allocs=1.5, bytes=1729) # needs `time`

@test_throws Union{ArgumentError, ErrorException} @b 1+1 evals=1 samples=typemax(Int) # too many samples to fit in an array

# 104
@test_throws ArgumentError("samples must be specified if seconds is infinite or nearly infinite (more than 292 years)") @b 1+1 seconds=Inf
@test_throws ArgumentError("samples must be specified if seconds is infinite or nearly infinite (more than 292 years)") @b 1+1 seconds=1e30
@test_throws ArgumentError("samples must be specified if seconds is infinite or nearly infinite (more than 292 years)") @b 1+1 seconds=293*365*24*60*60
@test_throws ArgumentError("samples must be specified if seconds is infinite or nearly infinite (more than 292 years)") @b 1+1 seconds=Int64(293)*365*24*60*60
@test_throws ArgumentError("Must specify either samples or seconds") @b 1+1 seconds=nothing
@test Chairmarks.only((@be 1+1 evals=1 samples=1 seconds=Inf).samples).evals == 1
@test Chairmarks.only((@be 1+1 evals=1 samples=1 seconds=1e30).samples).evals == 1
Expand Down Expand Up @@ -153,6 +155,30 @@ using Random: rand!
@test Chairmarks.writefixed(-0.005, 4) == "-0.0050"
end

@testset "floor_to_Int" begin
@test Chairmarks.floor_to_Int(17.29) === 17
@test Chairmarks.floor_to_Int(typemax(Int) + 0.5) === typemax(Int)
@test Chairmarks.floor_to_Int(typemax(Int) + 1.5) === typemax(Int)
@test Chairmarks.floor_to_Int(typemax(Int) + 17.29) === typemax(Int)
@test Chairmarks.floor_to_Int(Inf) === typemax(Int)
@test Chairmarks.floor_to_Int(Float64(typemax(Int))) === typemax(Int)
@test Chairmarks.floor_to_Int(prevfloat(Float64(typemax(Int)))) < typemax(Int)
@test Chairmarks.floor_to_Int(nextfloat(Float64(typemax(Int)))) === typemax(Int)
end

@testset "Long runtime budget doesn't throw right away" begin
# This test failed on 32 bit systems before the introduction of the floor_to_Int function
let counter = Ref{Int64}(0)
function f()
if counter[] == 1_000_000
error("Out of fuel")
end
counter[] += 1
end
@test_throws ErrorException("Out of fuel") @b f seconds=10_000
end
end

@testset "DEFAULTS" begin
@test Chairmarks.DEFAULTS.seconds === 0.1
@test Chairmarks.DEFAULTS.gc === true
Expand Down

0 comments on commit ec00541

Please sign in to comment.