Skip to content

Commit

Permalink
Add serialisation for remote call Future objects
Browse files Browse the repository at this point in the history
  • Loading branch information
FrameConsult authored and sschlenkrich committed Mar 28, 2024
1 parent ced3c38 commit 0b66a4e
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 3 deletions.
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ version = "0.4.0"
[deps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
Expand Down
1 change: 1 addition & 0 deletions src/DiffFusion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module DiffFusion

using ChainRulesCore
using DelimitedFiles
using Distributed
using Distributions
using FiniteDifferences
using ForwardDiff
Expand Down
25 changes: 22 additions & 3 deletions src/serialisation/Serialisations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ function serialise(o::Any)
return serialise_struct(o)
end

"""
serialise(o::Future)
Serialise a Future object from a `remotecall(...)`.
This operation is blocking. We require that the result is calculated such that
it actually can be serialised.
"""
serialise(o::Future) = serialise(fetch(o))

"""
serialise(o::Nothing)
Expand Down Expand Up @@ -108,7 +118,11 @@ end
De-serialise strings.
We incorporate some logic to handle external references."
We incorporate some logic to handle external references.
We allow that the repository disctionary `d` contains remote call
`Futures`. However, we want to ensure that the method returns actual
objects. Thus, we `fetch` any `Future` within this method.
"""
function deserialise(o::String, d::Union{AbstractDict, Nothing} = nothing)
if o == "nothing"
Expand All @@ -120,9 +134,14 @@ function deserialise(o::String, d::Union{AbstractDict, Nothing} = nothing)
(first(o, n_first) == _serialise_key_references[1]) &&
(last(o, n_last) == _serialise_key_references[2])
# we found a key
dict_key = o[begin+n_first:end-n_last]
@assert !isnothing(d)
@assert haskey(d, o[begin+n_first:end-n_last])
return d[o[begin+n_first:end-n_last]]
@assert haskey(d, dict_key)
obj = d[dict_key]
if isa(obj, Future)
return fetch(obj)
end
return obj
end
return o
end
Expand Down
8 changes: 8 additions & 0 deletions test/unittests/serialisation/basic_types.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DiffFusion
using Distributed
using OrderedCollections
using Test

Expand All @@ -19,6 +20,13 @@ using Test
)
end

@testset "Simple Remote call serialisation." begin
f = remotecall(()-> "Std", workers()[1])
@test DiffFusion.serialise(f) == "Std"
f = remotecall(()-> 42.1, workers()[1])
@test DiffFusion.serialise(f) == 42.1
end

@testset "Basic object types de-serialisation" begin
@test isnothing(DiffFusion.deserialise("nothing"))
@test DiffFusion.deserialise("Std") == "Std"
Expand Down
41 changes: 41 additions & 0 deletions test/unittests/serialisation/objects.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

using DiffFusion
using Distributed
using OrderedCollections
using Test

Expand Down Expand Up @@ -109,4 +110,44 @@ using Test
)
@test obj.X == obj_ref.X
end


@testset "Test object with remote calls" begin
model = hybrid_model_full
ch = ch_full
future_model = remotecall(()-> model, workers()[1])
future_ch = remotecall(()-> ch, workers()[1])
repository = Dict{String, Any}(
DiffFusion.alias(model) => future_model,
DiffFusion.alias(ch) => future_ch,
"true" => true,
"false" => false,
"SobolBrownianIncrements" => DiffFusion.sobol_brownian_increments
)
# println(keys(repository))
#
d = OrderedDict{String, Any}(
"typename" => "DiffFusion.Simulation",
"constructor" => "simple_simulation",
"model" => "{Std}",
"ch" => "{Full}",
"times" => [ 0.0, 2.0, 4.0, 6.0, 8.0, 10.0 ],
"n_paths" => 2^10,
"kwargs" => OrderedDict{String, Any}(
"with_progress_bar" => "{false}",
"brownian_increments" => "{SobolBrownianIncrements}",
),
)
obj = DiffFusion.deserialise(d, repository)
obj_ref = DiffFusion.simple_simulation(
model,
ch,
[ 0.0, 2.0, 4.0, 6.0, 8.0, 10.0 ],
2^10;
with_progress_bar = false,
brownian_increments = DiffFusion.sobol_brownian_increments,
)
@test obj.X == obj_ref.X
end

end

0 comments on commit 0b66a4e

Please sign in to comment.