diff --git a/Project.toml b/Project.toml index ab1d4515..dc42777f 100644 --- a/Project.toml +++ b/Project.toml @@ -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" diff --git a/src/DiffFusion.jl b/src/DiffFusion.jl index 25d89315..9631559b 100644 --- a/src/DiffFusion.jl +++ b/src/DiffFusion.jl @@ -2,6 +2,7 @@ module DiffFusion using ChainRulesCore using DelimitedFiles +using Distributed using Distributions using FiniteDifferences using ForwardDiff diff --git a/src/serialisation/Serialisations.jl b/src/serialisation/Serialisations.jl index 38a81a26..4fb76555 100644 --- a/src/serialisation/Serialisations.jl +++ b/src/serialisation/Serialisations.jl @@ -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) @@ -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" @@ -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 diff --git a/test/unittests/serialisation/basic_types.jl b/test/unittests/serialisation/basic_types.jl index a59d53fa..51caa6f4 100644 --- a/test/unittests/serialisation/basic_types.jl +++ b/test/unittests/serialisation/basic_types.jl @@ -1,4 +1,5 @@ using DiffFusion +using Distributed using OrderedCollections using Test @@ -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" diff --git a/test/unittests/serialisation/objects.jl b/test/unittests/serialisation/objects.jl index cb44d487..a397615b 100644 --- a/test/unittests/serialisation/objects.jl +++ b/test/unittests/serialisation/objects.jl @@ -1,5 +1,6 @@ using DiffFusion +using Distributed using OrderedCollections using Test @@ -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 \ No newline at end of file