Skip to content
Snippets Groups Projects
Commit 73e636ee authored by Florian Atteneder's avatar Florian Atteneder
Browse files

dg1d: Implement `Workspace` (!219)

This is a new caching mechanism which should be used for small temporary arrays.
parent b30417fb
No related branches found
No related tags found
1 merge request!219dg1d: Implement `Workspace`
Pipeline #7231 passed
...@@ -70,7 +70,7 @@ include("tensorbasis.jl") ...@@ -70,7 +70,7 @@ include("tensorbasis.jl")
include("box.jl") include("box.jl")
include("tree.jl") include("tree.jl")
include("objectcache.jl") include("objectcache.jl")
# include("refvector.jl") include("workspace.jl")
export Variables, n_variables, names, isregistered export Variables, n_variables, names, isregistered
include("variables.jl") include("variables.jl")
......
mutable struct Chunk
nborrowed::Int64
const sz::Int64
const arrays::Vector{Vector{Float64}}
end
Chunk(sz::Int64) = Chunk(0,sz,Vector{Float64}[])
function borrow(chunk::Chunk)
chunk.nborrowed += 1
if chunk.nborrowed <= length(chunk.arrays)
return chunk.arrays[chunk.nborrowed]
end
new_array = zeros(Float64, chunk.sz)
push!(chunk.arrays, new_array)
return new_array
end
"""
mutable struct Workspace
A lazy cache type to provide temporary `Float64` vector of arbitrary sizes.
See: `enter, borrow`.
# Example
To `borrow` vectors from a `Workspace`, you first have to `enter` it.
Borrowed vectors must not escape the `enter` block.
```
ws = Workspace()
enter(ws) do
sz1, sz2 = 3, 4
v1, v2 = borrow(ws, sz1), borrow(ws, sz2)
end
```
"""
mutable struct Workspace
entered::Bool
const chunks::Dict{Int64,Chunk}
end
Workspace() = Workspace(false, Dict{Int64,Chunk}())
"""
enter(fn::Function, ws::Workspace)
Enter `ws` to enable borrowing vector.
See: `Workspace, borrow`.
"""
function enter(fn::Function, ws::Workspace)
if ws.entered
error("Can only enter workspace once!")
end
try
ws.entered = true
fn()
finally
for chunk in values(ws.chunks)
chunk.nborrowed = 0
end
ws.entered = false
end
return
end
"""
borrow(ws::Workspace, sz::Int64)
Borrow a `Float64` vector of length `sz` from `ws`.
See: `Workspace, borrow`.
"""
function borrow(ws::Workspace, sz::Int64)
if !ws.entered
error("Can only borrow from workspace once entered!")
end
chunk = get!(ws.chunks, sz, Chunk(sz))
return borrow(chunk)
end
@testset "Workspace" begin
ws = dg1d.Workspace()
@test isempty(ws.chunks)
dg1d.enter(ws) do
v1 = dg1d.borrow(ws, 1)
v2 = dg1d.borrow(ws, 2)
v3 = dg1d.borrow(ws, 3)
@test length(v1) == 1
@test length(v2) == 2
@test length(v3) == 3
v4 = dg1d.borrow(ws, 1)
v5 = dg1d.borrow(ws, 2)
v6 = dg1d.borrow(ws, 3)
@test length(v4) == 1
@test length(v5) == 2
@test length(v6) == 3
end
@test length(ws.chunks) == 3
for chk in values(ws.chunks)
@test length(chk.arrays) == 2
end
dg1d.enter(ws) do
v1 = dg1d.borrow(ws, 1)
v2 = dg1d.borrow(ws, 2)
v3 = dg1d.borrow(ws, 3)
@test length(v1) == 1
@test length(v2) == 2
@test length(v3) == 3
end
@test length(ws.chunks) == 3
for chk in values(ws.chunks)
@test length(chk.arrays) == 2
end
@test_throws ErrorException dg1d.borrow(ws, 1)
dg1d.enter(ws) do
@test_throws ErrorException dg1d.enter(ws) do
println("sers")
end
end
end
...@@ -21,4 +21,5 @@ include("test_variables.jl") ...@@ -21,4 +21,5 @@ include("test_variables.jl")
include("test_cache.jl") include("test_cache.jl")
include("test_callbacks.jl") include("test_callbacks.jl")
include("test_output.jl") include("test_output.jl")
include("test_workspace.jl")
include("test_EquationOfState.jl") include("test_EquationOfState.jl")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment