Skip to content

Commit

Permalink
Merge pull request #18 from milankl/drwatson32,16-and-sherlog16
Browse files Browse the repository at this point in the history
logbook interface, min max
  • Loading branch information
milankl committed Jul 19, 2021
2 parents a6211f1 + 2e169c1 commit 30645f0
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 211 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Sherlogs"
uuid = "d4954a42-a18b-4f81-bb79-24f1192c93d8"
authors = ["Milan Kloewer"]
version = "0.1.1"
version = "0.2.0"

[deps]
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
Expand Down
3 changes: 2 additions & 1 deletion src/Sherlog16.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
struct Sherlog16{T<:AbstractFloat,i} <: AbstractSherlog # T is the bitpattern type for logging, i is the logbook #
# T is the bitpattern type for logging, i is the logbook number
struct Sherlog16{T<:AbstractFloat,i} <: AbstractSherlog
val::T
end

Expand Down
4 changes: 2 additions & 2 deletions src/Sherlog64.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
abstract type AbstractSherlog <: AbstractFloat end

struct Sherlog64{T<:AbstractFloat,i} <: AbstractSherlog # T is the bitpattern type for logging
val::Float64 # the value is always Float64
struct Sherlog64{T<:AbstractFloat,i} <: AbstractSherlog # T is the bitpattern type for logging, i the logbook id
val::Float64 # the value is always Float64
end

# conversions back from Sherlog64
Expand Down
46 changes: 34 additions & 12 deletions src/logbook.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
struct LogBook
struct LogBook{T<:AbstractFloat} # provide the number format as T
logbook::Array{UInt64,1}
end

# in case no type T is provided use Float16
LogBook(lb::Array{UInt64,1}) = LogBook{Float16}(lb)

const n16 = 2^16
const nlogbooks = 32
const logbooks = [LogBook(zeros(UInt64,n16)) for _ in 1:nlogbooks]
Expand All @@ -19,7 +22,8 @@ end
"""Change the type T of logbook #id. Must be a 16bit type."""
function set_logbook(T::DataType,id::Int=1)
if sizeof(T) == 2 # must be a 16bit type
logbook_types[id] = T
# copy over the logbook but change type to T
logbooks[id] = LogBook{T}(logbooks[id].logbook)
else
error("$(sizeof(T)*8)bit type $T was provided but must be a 16bit type.")
end
Expand All @@ -41,32 +45,50 @@ Base.sum(lb::LogBook)::Int64 = sum(lb.logbook)
entropy(lb::LogBook,b::Real) = entropy(lb.logbook/sum(lb),b)
entropy(lb::LogBook) = entropy(lb.logbook/sum(lb))
Base.length(lb::LogBook) = length(lb.logbook)
Base.getindex(lb::LogBook,i) = Int(getindex(lb.logbook,i))
Base.getindex(lb::LogBook,i::Integer) = Int(getindex(lb.logbook,i))
Base.getindex(lb::LogBook,u::UnitRange) = Int.(getindex(lb.logbook,u))
Base.getindex(lb::LogBook,s::StepRange) = Int.(getindex(lb.logbook,s))
Base.lastindex(lb::LogBook) = Int(lb.logbook[end])

function Base.show(io::IO,lb::LogBook)
function Base.show(io::IO,lb::LogBook{T}) where T
n = length(lb)
if n > 10
print(io,"$n-element LogBook(")
print(io,"$n-element LogBook{$T}(")
[print(io,string(Int(i)),", ") for i in lb.logbook[1:5]]
print(io,"… , ")
[print(io,string(Int(i)),", ") for i in lb.logbook[end-5:end-1]]
print(io,string(Int(lb.logbook[end])),")")
else
print(io,"$n-element LogBook(")
print(io,"$n-element LogBook{$T}(")
[print(io,string(Int(i)),", ") for i in lb.logbook[1:end-1]]
print(io,string(Int(lb.logbook[end])),")")
end
end

function Base.maximum(lb::LogBook,T::DataType)
"""Find the largest number that was logged into the logbook `lb`."""
function Base.maximum(lb::LogBook{T}) where T
n_half = length(lb)÷2
i = n_half - findfirst(x->x>0,lb.logbook[n_half:-1:1]) + 1
return reinterpret(Float16,UInt16(i))
i = n_half - findfirst(x->x>0,lb[n_half:-1:1])
return reinterpret(T,UInt16(i))
end

