Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ version = "0.3.5"
[deps]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[compat]
DataStructures = "0.18"
Distances = "0.8, 0.9, 0.10"
LightGraphs = "1.3"
Graphs = "1.4"
Reexport = "0.2, 1.0"
julia = "1.5, 1.6, 1.7"

Expand Down
2 changes: 1 addition & 1 deletion benchmark/bench_descent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module BenchDescent

using NearestNeighborDescent
using NearestNeighborDescent: local_join!, get_neighbors!
using LightGraphs
using Graphs
using Distances
using BenchmarkTools
using Random
Expand Down
2 changes: 1 addition & 1 deletion benchmark/bench_knn_graphs.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module BenchKNNGraphs

using NearestNeighborDescent.KNNGraphs
using LightGraphs
using Graphs
using Distances
using BenchmarkTools
using Random
Expand Down
2 changes: 1 addition & 1 deletion benchmark/benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ using Pkg
tempdir = mktempdir()
Pkg.activate(tempdir)
Pkg.develop(PackageSpec(path=joinpath(@__DIR__, "..")))
Pkg.add(["BenchmarkTools", "PkgBenchmark", "Random", "Distances", "LightGraphs"])
Pkg.add(["BenchmarkTools", "PkgBenchmark", "Random", "Distances", "Graphs"])
Pkg.resolve()

using NearestNeighborDescent
Expand Down
2 changes: 1 addition & 1 deletion docs/src/examples/descent_iters.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# print information over iterations of nndescent
using NearestNeighborDescent
using LightGraphs
using Graphs
using Distances
using MLDatasets
using Statistics
Expand Down
2 changes: 1 addition & 1 deletion src/NearestNeighborDescent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module NearestNeighborDescent

using DataStructures
using Distances
using LightGraphs
using Graphs
using Reexport

include("knn_graph/KNNGraphs.jl")
Expand Down
2 changes: 1 addition & 1 deletion src/knn_graph/KNNGraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module KNNGraphs

using DataStructures
using Distances
using LightGraphs
using Graphs
using SparseArrays

