Skip to content

Commit 9fbeaf5

Browse files
committed
Update for latest Derive
1 parent 0facc75 commit 9fbeaf5

File tree

5 files changed

+73
-27
lines changed

5 files changed

+73
-27
lines changed

examples/README.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ a = SparseArrayDOK{Float64}(2, 2)
5555
# AbstractArray interface:
5656

5757
a[1, 2] = 12
58+
@test a == [0 12; 0 0]
5859
@test a[1, 1] == 0
5960
@test a[2, 1] == 0
6061
@test a[1, 2] == 12
@@ -75,3 +76,12 @@ a[1, 2] = 12
7576
@test storedlength(a) == 1
7677
@test issetequal(storedpairs(a), [CartesianIndex(1, 2) => 12])
7778
@test issetequal(storedvalues(a), [12])
79+
80+
# AbstractArray functionality:
81+
82+
b = a .+ 2 .* a'
83+
@test b == [0 12; 24 0]
84+
@test storedlength(b) == 2
85+
@test b isa SparseArrayDOK{Float64}
86+
87+
a * a'

src/SparseArraysBase.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module SparseArraysBase
22

33
include("sparsearrayinterface.jl")
44
include("wrappers.jl")
5+
include("abstractsparsearray.jl")
56
include("sparsearraydok.jl")
67

78
end

src/abstractsparsearray.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
abstract type AbstractSparseArray{T,N} <: AbstractArray{T,N} end
2+
3+
using Derive: @array_aliases
4+
# Define AbstractSparseVector, AnyAbstractSparseArray, etc.
5+
@array_aliases AbstractSparseArray
6+
7+
using Derive: Derive
8+
function Derive.interface(::Type{<:AbstractSparseArray})
9+
return SparseArrayInterface()
10+
end
11+
12+
using Derive: @derive
13+
# Derive `Base.getindex`, `Base.setindex!`, etc.
14+
@derive AnyAbstractSparseArray AbstractArrayOps
15+
16+
using LinearAlgebra: LinearAlgebra
17+
@derive (T=AnyAbstractSparseVecOrMat,) begin
18+
LinearAlgebra.mul!(::AbstractMatrix, ::T, ::T, ::Number, ::Number)
19+
end
20+
21+
using ArrayLayouts: ArrayLayouts
22+
@derive (T=AnyAbstractSparseArray,) begin
23+
ArrayLayouts.MemoryLayout(::Type{<:T})
24+
end

src/sparsearraydok.jl

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
# TODO: Define `AbstractSparseArray`, make this a subtype.
2-
struct SparseArrayDOK{T,N} <: AbstractArray{T,N}
2+
struct SparseArrayDOK{T,N} <: AbstractSparseArray{T,N}
33
storage::Dict{CartesianIndex{N},T}
44
size::NTuple{N,Int}
55
end
66

7-
function SparseArrayDOK{T}(size::Int...) where {T}
8-
N = length(size)
7+
const SparseMatrixDOK{T} = SparseArrayDOK{T,2}
8+
const SparseVectorDOK{T} = SparseArrayDOK{T,1}
9+
10+
function SparseArrayDOK{T,N}(size::Vararg{Int,N}) where {T,N}
911
return SparseArrayDOK{T,N}(Dict{CartesianIndex{N},T}(), size)
1012
end
1113

12-
using Derive: @wrappedtype
13-
# Define `WrappedSparseArrayDOK` and `AnySparseArrayDOK`.
14-
@wrappedtype SparseArrayDOK
15-
16-
using Derive: Derive
17-
function Derive.interface(::Type{<:SparseArrayDOK})
18-
return SparseArrayInterface()
14+
function SparseArrayDOK{T}(size::Int...) where {T}
15+
return SparseArrayDOK{T,length(size)}(size...)
1916
end
2017

21-
using Derive: @derive
22-
@derive AnySparseArrayDOK AbstractArrayOps
18+
using Derive: @array_aliases
19+
# Define `SparseMatrixDOK`, `AnySparseArrayDOK`, etc.
20+
@array_aliases SparseArrayDOK
2321

2422
storage(a::SparseArrayDOK) = a.storage
2523
Base.size(a::SparseArrayDOK) = a.size

src/sparsearrayinterface.jl

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ storedvalues(a) = error()
55
isstored(a, I::Int...) = error()
66
eachstoredindex(a) = error()
77
getstoredindex(a, I::Int...) = error()
8-
getunstoredindex(a, I::Int...) = error()
98
setstoredindex!(a, value, I::Int...) = error()
109
setunstoredindex!(a, value, I::Int...) = error()
1110

11+
# Interface defaults.
12+
# TODO: Have a fallback that handles element types
13+
# that don't define `zero(::Type)`.
14+
getunstoredindex(a, I::Int...) = zero(eltype(a))
15+
1216
# Derived interface.
1317
storedlength(a) = length(storedvalues(a))
1418
storedpairs(a) = map(I -> I => getstoredindex(a, I), eachstoredindex(a))
@@ -19,22 +23,28 @@ function eachstoredindex(a1, a2, a_rest...)
1923
return union(eachstoredindex.((a1, a2, a_rest...))...)
2024
end
2125