function Base.minimum(lb::LogBook,T::DataType)
"""Find the smallest number that was logged into the logbook `lb`."""
function Base.minimum(lb::LogBook{T}) where T
n = length(lb)
i = n - findfirst(x->x>0,lb.logbook[n:-1:1]) + 1
return reinterpret(Float16,UInt16(i))
i = n - findfirst(x->x>0,lb[n:-1:1])
return reinterpret(T,UInt16(i))
end

"""Sort a logbook as [-NaNs,-∞,...,-0,0,...,∞,NaNs]"""
function Base.sort(lb::LogBook)
@views positives = lb.logbook[1:2^15]
@views negatives = lb.logbook[2^15+1:end]
lb_sorted = vcat(reverse(negatives),positives)
return LogBook(lb_sorted)
end

"""Convert a Float16/BFloat16 value to the corresponding UInt16 in a sorted logbook"""
function uint16_sort(x::AbstractFloat)
ui = reinterpret(UInt16,x) # will trigger an error for non-16bit floats
return signbit(x) ? 0x8000 - (ui - 0x7fff) : ui + 0x8000
end
7 changes: 4 additions & 3 deletions src/stacktraces.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function scent(f,r::Real)
function scent(f::Function,r::Real)
if f(r)
i = st_index[1]
if i <= nstackframes
Expand All @@ -13,14 +13,15 @@ function scent(f,r::Real)
end
end

const empty_sym = Symbol("")
const unknown_st = Base.StackTraces.StackFrame(empty_sym,empty_sym,-1,nothing,true,false,0)
empty_symbol = Symbol("")
const unknown_st = Base.StackTraces.StackFrame(empty_symbol,empty_symbol,-1,nothing,true,false,0)

const nstackframes = 10000 # quite arbitrary for the moment
const stackframe_depth = 3

const ST = [unknown_st for _ in 1:stackframe_depth, _ in 1:nstackframes]
const st_index = [1]

get_stacktrace(i::Int=1) = ST[:,i]
get_stacktraces() = ST[:,1:st_index[1]-1]
get_st_index() = st_index[1]
87 changes: 87 additions & 0 deletions test/logbook.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
@testset "Logbook count 64" begin

n = 100

# A SINGLE ENTRY IN THE LOGBOOK
reset_logbook()
Sherlog64(0)+Sherlog64(0)
lb = get_logbook()
@test 1 == sum(lb)

# N ENTRIES IN THE LOGBOOK
reset_logbook()
a = Sherlog64(1.0)
for i in 1:n
a + randn(Float64) # promotion included
end
lb = get_logbook()
@test n == sum(lb)
end

@testset "Logbook count 32" begin

n = 100

# A SINGLE ENTRY IN THE LOGBOOK
reset_logbook()
Sherlog32(0)+Sherlog32(0)
lb = get_logbook()
@test 1 == sum(lb)

# N ENTRIES IN THE LOGBOOK
reset_logbook()
a = Sherlog32(1.0)
for i in 1:n
a + randn(Float32) # promotion included
end
lb = get_logbook()
@test n == sum(lb)
end

@testset "Logbook count 16" begin

n = 100

# A SINGLE ENTRY IN THE LOGBOOK
reset_logbook()
Sherlog16(0)+Sherlog16(0)
lb = get_logbook()
@test 1 == sum(lb)

# N ENTRIES IN THE LOGBOOK
reset_logbook()
a = Sherlog16(1.0)
for i in 1:n
a + randn(Float16) # promotion included
end
lb = get_logbook()
@test n == sum(lb)
end

@testset "Minimum, maximum logbook Float16" begin

n = 100

for T in [Float16,Float32,Float64]

# MAXIMUM
for _ in 1:n
i = rand(1:32) # pick a random logbook
reset_logbook(i) # set it to zero
x = rand(T)
Sherlogs.log_it(Float16,x,i) # log a random Float16
logbook = get_logbook(i)
@test Float16(x) == maximum(logbook)
end

# MINIMUM
for _ in 1:n
i = rand(1:32) # pick a random logbook
reset_logbook(i) # set it to zero
x = -rand(Float16)
Sherlogs.log_it(Float16,x,i) # log a random Float16
logbook = get_logbook(i)
@test Float16(x) == minimum(logbook)
end
end
end
Loading

2 comments on commit 30645f0

@milankl
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/41180

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.2.0 -m "<description of version>" 30645f0f9c6fd32cddb71c79323b78fe9ac00334
git push origin v0.2.0

Please sign in to comment.