Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SparseArrayDOKs] Add setindex_maybe_grow! and macro @maybe_grow #1434

Merged
merged 10 commits into from
May 14, 2024
28 changes: 27 additions & 1 deletion NDTensors/src/lib/SparseArrayDOKs/src/sparsearraydok.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ using ..SparseArrayInterface:
SparseArrayInterface, AbstractSparseArray, getindex_zero_function

# TODO: Parametrize by `data`?
struct SparseArrayDOK{T,N,Zero} <: AbstractSparseArray{T,N}
mutable struct SparseArrayDOK{T,N,Zero} <: AbstractSparseArray{T,N}
emstoudenmire marked this conversation as resolved.
Show resolved Hide resolved
data::Dictionary{CartesianIndex{N},T}
dims::NTuple{N,Int}
zero::Zero
Expand Down Expand Up @@ -104,3 +104,29 @@ SparseArrayDOK{T}(a::AbstractArray) where {T} = SparseArrayDOK{T,ndims(a)}(a)
function SparseArrayDOK{T,N}(a::AbstractArray) where {T,N}
return SparseArrayInterface.sparse_convert(SparseArrayDOK{T,N}, a)
end

function Base.resize!(a::SparseArrayDOK{<:Any,N}, new_size::NTuple{N,Integer}) where {N}
a.dims = new_size
return a
end

function setindex_maybe_grow!(a::SparseArrayDOK{<:Any,N}, value, I::Vararg{Int,N}) where {N}
if any(I .> size(a))
resize!(a, max.(I, size(a)))
end
a[I...] = value
return a
end

macro maybe_grow(ex)
if ex.head != :(=)
emstoudenmire marked this conversation as resolved.
Show resolved Hide resolved
error("@maybe_grow must be used with setindex! syntax (@maybe_grow a[inds] = value)")
end
arr_name = esc(ex.args[1].args[1])
index = esc(ex.args[1].args[2:end])
value = esc(ex.args[2])
emstoudenmire marked this conversation as resolved.
Show resolved Hide resolved
e = quote
setindex_maybe_grow!($arr_name, $value, $index...)
end
return e
end
27 changes: 26 additions & 1 deletion NDTensors/src/lib/SparseArrayDOKs/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
# Slicing

using Test: @test, @testset, @test_broken
using NDTensors.SparseArrayDOKs: SparseArrayDOK, SparseMatrixDOK
using NDTensors.SparseArrayDOKs:
SparseArrayDOKs, SparseArrayDOK, SparseMatrixDOK, @maybe_grow
using NDTensors.SparseArrayInterface: storage_indices, nstored
using SparseArrays: SparseMatrixCSC, nnz
@testset "SparseArrayDOK (eltype=$elt)" for elt in
Expand Down Expand Up @@ -94,5 +95,29 @@ using SparseArrays: SparseMatrixCSC, nnz
end
end
end
@testset "Maybe Grow Feature" begin
a = SparseArrayDOK{elt,2}((0, 0))
SparseArrayDOKs.setindex_maybe_grow!(a, 230, 2, 3)
@test size(a) == (2, 3)
@test a[2, 3] == 230
# Test @maybe_grow macro
@maybe_grow a[5, 5] = 550
@test size(a) == (5, 5)
@test a[2, 3] == 230
@test a[5, 5] == 550
# Test that size remains same
# if we set at an index smaller than
# the maximum size:
@maybe_grow a[3, 4] = 340
@test size(a) == (5, 5)
@test a[2, 3] == 230
@test a[5, 5] == 550
@test a[3, 4] == 340
# Test vector case
v = SparseArrayDOK{elt,1}((0,))
@maybe_grow v[5] = 50
@test size(v) == (5,)
@test v[5] == 50
end
end
end
Loading