Skip to content

Commit b89390a

Browse files
committed
Add tests.
1 parent 79c81ab commit b89390a

13 files changed

Lines changed: 260 additions & 142 deletions

ext/AMDExt.jl

Lines changed: 151 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,201 @@
11
module AMDExt
22

3-
using AMD: AMD as AMDLib
3+
using Base: oneto
44
using CliqueTrees
55
using Graphs
66

7+
import AMD as AMDLib
8+
9+
const AMD_DENSE = AMDLib.AMD_DENSE
10+
const AMD_AGGRESSIVE = AMDLib.AMD_AGGRESSIVE
11+
const COLAMD_DENSE_ROW = AMDLib.COLAMD_DENSE_ROW
12+
const COLAMD_DENSE_COL = AMDLib.COLAMD_DENSE_COL
13+
const COLAMD_AGGRESSIVE = AMDLib.COLAMD_AGGRESSIVE
14+
715
function CliqueTrees.permutation(graph, alg::Union{AMD, SymAMD})
816
return permutation(BipartiteGraph(graph), alg)
917
end
1018

11-
function CliqueTrees.permutation(graph::BipartiteGraph{V}, alg::AMD) where {V}
19+
function CliqueTrees.permutation(graph::AbstractGraph, alg::Union{AMD, SymAMD})
20+
order = amd(graph, alg)
21+
return order, invperm(order)
22+
end
23+
24+
function amd(graph::AbstractGraph{V}, alg::Union{AMD, SymAMD}) where {V}
25+
new = BipartiteGraph{Cint, Cint}(graph)
26+
order::Vector{V} = amd(new, alg)
27+
return order
28+
end
29+
30+
function amd(graph::AbstractGraph{Int64}, alg::Union{AMD, SymAMD})
31+
new = BipartiteGraph{Int64, Int64}(graph)
32+
return amd(new, alg)
33+
end
34+
35+
function amd(graph::BipartiteGraph{Cint, Cint, Vector{Cint}, Vector{Cint}}, alg::AMD)
36+
n = nv(graph); m = ne(graph); nn = n + one(Cint)
37+
1238
# set parameters
1339
meta = AMDLib.Amd()
14-
meta.control[AMDLib.AMD_DENSE] = alg.dense
15-
meta.control[AMDLib.AMD_AGGRESSIVE] = alg.aggressive
40+
setmeta!(meta, alg)
1641

1742
# construct AMD graph
18-
nrow = convert(Cint, nv(graph))
19-
colptr = Vector{Cint}(pointers(graph))
20-
rowval = Vector{Cint}(targets(graph))
21-
colptr .-= one(Cint) # 0-based indexing
22-
rowval .-= one(Cint) # 0-based indexing
43+
xadj = pointers(graph)
44+
adjncy = targets(graph)
45+
46+
@inbounds for v in oneto(nn)
47+
xadj[v] -= one(Cint)
48+
end
49+
50+
@inbounds for v in oneto(m)
51+
adjncy[v] -= one(Cint)
52+
end
2353

2454
# construct permutation
25-
p = zeros(Cint, nv(graph))
26-
AMDLib.amd_order(nrow, colptr, rowval, p, meta.control, meta.info)
27-
p .+= one(Cint) # 1-based indexing
55+
order = zeros(Cint, n)
56+
AMDLib.amd_order(n, xadj, adjncy, order, meta.control, meta.info)
2857

29-
# restore vertex type
30-
order::Vector{V} = p
31-
return order, invperm(order)
58+
@inbounds for v in oneto(n)
59+
xadj[v] += one(Cint)
60+
order[v] += one(Cint)
61+
end
62+
63+
xadj[nn] += one(Cint)
64+
65+
@inbounds for v in oneto(m)
66+
adjncy[v] += one(Cint)
67+
end
68+
69+
return order
3270
end
3371

