|
1 |
| -@testset "Query" begin |
2 |
| - @testset "is_bidirected" begin |
3 |
| - g = rand_graph(10, 20, bidirected = true, graph_type = GRAPH_T) |
4 |
| - @test is_bidirected(g) |
| 1 | +@testset "is_bidirected" begin |
| 2 | + g = rand_graph(10, 20, bidirected = true, graph_type = GRAPH_T) |
| 3 | + @test is_bidirected(g) |
5 | 4 |
|
6 |
| - g = rand_graph(10, 20, bidirected = false, graph_type = GRAPH_T) |
7 |
| - @test !is_bidirected(g) |
| 5 | + g = rand_graph(10, 20, bidirected = false, graph_type = GRAPH_T) |
| 6 | + @test !is_bidirected(g) |
| 7 | +end |
| 8 | + |
| 9 | +@testset "has_multi_edges" begin if GRAPH_T == :coo |
| 10 | + s = [1, 1, 2, 3] |
| 11 | + t = [2, 2, 2, 4] |
| 12 | + g = GNNGraph(s, t, graph_type = GRAPH_T) |
| 13 | + @test has_multi_edges(g) |
| 14 | + |
| 15 | + s = [1, 2, 2, 3] |
| 16 | + t = [2, 1, 2, 4] |
| 17 | + g = GNNGraph(s, t, graph_type = GRAPH_T) |
| 18 | + @test !has_multi_edges(g) |
| 19 | +end end |
| 20 | + |
| 21 | +@testset "edges" begin |
| 22 | + g = rand_graph(4, 10, graph_type = GRAPH_T) |
| 23 | + @test edgetype(g) <: Graphs.Edge |
| 24 | + for e in edges(g) |
| 25 | + @test e isa Graphs.Edge |
8 | 26 | end
|
| 27 | +end |
| 28 | + |
| 29 | +@testset "has_isolated_nodes" begin |
| 30 | + s = [1, 2, 3] |
| 31 | + t = [2, 3, 2] |
| 32 | + g = GNNGraph(s, t, graph_type = GRAPH_T) |
| 33 | + @test has_isolated_nodes(g) == false |
| 34 | + @test has_isolated_nodes(g, dir = :in) == true |
| 35 | +end |
| 36 | + |
| 37 | +@testset "has_self_loops" begin |
| 38 | + s = [1, 1, 2, 3] |
| 39 | + t = [2, 2, 2, 4] |
| 40 | + g = GNNGraph(s, t, graph_type = GRAPH_T) |
| 41 | + @test has_self_loops(g) |
9 | 42 |
|
10 |
| - @testset "has_multi_edges" begin if GRAPH_T == :coo |
| 43 | + s = [1, 1, 2, 3] |
| 44 | + t = [2, 2, 3, 4] |
| 45 | + g = GNNGraph(s, t, graph_type = GRAPH_T) |
| 46 | + @test !has_self_loops(g) |
| 47 | +end |
| 48 | + |
| 49 | +@testset "degree" begin |
| 50 | + @testset "unweighted" begin |
11 | 51 | s = [1, 1, 2, 3]
|
12 | 52 | t = [2, 2, 2, 4]
|
13 | 53 | g = GNNGraph(s, t, graph_type = GRAPH_T)
|
14 |
| - @test has_multi_edges(g) |
15 | 54 |
|
16 |
| - s = [1, 2, 2, 3] |
17 |
| - t = [2, 1, 2, 4] |
18 |
| - g = GNNGraph(s, t, graph_type = GRAPH_T) |
19 |
| - @test !has_multi_edges(g) |
20 |
| - end end |
21 |
| - |
22 |
| - @testset "edges" begin |
23 |
| - g = rand_graph(4, 10, graph_type = GRAPH_T) |
24 |
| - @test edgetype(g) <: Graphs.Edge |
25 |
| - for e in edges(g) |
26 |
| - @test e isa Graphs.Edge |
| 55 | + @test degree(g) == degree(g; dir = :out) == [2, 1, 1, 0] # default is outdegree |
| 56 | + @test degree(g; dir = :in) == [0, 3, 0, 1] |
| 57 | + @test degree(g; dir = :both) == [2, 4, 1, 1] |
| 58 | + @test eltype(degree(g, Float32)) == Float32 |
| 59 | + |
| 60 | + if TEST_GPU |
| 61 | + g_gpu = g |> gpu |
| 62 | + d = degree(g) |
| 63 | + d_gpu = degree(g_gpu) |
| 64 | + @test d_gpu isa CuVector{Int} |
| 65 | + @test Array(d_gpu) == d |
27 | 66 | end
|
28 | 67 | end
|
29 | 68 |
|
30 |
| - @testset "has_isolated_nodes" begin |
31 |
| - s = [1, 2, 3] |
32 |
| - t = [2, 3, 2] |
33 |
| - g = GNNGraph(s, t, graph_type = GRAPH_T) |
34 |
| - @test has_isolated_nodes(g) == false |
35 |
| - @test has_isolated_nodes(g, dir = :in) == true |
36 |
| - end |
37 |
| - |
38 |
| - @testset "has_self_loops" begin |
| 69 | + @testset "weighted" begin |
| 70 | + # weighted degree |
39 | 71 | s = [1, 1, 2, 3]
|
40 | 72 | t = [2, 2, 2, 4]
|
41 |
| - g = GNNGraph(s, t, graph_type = GRAPH_T) |
42 |
| - @test has_self_loops(g) |
43 |
| - |
44 |
| - s = [1, 1, 2, 3] |
45 |
| - t = [2, 2, 3, 4] |
46 |
| - g = GNNGraph(s, t, graph_type = GRAPH_T) |
47 |
| - @test !has_self_loops(g) |
48 |
| - end |
| 73 | + eweight = [0.1, 2.1, 1.2, 1] |
| 74 | + g = GNNGraph((s, t, eweight), graph_type = GRAPH_T) |
| 75 | + @test degree(g) == [2.2, 1.2, 1.0, 0.0] |
| 76 | + @test degree(g, edge_weight = nothing) == degree(g) |
| 77 | + d = degree(g, edge_weight = false) |
| 78 | + if GRAPH_T == :coo |
| 79 | + @test d == [2, 1, 1, 0] |
| 80 | + else |
| 81 | + # Adjacency matrix representation cannot disambiguate multiple edges |
| 82 | + # and edge weights |
| 83 | + @test d == [1, 1, 1, 0] |
| 84 | + end |
| 85 | + @test eltype(d) <: Integer |
| 86 | + if GRAPH_T == :coo |
| 87 | + # TODO use the @test option broken = (GRAPH_T != :coo) on julia >= 1.7 |
| 88 | + @test degree(g, edge_weight = 2 * eweight) == [4.4, 2.4, 2.0, 0.0] |
| 89 | + else |
| 90 | + @test_broken degree(g, edge_weight = 2 * eweight) == [4.4, 2.4, 2.0, 0.0] |
| 91 | + end |
49 | 92 |
|
50 |
| - @testset "degree" begin |
51 |
| - @testset "unweighted" begin |
52 |
| - s = [1, 1, 2, 3] |
53 |
| - t = [2, 2, 2, 4] |
54 |
| - g = GNNGraph(s, t, graph_type = GRAPH_T) |
55 |
| - |
56 |
| - @test degree(g) == degree(g; dir = :out) == [2, 1, 1, 0] # default is outdegree |
57 |
| - @test degree(g; dir = :in) == [0, 3, 0, 1] |
58 |
| - @test degree(g; dir = :both) == [2, 4, 1, 1] |
59 |
| - @test eltype(degree(g, Float32)) == Float32 |
60 |
| - |
61 |
| - if TEST_GPU |
62 |
| - g_gpu = g |> gpu |
63 |
| - d = degree(g) |
64 |
| - d_gpu = degree(g_gpu) |
65 |
| - @test d_gpu isa CuVector{Int} |
66 |
| - @test Array(d_gpu) == d |
67 |
| - end |
| 93 | + if TEST_GPU |
| 94 | + g_gpu = g |> gpu |
| 95 | + d = degree(g) |
| 96 | + d_gpu = degree(g_gpu) |
| 97 | + @test d_gpu isa CuVector{Float32} |
| 98 | + @test Array(d_gpu) ≈ d |
68 | 99 | end
|
| 100 | + @testset "gradient" begin |
| 101 | + gw = gradient(eweight) do w |
| 102 | + g = GNNGraph((s, t, w), graph_type = GRAPH_T) |
| 103 | + sum(degree(g, edge_weight = false)) |
| 104 | + end[1] |
69 | 105 |
|
70 |
| - @testset "weighted" begin |
71 |
| - # weighted degree |
72 |
| - s = [1, 1, 2, 3] |
73 |
| - t = [2, 2, 2, 4] |
74 |
| - eweight = [0.1, 2.1, 1.2, 1] |
75 |
| - g = GNNGraph((s, t, eweight), graph_type = GRAPH_T) |
76 |
| - @test degree(g) == [2.2, 1.2, 1.0, 0.0] |
77 |
| - @test degree(g, edge_weight = nothing) == degree(g) |
78 |
| - d = degree(g, edge_weight = false) |
79 |
| - if GRAPH_T == :coo |
80 |
| - @test d == [2, 1, 1, 0] |
81 |
| - else |
82 |
| - # Adjacency matrix representation cannot disambiguate multiple edges |
83 |
| - # and edge weights |
84 |
| - @test d == [1, 1, 1, 0] |
85 |
| - end |
86 |
| - @test eltype(d) <: Integer |
87 |
| - if GRAPH_T == :coo |
88 |
| - # TODO use the @test option broken = (GRAPH_T != :coo) on julia >= 1.7 |
89 |
| - @test degree(g, edge_weight = 2 * eweight) == [4.4, 2.4, 2.0, 0.0] |
90 |
| - else |
91 |
| - @test_broken degree(g, edge_weight = 2 * eweight) == [4.4, 2.4, 2.0, 0.0] |
92 |
| - end |
| 106 | + @test gw === nothing |
93 | 107 |
|
94 |
| - if TEST_GPU |
95 |
| - g_gpu = g |> gpu |
96 |
| - d = degree(g) |
97 |
| - d_gpu = degree(g_gpu) |
98 |
| - @test d_gpu isa CuVector{Float32} |
99 |
| - @test Array(d_gpu) ≈ d |
100 |
| - end |
101 |
| - @testset "gradient" begin |
102 |
| - gw = gradient(eweight) do w |
103 |
| - g = GNNGraph((s, t, w), graph_type = GRAPH_T) |
104 |
| - sum(degree(g, edge_weight = false)) |
105 |
| - end[1] |
106 |
| - |
107 |
| - @test gw === nothing |
108 |
| - |
109 |
| - gw = gradient(eweight) do w |
110 |
| - g = GNNGraph((s, t, w), graph_type = GRAPH_T) |
111 |
| - sum(degree(g, edge_weight = true)) |
112 |
| - end[1] |
113 |
| - |
114 |
| - if GRAPH_T == :sparse |
115 |
| - @test_broken gw isa Vector{Float64} |
116 |
| - @test gw isa AbstractVector{Float64} |
117 |
| - else |
118 |
| - @test gw isa Vector{Float64} |
119 |
| - end |
| 108 | + gw = gradient(eweight) do w |
| 109 | + g = GNNGraph((s, t, w), graph_type = GRAPH_T) |
| 110 | + sum(degree(g, edge_weight = true)) |
| 111 | + end[1] |
| 112 | + |
| 113 | + if GRAPH_T == :sparse |
| 114 | + @test_broken gw isa Vector{Float64} |
| 115 | + @test gw isa AbstractVector{Float64} |
| 116 | + else |
| 117 | + @test gw isa Vector{Float64} |
120 | 118 | end
|
121 | 119 | end
|
122 | 120 | end
|
| 121 | +end |
123 | 122 |
|
124 |
| - @testset "laplacian_matrix" begin |
125 |
| - g = rand_graph(10, 30, graph_type = GRAPH_T) |
126 |
| - A = adjacency_matrix(g) |
127 |
| - D = Diagonal(vec(sum(A, dims = 2))) |
128 |
| - L = laplacian_matrix(g) |
129 |
| - @test eltype(L) == eltype(g) |
130 |
| - @test L ≈ D - A |
131 |
| - end |
132 |
| - |
133 |
| - @testset "laplacian_lambda_max" begin |
134 |
| - s = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] |
135 |
| - t = [2, 3, 4, 5, 1, 5, 1, 2, 3, 4] |
136 |
| - g = GNNGraph(s, t) |
137 |
| - @test laplacian_lambda_max(g) ≈ Float32(1.809017) |
138 |
| - data1 = [g for i in 1:5] |
139 |
| - gall1 = Flux.batch(data1) |
140 |
| - @test laplacian_lambda_max(gall1) ≈ [Float32(1.809017) for i in 1:5] |
141 |
| - data2 = [rand_graph(10, 20) for i in 1:3] |
142 |
| - gall2 = Flux.batch(data2) |
143 |
| - @test length(laplacian_lambda_max(gall2)) == 3 |
144 |
| - end |
145 |
| - |
146 |
| - @testset "adjacency_matrix" begin |
147 |
| - a = sprand(5, 5, 0.5) |
148 |
| - abin = map(x -> x > 0 ? 1 : 0, a) |
| 123 | +@testset "laplacian_matrix" begin |
| 124 | + g = rand_graph(10, 30, graph_type = GRAPH_T) |
| 125 | + A = adjacency_matrix(g) |
| 126 | + D = Diagonal(vec(sum(A, dims = 2))) |
| 127 | + L = laplacian_matrix(g) |
| 128 | + @test eltype(L) == eltype(g) |
| 129 | + @test L ≈ D - A |
| 130 | +end |
149 | 131 |
|
150 |
| - g = GNNGraph(a, graph_type = GRAPH_T) |
151 |
| - A = adjacency_matrix(g, Float32) |
152 |
| - @test A ≈ a |
153 |
| - @test eltype(A) == Float32 |
| 132 | +@testset "laplacian_lambda_max" begin |
| 133 | + s = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] |
| 134 | + t = [2, 3, 4, 5, 1, 5, 1, 2, 3, 4] |
| 135 | + g = GNNGraph(s, t) |
| 136 | + @test laplacian_lambda_max(g) ≈ Float32(1.809017) |
| 137 | + data1 = [g for i in 1:5] |
| 138 | + gall1 = Flux.batch(data1) |
| 139 | + @test laplacian_lambda_max(gall1) ≈ [Float32(1.809017) for i in 1:5] |
| 140 | + data2 = [rand_graph(10, 20) for i in 1:3] |
| 141 | + gall2 = Flux.batch(data2) |
| 142 | + @test length(laplacian_lambda_max(gall2, add_self_loops=true)) == 3 |
| 143 | +end |
154 | 144 |
|
155 |
| - Abin = adjacency_matrix(g, Float32, weighted = false) |
156 |
| - @test Abin ≈ abin |
157 |
| - @test eltype(Abin) == Float32 |
| 145 | +@testset "adjacency_matrix" begin |
| 146 | + a = sprand(5, 5, 0.5) |
| 147 | + abin = map(x -> x > 0 ? 1 : 0, a) |
158 | 148 |
|
159 |
| - @testset "gradient" begin |
160 |
| - s = [1, 2, 3] |
161 |
| - t = [2, 3, 1] |
162 |
| - w = [0.1, 0.1, 0.2] |
163 |
| - gw = gradient(w) do w |
164 |
| - g = GNNGraph(s, t, w, graph_type = GRAPH_T) |
165 |
| - A = adjacency_matrix(g, weighted = false) |
166 |
| - sum(A) |
167 |
| - end[1] |
168 |
| - @test gw === nothing |
| 149 | + g = GNNGraph(a, graph_type = GRAPH_T) |
| 150 | + A = adjacency_matrix(g, Float32) |
| 151 | + @test A ≈ a |
| 152 | + @test eltype(A) == Float32 |
169 | 153 |
|
170 |
| - gw = gradient(w) do w |
171 |
| - g = GNNGraph(s, t, w, graph_type = GRAPH_T) |
172 |
| - A = adjacency_matrix(g, weighted = true) |
173 |
| - sum(A) |
174 |
| - end[1] |
| 154 | + Abin = adjacency_matrix(g, Float32, weighted = false) |
| 155 | + @test Abin ≈ abin |
| 156 | + @test eltype(Abin) == Float32 |
175 | 157 |
|
176 |
| - @test gw == [1, 1, 1] |
177 |
| - end |
| 158 | + @testset "gradient" begin |
| 159 | + s = [1, 2, 3] |
| 160 | + t = [2, 3, 1] |
| 161 | + w = [0.1, 0.1, 0.2] |
| 162 | + gw = gradient(w) do w |
| 163 | + g = GNNGraph(s, t, w, graph_type = GRAPH_T) |
| 164 | + A = adjacency_matrix(g, weighted = false) |
| 165 | + sum(A) |
| 166 | + end[1] |
| 167 | + @test gw === nothing |
| 168 | + |
| 169 | + gw = gradient(w) do w |
| 170 | + g = GNNGraph(s, t, w, graph_type = GRAPH_T) |
| 171 | + A = adjacency_matrix(g, weighted = true) |
| 172 | + sum(A) |
| 173 | + end[1] |
| 174 | + |
| 175 | + @test gw == [1, 1, 1] |
| 176 | + end |
178 | 177 |
|
179 |
| - @testset "khop_adj" begin |
180 |
| - s = [1, 2, 3] |
181 |
| - t = [2, 3, 1] |
182 |
| - w = [0.1, 0.1, 0.2] |
183 |
| - g = GNNGraph(s, t, w) |
184 |
| - @test khop_adj(g, 2) == adjacency_matrix(g) * adjacency_matrix(g) |
185 |
| - @test khop_adj(g, 2, Int8; weighted = false) == sparse([0 0 1; 1 0 0; 0 1 0]) |
186 |
| - @test khop_adj(g, 2, Int8; dir = in, weighted = false) == |
187 |
| - sparse([0 0 1; 1 0 0; 0 1 0]') |
188 |
| - @test khop_adj(g, 1) == adjacency_matrix(g) |
189 |
| - @test eltype(khop_adj(g, 4)) == Float64 |
190 |
| - @test eltype(khop_adj(g, 10, Float32)) == Float32 |
191 |
| - end |
| 178 | + @testset "khop_adj" begin |
| 179 | + s = [1, 2, 3] |
| 180 | + t = [2, 3, 1] |
| 181 | + w = [0.1, 0.1, 0.2] |
| 182 | + g = GNNGraph(s, t, w) |
| 183 | + @test khop_adj(g, 2) == adjacency_matrix(g) * adjacency_matrix(g) |
| 184 | + @test khop_adj(g, 2, Int8; weighted = false) == sparse([0 0 1; 1 0 0; 0 1 0]) |
| 185 | + @test khop_adj(g, 2, Int8; dir = in, weighted = false) == |
| 186 | + sparse([0 0 1; 1 0 0; 0 1 0]') |
| 187 | + @test khop_adj(g, 1) == adjacency_matrix(g) |
| 188 | + @test eltype(khop_adj(g, 4)) == Float64 |
| 189 | + @test eltype(khop_adj(g, 10, Float32)) == Float32 |
192 | 190 | end
|
193 | 191 | end
|
0 commit comments