Skip to content

Commit be19492

Browse files
authored
Merge pull request #1670 from JuliaRobotics/master
release v0.32.1-rc1
2 parents 15d4fbc + 94310b6 commit be19492

16 files changed

+387
-367
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ The list below highlights breaking changes according to normal semver workflow -
1919
- Now have `CalcFactor.manifold` to reduce new allocation load inside hot-loop for solving.
2020
- Fixed tesing issues in `testSpecialEuclidean2Mani.jl`.
2121
- Refactored, consolidated, and added more in-place operations in surrounding `ccw.measurement`.
22+
- Refactor `CommonConvWrapper` to a not non-mutable struct, with several cleanups and some updated compat requirements.
23+
- Refactor interal hard type `HypoRecipe`.
2224

2325
# Changes in v0.31
2426
- `FactorMetaData` is deprecated and replaced by `CalcFactor`.

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "IncrementalInference"
22
uuid = "904591bb-b899-562f-9e6f-b8df64c7d480"
33
keywords = ["MM-iSAMv2", "Bayes tree", "junction tree", "Bayes network", "variable elimination", "graphical models", "SLAM", "inference", "sum-product", "belief-propagation"]
44
desc = "Implements the Multimodal-iSAMv2 algorithm."
5-
version = "0.32.0"
5+
version = "0.32.1"
66

77
[deps]
88
ApproxManifoldProducts = "9bbbb610-88a1-53cd-9763-118ce10c1f89"
@@ -50,7 +50,7 @@ ApproxManifoldProducts = "0.6"
5050
BSON = "0.2, 0.3"
5151
Combinatorics = "1.0"
5252
DataStructures = "0.16, 0.17, 0.18"
53-
DistributedFactorGraphs = "0.18.4"
53+
DistributedFactorGraphs = "0.18.10"
5454
Distributions = "0.24, 0.25"
5555
DocStringExtensions = "0.8, 0.9"
5656
FileIO = "1"