34-
function CliqueTrees.permutation(graph::BipartiteGraph{Int64}, alg::AMD)
72+
73+
function amd(graph::BipartiteGraph{Int64, Int64, Vector{Int64}, Vector{Int64}}, alg::AMD)
74+
n = nv(graph); m = ne(graph); nn = n + one(Int64)
75+
3576
# set parameters
3677
meta = AMDLib.Amd()
37-
meta.control[AMDLib.AMD_DENSE] = alg.dense
38-
meta.control[AMDLib.AMD_AGGRESSIVE] = alg.aggressive
78+
setmeta!(meta, alg)
3979

4080
# construct AMD graph
41-
nrow = nv(graph)
42-
colptr = Vector{Int64}(pointers(graph))
43-
rowval = Vector{Int64}(targets(graph))
44-
colptr .-= one(Int64) # 0-based indexing
45-
rowval .-= one(Int64) # 0-based indexing
81+
xadj = pointers(graph)
82+
adjncy = targets(graph)
83+
84+
@inbounds for v in oneto(nn)
85+
xadj[v] -= one(Int64)
86+
end
87+
88+
@inbounds for v in oneto(m)
89+
adjncy[v] -= one(Int64)
90+
end
4691

4792
# construct permutation
48-
p = zeros(Int64, nv(graph))
49-
AMDLib.amd_l_order(nrow, colptr, rowval, p, meta.control, meta.info)
50-
p .+= one(Int64) # 1-based indexing
93+
order = zeros(Int64, n)
94+
AMDLib.amd_l_order(n, xadj, adjncy, order, meta.control, meta.info)
5195

52-
# restore vertex type
53-
order = p
54-
return order, invperm(order)
96+
@inbounds for v in oneto(n)
97+
xadj[v] += one(Int64)
98+
order[v] += one(Int64)
99+
end
100+
101+
xadj[nn] += one(Int64)
102+
103+
@inbounds for v in oneto(m)
104+
adjncy[v] += one(Int64)
105+
end
106+
107+
return order
55108
end
56109

57-
function CliqueTrees.permutation(graph::BipartiteGraph{V}, alg::SymAMD) where {V}
110+
function amd(graph::BipartiteGraph{Cint, Cint, Vector{Cint}, Vector{Cint}}, alg::SymAMD)
111+
n = nv(graph); m = ne(graph); nn = n + one(Cint)
112+
58113
# set parameters
59114
meta = AMDLib.Colamd{Cint}()
60-
meta.knobs[AMDLib.COLAMD_DENSE_ROW] = alg.dense_row
61-
meta.knobs[AMDLib.COLAMD_DENSE_COL] = alg.dense_col
62-
meta.knobs[AMDLib.COLAMD_AGGRESSIVE] = alg.aggressive
115+
setmeta!(meta, alg)
63116

64117
# construct AMD graph
65-
nrow = convert(Cint, nv(graph))
66-
colptr = Vector{Cint}(pointers(graph))
67-
rowval = Vector{Cint}(targets(graph))
68-
colptr .-= one(Cint) # 0-based indexing
69-
rowval .-= one(Cint) # 0-based indexing
118+
xadj = pointers(graph)
119+
adjncy = targets(graph)
120+
121+
@inbounds for v in oneto(nn)
122+
xadj[v] -= one(Cint)
123+
end
124+
125+
@inbounds for v in oneto(m)
126+
adjncy[v] -= one(Cint)
127+
end
70128

71129
# construct permutation
72-
p = zeros(Cint, nv(graph) + 1)
130+
order = zeros(Cint, nn)
73131
cfun_calloc = @cfunction(Base.Libc.calloc, Ptr{Cvoid}, (Cint, Cint))
74132
cfun_free = @cfunction(Base.Libc.free, Cvoid, (Ptr{Cvoid},))
75-
AMDLib.symamd(nrow, rowval, colptr, p, meta.knobs, meta.stats, cfun_calloc, cfun_free)
76-
p .+= one(Cint) # 1-based indexing
133+
AMDLib.symamd(n, adjncy, xadj, order, meta.knobs, meta.stats, cfun_calloc, cfun_free)
77134

