Skip to content

Commit e2ef5c9

Browse files
authored
Merge pull request #257 from devmotion/dw/aqua
Add tests with Aqua
2 parents 9ce4ab4 + 435dfcf commit e2ef5c9

File tree

8 files changed

+71
-14
lines changed

8 files changed

+71
-14
lines changed

Project.toml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,26 @@ SparseArraysExt = "SparseArrays"
1818
StatisticsExt = "Statistics"
1919

2020
[compat]
21+
Aqua = "0.8.12"
22+
Distributed = "<0.0.1, 1"
2123
ExplicitImports = "1.13.2"
24+
LinearAlgebra = "<0.0.1, 1"
2225
Primes = "0.4, 0.5"
26+
Random = "<0.0.1, 1"
27+
Serialization = "<0.0.1, 1"
2328
SparseArrays = "<0.0.1, 1"
29+
SpecialFunctions = "0.8, 1, 2"
2430
Statistics = "<0.0.1, 1"
31+
Test = "<0.0.1, 1"
2532
julia = "1.10"
2633

2734
[extras]
35+
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
2836
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
2937
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
3038
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
3139
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
3240
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3341

3442
[targets]
35-
test = ["ExplicitImports", "SparseArrays", "SpecialFunctions", "Statistics", "Test"]
43+
test = ["Aqua", "ExplicitImports", "SparseArrays", "SpecialFunctions", "Statistics", "Test"]

ext/SparseArraysExt.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module SparseArraysExt
22

3-
using DistributedArrays: DArray, localpart
3+
using DistributedArrays: DArray, SubDArray, SubOrDArray, localpart
44
using DistributedArrays.Distributed: remotecall_fetch
55
using SparseArrays: SparseArrays, nnz
66

@@ -11,4 +11,21 @@ function SparseArrays.nnz(A::DArray)
1111
return reduce(+, B)
1212
end
1313

14+
# Fix method ambiguities
15+
# TODO: Improve efficiency?
16+
Base.copyto!(dest::SubOrDArray{<:Any,2}, src::SparseArrays.AbstractSparseMatrixCSC) = copyto!(dest, Matrix(src))
17+
@static if isdefined(SparseArrays, :CHOLMOD)
18+
Base.copyto!(dest::SubOrDArray, src::SparseArrays.CHOLMOD.Dense) = copyto!(dest, Array(src))
19+
Base.copyto!(dest::SubOrDArray{T}, src::SparseArrays.CHOLMOD.Dense{T}) where {T<:Union{Float32,Float64,ComplexF32,ComplexF64}} = copyto!(dest, Array(src))
20+
Base.copyto!(dest::SubOrDArray{T,2}, src::SparseArrays.CHOLMOD.Dense{T}) where {T<:Union{Float32,Float64,ComplexF32,ComplexF64}} = copyto!(dest, Array(src))
21+
end
22+
23+
# Fix method ambiguities
24+
for T in (:DArray, :SubDArray)
25+
@eval begin
26+
Base.:(==)(d1::$T{<:Any,1}, d2::SparseArrays.ReadOnly) = d1 == parent(d2)
27+
Base.:(==)(d1::SparseArrays.ReadOnly, d2::$T{<:Any,1}) = parent(d1) == d2
28+
end
29+
end
30+
1431
end

src/broadcast.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ end
6060
# - Q: How do decide on the cuts
6161
# - then localise arguments on each node
6262
##
63-
@inline function Base.copyto!(dest::DDestArray, bc::Broadcasted)
63+
@inline function Base.copyto!(dest::DDestArray, bc::Broadcasted{Nothing})
6464
axes(dest) == axes(bc) || Broadcast.throwdm(axes(dest), axes(bc))
6565

6666
# Distribute Broadcasted

src/darray.jl

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,9 @@ Can return a view into `localpart(A)`
368368
end
369369

