Skip to content

Commit d5a5ced

Browse files
authored
Merge pull request #205 from JuliaRobotics/feature/4Q19/wipsolvablegraphs
solvable for GraphsDFG
2 parents 274ac7a + 0be2005 commit d5a5ced

File tree

15 files changed

+98
-99
lines changed

15 files changed

+98
-99
lines changed

src/CloudGraphsDFG/services/CloudGraphsDFG.jl

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ function addVariable!(dfg::CloudGraphsDFG, variable::DFGVariable)::Bool
9898
props["estimateDict"] = JSON2.write(variable.estimateDict)
9999
props["solverDataDict"] = JSON2.write(Dict(keys(variable.solverDataDict) .=> map(vnd -> pack(dfg, vnd), values(variable.solverDataDict))))
100100
props["smallData"] = JSON2.write(variable.smallData)
101-
props["ready"] = variable.ready
102-
props["backendset"] = variable.backendset
101+
props["ready"] = variable.solvable
102+
props["backendset"] = variable.solveInProgress
103103
# Don't handle big data at the moment.
104104

105105
neo4jNode = Neo4j.createnode(dfg.neo4jInstance.graph, props);
@@ -143,8 +143,8 @@ function addFactor!(dfg::CloudGraphsDFG, variables::Vector{DFGVariable}, factor:
143143
# Include the type
144144
props["fnctype"] = String(_getname(fnctype))
145145
props["_variableOrderSymbols"] = JSON2.write(factor._variableOrderSymbols)
146-
props["backendset"] = factor.backendset
147-
props["ready"] = factor.ready
146+
props["backendset"] = factor.solveInProgress
147+
props["ready"] = factor.solvable
148148
# Don't handle big data at the moment.
149149

150150
neo4jNode = Neo4j.createnode(dfg.neo4jInstance.graph, props);
@@ -201,8 +201,8 @@ function getVariable(dfg::CloudGraphsDFG, variableId::Int64)::DFGVariable
201201
variable.estimateDict = estimateDict
202202
variable.solverDataDict = solverData
203203
variable.smallData = smallData
204-
variable.ready = props["ready"]
205-
variable.backendset = props["backendset"]
204+
variable.solvable = props["ready"]
205+
variable.solveInProgress = props["backendset"]
206206

207207
# Add to cache
208208
push!(dfg.variableCache, variable.label=>variable)
@@ -256,8 +256,8 @@ function getFactor(dfg::CloudGraphsDFG, factorId::Int64)::DFGFactor
256256
factor.tags = tags
257257
factor.data = fullFactor
258258
factor._variableOrderSymbols = _variableOrderSymbols
259-
factor.ready = ready
260-
factor.backendset = backendset
259+
factor.solvable = ready
260+
factor.solveInProgress = backendset
261261

262262
# Lastly, rebuild the metadata
263263
factor = dfg.rebuildFactorMetadata!(dfg, factor)
@@ -310,8 +310,8 @@ function updateVariable!(dfg::CloudGraphsDFG, variable::DFGVariable)::DFGVariabl
310310
props["estimateDict"] = JSON2.write(variable.estimateDict)
311311
props["solverDataDict"] = JSON2.write(Dict(keys(variable.solverDataDict) .=> map(vnd -> pack(dfg, vnd), values(variable.solverDataDict))))
312312
props["smallData"] = JSON2.write(variable.smallData)
313-
props["ready"] = variable.ready
314-
props["backendset"] = variable.backendset
313+
props["ready"] = variable.solvable
314+
props["backendset"] = variable.solveInProgress
315315
# Don't handle big data at the moment.
316316

317317
Neo4j.updatenodeproperties(neo4jNode, props)
@@ -361,8 +361,8 @@ function updateFactor!(dfg::CloudGraphsDFG, factor::DFGFactor)::DFGFactor
361361
# Include the type
362362
props["fnctype"] = String(_getname(fnctype))
363363
props["_variableOrderSymbols"] = JSON2.write(factor._variableOrderSymbols)
364-
props["backendset"] = factor.backendset
365-
props["ready"] = factor.ready
364+
props["backendset"] = factor.solveInProgress
365+
props["ready"] = factor.solvable
366366
# Don't handle big data at the moment.
367367

368368
Neo4j.updatenodeproperties(neo4jNode, props)
@@ -374,7 +374,7 @@ end
374374

375375
"""
376376
$(SIGNATURES)
377-
Update a complete DFGFactor in the DFG and update it's relationships.
377+
Update a complete DFGFactor in the DFG and update its relationships.
378378
"""
379379
function updateFactor!(dfg::CloudGraphsDFG, variables::Vector{DFGVariable}, factor::DFGFactor)::DFGFactor
380380
# Update the body
@@ -597,7 +597,7 @@ function getNeighbors(dfg::CloudGraphsDFG, node::T; ready::Union{Nothing, Int}=n
597597
query = "(n:$(dfg.userId):$(dfg.robotId):$(dfg.sessionId):$(node.label))--(node) where (node:VARIABLE or node:FACTOR) "
598598
if ready != nothing || backendset != nothing
599599
if ready != nothing
600-
query = query * " and node.ready = $(ready)"
600+
query = query * " and node.ready >= $(ready)"
601601
end
602602
if backendset != nothing
603603
query = query * " and node.backendset = $(backendset)"
@@ -620,7 +620,7 @@ function getNeighbors(dfg::CloudGraphsDFG, label::Symbol; ready::Union{Nothing,
620620
query = "(n:$(dfg.userId):$(dfg.robotId):$(dfg.sessionId):$(label))--(node) where (node:VARIABLE or node:FACTOR) "
621621
if ready != nothing || backendset != nothing
622622
if ready != nothing
623-
query = query * " and node.ready = $(ready)"
623+
query = query * " and node.ready >= $(ready)"
624624
end
625625
if backendset != nothing
626626
query = query * " and node.backendset = $(backendset)"

src/DistributedFactorGraphs.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export pushUserData!, pushRobotData!, pushSessionData!, popUserData!, popRobotDa
3333

3434
# Services/AbstractDFG Exports
3535
export hasFactor, hasVariable, isInitialized, getFactorFunction, isVariable, isFactor
36+
export isSolvable, isSolveInProgress
3637
export mergeUpdateVariableSolverData!, mergeUpdateGraphSolverData!
3738

3839
# Solver (IIF) Exports

src/GraphsDFG/services/GraphsDFG.jl

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,20 @@ end
235235
List the DFGVariables in the DFG.
236236
Optionally specify a label regular expression to retrieves a subset of the variables.
237237
"""
238-
function getVariables(dfg::GraphsDFG, regexFilter::Union{Nothing, Regex}=nothing; tags::Vector{Symbol}=Symbol[])::Vector{DFGVariable}
239-
variables = map(v -> v.dfgNode, filter(n -> n.dfgNode isa DFGVariable, Graphs.vertices(dfg.g)))
238+
function getVariables(dfg::GraphsDFG,
239+
regexFilter::Union{Nothing, Regex}=nothing;
240+
tags::Vector{Symbol}=Symbol[],
241+
solvable::Int=0 )::Vector{DFGVariable}
242+
#
243+
variables = map(v -> v.dfgNode, filter(n -> (n.dfgNode isa DFGVariable) && (solvable <= isSolvable(n.dfgNode)), Graphs.vertices(dfg.g)))
244+
# filter on solvable
245+
246+
# filter on regex
240247
if regexFilter != nothing
241248
variables = filter(v -> occursin(regexFilter, String(v.label)), variables)
242249
end
250+
251+
# filter on tags
243252
if length(tags) > 0
244253
mask = map(v -> length(intersect(v.tags, tags)) > 0, variables )
245254
return variables[mask]
@@ -279,8 +288,8 @@ function getNeighbors(dfg::GraphsDFG, node::T; ready::Union{Nothing, Int}=nothin
279288
vert = dfg.g.vertices[dfg.labelDict[node.label]]
280289
neighbors = in_neighbors(vert, dfg.g) #Don't use out_neighbors! It enforces directiveness even if we don't want it
281290
# Additional filtering
282-
neighbors = ready != nothing ? filter(v -> v.dfgNode.ready == ready, neighbors) : neighbors
283-
neighbors = backendset != nothing ? filter(v -> v.dfgNode.backendset == backendset, neighbors) : neighbors
291+
neighbors = ready != nothing ? filter(v -> isSolvable(v.dfgNode) >= ready, neighbors) : neighbors
292+
neighbors = backendset != nothing ? filter(v -> isSolveInProgress(v.dfgNode) == backendset, neighbors) : neighbors
284293
# Variable sorting (order is important)
285294
if node isa DFGFactor
286295
order = intersect(node._variableOrderSymbols, map(v->v.dfgNode.label, neighbors))
@@ -300,8 +309,8 @@ function getNeighbors(dfg::GraphsDFG, label::Symbol; ready::Union{Nothing, Int}=
300309
vert = dfg.g.vertices[dfg.labelDict[label]]
301310
neighbors = in_neighbors(vert, dfg.g) #Don't use out_neighbors! It enforces directiveness even if we don't want it
302311
# Additional filtering
303-
neighbors = ready != nothing ? filter(v -> v.dfgNode.ready == ready, neighbors) : neighbors
304-
neighbors = backendset != nothing ? filter(v -> v.dfgNode.backendset == backendset, neighbors) : neighbors
312+
neighbors = ready != nothing ? filter(v -> isSolvable(v.dfgNode) >= ready, neighbors) : neighbors
313+
neighbors = backendset != nothing ? filter(v -> isSolveInProgress(v.dfgNode) == backendset, neighbors) : neighbors
305314
# Variable sorting when using a factor (function order is important)
306315
if vert.dfgNode isa DFGFactor
307316
vert.dfgNode._variableOrderSymbols
@@ -312,41 +321,6 @@ function getNeighbors(dfg::GraphsDFG, label::Symbol; ready::Union{Nothing, Int}=
312321
return map(n -> n.dfgNode.label, neighbors)
313322
end
314323

315-
# function _copyIntoGraph!(sourceDFG::GraphsDFG, destDFG::GraphsDFG, variableFactorLabels::Vector{Symbol}, includeOrphanFactors::Bool=false)::Nothing
316-
# # Split into variables and factors
317-
# verts = map(id -> sourceDFG.g.vertices[sourceDFG.labelDict[id]], variableFactorLabels)
318-
# sourceVariables = filter(n -> n.dfgNode isa DFGVariable, verts)
319-
# sourceFactors = filter(n -> n.dfgNode isa DFGFactor, verts)
320-
#
321-
# # Now we have to add all variables first,
322-
# for variable in sourceVariables
323-
# if !haskey(destDFG.labelDict, variable.dfgNode.label)
324-
# addVariable!(destDFG, deepcopy(variable.dfgNode))
325-
# end
326-
# end
327-
# # And then all factors to the destDFG.
328-
# for factor in sourceFactors
329-
# if !haskey(destDFG.labelDict, factor.dfgNode.label)
330-
# # Get the original factor variables (we need them to create it)
331-
# neighVarIds = getNeighbors(sourceDFG, factor.dfgNode.label) #OLD: in_neighbors(factor, sourceDFG.g)
332-
# # Find the labels and associated neighVarIds in our new subgraph
333-
# factVariables = DFGVariable[]
334-
# for neighVarId in neighVarIds
335-
# if haskey(destDFG.labelDict, neighVarId)
336-
# push!(factVariables, getVariable(destDFG, neighVarId))
337-
# #otherwise ignore
338-
# end
339-
# end
340-
#
341-
# # Only if we have all of them should we add it (otherwise strange things may happen on evaluation)
342-
# if includeOrphanFactors || length(factVariables) == length(neighVarIds)
343-
# addFactor!(destDFG, factVariables, deepcopy(factor.dfgNode))
344-
# end
345-
# end
346-
# end
347-
# return nothing
348-
# end
349-
350324
"""
351325
$(SIGNATURES)
352326
Retrieve a deep subgraph copy around a given variable or factor.

src/LightDFG/services/LightDFG.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,17 +273,17 @@ end
273273

274274
function _isready(dfg::LightDFG, label::Symbol, ready::Int)::Bool
275275

276-
haskey(dfg.g.variables, label) && (return dfg.g.variables[label].ready == ready)
277-
haskey(dfg.g.factors, label) && (return dfg.g.factors[label].ready == ready)
276+
haskey(dfg.g.variables, label) && (return dfg.g.variables[label].solvable >= ready)
277+
haskey(dfg.g.factors, label) && (return dfg.g.factors[label].solvable >= ready)
278278

279279
#TODO should this be a breaking error?
280280
@error "Node not in factor or variable"
281281
return false
282282
end
283283

284284
function _isbackendset(dfg::LightDFG, label::Symbol, backendset::Int)::Bool
285-
haskey(dfg.g.variables, label) && (return dfg.g.variables[label].backendset == backendset)
286-
haskey(dfg.g.factors, label) && (return dfg.g.factors[label].backendset == backendset)
285+
haskey(dfg.g.variables, label) && (return dfg.g.variables[label].solveInProgress == backendset)
286+
haskey(dfg.g.factors, label) && (return dfg.g.factors[label].solveInProgress == backendset)
287287

288288
#TODO should this be a breaking error?
289289
@error "Node not a factor or variable"

src/MetaGraphsDFG/services/MetaGraphsDFG.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,8 @@ hasOrphans(dfg::MetaGraphsDFG)::Bool = !isFullyConnected(dfg)
318318

319319
function _isready(dfg::MetaGraphsDFG, idx::Int, ready::Int)::Bool
320320
p = props(dfg.g, idx)
321-
haskey(p, :variable) && (return p[:variable].ready == ready)
322-
haskey(p, :factor) && (return p[:factor].ready == ready)
321+
haskey(p, :variable) && (return p[:variable].solvable >= ready)
322+
haskey(p, :factor) && (return p[:factor].solvable >= ready)
323323

324324
#TODO should this be an error?
325325
@warn "Node not a factor or variable"
@@ -328,8 +328,8 @@ end
328328

329329
function _isbackendset(dfg::MetaGraphsDFG, idx::Int, backendset::Int)::Bool
330330
p = props(dfg.g, idx)
331-
haskey(p, :variable) && (return p[:variable].backendset == backendset)
332-
haskey(p, :factor) && (return p[:factor].backendset == backendset)
331+
haskey(p, :variable) && (return p[:variable].solveInProgress == backendset)
332+
haskey(p, :factor) && (return p[:factor].solveInProgress == backendset)
333333

334334
#TODO should this be an error?
335335
@warn "Node not a factor or variable"

src/SymbolDFG/services/SymbolDFG.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,17 +275,17 @@ hasOrphans(dfg::SymbolDFG)::Bool = !isFullyConnected(dfg)
275275

276276
function _isready(dfg::SymbolDFG, label::Symbol, ready::Int)::Bool
277277

278-
haskey(dfg.g.variables, label) && (return dfg.g.variables[label].ready == ready)
279-
haskey(dfg.g.factors, label) && (return dfg.g.factors[label].ready == ready)
278+
haskey(dfg.g.variables, label) && (return dfg.g.variables[label].solvable >= ready)
279+
haskey(dfg.g.factors, label) && (return dfg.g.factors[label].solvable >= ready)
280280

281281
#TODO should this be a breaking error?
282282
@error "Node not in factor or variable"
283283
return false
284284
end
285285

286286
function _isbackendset(dfg::SymbolDFG, label::Symbol, backendset::Int)::Bool
287-
haskey(dfg.g.variables, label) && (return dfg.g.variables[label].backendset == backendset)
288-
haskey(dfg.g.factors, label) && (return dfg.g.factors[label].backendset == backendset)
287+
haskey(dfg.g.variables, label) && (return dfg.g.variables[label].solveInProgress == backendset)
288+
haskey(dfg.g.factors, label) && (return dfg.g.factors[label].solveInProgress == backendset)
289289

290290
#TODO should this be a breaking error?
291291
@error "Node not a factor or variable"

src/entities/DFGFactor.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ mutable struct DFGFactor{T, S} <: AbstractDFGFactor
3838
label::Symbol
3939
tags::Vector{Symbol}
4040
data::GenericFunctionNodeData{T, S}
41-
ready::Int
42-
backendset::Int
41+
solvable::Int
42+
solveInProgress::Int
4343
_internalId::Int64
4444
_variableOrderSymbols::Vector{Symbol}
4545
DFGFactor{T, S}(label::Symbol) where {T, S} = new{T, S}(label, Symbol[], GenericFunctionNodeData{T, S}(), 0, 0, 0, Symbol[])

src/entities/DFGVariable.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ mutable struct DFGVariable <: AbstractDFGVariable
114114
solverDataDict::Dict{Symbol, VariableNodeData}
115115
smallData::Dict{String, String}
116116
bigData::Dict{Symbol, AbstractBigDataEntry}
117-
ready::Int
118-
backendset::Int
117+
solvable::Int
118+
solveInProgress::Int
119119
_internalId::Int64
120120
end
121121

src/services/AbstractDFG.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,31 @@ function ls(dfg::G, label::Symbol)::Vector{Symbol} where G <: AbstractDFG
327327
return getNeighbors(dfg, label)
328328
end
329329

330+
"""
331+
$SIGNATURES
332+
333+
Variables or factors may or may not be 'solvable', depending on a user definition. Useful for ensuring atomic transactions.
334+
335+
Related
336+
337+
isSolveInProgress
338+
"""
339+
isSolvable(var::Union{DFGVariable, DFGFactor}) = var.solvable
340+
341+
"""
342+
$SIGNATURES
343+
344+
Which variables or factors are currently being used by an active solver. Useful for ensuring atomic transactions.
345+
346+
DevNotes:
347+
- Will be renamed to `data.solveinprogress` which will be in VND, not DFGNode -- see DFG #201
348+
349+
Related
350+
351+
isSolvable
352+
"""
353+
isSolveInProgress(var::Union{DFGVariable, DFGFactor}; solveKey::Symbol=:default) = var.solveInProgress
354+
330355
"""
331356
$(SIGNATURES)
332357
Gets an empty and unique CloudGraphsDFG derived from an existing DFG.

src/services/DFGFactor.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ function packFactor(dfg::G, f::DFGFactor)::Dict{String, Any} where G <: Abstract
2525
# Include the type
2626
props["fnctype"] = String(_getname(fnctype))
2727
props["_variableOrderSymbols"] = JSON2.write(f._variableOrderSymbols)
28-
props["backendset"] = f.backendset
29-
props["ready"] = f.ready
28+
props["solveInProgress"] = f.solveInProgress
29+
props["solvable"] = f.solvable
3030

3131
return props
3232
end
@@ -54,16 +54,16 @@ function unpackFactor(dfg::G, packedProps::Dict{String, Any}, iifModule)::DFGFac
5454

5555
# Include the type
5656
_variableOrderSymbols = JSON2.read(packedProps["_variableOrderSymbols"], Vector{Symbol})
57-
backendset = packedProps["backendset"]
58-
ready = packedProps["ready"]
57+
solveInProgress = packedProps["solveInProgress"]
58+
solvable = packedProps["solvable"]
5959

6060
# Rebuild DFGVariable
6161
factor = DFGFactor{typeof(fullFactor.fnc), Symbol}(Symbol(label))
6262
factor.tags = tags
6363
factor.data = fullFactor
6464
factor._variableOrderSymbols = _variableOrderSymbols
65-
factor.ready = ready
66-
factor.backendset = backendset
65+
factor.solvable = solvable
66+
factor.solveInProgress = solveInProgress
6767

6868
# GUARANTEED never to bite us in the ass in the future...
6969
# ... TODO: refactor if changed: https://github.com/JuliaRobotics/IncrementalInference.jl/issues/350

0 commit comments

Comments
 (0)