diff --git a/src/Deprecated.jl b/src/Deprecated.jl index 5e94a7c8..799a805b 100644 --- a/src/Deprecated.jl +++ b/src/Deprecated.jl @@ -20,6 +20,37 @@ const InferenceType = AbstractPackedFactorObservation const PackedSamplableBelief = PackedBelief +export setSolverData! +""" + $SIGNATURES +Set solver data structure stored in a variable. +""" +function setSolverData!(v::VariableCompute, data::VariableState, key::Symbol = :default) + Base.depwarn( + "setSolverData!(v::VariableCompute, data::VariableState, key::Symbol = :default) is deprecated, use mergeVariableState! instead.", + :setSolverData!, + ) + @assert key == data.solveKey "VariableState.solveKey=:$(data.solveKey) does not match requested :$(key)" + return v.solverDataDict[key] = data +end + +@deprecate mergeVariableSolverData!(args...; kwargs...) mergeVariableState!( + args...; + kwargs..., +) + +export mergeVariableData!, mergeGraphVariableData! +function mergeVariableData!(args...) + return error( + "mergeVariableData! is obsolete, use mergeVariableState! for state, PPEs are obsolete", + ) +end +function mergeGraphVariableData!(args...) + return error( + "mergeGraphVariableData! is obsolete, use mergeVariableState! for state, PPEs are obsolete", + ) +end + ## ================================================================================ ## Deprecated in v0.27 ##================================================================================= diff --git a/src/DistributedFactorGraphs.jl b/src/DistributedFactorGraphs.jl index 160b5221..f23c9770 100644 --- a/src/DistributedFactorGraphs.jl +++ b/src/DistributedFactorGraphs.jl @@ -58,9 +58,9 @@ using InteractiveUtils: subtypes ##============================================================================== # v1 name, signiture, return, and error checked +export getFactor, getBlobentry, getGraphBlobentry # v1 name, signiture, and return -export getFactor, getBlobentry, getGraphBlobentry, getVariableState, getFactorState # v1 name only export getVariable, getBlob, addBlob! @@ -71,6 +71,9 @@ export DFG export GraphsDFGs, GraphsDFG +## +export getVariableState, getFactorState # FIXME these were questioned and being reviewed again for name, other than that they are checked. + ##------------------------------------------------------------------------------ ## DFG ##------------------------------------------------------------------------------ @@ -174,7 +177,7 @@ export listTags, mergeTags!, removeTags!, emptyTags! export VariableStateType # accessors -export getSolverDataDict, setSolverData! +export getSolverDataDict export getVariableType, getVariableTypeName export getObservation @@ -201,7 +204,6 @@ export getVariableStates, mergeVariableState!, deleteVariableState!, listVariableStates, - mergeVariableSolverData!, cloneSolveKey! # PPE @@ -264,9 +266,6 @@ export FactorSolverCache export getVariableOrder export getFactorType, getFactorFunction -# Node Data -export mergeVariableData!, mergeGraphVariableData! - # Serialization type conversion export convertPackedType, convertStructType diff --git a/src/GraphsDFG/services/GraphsDFG.jl b/src/GraphsDFG/services/GraphsDFG.jl index b3a635c6..11afe3f3 100644 --- a/src/GraphsDFG/services/GraphsDFG.jl +++ b/src/GraphsDFG/services/GraphsDFG.jl @@ -512,6 +512,9 @@ end # FG blob entries function getGraphBlobentry(fg::GraphsDFG, label::Symbol) + if !haskey(fg.graphBlobEntries, label) + throw(LabelNotFoundError("GraphBlobentry", label)) + end return fg.graphBlobEntries[label] end diff --git a/src/services/AbstractDFG.jl b/src/services/AbstractDFG.jl index 8f6d9468..9c37b606 100644 --- a/src/services/AbstractDFG.jl +++ b/src/services/AbstractDFG.jl @@ -1418,52 +1418,6 @@ function mergeGraph!( return destDFG end -##============================================================================== -## Variable Data: VND and PPE -##============================================================================== - -#TODO API -""" - $(SIGNATURES) -Merges and updates solver and estimate data for a variable (variable can be from another graph). -Note: Makes a copy of the estimates and solver data so that there is no coupling between graphs. -""" -function mergeVariableData!(dfg::AbstractDFG, sourceVariable::AbstractDFGVariable) - var = getVariable(dfg, sourceVariable.label) - - mergePPEs!(var, sourceVariable) - # If this variable has solverDataDict (summaries do not) - :solverDataDict in fieldnames(typeof(var)) && - mergeVariableSolverData!(var, sourceVariable) - - #update if its not a InMemoryDFGTypes, otherwise it was a reference - # if satelite nodes are used it can be updated separately - # !(isa(dfg, InMemoryDFGTypes)) && mergeVariable!(dfg, var) - - return var -end - -#TODO API -""" - $(SIGNATURES) -Common function to update all solver data and estimates from one graph to another. -This should be used to push local solve data back into a cloud graph, for example. - -Notes -- Returns `::Nothing` -""" -function mergeGraphVariableData!( - destDFG::H, - sourceDFG::G, - varSyms::Vector{Symbol}, -) where {G <: AbstractDFG, H <: AbstractDFG} - # Update all variables in the destination - # (For now... we may change this soon) - for variableId in varSyms - mergeVariableData!(destDFG, getVariable(sourceDFG, variableId)) - end -end - ##============================================================================== ## Graphs Structures (Abstract, overwrite for performance) ##============================================================================== diff --git a/src/services/CompareUtils.jl b/src/services/CompareUtils.jl index 276aa132..d5c84e85 100644 --- a/src/services/CompareUtils.jl +++ b/src/services/CompareUtils.jl @@ -253,8 +253,8 @@ function compareVariable( union!(skiplist, skip) TP = TP && compareAll(A.solverDataDict, B.solverDataDict; skip = skiplist, show = show) - Ad = getVariableState(A) - Bd = getVariableState(B) + Ad = getVariableState(A, :default) #FIXME why onlly comparing default? + Bd = getVariableState(B, :default) # TP = TP && compareAll(A.attributes, B.attributes, skip=[:variableType;], show=show) varskiplist = union(varskiplist, [:variableType]) diff --git a/src/services/DFGVariable.jl b/src/services/DFGVariable.jl index 639c7a5d..9ca42c2e 100644 --- a/src/services/DFGVariable.jl +++ b/src/services/DFGVariable.jl @@ -538,26 +538,15 @@ getSolverDataDict(v::VariableCompute) = v.solverDataDict Retrieve solver data structure stored in a variable. """ -function getVariableState(v::VariableCompute, key::Symbol = :default) - #TODO this does not fit in with some of the other error behaviour. but its used so added @error - vnd = if haskey(getSolverDataDict(v), key) - return getSolverDataDict(v)[key] +function getVariableState(v::VariableCompute, label::Symbol) + vnd = if haskey(getSolverDataDict(v), label) + return getSolverDataDict(v)[label] else - throw(LabelNotFoundError("State", key)) + throw(LabelNotFoundError("State", label)) end return vnd end -#TODO Repeated functionality? same as update -""" - $SIGNATURES -Set solver data structure stored in a variable. -""" -function setSolverData!(v::VariableCompute, data::VariableState, key::Symbol = :default) - @assert key == data.solveKey "VariableState.solveKey=:$(data.solveKey) does not match requested :$(key)" - return v.solverDataDict[key] = data -end - ##------------------------------------------------------------------------------ ## Variable Metadata ##------------------------------------------------------------------------------ @@ -682,18 +671,14 @@ end $(SIGNATURES) Get variable solverdata for a given solve key. """ -function getVariableState( - dfg::AbstractDFG, - variablekey::Symbol, - solvekey::Symbol = :default, -) - v = getVariable(dfg, variablekey) - !haskey(v.solverDataDict, solvekey) && throw(LabelNotFoundError("State", solvekey)) - return v.solverDataDict[solvekey] +function getVariableState(dfg::AbstractDFG, variableLabel::Symbol, label::Symbol) + v = getVariable(dfg, variableLabel) + !haskey(v.solverDataDict, label) && throw(LabelNotFoundError("State", label)) + return v.solverDataDict[label] end -function getVariableStates(dfg::AbstractDFG, variablekey::Symbol) - v = getVariable(dfg, variablekey) +function getVariableStates(dfg::AbstractDFG, variableLabel::Symbol) + v = getVariable(dfg, variableLabel) return collect(values(v.solverDataDict)) end @@ -701,30 +686,21 @@ end $(SIGNATURES) Add variable solver data, errors if it already exists. """ -function addVariableState!(dfg::AbstractDFG, variablekey::Symbol, vnd::VariableState) +function addVariableState!(dfg::AbstractDFG, variablekey::Symbol, state::VariableState) var = getVariable(dfg, variablekey) - if haskey(var.solverDataDict, vnd.solveKey) - throw(LabelExistsError("VariableState", vnd.solveKey)) + if haskey(var.solverDataDict, state.solveKey) + throw(LabelExistsError("VariableState", state.solveKey)) end - var.solverDataDict[vnd.solveKey] = vnd - return vnd + var.solverDataDict[state.solveKey] = state + return state end -""" - $(SIGNATURES) -Add a new solver data entry from a deepcopy of the source variable solver data. -NOTE: Copies the solver data. -""" -function addVariableState!( - dfg::AbstractDFG, - sourceVariable::VariableCompute, - solveKey::Symbol = :default, -) - return addVariableState!( - dfg, - sourceVariable.label, - deepcopy(getVariableState(sourceVariable, solveKey)), - ) +function addVariableState!(v, state::VariableState) + if haskey(v.solverDataDict, state.solveKey) + throw(LabelExistsError("VariableState", state.solveKey)) + end + v.solverDataDict[state.solveKey] = state + return state end """ @@ -747,6 +723,16 @@ function mergeVariableState!(dfg::AbstractDFG, variablekey::Symbol, vnd::Variabl return 1 end +function mergeVariableState!(v::VariableCompute, vnd::VariableState) + if !haskey(v.solverDataDict, vnd.solveKey) + addVariableState!(v, vnd) + else + v.solverDataDict[vnd.solveKey] = vnd + end + + return 1 +end + function copytoVariableState!( dfg::AbstractDFG, variableLabel::Symbol, @@ -797,13 +783,9 @@ end """ $(SIGNATURES) -Delete variable solver data, returns the deleted element. +Delete variable solver data, returns the number of deleted elements. """ -function deleteVariableState!( - dfg::AbstractDFG, - variablekey::Symbol, - solveKey::Symbol = :default, -) +function deleteVariableState!(dfg::AbstractDFG, variablekey::Symbol, solveKey::Symbol) var = getVariable(dfg, variablekey) if !haskey(var.solverDataDict, solveKey) @@ -815,12 +797,12 @@ end """ $(SIGNATURES) -Delete variable solver data, returns the deleted element. +Delete variable solver data, returns the number of deleted elements. """ function deleteVariableState!( dfg::AbstractDFG, sourceVariable::VariableCompute, - solveKey::Symbol = :default, + solveKey::Symbol, ) return deleteVariableState!(dfg, sourceVariable.label, solveKey) end @@ -838,28 +820,6 @@ function listVariableStates(dfg::AbstractDFG, variablekey::Symbol) return collect(keys(v.solverDataDict)) end -""" - $(SIGNATURES) -Merges and updates solver and estimate data for a variable (variable can be from another graph). -If the same key is present in another collection, the value for that key will be the value it has in the last collection listed (updated). -Note: Makes a copy of the estimates and solver data so that there is no coupling between graphs. -""" -function mergeVariableSolverData!( - destVariable::VariableCompute, - sourceVariable::VariableCompute, -) - # We don't know which graph this came from, must be copied! - merge!(destVariable.solverDataDict, deepcopy(sourceVariable.solverDataDict)) - return destVariable -end - -function mergeVariableSolverData!(dfg::AbstractDFG, sourceVariable::VariableCompute) - return mergeVariableSolverData!( - getVariable(dfg, getLabel(sourceVariable)), - sourceVariable, - ) -end - ##============================================================================== ## Point Parametric Estimates ##============================================================================== diff --git a/test/fileDFGTests.jl b/test/fileDFGTests.jl index fb1f06d7..bbac060e 100644 --- a/test/fileDFGTests.jl +++ b/test/fileDFGTests.jl @@ -19,7 +19,10 @@ using UUIDs 1:numNodes, ) map(v -> setSolvable!(v, Int(round(rand()))), verts) - map(v -> getVariableState(verts[4]).solveInProgress = Int(round(rand())), verts) + map( + v -> getVariableState(verts[4], :default).solveInProgress = Int(round(rand())), + verts, + ) map(v -> setSolvedCount!(v, Int(round(10 * rand()))), verts) # Add some data entries diff --git a/test/iifInterfaceTests.jl b/test/iifInterfaceTests.jl index f8fce79d..5d9c6aca 100644 --- a/test/iifInterfaceTests.jl +++ b/test/iifInterfaceTests.jl @@ -8,10 +8,6 @@ global dfg, v1, v2, f1 v2 = addVariable!(dfg, :b, Position{1}; tags = [:LANDMARK], solvable = 1) f1 = addFactor!(dfg, [:a; :b], LinearRelative(Normal(50.0, 2.0)); solvable = 0) end - -println() -println() - #test before anything changes @testset "Producing Dot Files" begin global dfg @@ -187,8 +183,6 @@ end @test getTimestamp(v1) == v1.timestamp @test getVariablePPEDict(v1) == v1.ppeDict @test_throws LabelNotFoundError DistributedFactorGraphs.getVariablePPE(v1, :notfound) - @test getVariableState(v1) === v1.solverDataDict[:default] - @test getVariableState(v1) === v1.solverDataDict[:default] @test getVariableState(v1, :default) === v1.solverDataDict[:default] @test getSolverDataDict(v1) == v1.solverDataDict # legacy compat test @@ -287,50 +281,6 @@ end @test listBlobentries(v1) == Symbol[] end -@testset "Updating Nodes and Estimates" begin - global dfg - #get the variable - var1 = getVariable(dfg, :a) - #make a copy and simulate external changes - newvar = deepcopy(var1) - getVariablePPEDict(newvar)[:default] = MeanMaxPPE(:default, [150.0], [100.0], [50.0]) - mergeVariableData!(dfg, newvar) - - #Check if variable is updated - var1 = getVariable(dfg, :a) - @test getVariablePPEDict(newvar) == getVariablePPEDict(var1) - - # Add a new estimate. - getVariablePPEDict(newvar)[:second] = MeanMaxPPE(:second, [15.0], [10.0], [5.0]) - - # Confirm they're different - @test getVariablePPEDict(newvar) != getVariablePPEDict(var1) - # Persist it. - mergeVariableData!(dfg, newvar) - # Get the latest - var1 = getVariable(dfg, :a) - @test symdiff(collect(keys(getVariablePPEDict(var1))), [:default, :second]) == Symbol[] - - #Check if variable is updated - @test getVariablePPEDict(newvar) == getVariablePPEDict(var1) - - # Delete :default and replace to see if new ones can be added - delete!(getVariablePPEDict(newvar), :default) - #confirm delete - @test symdiff(collect(keys(getVariablePPEDict(newvar))), [:second]) == Symbol[] - # Persist it., and test - mergeVariableData!(dfg, newvar) #357 #358 - - # Get the latest and confirm they're the same, :second - var1 = getVariable(dfg, :a) - - # TODO issue #166 - @test getVariablePPEDict(newvar) != getVariablePPEDict(var1) - @test collect(keys(getVariablePPEDict(var1))) == [:default, :second] - - # @test symdiff(collect(keys(getVariablePPE(getVariable(dfg, :a)))), [:default, :second]) == Symbol[] -end - # Connectivity test @testset "Connectivity Test" begin global dfg, v1, v2, f1 @@ -395,7 +345,7 @@ verts = map(n -> addVariable!(dfg, Symbol("x$n"), Position{1}; tags = [:POSE]), #TODO fix this to use accessors setSolvable!(verts[7], 1) setSolvable!(verts[8], 0) -getVariableState(verts[8]).solveInProgress = 1 +getVariableState(verts[8], :default).solveInProgress = 1 #call update to set it on cloud mergeVariable!(dfg, verts[7]) mergeVariable!(dfg, verts[8]) diff --git a/test/testBlocks.jl b/test/testBlocks.jl index 971633af..ba484c80 100644 --- a/test/testBlocks.jl +++ b/test/testBlocks.jl @@ -325,7 +325,7 @@ function DFGVariableSCA() # v3.solverDataDict[:default].val[1] = [0.0;0.0] # v3.solverDataDict[:default].bw[1] = [1.0;1.0] - getVariableState(v1).solveInProgress = 1 + getVariableState(v1, :default).solveInProgress = 1 @test getLabel(v1) == v1_lbl @test getTags(v1) == v1_tags @@ -373,7 +373,6 @@ function DFGVariableSCA() # #TODO sort out # getPPEs # getVariableState - # setSolverData # getVariablePPEs # getVariablePPE # getSolvedCount @@ -770,8 +769,6 @@ function VSDTestBlock!(fg, v1) # **Set like** # - `listVariableStates` # - # > - `emptyVariableSolverData!` #TODO ? - # > - `mergeVariableSolverData!` #TODO ? # # **VariableState** # - `getSolveInProgress` @@ -822,7 +819,7 @@ function VSDTestBlock!(fg, v1) @test_throws LabelNotFoundError getVariableState(fg, :a, :parametric) #FIXME copied from lower - @test getVariableState(v1) === v1.solverDataDict[:default] + @test getVariableState(v1, :default) === v1.solverDataDict[:default] # Add new VND of type ContinuousScalar to :x0 # Could also do VariableState(ContinuousScalar()) @@ -848,18 +845,11 @@ function VSDTestBlock!(fg, v1) deleteVariableState!(fg, :a, :parametric) return nothing - #TODO - # mergeVariableSolverData!(...) #TODO solverDataDict() not deprecated # @test getSolverDataDict(newvar) == getSolverDataDict(v1) # @test @test_deprecated mergeUpdateVariableSolverData!(fg, newvar) - # TODO - # mergeVariableSolverData! - # mergePPEs! - # mergeVariableData! - # mergeGraphVariableData! end @@ -1806,7 +1796,7 @@ function FileDFGTestBlock(testDFGAPI; kwargs...) for filename in ["/tmp/fileDFG", "/tmp/FileDFGExtension.tar.gz"] v4 = getVariable(dfg, :x4) - vnd = getVariableState(v4) + vnd = getVariableState(v4, :default) # set everything vnd.BayesNetVertID = :outid push!(vnd.BayesNetOutVertIDs, :id)