include("abstract.jl")
Expand Down
4 changes: 2 additions & 2 deletions src/knn_graph/abstract.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ abstract type ApproximateKNNGraph{V<:Integer,
# interface
Base.eltype(::ApproximateKNNGraph{V}) where V = V
# all knn graphs are directed
LightGraphs.is_directed(::Type{<:ApproximateKNNGraph}) = true
LightGraphs.is_directed(::ApproximateKNNGraph) = true
Graphs.is_directed(::Type{<:ApproximateKNNGraph}) = true
Graphs.is_directed(::ApproximateKNNGraph) = true

"""
knn_diameter(g::ApproximateKNNGraph{V}, v::V)
Expand Down
8 changes: 4 additions & 4 deletions src/knn_graph/heap_edge.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Base.eltype(e::HeapKNNGraphEdge{V}) where V = V

@inline flag(e::HeapKNNGraphEdge) = e.flag
@inline weight(e::HeapKNNGraphEdge) = e.weight
# lightgraphs interface
@inline LightGraphs.src(e::HeapKNNGraphEdge) = e.src
@inline LightGraphs.dst(e::HeapKNNGraphEdge) = e.dst
@inline LightGraphs.reverse(e::E) where {E <: HeapKNNGraphEdge} = E(dst(e), src(e), weight(e), flag(e))
# graphs interface
@inline Graphs.src(e::HeapKNNGraphEdge) = e.src
@inline Graphs.dst(e::HeapKNNGraphEdge) = e.dst
@inline Graphs.reverse(e::E) where {E <: HeapKNNGraphEdge} = E(dst(e), src(e), weight(e), flag(e))
26 changes: 13 additions & 13 deletions src/knn_graph/heap_graph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ function HeapKNNGraph(data::D, args...; kwargs...) where D <: AbstractMatrix
end


# lightgraphs interface
# graphs interface
"""
edges(g::HeapKNNGraph)

Return an iterator of the edges in this KNN graph. Note that mutating the edges
while iterating through `edges(g)` may result in undefined behavior.
"""
@inline function LightGraphs.edges(g::Union{HeapKNNGraph, LockHeapKNNGraph})
@inline function Graphs.edges(g::Union{HeapKNNGraph, LockHeapKNNGraph})
return (e for heap in g.heaps for e in heap.valtree)
end

Expand All @@ -96,7 +96,7 @@ end

Return an iterator of the vertices in the KNN graph.
"""
@inline function LightGraphs.vertices(g::Union{HeapKNNGraph{V}, LockHeapKNNGraph{V}}) where V
@inline function Graphs.vertices(g::Union{HeapKNNGraph{V}, LockHeapKNNGraph{V}}) where V
return one(V):V(length(g.heaps))
end

Expand All @@ -106,7 +106,7 @@ end
Returns a SparseMatrixCSC{U, V} `w` where `w[j, i]` returns the weight of the
directed edge from vertex `i` to `j`.
"""
function LightGraphs.weights(g::Union{HeapKNNGraph{V, U}, LockHeapKNNGraph{V, U}}) where {V, U}
function Graphs.weights(g::Union{HeapKNNGraph{V, U}, LockHeapKNNGraph{V, U}}) where {V, U}
# dests, srcs, ws where weights[dests[k], srcs[k]] = ws[k]
srcs, dsts = V[], V[]
vals = U[]
Expand All @@ -123,7 +123,7 @@ end

Return the type of the edges in `g`.
"""
function LightGraphs.edgetype(g::Union{HeapKNNGraph{V, U}, LockHeapKNNGraph{V, U}}) where {V, U}
function Graphs.edgetype(g::Union{HeapKNNGraph{V, U}, LockHeapKNNGraph{V, U}}) where {V, U}
return HeapKNNGraphEdge{V, U}
end

Expand All @@ -132,7 +132,7 @@ end

Return true if the graph g has an edge from `s` to `d`, else false.
"""
@inline function LightGraphs.has_edge(g::Union{HeapKNNGraph{V}, LockHeapKNNGraph{V}}, s, d) where V
@inline function Graphs.has_edge(g::Union{HeapKNNGraph{V}, LockHeapKNNGraph{V}}, s, d) where V
for e in g.heaps[s].valtree
if dst(e) == d
return true
Expand All @@ -145,7 +145,7 @@ end

Return true if `g` contains the edge `e`.
"""
@inline function LightGraphs.has_edge(g::Union{HeapKNNGraph{V, U}, LockHeapKNNGraph{V, U}},
@inline function Graphs.has_edge(g::Union{HeapKNNGraph{V, U}, LockHeapKNNGraph{V, U}},
e::HeapKNNGraphEdge{V, U}) where {V, U}
return e in g.heaps[src(e)].valtree
end
Expand All @@ -155,21 +155,21 @@ end

Return true if vertex `v` is in `g`.
"""
@inline LightGraphs.has_vertex(g::Union{HeapKNNGraph{V}, LockHeapKNNGraph{V}}, v::V) where V = v in 1:nv(g)
@inline Graphs.has_vertex(g::Union{HeapKNNGraph{V}, LockHeapKNNGraph{V}}, v::V) where V = v in 1:nv(g)

"""
ne(g::HeapKNNGraph)

Return the number of edges in `g`.
"""
@inline LightGraphs.ne(g::Union{HeapKNNGraph{V, U}, LockHeapKNNGraph{V, U}}) where {V, U} = g.n_neighbors*nv(g)
@inline Graphs.ne(g::Union{HeapKNNGraph{V, U}, LockHeapKNNGraph{V, U}}) where {V, U} = g.n_neighbors*nv(g)

"""
nv(g::HeapKNNGraph)

Return the number of vertices in `g`.
"""
@inline LightGraphs.nv(g::Union{HeapKNNGraph, LockHeapKNNGraph}) = length(g.heaps)
@inline Graphs.nv(g::Union{HeapKNNGraph, LockHeapKNNGraph}) = length(g.heaps)

"""
inneighbors(g::HeapKNNGraph, v)
Expand All @@ -182,7 +182,7 @@ HeapKNNGraph doesn't store inneighbors directly; it must find them by iterating
over the outgoing edges for each vertex and saving those where `v == dst(e)`.
Thus, this has time complexity `𝒪(nv(g)*K)`.
"""
@inline function LightGraphs.inneighbors(g::HeapKNNGraph{V}, v::V) where V
@inline function Graphs.inneighbors(g::HeapKNNGraph{V}, v::V) where V
return collect(src(e) for e in edges(g) if dst(e) == v)
end

Expand All @@ -196,7 +196,7 @@ Return a list of the neighbors of `v` connected by outgoing edges.
HeapKNNGraph stores each vertex's outgoing edges in a heap, so this has a time
complexity of `𝒪(K)`.
"""
@inline LightGraphs.outneighbors(g::HeapKNNGraph{V}, v::V) where V = dst.(g.heaps[v].valtree)
@inline Graphs.outneighbors(g::HeapKNNGraph{V}, v::V) where V = dst.(g.heaps[v].valtree)

"""
add_edge!(g::HeapKNNGraph, e::HeapKNNGraphEdge)
Expand All @@ -205,7 +205,7 @@ Try to add an edge `e`, indicating a new candidate nearest neighbor `e.dest` for
vertex `e.src`, by pushing onto `e.src`'s heap. This will fail (return `false`) if
`e` is already in the heap or if `e.weight > first(heap).weight`. Otherwise return `true`.
"""
function LightGraphs.add_edge!(g::HeapKNNGraph, e::HeapKNNGraphEdge)
function Graphs.add_edge!(g::HeapKNNGraph, e::HeapKNNGraphEdge)
# NOTE we can assume the invariants for heap knn graphs hold
if e < first(g.heaps[src(e)]) && !has_edge(g, src(e), dst(e))
# we know this edge is smaller than the first, so we can start by removing that
Expand Down
6 changes: 3 additions & 3 deletions src/knn_graph/threaded_heap_graph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Similar to `inneighbors(g::HeapKNNGraph, v)`, except it acquires locks for the n
as it iterates in order for this to be thread-safe.

"""
@inline function LightGraphs.inneighbors(g::LockHeapKNNGraph{V}, v::V) where V
@inline function Graphs.inneighbors(g::LockHeapKNNGraph{V}, v::V) where V
neighbs = V[]
for i in nv(g)
lock(g.locks[i]) do
Expand All @@ -99,7 +99,7 @@ end
Similar to `outneighbors(g::HeapKNNGraph, v)`, except locks the neighbor heap before collecting
to make this thread-safe.
"""
@inline function LightGraphs.outneighbors(g::LockHeapKNNGraph{V}, v::V) where V
@inline function Graphs.outneighbors(g::LockHeapKNNGraph{V}, v::V) where V
neighbs = lock(g.locks[v]) do
dst.(g.heaps[v].valtree)
end
Expand All @@ -111,7 +111,7 @@ end

Similar to `add_edge!(g::HeapKNNGraph, e)`, but made thread-safe using locks.
"""
function LightGraphs.add_edge!(g::LockHeapKNNGraph, e::HeapKNNGraphEdge)
function Graphs.add_edge!(g::LockHeapKNNGraph, e::HeapKNNGraphEdge)
# NOTE we can assume the invariants for heap knn graphs hold
lock(g.locks[src(e)]) do
if e < first(g.heaps[src(e)]) && !has_edge(g, src(e), dst(e))
Expand Down
4 changes: 2 additions & 2 deletions test/knn_graph/heap_graph_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
@test is_valid_knn_graph(g)
end
end
@testset "LightGraphs interface tests" begin
# test LightGraphs interface methods exist on HeapKNNGraph, LockHeapKNNGraph
@testset "Graphs interface tests" begin
# test Graphs interface methods exist on HeapKNNGraph, LockHeapKNNGraph
for GraphT in [HeapKNNGraph, LockHeapKNNGraph]
for m in (edges, vertices, weights, edgetype, ne, nv, eltype)
@test hasmethod(m, (GraphT,))
Expand Down
2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# tests
using NearestNeighborDescent
using NearestNeighborDescent.KNNGraphs
using LightGraphs
using Graphs
using DataStructures
using Distances
using Test
Expand Down