370370
# shortcut to set/get localparts of a distributed object
371-
function Base.getindex(d::DArray, s::Symbol)
371+
Base.getindex(d::DArray, s::Symbol) = _getindex(d, s)
372+
Base.getindex(d::DArray{<:Any, 1}, s::Symbol) = _getindex(d, s)
373+
function _getindex(d::DArray, s::Symbol)
372374
@assert s in [:L, :l, :LP, :lp]
373375
return localpart(d)
374376
end
@@ -497,10 +499,28 @@ dfill(v, d1::Integer, drest::Integer...) = dfill(v, convert(Dims, tuple(d1, dres
497499
Construct a distributed uniform random array.
498500
Trailing arguments are the same as those accepted by `DArray`.
499501
"""
500-
drand(r, dims::Dims, args...) = DArray(I -> rand(r, map(length,I)), dims, args...)
501-
drand(r, d1::Integer, drest::Integer...) = drand(r, convert(Dims, tuple(d1, drest...)))
502-
drand(d1::Integer, drest::Integer...) = drand(Float64, convert(Dims, tuple(d1, drest...)))
503-
drand(d::Dims, args...) = drand(Float64, d, args...)
502+
drand(::Type{T}, dims::Dims) where {T} = DArray(I -> rand(T, map(length, I)), dims)
503+
drand(X, dims::Dims) = DArray(I -> rand(X, map(length, I)), dims)
504+
drand(dims::Dims) = drand(Float64, dims)
505+
506+
drand(::Type{T}, d1::Integer, drest::Integer...) where {T} = drand(T, Dims((d1, drest...)))
507+
drand(X, d1::Integer, drest::Integer...) = drand(X, Dims((d1, drest...)))
508+
drand(d1::Integer, drest::Integer...) = drand(Float64, Dims((d1, drest...)))
509+
510+
# With optional process IDs and number of chunks
511+
for N in (1, 2)
512+
@eval begin
513+
drand(::Type{T}, dims::Dims, args::Vararg{Any,$N}) where {T} = DArray(I -> rand(T, map(length, I)), dims, args...)
514+
drand(X, dims::Dims, args::Vararg{Any,$N}) = DArray(I -> rand(X, map(length, I)), dims, args...)
515+
drand(dims::Dims, args::Vararg{Any,$N}) = drand(Float64, dims, args...)
516+
end
517+
end
518+
519+
# Fix method ambiguities
520+
drand(dims::Dims, procs::Tuple{Vararg{Int}}) = drand(Float64, dims, procs)
521+
drand(dims::Dims, procs::Tuple{Vararg{Int}}, dist) = drand(Float64, dims, procs, dist)
522+
drand(X::Tuple{Vararg{Int}}, dim::Integer) = drand(X, Dims((dim,)))
523+
drand(X::Tuple{Vararg{Int}}, d1::Integer, d2::Integer) = drand(X, Dims((d1, d2)))
504524

505525
"""
506526
drandn(dims, ...)
@@ -620,7 +640,7 @@ allowscalar(flag = true) = (_allowscalar[] = flag)
620640
_scalarindexingallowed() = _allowscalar[] || throw(ErrorException("scalar indexing disabled"))
621641

622642
getlocalindex(d::DArray, idx...) = localpart(d)[idx...]
623-
function getindex_tuple(d::DArray{T}, I::Tuple{Vararg{Int}}) where T
643+
function getindex_tuple(d::DArray{T,N}, I::NTuple{N,Int}) where {T,N}
624644
chidx = locate(d, I...)
625645
idxs = d.indices[chidx...]
626646
localidx = ntuple(i -> (I[i] - first(idxs[i]) + 1), ndims(d))
@@ -632,11 +652,10 @@ function Base.getindex(d::DArray, i::Int)
632652
_scalarindexingallowed()
633653
return getindex_tuple(d, Tuple(CartesianIndices(d)[i]))
634654
end
635-
function Base.getindex(d::DArray, i::Int...)
655+
function Base.getindex(d::DArray{<:Any,N}, i::Vararg{Int,N}) where {N}
636656
_scalarindexingallowed()
637657
return getindex_tuple(d, i)
638658
end
639-
640659
Base.getindex(d::DArray) = d[1]
641660
Base.getindex(d::SubDArray, I::Int...) = invoke(getindex, Tuple{SubArray{<:Any,N},Vararg{Int,N}} where N, d, I...)
642661
Base.getindex(d::SubOrDArray, I::Union{Int,UnitRange{Int},Colon,Vector{Int},StepRange{Int,Int}}...) = view(d, I...)

src/mapreduce.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ function Base.map!(f::F, dest::DArray, src::DArray{<:Any,<:Any,A}) where {F,A}
1111
return dest
1212
end
1313

14-
function Base.reduce(f, d::DArray)
14+
# Only defining `reduce(f, ::DArray)` causes method ambiguity issues with
15+
# - `reduce(hcat, ::AbstractVector{<:AbstractVecOrMat})`
16+
# - `reduce(vcat, ::AbstractVector{<:AbstractVecOrMat})`
17+
Base.reduce(f, d::DArray) = _reduce(f, d)
18+
Base.reduce(::typeof(hcat), d::DArray{<:AbstractVecOrMat, 1}) = _reduce(hcat, d)
19+
Base.reduce(::typeof(vcat), d::DArray{<:AbstractVecOrMat, 1}) = _reduce(vcat, d)
20+
function _reduce(f, d::DArray)
1521
results = asyncmap(procs(d)) do p
1622
remotecall_fetch(p) do
1723
return reduce(f, localpart(d))

src/spmd.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct WorkerChannelDict
4343
end
4444
const WORKERCHANNELS = WorkerChannelDict()
4545

46-
Base.get!(f, x::WorkerChannelDict, id::Int) = @lock x.lock get!(f, x.data, id)
46+
Base.get!(f::Function, x::WorkerChannelDict, id::Int) = @lock x.lock get!(f, x.data, id)
4747

4848
# mapping between a context id and context object
4949
struct SPMDContextDict
@@ -54,7 +54,7 @@ end
5454
const CONTEXTS = SPMDContextDict()
5555

5656
Base.delete!(x::SPMDContextDict, id::Tuple{Int,Int}) = @lock x.lock delete!(x.data, id)
57-
Base.get!(f, x::SPMDContextDict, id::Tuple{Int,Int}) = @lock x.lock get!(f, x.data, id)
57+
Base.get!(f::Function, x::SPMDContextDict, id::Tuple{Int,Int}) = @lock x.lock get!(f, x.data, id)
5858

5959
function context_local_storage()
6060
ctxt = get_ctxt_from_id(task_local_storage(:SPMD_CTXT))

test/aqua.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
using DistributedArrays, Test
2+
import Aqua
3+
4+
@testset "Aqua" begin
5+
Aqua.test_all(DistributedArrays; ambiguities = (; broken = true))
6+
end

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ function check_leaks()
3636
end
3737
end
3838

39+
include("aqua.jl")
3940
include("explicit_imports.jl")
4041
include("darray.jl")
4142
include("spmd.jl")

0 commit comments

Comments
 (0)