Skip to content

Commit 0df8b59

Browse files
committed
initial code from IncrementalInference
1 parent 80e08bb commit 0df8b59

File tree

2 files changed

+302
-0
lines changed

2 files changed

+302
-0
lines changed

src/DistributedFactorGraphs.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ using
55
DocStringExtensions
66

77

8+
include("FGOSUtils.jl")
89

910
end

src/FGOSUtils.jl

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
# Factor Graph OS type utilities
2+
# IIF methods should direclty detect extended types from user import
3+
# of convert in their namespace
4+
5+
6+
function convert{PT <: PackedInferenceType, T <:FunctorInferenceType}(::Type{PT}, ::T)
7+
getfield(T.name.module, Symbol("Packed$(T.name.name)"))
8+
end
9+
function convert{T <: FunctorInferenceType, PT <: PackedInferenceType}(::Type{T}, ::PT)
10+
getfield(PT.name.module, Symbol(string(PT.name.name)[7:end]))
11+
end
12+
13+
14+
15+
"""
16+
convert2packedfunctionnode(fgl::FactorGraph, fsym::Symbol)
17+
18+
Encode complicated function node type with assumed to exist, user supplied convert
19+
function to related 'Packed<type>' format.
20+
"""
21+
function convert2packedfunctionnode(fgl::FactorGraph,
22+
fsym::Symbol,
23+
api::DataLayerAPI=localapi )
24+
#
25+
fid = fgl.fIDs[fsym]
26+
fnc = getfnctype(fgl, fid)
27+
usrtyp = convert(PackedInferenceType, fnc)
28+
cfnd = convert(PackedFunctionNodeData{usrtyp},getData(fgl, fid, api=api) )
29+
return cfnd, usrtyp
30+
end
31+
32+
33+
34+
35+
"""
36+
encodefg(fgl::FactorGraph)
37+
38+
Make a full memory copy of the graph and encode all complicated function node
39+
types with assumed to exist convert to 'Packed<type>' formats. Same converters
40+
as used for database persistence storage with CloudGraphs.jl.
41+
"""
42+
function encodefg(fgl::FactorGraph;
43+
api::DataLayerAPI=localapi )
44+
#
45+
fgs = deepcopy(fgl)
46+
fgs.cg = nothing
47+
fgs.registeredModuleFunctions = nothing
48+
fgs.g = Graphs.incdict(Graphs.ExVertex,is_directed=false)
49+
@showprogress 1 "Encoding variables..." for (vsym,vid) in fgl.IDs
50+
cpvert = deepcopy(getVert(fgl, vid, api=api))
51+
api.addvertex!(fgs, cpvert) #, labels=vnlbls) # currently losing labels
52+
end
53+
54+
@showprogress 1 "Encoding factors..." for (fsym,fid) in fgs.fIDs
55+
data,ftyp = convert2packedfunctionnode(fgl, fsym)
56+
# data = FunctionNodeData{ftyp}(Int[], false, false, Int[], m, gwpf)
57+
newvert = ExVertex(fid,string(fsym))
58+
for (key,val) in getVert(fgl,fid,api=api).attributes
59+
newvert.attributes[key] = val
60+
end
61+
setData!(newvert, data)
62+
api.addvertex!(fgs, newvert)
63+
end
64+
fgs.g.inclist = typeof(fgl.g.inclist)()
65+
66+
# iterated over all edges
67+
@showprogress 1 "Encoding edges..." for (eid, edges) in fgl.g.inclist
68+
fgs.g.inclist[eid] = Vector{typeof(edges[1])}()
69+
for ed in edges
70+
newed = Graphs.Edge(ed.index,
71+
fgs.g.vertices[ed.source.index],
72+
fgs.g.vertices[ed.target.index] )
73+
push!(fgs.g.inclist[eid], newed)
74+
end
75+
end
76+
77+
return fgs
78+
end
79+
80+
"""
81+
savefgjld(fgl::FactorGraph; file::AbstractString="tempfg.jld")
82+
83+
Save mostly complete Factor Graph type by converting complicated FunctionNodeData
84+
types to 'Packed' types using user supplied converters. Ground truth can also be
85+
saved and recovered by the associated loadjld(file="tempfg.jld") method.
86+
"""
87+
function savejld(fgl::FactorGraph;
88+
file::AbstractString="tempfg.jld",
89+
groundtruth=nothing)
90+
fgs = encodefg(fgl)
91+
if groundtruth == nothing
92+
@save file fgs
93+
else
94+
@save file fgs groundtruth
95+
end
96+
return file
97+
end
98+
99+
100+
"""
101+
convertfrompackedfunctionnode(fgl, fsym)
102+
103+
If you get unknown type conversion error when loading a .jld, while using your own
104+
FunctorInferenceTypes, you should:
105+
Copy these functions below, and overload in your package with local extented
106+
FunctorInferenceType definitions.
107+
See RoME/src/fgos.jl for example.
108+
"""
109+
function convertfrompackedfunctionnode(fgl::FactorGraph,
110+
fsym::Symbol,
111+
api::DataLayerAPI=localapi )
112+
#
113+
fid = fgl.fIDs[fsym]
114+
fnc = getData(fgl, fid).fnc #getfnctype(fgl, fid)
115+
usrtyp = convert(FunctorInferenceType, fnc)
116+
data = getData(fgl, fid, api=api)
117+
newtype = FunctionNodeData{GenericWrapParam{usrtyp}}
118+
cfnd = convert(newtype, data)
119+
return cfnd, usrtyp
120+
end
121+
122+
"""
123+
decodefg(fgs::FactorGraph)
124+
125+
Unpack PackedFunctionNodeData formats back to regular FunctonNodeData.
126+
"""
127+
function decodefg(fgs::FactorGraph; api::DataLayerAPI=localapi)
128+
fgu = deepcopy(fgs)
129+
fgu.cg = nothing
130+
fgu.registeredModuleFunctions = nothing
131+
fgu.g = Graphs.incdict(Graphs.ExVertex,is_directed=false)
132+
@showprogress 1 "Decoding variables..." for (vsym,vid) in fgs.IDs
133+
cpvert = deepcopy(getVert(fgs, vid, api=api))
134+
api.addvertex!(fgu, cpvert) #, labels=vnlbls) # currently losing labels
135+
end
136+
137+
@showprogress 1 "Decoding factors..." for (fsym,fid) in fgu.fIDs
138+
data,ftyp = convertfrompackedfunctionnode(fgs, fsym)
139+
# data = FunctionNodeData{ftyp}(Int[], false, false, Int[], m, gwpf)
140+
newvert = ExVertex(fid,string(fsym))
141+
for (key,val) in getVert(fgs,fid,api=api).attributes
142+
newvert.attributes[key] = val
143+
end
144+
setData!(newvert, data)
145+
api.addvertex!(fgu, newvert)
146+
end
147+
fgu.g.inclist = typeof(fgs.g.inclist)()
148+
149+
# iterated over all edges
150+
@showprogress 1 "Decoding edges..." for (eid, edges) in fgs.g.inclist
151+
fgu.g.inclist[eid] = Vector{typeof(edges[1])}()
152+
for ed in edges
153+
newed = Graphs.Edge(ed.index,
154+
fgu.g.vertices[ed.source.index],
155+
fgu.g.vertices[ed.target.index] )
156+
push!(fgu.g.inclist[eid], newed)
157+
end
158+
end
159+
160+
return fgu
161+
end
162+
163+
"""
164+
loadjld(file="tempfg.jld")
165+
166+
Opposite of savejld(fg, gt=gt, file="tempfg.jl") to load data from file. This function
167+
uses the unpacking converters for converting all PackedInferenceType to FunctorInferenceType.
168+
"""
169+
function loadjld(;file::AbstractString="tempfg.jld")
170+
dd = JLD.load(file)
171+
# fgs = jldopen(file,"r") do file
172+
# read(file, "fgs")
173+
# end
174+
fgs, gt = nothing, nothing
175+
if haskey(dd, "fgs")
176+
fgs = dd["fgs"]
177+
else
178+
error("No factor graph (fgs) data found in this file, only found $(keys(dd))")
179+
end
180+
if haskey(dd, "groundtruth")
181+
gt = dd["groundtruth"]
182+
println("Also found ground truth data")
183+
end
184+
fgd = decodefg(fgs)
185+
return fgd, gt
186+
end
187+
188+
189+
190+
191+
function ls(fgl::FactorGraph, lbl::Symbol; api::DataLayerAPI=dlapi, ring::Int=1)
192+
# TODO ring functionality must still be implemented
193+
lsa = Symbol[]
194+
# v = nothing
195+
if haskey(fgl.IDs, lbl)
196+
id = fgl.IDs[lbl]
197+
else
198+
return lsa
199+
end
200+
# this is unnecessary
201+
v = getVert(fgl,id, api=api)
202+
for outn in api.outneighbors(fgl, v)
203+
# if outn.attributes["ready"] = 1 && outn.attributes["backendset"]=1
204+
push!(lsa, Symbol(outn.label))
205+
# end
206+
end
207+
return lsa
208+
end
209+
ls(fgl::FactorGraph, lbl::T) where {T <: AbstractString} = ls(fgl, Symbol(lbl))
210+
211+
function ls(fgl::FactorGraph)
212+
k = collect(keys(fgl.IDs))
213+
l = Int[]
214+
x = Int[]
215+
for kk in k
216+
kstr = string(kk)
217+
val = parse(Int,kstr[2:end]) # kk
218+
if kstr[1] == 'l'
219+
push!(l,val)
220+
elseif kstr[1] == 'x'
221+
push!(x,val)
222+
end
223+
end
224+
l = sort(l)
225+
x = sort(x)
226+
ll = Array{Symbol,1}(length(l))
227+
xx = Array{Symbol,1}(length(x))
228+
for i in 1:length(l)
229+
ll[i] = Symbol(string("l",l[i]))
230+
end
231+
for i in 1:length(x)
232+
xx[i] = Symbol(string("x",x[i]))
233+
end
234+
return xx,ll
235+
end
236+
237+
function lsf(fgl::FactorGraph, lbl::Symbol; api::DataLayerAPI=dlapi)
238+
lsa = Symbol[]
239+
# v = Union{}
240+
if haskey(fgl.fIDs, lbl)
241+
id = fgl.fIDs[lbl]
242+
else
243+
return lsa
244+
end
245+
v = getVert(fgl, id, api=api) # fgl.g.vertices[id] #fgl.f[id]
246+
for outn in api.outneighbors(fgl, v) # out_neighbors(v, fgl.g)
247+
push!(lsa, Symbol(outn.label))
248+
end
249+
return lsa
250+
end
251+
lsf{T <: AbstractString}(fgl::FactorGraph, lbl::T) = lsf(fgl,Symbol(lbl))
252+
253+
function lsf{T <: FunctorInferenceType}(fgl::FactorGraph,
254+
mt::Type{T};
255+
api::DataLayerAPI=dlapi )
256+
#
257+
syms = Symbol[]
258+
for (fsym,fid) in fgl.fIDs
259+
if typeof(getfnctype(fgl, fid, api=api))==T
260+
push!(syms, fsym)
261+
end
262+
end
263+
return syms
264+
end
265+
266+
function ls2(fgl::FactorGraph, vsym::Symbol)
267+
xxf = ls(fgl, vsym)
268+
xlxl = Symbol[]
269+
for xf in xxf
270+
xx = lsf(fgl,xf)
271+
xlxl = union(xlxl, xx)
272+
end
273+
xlxl = setdiff(xlxl, [vsym])
274+
return xlxl
275+
end
276+
277+
278+
"""
279+
landmarks(fgl::FactorGraph, vsym::Symbol)
280+
281+
Return Vector{Symbol} of landmarks attached to vertex vsym in fgl.
282+
"""
283+
function landmarks(fgl::FactorGraph, vsym::Symbol)
284+
fsyms = ls(fgl, vsym)
285+
lms = Symbol[]
286+
for fs in fsyms
287+
for varv = lsf(fgl, fs)
288+
if string(varv)[1] == 'l'
289+
push!(lms, varv)
290+
end
291+
end
292+
end
293+
lms
294+
end
295+
296+
297+
298+
299+
300+
301+
#

0 commit comments

Comments
 (0)