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
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "ArrayInterface"
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
version = "6.0.21"
version = "6.0.22"

[deps]
ArrayInterfaceCore = "30b0a656-2188-435a-8636-2ec0e6a096e2"
Expand Down
4 changes: 2 additions & 2 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
ArrayInterfaceCore.can_avx
ArrayInterfaceCore.can_change_size
ArrayInterfaceCore.can_setindex
ArrayInterfaceCore.device
ArrayInterfaceCore.defines_strides
ArrayInterfaceCore.fast_matrix_colors
ArrayInterfaceCore.fast_scalar_indexing
ArrayInterfaceCore.is_forwarding_wrapper
Expand Down Expand Up @@ -52,8 +54,6 @@ ArrayInterfaceCore.SetIndex!
ArrayInterface.contiguous_axis
ArrayInterface.contiguous_axis_indicator
ArrayInterface.contiguous_batch_size
ArrayInterface.defines_strides
ArrayInterface.device
ArrayInterface.dimnames
ArrayInterface.has_dimnames
ArrayInterface.has_parent
Expand Down
2 changes: 1 addition & 1 deletion lib/ArrayInterfaceCore/Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "ArrayInterfaceCore"
uuid = "30b0a656-2188-435a-8636-2ec0e6a096e2"
version = "0.1.16"
version = "0.1.17"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
55 changes: 55 additions & 0 deletions lib/ArrayInterfaceCore/src/ArrayInterfaceCore.jl
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,32 @@ struct CheckParent end
struct CPUIndex <: AbstractCPU end
struct GPU <: AbstractDevice end

"""
device(::Type{T}) -> AbstractDevice

Indicates the most efficient way to access elements from the collection in low-level code.
For `GPUArrays`, will return `ArrayInterface.GPU()`.
For `AbstractArray` supporting a `pointer` method, returns `ArrayInterface.CPUPointer()`.
For other `AbstractArray`s and `Tuple`s, returns `ArrayInterface.CPUIndex()`.
Otherwise, returns `nothing`.
"""
device(A) = device(typeof(A))
device(::Type) = nothing
device(::Type{<:Tuple}) = CPUTuple()
device(::Type{T}) where {T<:Array} = CPUPointer()
device(::Type{T}) where {T<:AbstractArray} = _device(parent_type(T), T)
function _device(::Type{P}, ::Type{T}) where {P,T}
if defines_strides(T)
return device(P)
else
return _not_pointer(device(P))
end
end
_not_pointer(::CPUPointer) = CPUIndex()
_not_pointer(x) = x
_device(::Type{T}, ::Type{T}) where {T<:DenseArray} = CPUPointer()
_device(::Type{T}, ::Type{T}) where {T} = CPUIndex()

"""
can_avx(f) -> Bool

Expand Down Expand Up @@ -836,4 +862,33 @@ indices_do_not_alias(::Type{Transpose{T,A}}) where {T, A <: AbstractArray{T}} =
indices_do_not_alias(::Type{<:SubArray{<:Any,<:Any,A,I}}) where {
A,I<:Tuple{Vararg{Union{Integer, UnitRange, Base.ReshapedUnitRange, Base.AbstractCartesianIndex}}}} = indices_do_not_alias(A)

"""
defines_strides(::Type{T}) -> Bool

