Skip to content

Commit 0b786d7

Browse files
committed
Unblocked slicing
1 parent 9eb742b commit 0b786d7

File tree

5 files changed

+64
-5
lines changed

5 files changed

+64
-5
lines changed

src/BlockArraysExtensions/BlockArraysExtensions.jl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ using SparseArraysBase:
3030

3131
# A return type for `blocks(array)` when `array` isn't blocked.
3232
# Represents a vector with just that single block.
33-
struct SingleBlockView{T,N,Array<:AbstractArray{T,N}} <: AbstractArray{T,N}
33+
struct SingleBlockView{N,Array<:AbstractArray{<:Any,N}} <: AbstractArray{Array,N}
3434
array::Array
3535
end
3636
Base.parent(a::SingleBlockView) = a.array
37+
Base.size(a::SingleBlockView) = ntuple(Returns(1), ndims(a))
3738
blocks_maybe_single(a) = blocks(a)
3839
blocks_maybe_single(a::Array) = SingleBlockView(a)
39-
function Base.getindex(a::SingleBlockView{<:Any,N}, index::Vararg{Int,N}) where {N}
40+
function Base.getindex(a::SingleBlockView{N}, index::Vararg{Int,N}) where {N}
4041
@assert all(isone, index)
4142
return parent(a)
4243
end
@@ -357,7 +358,11 @@ function blockrange(axis::AbstractUnitRange, r::Base.Slice)
357358
end
358359

359360
function blockrange(axis::AbstractUnitRange, r::NonBlockedVector)
360-
return Block(1):Block(1)
361+
return Block.(Base.OneTo(1))
362+
end
363+
364+
function blockrange(axis::AbstractUnitRange, r::AbstractVector{<:Integer})
365+
return Block.(Base.OneTo(1))
361366
end
362367

363368
function blockrange(axis::AbstractUnitRange, r)

src/BlockSparseArrays.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ include("abstractblocksparsearray/abstractblocksparsearray.jl")
2727
include("abstractblocksparsearray/abstractblocksparsematrix.jl")
2828
include("abstractblocksparsearray/abstractblocksparsevector.jl")
2929
include("abstractblocksparsearray/wrappedabstractblocksparsearray.jl")
30+
include("abstractblocksparsearray/unblockedsubarray.jl")
3031
include("abstractblocksparsearray/views.jl")
3132
include("abstractblocksparsearray/arraylayouts.jl")
3233
include("abstractblocksparsearray/sparsearrayinterface.jl")

src/abstractblocksparsearray/arraylayouts.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,20 @@ function ArrayLayouts.sub_materialize(layout::BlockLayout{<:SparseLayout}, a, ax
4343
return a_dest
4444
end
4545

46+
function _similar(arraytype::Type{<:AbstractArray}, size::Tuple)
47+
return similar(arraytype, size)
48+
end
49+
function _similar(
50+
::Type{<:SubArray{<:Any,<:Any,<:ArrayType}}, size::Tuple
51+
) where {ArrayType}
52+
return similar(ArrayType, size)
53+
end
54+
4655
# Materialize a SubArray view.
4756
function ArrayLayouts.sub_materialize(
4857
layout::BlockLayout{<:SparseLayout}, a, axes::Tuple{Vararg{Base.OneTo}}
4958
)
50-
a_dest = blocktype(a)(undef, length.(axes))
59+
a_dest = _similar(blocktype(a), length.(axes))
5160
a_dest .= a
5261
return a_dest
5362
end
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using ArrayLayouts: ArrayLayouts, MemoryLayout
2+
using Base.Broadcast: Broadcast, BroadcastStyle
3+
using BlockArrays: BlockArrays
4+
using TypeParameterAccessors: TypeParameterAccessors, parenttype, similartype
5+
6+
const UnblockedSubArray{T,N} = SubArray{
7+
T,N,<:AbstractBlockSparseArray{T,N},<:Tuple{Vararg{Vector{<:Integer}}}
8+
}
9+
10+
function BlockArrays.blocks(a::UnblockedSubArray)
11+
return SingleBlockView(a)
12+
end
13+
14+
function DerivableInterfaces.interface(arraytype::Type{<:UnblockedSubArray})
15+
return interface(blocktype(parenttype(arraytype)))
16+
end
17+
18+
function ArrayLayouts.MemoryLayout(arraytype::Type{<:UnblockedSubArray})
19+
return MemoryLayout(blocktype(parenttype(arraytype)))
20+
end
21+
22+
function Broadcast.BroadcastStyle(arraytype::Type{<:UnblockedSubArray})
23+
return BroadcastStyle(blocktype(parenttype(arraytype)))
24+
end
25+
26+
function TypeParameterAccessors.similartype(arraytype::Type{<:UnblockedSubArray}, elt::Type)
27+
return similartype(blocktype(parenttype(arraytype)), elt)
28+
end
29+
30+
function Base.map!(
31+
f, a_dest::AbstractArray, a_src1::UnblockedSubArray, a_src_rest::UnblockedSubArray...
32+
)
33+
return invoke(
34+
map!,
35+
Tuple{Any,AbstractArray,AbstractArray,Vararg{AbstractArray}},
36+
f,
37+
a_dest,
38+
a_src1,
39+
a_src_rest...,
40+
)
41+
end
42+
function Base.iszero(a::UnblockedSubArray)
43+
return invoke(iszero, Tuple{AbstractArray}, a)
44+
end

src/blocksparsearrayinterface/blocksparsearrayinterface.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ function Base.isassigned(a::SparseSubArrayBlocks{<:Any,N}, I::Vararg{Int,N}) whe
400400
# TODO: Implement this properly.
401401
return true
402402
end
403-
function SparseArraysBase.eachstoredindex(a::SparseSubArrayBlocks)
403+
function SparseArraysBase.eachstoredindex(::IndexCartesian, a::SparseSubArrayBlocks)
404404
return eachstoredindex(view(blocks(parent(a.array)), blockrange(a)...))
405405
end
406406
# TODO: Either make this the generic interface or define

0 commit comments

Comments
 (0)