src/entities/FactorOperationalMemory.jl

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,21 @@ Related
8080
8181
[`CalcFactor`](@ref), [`CalcFactorMahalanobis`](@ref)
8282
"""
83-
mutable struct CommonConvWrapper{
83+
struct CommonConvWrapper{
8484
T <: AbstractFactor,
85+
VT <: Tuple,
8586
NTP <: Tuple,
86-
G,
87-
MT,
8887
CT,
88+
AM <: AbstractManifold,
8989
HP <: Union{Nothing, <:Distributions.Categorical{Float64, Vector{Float64}}},
9090
CH <: Union{Nothing, Vector{Int}},
91-
VT <: Tuple,
92-
AM <: AbstractManifold
91+
MT,
92+
G
9393
} <: FactorOperationalMemory
9494
# Basic factor topological info
9595
""" Values consistent across all threads during approx convolution """
9696
usrfnc!::T # user factor / function
97-
""" Consolidation from FMD, ordered tuple of all variables connected to this factor """
97+
""" Ordered tuple of all variables connected to this factor """
9898
fullvariables::VT
9999
# shortcuts to numerical containers
100100
""" Numerical containers for all connected variables. Hypo selection needs to be passed
@@ -109,10 +109,6 @@ mutable struct CommonConvWrapper{
109109
partialDims::Vector{<:Integer}
110110
""" is this a partial constraint as defined by the existance of factor field `.partial::Tuple` """
111111
partial::Bool
112-
""" coordinate dimension size of current target variable (see .fullvariables[.varidx]), TODO remove once only use under AbstractRelativeRoots is deprecated or resolved """
113-
xDim::Int
114-
""" coordinate dimension size of factor, same as manifold_dimension(.manifold) """
115-
zDim::Int
116112
""" probability that this factor is wholly incorrect and should be ignored during solving """
117113
nullhypo::Float64
118114
""" inflationSpread particular to this factor (by how much to dispurse the belief initial values before numerical optimization is run). Analogous to stochastic search """
@@ -131,9 +127,9 @@ mutable struct CommonConvWrapper{
131127
can be a Vector{<:Tuple} or more direct Vector{<: pointortangenttype} """
132128
measurement::Vector{MT}
133129
""" which index is being solved for in params? """
134-
varidx::Int
130+
varidx::Base.RefValue{Int}
135131
""" Consolidation from CPT, the actual particle being solved at this moment """
136-
particleidx::Int
132+
particleidx::Base.RefValue{Int}
137133
""" working memory to store residual for optimization routines """
138134
res::Vector{Float64}
139135
""" experimental feature to embed gradient calcs with ccw """

src/services/CalcFactor.jl

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ getFactorOperationalMemoryType(dfg::SolverParams) = CommonConvWrapper
77
# difficult type piracy case needing both types NoSolverParams and CommonConvWrapper.
88
getFactorOperationalMemoryType(dfg::NoSolverParams) = CommonConvWrapper
99

10+
getManifold(fct::DFGFactor{<:CommonConvWrapper}) = getManifold(_getCCW(fct))
11+
1012
function _getDimensionsPartial(ccw::CommonConvWrapper)
1113
# @warn "_getDimensionsPartial not ready for use yet"
1214
return ccw.partialDims
@@ -28,7 +30,7 @@ function CalcFactor(
2830
_allowThreads = true,
2931
cache = ccwl.dummyCache,
3032
fullvariables = ccwl.fullvariables,
31-
solvefor = ccwl.varidx,
33+
solvefor = ccwl.varidx[],
3234
manifold = getManifold(ccwl)
3335
)
3436
#
@@ -76,7 +78,7 @@ Notes
7678
"""
7779
function calcZDim(cf::CalcFactor{T}) where {T <: AbstractFactor}
7880
#
79-
M = cf.manifold # getManifold(T)
81+
M = getManifold(cf) # getManifold(T)
8082
try
8183
return manifold_dimension(M)
8284
catch
@@ -191,9 +193,8 @@ function CommonConvWrapper(
191193
usrfnc::T,
192194
fullvariables, #::Tuple ::Vector{<:DFGVariable};
193195
varValsAll::Tuple,
194-
X::AbstractVector{P}, #TODO remove X completely
195-
zDim::Int;
196-
xDim::Int = size(X, 1),
196+
X::AbstractVector{P}; #TODO remove X completely
197+
# xDim::Int = size(X, 1),
197198
userCache::CT = nothing,
198199
manifold = getManifold(usrfnc),
199200
partialDims::AbstractVector{<:Integer} = 1:length(X),
@@ -206,7 +207,7 @@ function CommonConvWrapper(
206207
measurement::AbstractVector = Vector(Vector{Float64}()),
207208
varidx::Int = 1,
208209
particleidx::Int = 1,
209-
res::AbstractVector{<:Real} = zeros(zDim),
210+
res::AbstractVector{<:Real} = zeros(manifold_dimension(manifold)), # zDim
210211
gradients = nothing,
211212
) where {T <: AbstractFactor, P, H, CT}
212213
#
@@ -218,22 +219,23 @@ function CommonConvWrapper(
218219
manifold,
219220
partialDims,
220221
partial,
221-
xDim,
222-
zDim,
222+
# xDim,
223223
Float64(nullhypo),
224224
inflation,
225225
hypotheses,
226226
certainhypo,
227227
activehypo,
228228
measurement,
229-
varidx,
230-
particleidx,
229+
Ref(varidx),
230+
Ref(particleidx),
231231
res,
232232
gradients,
233233
)
234234
end
235235

236-
getManifold(ccwl::CommonConvWrapper) = ccwl.manifold # getManifold(ccwl.usrfnc!)
236+
# the same as legacy, getManifold(ccwl.usrfnc!)
237+
getManifold(ccwl::CommonConvWrapper) = ccwl.manifold
238+
getManifold(cf::CalcFactor) = cf.manifold
237239

238240
function _resizePointsVector!(
239241
vecP::AbstractVector{P},
@@ -279,10 +281,13 @@ function _prepParamVec(
279281
#
280282
# FIXME refactor to new NamedTuple instead
281283
varParamsAll = getVal.(Xi; solveKey)
282-
Xi_labels = getLabel.(Xi)
283-
sfidx = findfirst(==(solvefor), Xi_labels)
284-
285-
sfidx = isnothing(sfidx) ? 0 : sfidx
284+
# Xi_labels = getLabel.(Xi)
285+
sfidx = if isnothing(solvefor)
286+
0
287+
else
288+
findfirst(==(solvefor), getLabel.(Xi))
289+
end
290+
# sfidx = isnothing(sfidx) ? 0 : sfidx
286291

287292
# this line does nothing...
288293
# maxlen = N # FIXME see #105
@@ -292,7 +297,7 @@ function _prepParamVec(
292297

293298
# resample variables with too few kernels (manifolds points)
294299
SAMP = LEN .< maxlen
295-
for i = 1:length(Xi_labels)
300+
for i = 1:length(Xi)
296301
if SAMP[i]
297302
Pr = getBelief(Xi[i], solveKey)
298303
_resizePointsVector!(varParamsAll[i], Pr, maxlen)
@@ -317,6 +322,7 @@ Internal method to set which dimensions should be used as the decision variables
317322
"""
318323
function _setCCWDecisionDimsConv!(
319324
ccwl::Union{CommonConvWrapper{F}, CommonConvWrapper{Mixture{N_, F, S, T}}},
325+
xDim::Int
320326
) where {
321327
N_,
322328
F <: Union{
@@ -331,12 +337,14 @@ function _setCCWDecisionDimsConv!(
331337
#
332338

333339
# NOTE should only be done in the constructor
334-
ccwl.partialDims = if ccwl.partial
340+
newval = if ccwl.partial
335341
Int[ccwl.usrfnc!.partial...]
336342
else
337343
# NOTE this is the target variable dimension (not factor manifold dimension)
338-
Int[1:(ccwl.xDim)...]
344+
Int[1:xDim...] # ccwl.xDim
339345
end
346+
resize!(ccwl.partialDims, length(newval))
347+
ccwl.partialDims[:] = newval
340348

341349
return nothing
342350
end
@@ -411,22 +419,19 @@ function _prepCCW(
411419
end
412420

413421
# TODO check no Anys, see #1321
414-
_varValsQuick, maxlen, sfidx = _prepParamVec(Xi, nothing, 0; solveKey) # Nothing for init.
422+
_varValsAll, maxlen, sfidx = _prepParamVec(Xi, nothing, 0; solveKey) # Nothing for init.
415423

416424
manifold = getManifold(usrfnc)
417425
# standard factor metadata
418426
solvefor = length(Xi)
419-
# sflbl = 0 == length(Xi) ? :null : getLabel(Xi[end])
420-
# lbs = getLabel.(Xi)
421-
# fmd = FactorMetadata(Xi, lbs, _varValsQuick, sflbl, nothing)
422427
fullvariables = tuple(Xi...) # convert(Vector{DFGVariable}, Xi)
423428
# create a temporary CalcFactor object for extracting the first sample
424429
# TODO, deprecate this: guess measurement points type
425430
# MeasType = Vector{Float64} # FIXME use `usrfnc` to get this information instead
426431
_cf = CalcFactor(
427432
usrfnc,
428433
0,
429-
_varValsQuick,
434+
_varValsAll,
430435
false,
431436
userCache,
432437
fullvariables,
@@ -457,7 +462,7 @@ function _prepCCW(
457462
gradients = attemptGradientPrep(
458463
varTypes,
459464
usrfnc,
460-
_varValsQuick,
465+
_varValsAll,
461466
multihypo,
462467
meas_single,
463468
_blockRecursion,
@@ -466,15 +471,15 @@ function _prepCCW(
466471
# variable Types
467472
pttypes = getVariableType.(Xi) .|> getPointType
468473
PointType = 0 < length(pttypes) ? pttypes[1] : Vector{Float64}
469-
470-
# @info "CCW" typeof(measurement)
474+
if !isconcretetype(PointType)
475+
@warn "_prepCCW PointType is not concrete $PointType" maxlog=50
476+
end
471477

472478
return CommonConvWrapper(
473479
usrfnc,
474480
fullvariables,
475-
_varValsQuick,
476-
PointType[],
477-
calcZDim(_cf);
481+
_varValsAll,
482+
PointType[];
478483
userCache, # should be higher in args list
479484
manifold, # should be higher in args list
480485
partialDims,
@@ -501,9 +506,6 @@ function updateMeasurement!(
501506
if needFreshMeasurements
502507
# TODO this is only one thread, make this a for loop for multithreaded sampling
503508
sampleFactor!(ccwl, N; _allowThreads)
504-
# TODO use common sampleFactor! call instead
505-
# cf = CalcFactor(ccwl; _allowThreads)
506-
# ccwl.measurement = sampleFactor(cf, N)
507509
elseif 0 < length(measurement)
508510
resize!(ccwl.measurement, length(measurement))
509511
ccwl.measurement[:] = measurement
@@ -541,40 +543,38 @@ function _updateCCW!(
541543

542544
# FIXME, order of fmd ccwl cf are a little weird and should be revised.
543545
# FIXME maxlen should parrot N (barring multi-/nullhypo issues)
544-
_varValsQuick, maxlen, sfidx = _prepParamVec(Xi, solvefor, N; solveKey)
546+
_varValsAll, maxlen, sfidx = _prepParamVec(Xi, solvefor, N; solveKey)
547+
548+
# TODO, ensure all values (not just multihypothesis) is correctly used from here
549+
for (i,varVal) in enumerate(_varValsAll)
550+
resize!(ccwl.varValsAll[i],length(varVal))
551+
ccwl.varValsAll[i][:] = varVal
552+
end
553+
554+
# set the 'solvefor' variable index -- i.e. which connected variable of the factor is being computed in this convolution.
555+
ccwl.varidx[] = sfidx
545556

546-
# NOTE should be selecting for the correct multihypothesis mode
547-
ccwl.varValsAll = _varValsQuick
548557
# TODO better consolidation still possible
549558
# FIXME ON FIRE, what happens if this is a partial dimension factor? See #1246
550559
# FIXME, confirm this is hypo sensitive selection from Xi, better to use double indexing for clarity getDimension(ccw.fullvariables[hypoidx[sfidx]])
551-
ccwl.xDim = getDimension(getVariableType(Xi[sfidx]))
552-
# TODO maybe refactor new type higher up?
560+
xDim = getDimension(getVariableType(Xi[sfidx])) # ccwl.varidx[]
561+
# ccwl.xDim = xDim
562+
# TODO maybe refactor different type or api call?
553563

554564
# setup the partial or complete decision variable dimensions for this ccwl object
555565
# NOTE perhaps deconv has changed the decision variable list, so placed here during consolidation phase
556566
# TODO, should this not be part of `prepareCommonConvWrapper` -- only here do we look for .partial
557-
_setCCWDecisionDimsConv!(ccwl)
558-
559-
# set the 'solvefor' variable index -- i.e. which connected variable of the factor is being computed in this convolution.
560-
ccwl.varidx = sfidx
567+
_setCCWDecisionDimsConv!(ccwl, xDim)
561568

562569
# FIXME do not divert Mixture for sampling
563570

564-
# TODO remove ccwl.zDim updating
565-
# cache the measurement dimension
566-
cf = CalcFactor(ccwl; _allowThreads = true)
567-
@assert ccwl.zDim == calcZDim(cf) "refactoring in progress, cannot drop assignment ccwl.zDim:$(ccwl.zDim) = calcZDim( cf ):$(calcZDim( cf ))"
568-
# ccwl.zDim = calcZDim( cf ) # CalcFactor(ccwl) )
569-
570571
updateMeasurement!(ccwl, maxlen; needFreshMeasurements, measurement, _allowThreads=true)
571572

572-
# set each CPT
573573
# used in ccw functor for AbstractRelativeMinimize
574-
resize!(ccwl.res, ccwl.zDim)
574+
resize!(ccwl.res, _getZDim(ccwl))
575575
fill!(ccwl.res, 0.0)
576576

577-
# calculate new gradients perhaps
577+
# calculate new gradients
578578
# J = ccwl.gradients(measurement..., pts...)
579579

580580
return sfidx, maxlen
@@ -590,14 +590,16 @@ function _updateCCW!(
590590
needFreshMeasurements::Bool = true,
591591
solveKey::Symbol = :default,
592592
) where {F <: AbstractFactor} # F might be Mixture
593-
# setup the partial or complete decision variable dimensions for this ccwl object
594-
# NOTE perhaps deconv has changed the decision variable list, so placed here during consolidation phase
595-
_setCCWDecisionDimsConv!(ccwl)
596-
597593
# FIXME, NEEDS TO BE CLEANED UP AND WORK ON MANIFOLDS PROPER
598594
# fnc = ccwl.usrfnc!
599595
sfidx = findfirst(getLabel.(Xi) .== solvefor)
596+
@assert sfidx == 1 "Solving on Prior with CCW should have sfidx=1, priors are unary factors."
600597
# sfidx = 1 # why hardcoded to 1, maybe for only the AbstractPrior case here
598+
599+
# setup the partial or complete decision variable dimensions for this ccwl object
600+
# NOTE perhaps deconv has changed the decision variable list, so placed here during consolidation phase
601+
_setCCWDecisionDimsConv!(ccwl, getDimension(getVariableType(Xi[sfidx])))
602+
601603
solveForPts = getVal(Xi[sfidx]; solveKey)
602604
maxlen = maximum([N; length(solveForPts); length(ccwl.varValsAll[sfidx])]) # calcZDim(ccwl); length(measurement[1])
603605

src/services/DeconvUtils.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ function approxDeconv(
3737
retries::Int = 3,
3838
)
3939
#
40+
# FIXME needs xDim for all variables at once? xDim = 0 likely to break?
41+
4042
# but what if this is a partial factor -- is that important for general cases in deconv?
41-
_setCCWDecisionDimsConv!(ccw)
43+
_setCCWDecisionDimsConv!(ccw, 0) # ccwl.xDim used to hold the last forward solve getDimension(getVariableType(Xi[sfidx]))
4244

4345
# FIXME This does not incorporate multihypo??
4446
varsyms = getVariableOrder(fcto)
@@ -74,7 +76,8 @@ function approxDeconv(
7476
targeti_ = makeTarget(idx)
7577

7678
# TODO must first resolve hypothesis selection before unrolling them -- deferred #1096
77-
ccw.activehypo = hyporecipe.activehypo[2][2]
79+
resize!(ccw.activehypo, length(hyporecipe.activehypo[2][2]))
80+
ccw.activehypo[:] = hyporecipe.activehypo[2][2]
7881

7982
onehypo!, _ = _buildCalcFactorLambdaSample(ccw, idx, targeti_, measurement)
8083
#
@@ -84,7 +87,7 @@ function approxDeconv(
8487

8588
# find solution via SubArray view pointing to original memory location
8689
if fcttype isa AbstractManifoldMinimize
87-
sfidx = ccw.varidx
90+
sfidx = ccw.varidx[]
8891
targeti_ .= _solveLambdaNumericMeas(
8992
fcttype,
9093
hypoObj,

0 commit comments

Comments
 (0)