Is strides(::T) defined? It is assumed that types returning `true` also return a valid
pointer on `pointer(::T)`.
"""
defines_strides(x) = defines_strides(typeof(x))
_defines_strides(::Type{T}, ::Type{T}) where {T} = false
_defines_strides(::Type{P}, ::Type{T}) where {P,T} = defines_strides(P)
defines_strides(::Type{T}) where {T} = _defines_strides(parent_type(T), T)
defines_strides(@nospecialize T::Type{<:StridedArray}) = true
defines_strides(@nospecialize T::Type{<:BitArray}) = true
@inline function defines_strides(@nospecialize T::Type{<:SubArray})
stride_preserving_index(fieldtype(T, :indices))
end

#=
stride_preserving_index(::Type{T}) -> Bool

Returns `True` if strides between each element can still be derived when indexing with an
instance of type `T`.
=#
stride_preserving_index(@nospecialize T::Type{<:AbstractRange}) = true
stride_preserving_index(@nospecialize T::Type{<:Number}) = true
@inline function stride_preserving_index(@nospecialize T::Type{<:Tuple})
all(map_tuple_type(stride_preserving_index, T))
end
stride_preserving_index(@nospecialize T::Type) = false

end # module
31 changes: 3 additions & 28 deletions src/ArrayInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import ArrayInterfaceCore: allowed_getindex, allowed_setindex!, aos_to_soa, buff
issingular, isstructured, matrix_colors, restructure, lu_instance,
safevec, zeromatrix, ColoringAlgorithm, fast_scalar_indexing, parameterless_type,
ndims_index, ndims_shape, is_splat_index, is_forwarding_wrapper, IndicesInfo,
map_tuple_type, flatten_tuples, GetIndex, SetIndex!
map_tuple_type, flatten_tuples, GetIndex, SetIndex!, defines_strides,
stride_preserving_index

# ArrayIndex subtypes and methods
import ArrayInterfaceCore: ArrayIndex, MatrixIndex, VectorIndex, BidiagonalIndex, TridiagonalIndex
Expand All @@ -16,7 +17,7 @@ import ArrayInterfaceCore: ismutable, can_change_size, can_setindex
import ArrayInterfaceCore: MatAdjTrans, VecAdjTrans, UpTri, LoTri
# device pieces
import ArrayInterfaceCore: AbstractDevice, AbstractCPU, CPUPointer, CPUTuple, CheckParent,
CPUIndex, GPU, can_avx
CPUIndex, GPU, can_avx, device

import ArrayInterfaceCore: known_first, known_step, known_last

Expand Down Expand Up @@ -109,32 +110,6 @@ has_parent(::Type{T}) where {T} = _has_parent(parent_type(T), T)
_has_parent(::Type{T}, ::Type{T}) where {T} = False()
_has_parent(::Type{T1}, ::Type{T2}) where {T1,T2} = True()

"""
device(::Type{T}) -> AbstractDevice

Indicates the most efficient way to access elements from the collection in low-level code.
For `GPUArrays`, will return `ArrayInterface.GPU()`.
For `AbstractArray` supporting a `pointer` method, returns `ArrayInterface.CPUPointer()`.
For other `AbstractArray`s and `Tuple`s, returns `ArrayInterface.CPUIndex()`.
Otherwise, returns `nothing`.
"""
device(A) = device(typeof(A))
device(::Type) = nothing
device(::Type{<:Tuple}) = CPUTuple()
device(::Type{T}) where {T<:Array} = CPUPointer()
device(::Type{T}) where {T<:AbstractArray} = _device(has_parent(T), T)
function _device(::True, ::Type{T}) where {T}
if defines_strides(T)
return device(parent_type(T))
else
return _not_pointer(device(parent_type(T)))
end
end
_not_pointer(::CPUPointer) = CPUIndex()
_not_pointer(x) = x
_device(::False, ::Type{T}) where {T<:DenseArray} = CPUPointer()
_device(::False, ::Type{T}) where {T} = CPUIndex()

"""
is_lazy_conjugate(::AbstractArray) -> Bool

Expand Down
28 changes: 0 additions & 28 deletions src/stridelayout.jl
Original file line number Diff line number Diff line change
@@ -1,32 +1,4 @@

"""
defines_strides(::Type{T}) -> Bool

Is strides(::T) defined? It is assumed that types returning `true` also return a valid
pointer on `pointer(::T)`.
"""
defines_strides(x) = defines_strides(typeof(x))
_defines_strides(::Type{T}, ::Type{T}) where {T} = false
_defines_strides(::Type{P}, ::Type{T}) where {P,T} = defines_strides(P)
defines_strides(::Type{T}) where {T} = _defines_strides(parent_type(T), T)
defines_strides(@nospecialize T::Type{<:StridedArray}) = true
defines_strides(@nospecialize T::Type{<:BitArray}) = true
@inline function defines_strides(@nospecialize T::Type{<:SubArray})
stride_preserving_index(fieldtype(T, :indices))
end
#=
stride_preserving_index(::Type{T}) -> StaticBool

Returns `True` if strides between each element can still be derived when indexing with an
instance of type `T`.
=#
stride_preserving_index(@nospecialize T::Type{<:AbstractRange}) = true
stride_preserving_index(@nospecialize T::Type{<:Number}) = true
@inline function stride_preserving_index(@nospecialize T::Type{<:Tuple})
all(map_tuple_type(stride_preserving_index, T))
end
stride_preserving_index(@nospecialize T::Type) = false

"""
known_offsets(::Type{T}) -> Tuple
known_offsets(::Type{T}, dim) -> Union{Int,Nothing}
Expand Down