@@ -288,12 +288,22 @@ end
288
288
289
289
function tograph (ag:: AliasGraph , var_to_diff:: DiffGraph )
290
290
g = SimpleDiGraph {Int} (length (var_to_diff))
291
+ zero_vars = Int[]
291
292
for (v, (_, a)) in ag
292
- iszero (a) && continue
293
+ if iszero (a)
294
+ push! (zero_vars, v)
295
+ continue
296
+ end
293
297
add_edge! (g, v, a)
294
298
add_edge! (g, a, v)
295
299
end
296
300
transitiveclosure! (g)
301
+ zero_vars_set = BitSet (zero_vars)
302
+ for v in zero_vars
303
+ for a in outneighbors (g, v)
304
+ push! (zero_vars_set, a)
305
+ end
306
+ end
297
307
# Compute the largest transitive closure that doesn't include any diff
298
308
# edges.
299
309
og = g
@@ -319,7 +329,7 @@ function tograph(ag::AliasGraph, var_to_diff::DiffGraph)
319
329
add_edge! (g, v, dv)
320
330
add_edge! (g, dv, v)
321
331
end
322
- g, edge_styles
332
+ g, zero_vars_set, edge_styles
323
333
end
324
334
325
335
using Graphs. Experimental. Traversals
@@ -780,18 +790,16 @@ function alias_eliminate_graph!(graph, var_to_diff, mm_orig::SparseMatrixCLIL)
780
790
# Note that since we always prefer the higher differentiated variable and
781
791
# with a tie breaking strategy, the root variable (in this case `z`) is
782
792
# always uniquely determined. Thus, the result is well-defined.
793
+ dag = AliasGraph (nvars) # alias graph for differentiated variables
794
+ updated_diff_vars = Int[]
783
795
diff_to_var = invview (var_to_diff)
784
- invag = SimpleDiGraph (nvars)
785
- for (v, (coeff, alias)) in pairs (ag)
786
- iszero (coeff) && continue
787
- add_edge! (invag, alias, v)
788
- end
789
796
processed = falses (nvars)
790
- g, = tograph (ag, var_to_diff)
797
+ g, zero_vars_set = tograph (ag, var_to_diff)
791
798
dls = DiffLevelState (g, var_to_diff)
792
799
is_diff_edge = let var_to_diff = var_to_diff
793
800
(v, w) -> var_to_diff[v] == w || var_to_diff[w] == v
794
801
end
802
+ diff_aliases = Vector{Pair{Int, Int}}[]
795
803
for (v, dv) in enumerate (var_to_diff)
796
804
processed[v] && continue
797
805
(dv === nothing && diff_to_var[v] === nothing ) && continue
@@ -801,15 +809,67 @@ function alias_eliminate_graph!(graph, var_to_diff, mm_orig::SparseMatrixCLIL)
801
809
extreme_var (var_to_diff, r, nothing , Val (false ),
802
810
callback = Base. Fix1 (push!, level_to_var))
803
811
nlevels = length (level_to_var)
804
- current_coeff_level = Ref ((0 , 0 ))
812
+ prev_r = - 1
813
+ for _ in 1 : 10_000 # just to make sure that we don't stuck in an infinite loop
814
+ reach₌ = Pair{Int, Int}[]
815
+ r === nothing || for n in neighbors (g, r)
816
+ (n == r || is_diff_edge (r, n)) && continue
817
+ c = 1
818
+ push! (reach₌, c => n)
819
+ end
820
+ if (n = length (diff_aliases)) >= 2
821
+ as = diff_aliases[n- 1 ]
822
+ for (c, a) in as
823
+ (da = var_to_diff[a]) === nothing && continue
824
+ da === r && continue
825
+ push! (reach₌, c => da)
826
+ end
827
+ end
828
+ for (c, a) in reach₌
829
+ @info fullvars[r] => c * fullvars[a]
830
+ end
831
+ if r === nothing
832
+ # TODO : updated_diff_vars check
833
+ isempty (reach₌) && break
834
+ dr = first (reach₌)
835
+ var_to_diff[prev_r] = dr
836
+ push! (updated_diff_vars, prev_r)
837
+ prev_r = dr
838
+ else
839
+ prev_r = r
840
+ r = var_to_diff[r]
841
+ end
842
+ for (c, v) in reach₌
843
+ v == prev_r && continue
844
+ dag[v] = c => prev_r
845
+ end
846
+ push! (diff_aliases, reach₌)
847
+ end
848
+ for v in zero_vars_set
849
+ dag[v] = 0
850
+ end
851
+ @show nlevels
852
+ display (diff_aliases)
853
+ @assert length (diff_aliases) == nlevels
854
+ @show zero_vars_set
855
+
856
+ # clean up
805
857
for v in dls. visited
806
858
dls. dists[v] = typemax (Int)
807
859
processed[v] = true
808
860
end
809
861
empty! (dls. visited)
862
+ empty! (diff_aliases)
810
863
end
864
+ @show dag
811
865
866
+ #=
812
867
processed = falses(nvars)
868
+ invag = SimpleDiGraph(nvars)
869
+ for (v, (coeff, alias)) in pairs(ag)
870
+ iszero(coeff) && continue
871
+ add_edge!(invag, alias, v)
872
+ end
813
873
iag = InducedAliasGraph(ag, invag, var_to_diff)
814
874
dag = AliasGraph(nvars) # alias graph for differentiated variables
815
875
newinvag = SimpleDiGraph(nvars)
@@ -920,6 +980,7 @@ function alias_eliminate_graph!(graph, var_to_diff, mm_orig::SparseMatrixCLIL)
920
980
end
921
981
end
922
982
end
983
+ =#
923
984
924
985
for (v, (c, a)) in dag
925
986
a = iszero (a) ? 0 : c * fullvars[a]
@@ -949,6 +1010,7 @@ function alias_eliminate_graph!(graph, var_to_diff, mm_orig::SparseMatrixCLIL)
949
1010
push! (removed_aliases, a)
950
1011
end
951
1012
for (v, (c, a)) in ag
1013
+ (processed[v] || processed[a]) && continue
952
1014
v in removed_aliases && continue
953
1015
freshag[v] = c => a
954
1016
end
@@ -959,6 +1021,10 @@ function alias_eliminate_graph!(graph, var_to_diff, mm_orig::SparseMatrixCLIL)
959
1021
mm = reduce! (copy (echelon_mm), ag)
960
1022
@warn " wow" mm
961
1023
end
1024
+ for (v, (c, a)) in ag
1025
+ a = iszero (a) ? 0 : c * fullvars[a]
1026
+ @info " ag" fullvars[v] => a
1027
+ end
962
1028
963
1029
# Step 5: Reflect our update decisions back into the graph, and make sure
964
1030
# that the RHS of observable variables are defined.
0 commit comments