Skip to content

Commit 80afa46

Browse files
Oscar SmithYingboMa
andauthored
fix all loops in alias graph rather than just first order loops (#2149)
Co-authored-by: Yingbo Ma <[email protected]>
1 parent 484dfcb commit 80afa46

File tree

2 files changed

+48
-11
lines changed

2 files changed

+48
-11
lines changed

src/structural_transformation/pantelides.jl

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,25 +121,33 @@ function computed_highest_diff_variables(structure, ag::Union{AliasGraph, Nothin
121121
if ag !== nothing && haskey(ag, var)
122122
(_, stem) = ag[var]
123123
stem == 0 && continue
124-
# Ascend the stem
125-
while isempty(𝑑neighbors(graph, var))
126-
var′ = invview(var_to_diff)[var]
127-
var′ === nothing && break
128-
stem′ = invview(var_to_diff)[stem]
129-
avar′ = haskey(ag, var′) ? ag[var′][2] : nothing
130-
if avar′ == stem || var′ == stem
131-
# If we have a self-loop in the stem, we could have the
132-
# var′ also alias to the original stem. In that case, the
133-
# derivative of the stem is highest differentiated, because of the loop
124+
# If we have a self-loop in the stem, we could have the
125+
# var′ also alias to the original stem. In that case, the
126+
# derivative of the stem is highest differentiated, because of the loop
127+
loop_found = false
128+
var′ = invview(var_to_diff)[var]
129+
while var′ !== nothing
130+
if var′ == stem || (haskey(ag, var′) && ag[var′][2] == stem)
134131
dstem = var_to_diff[stem]
135132
@assert dstem !== nothing
136133
varwhitelist[dstem] = true
134+
loop_found = true
137135
break
138136
end
137+
var′ = invview(var_to_diff)[var′]
138+
end
139+
loop_found && continue
140+
# Ascend the stem
141+
while isempty(𝑑neighbors(graph, var))
142+
var′ = invview(var_to_diff)[var]
143+
var′ === nothing && break
144+
loop_found = false
145+
cvar = var′
139146
# Invariant from alias elimination: Stem is chosen to have
140147
# the highest differentiation order.
148+
stem′ = invview(var_to_diff)[stem]
141149
@assert stem′ !== nothing
142-
if avar′ != stem′
150+
if !haskey(ag, var′) || (ag[var′][2] != stem′)
143151
varwhitelist[stem] = true
144152
break
145153
end

test/pantelides.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,32 @@ begin
9696
# Correct answer is: ẋ
9797
@test varwhitelist == Bool[1, 0, 0, 1]
9898
end
99+
100+
begin
101+
"""
102+
Vars: y
103+
Eqs: 0 = f(y)
104+
Alias: y = ÿ
105+
"""
106+
n_vars = 3
107+
ag = AliasGraph(n_vars)
108+
109+
# Alias: z = 1 * ÿ
110+
ag[3] = 1 => 1
111+
112+
# 0 = f(y)
113+
graph = complete(BipartiteGraph([Int[]], n_vars))
114+
115+
# [y, ẏ, ÿ]
116+
var_to_diff = DiffGraph([2, 3, nothing], # primal_to_diff
117+
[nothing, 1, 2]) # diff_to_primal
118+
119+
# [f(x)]
120+
eq_to_diff = DiffGraph([nothing], # primal_to_diff
121+
[nothing]) # diff_to_primal
122+
structure = SystemStructure(var_to_diff, eq_to_diff, graph, nothing, nothing, false)
123+
varwhitelist = computed_highest_diff_variables(structure, ag)
124+
125+
# Correct answer is: ẏ
126+
@test varwhitelist == Bool[0, 1, 0]
127+
end

0 commit comments

Comments
 (0)