78-
# restore vertex type
79-
order::Vector{V} = @view p[begin:(end - 1)]
80-
return order, invperm(order)
135+
@inbounds for v in oneto(n)
136+
xadj[v] += one(Cint)
137+
order[v] += one(Cint)
138+
end
139+
140+
xadj[nn] += one(Cint)
141+
142+
@inbounds for v in oneto(m)
143+
adjncy[v] += one(Cint)
144+
end
145+
146+
return resize!(order, n)
81147
end
82148

83-
function CliqueTrees.permutation(graph::BipartiteGraph{Int64}, alg::SymAMD)
149+
function amd(graph::BipartiteGraph{Int64, Int64, Vector{Int64}, Vector{Int64}}, alg::SymAMD)
150+
n = nv(graph); m = ne(graph); nn = n + one(Int64)
151+
84152
# set parameters
85153
meta = AMDLib.Colamd{Int64}()
86-
meta.knobs[AMDLib.COLAMD_DENSE_ROW] = alg.dense_row
87-
meta.knobs[AMDLib.COLAMD_DENSE_COL] = alg.dense_col
88-
meta.knobs[AMDLib.COLAMD_AGGRESSIVE] = alg.aggressive
154+
setmeta!(meta, alg)
89155

90156
# construct AMD graph
91-
nrow = nv(graph)
92-
colptr = Vector{Int64}(pointers(graph))
93-
rowval = Vector{Int64}(targets(graph))
94-
colptr .-= one(Int64) # 0-based indexing
95-
rowval .-= one(Int64) # 0-based indexing
157+
xadj = pointers(graph)
158+
adjncy = targets(graph)
159+
160+
@inbounds for v in oneto(nn)
161+
xadj[v] -= one(Int64)
162+
end
163+
164+
@inbounds for v in oneto(m)
165+
adjncy[v] -= one(Int64)
166+
end
96167

97168
# construct permutation
98-
p = zeros(Int64, nv(graph) + 1)
169+
order = zeros(Int64, nn)
99170
cfun_calloc = @cfunction(Base.Libc.calloc, Ptr{Cvoid}, (Int64, Int64))
100171
cfun_free = @cfunction(Base.Libc.free, Cvoid, (Ptr{Cvoid},))
101-
AMDLib.symamd_l(nrow, rowval, colptr, p, meta.knobs, meta.stats, cfun_calloc, cfun_free)
102-
p .+= one(Int64) # 1-based indexing
172+
AMDLib.symamd_l(n, adjncy, xadj, order, meta.knobs, meta.stats, cfun_calloc, cfun_free)
103173

104-
# restore vertex type
105-
order = p[begin:(end - 1)]
106-
return order, invperm(order)
174+
@inbounds for v in oneto(n)
175+
xadj[v] += one(Int64)
176+
order[v] += one(Int64)
177+
end
178+
179+
xadj[nn] += one(Int64)
180+
181+
@inbounds for v in oneto(m)
182+
adjncy[v] += one(Int64)
183+
end
184+
185+
return resize!(order, n)
186+
end
187+
188+
function setmeta!(meta::AMDLib.Amd, alg::AMD)
189+
meta.control[AMD_DENSE] = alg.dense
190+
meta.control[AMD_AGGRESSIVE] = alg.aggressive
191+
return
192+
end
193+
194+
function setmeta!(meta::AMDLib.Colamd, alg::SymAMD)
195+
meta.knobs[COLAMD_DENSE_ROW] = alg.dense_row
196+
meta.knobs[COLAMD_DENSE_COL] = alg.dense_col
197+
meta.knobs[COLAMD_AGGRESSIVE] = alg.aggressive
198+
return
107199
end
108200

109201
end

0 commit comments

Comments
 (0)