22-
# TODO: Add `ndims` type parameter.
23-
# TODO: Define `AbstractSparseArrayInterface`, make this a subtype.
2426
using Derive: Derive, @interface, AbstractArrayInterface
25-
struct SparseArrayInterface <: AbstractArrayInterface end
27+
28+
# TODO: Add `ndims` type parameter.
29+
# TODO: This isn't used to define interface functions right now.
30+
# Currently, `@interface` expects an instance, probably it should take a
31+
# type instead so fallback functions can use abstract types.
32+
abstract type AbstractSparseArrayInterface <: AbstractArrayInterface end
33+
34+
struct SparseArrayInterface <: AbstractSparseArrayInterface end
2635

2736
# Convenient shorthand to refer to the sparse interface.
37+
# TODO: Define this as `InterfaceFunction(AbstractSparseArrayInterface)`
2838
const sparse = SparseArrayInterface()
2939

3040
# TODO: Use `ArrayLayouts.layout_getindex`, `ArrayLayouts.sub_materialize`
3141
# to handle slicing (implemented by copying SubArray).
32-
@interface sparse function Base.getindex(a, I::Int...)
42+
@interface AbstractSparseArrayInterface function Base.getindex(a, I::Int...)
3343
!isstored(a, I...) && return getunstoredindex(a, I...)
3444
return getstoredindex(a, I...)
3545
end
3646

37-
@interface sparse function Base.setindex!(a, value, I::Int...)
47+
@interface AbstractSparseArrayInterface function Base.setindex!(a, value, I::Int...)
3848
iszero(value) && return a
3949
if !isstored(a, I...)
4050
setunstoredindex!(a, value, I...)
@@ -46,23 +56,25 @@ end
4656

4757
# TODO: This may need to be defined in `sparsearraydok.jl`, after `SparseArrayDOK`
4858
# is defined. And/or define `default_type(::SparseArrayStyle, T::Type) = SparseArrayDOK{T}`.
49-
@interface sparse function Base.similar(a, T::Type, size::Tuple{Vararg{Int}})
59+
@interface AbstractSparseArrayInterface function Base.similar(
60+
a, T::Type, size::Tuple{Vararg{Int}}
61+
)
5062
return SparseArrayDOK{T}(size...)
5163
end
5264

5365
## TODO: Make this more general, handle mixtures of integers and ranges.
5466
## TODO: Make this logic generic to all `similar(::AbstractInterface, ...)`.
55-
## @interface sparse function Base.similar(a, T::Type, dims::Tuple{Vararg{Base.OneTo}})
67+
## @interface AbstractSparseArrayInterface function Base.similar(a, T::Type, dims::Tuple{Vararg{Base.OneTo}})
5668
## return sparse(similar)(interface, a, T, Base.to_shape(dims))
5769
## end
5870

59-
@interface sparse function Base.map(f, as...)
71+
@interface AbstractSparseArrayInterface function Base.map(f, as...)
6072
# This is defined in this way so we can rely on the Broadcast logic
6173
# for determining the destination of the operation (element type, shape, etc.).
6274
return f.(as...)
6375
end
6476

65-
@interface sparse function Base.map!(f, dest, as...)
77+
@interface AbstractSparseArrayInterface function Base.map!(f, dest, as...)
6678
# Check `f` preserves zeros.
6779
# Define as `map_stored!`.
6880
# Define `eachstoredindex` promotion.
@@ -72,12 +84,13 @@ end
7284
return dest
7385
end
7486

75-
# TODO: Define `AbstractSparseArrayStyle`, make this a subtype.
76-
struct SparseArrayStyle{N} <: Broadcast.AbstractArrayStyle{N} end
87+
abstract type AbstractSparseArrayStyle{N} <: Broadcast.AbstractArrayStyle{N} end
88+
89+
struct SparseArrayStyle{N} <: AbstractSparseArrayStyle{N} end
7790

7891
SparseArrayStyle{M}(::Val{N}) where {M,N} = SparseArrayStyle{N}()
7992

80-
@interface sparse function Broadcast.BroadcastStyle(type::Type)
93+
@interface AbstractSparseArrayInterface function Broadcast.BroadcastStyle(type::Type)
8194
return SparseArrayStyle{ndims(type)}()
8295
end
8396

@@ -100,12 +113,12 @@ abstract type AbstractSparseLayout <: ArrayLayouts.MemoryLayout end
100113

101114
struct SparseLayout <: AbstractSparseLayout end
102115

103-
@interface sparse function ArrayLayouts.MemoryLayout(type::Type)
116+
@interface AbstractSparseArrayInterface function ArrayLayouts.MemoryLayout(type::Type)
104117
return SparseLayout()
105118
end
106119

107120
using LinearAlgebra: LinearAlgebra
108-
@interface sparse function LinearAlgebra.mul!(a_dest, a1, a2, α, β)
121+
@interface AbstractSparseArrayInterface function LinearAlgebra.mul!(a_dest, a1, a2, α, β)
109122
return ArrayLayouts.mul!(a_dest, a1, a2, α, β)
110123
end
111124

0 commit comments

Comments
 (0)