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

Deprecate generic stride implementation (#17812), allow AbstractArrays to use BLAS/LAPACK routines (#25247) #25321

Merged
merged 16 commits into from
Jan 5, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,8 @@ julia> strides(A)
"""
function strides end

# the definition of strides for Array is the cumsum of the product of sizes
function _cumsumprodsizes(a::AbstractArray, i)
# the definition of strides for Array is cumprod([1;collect(size(A))[1:end-1]])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, technically cumprod would return an array, whereas strides returns a tuple

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that's not quite right since:

julia> A = Array{Float64,0}()
0-dimensional Array{Float64,0}:
0.0

julia> strides(A)
()

How about saying:

the defition of strides for Array{T,N} is tuple() if N = 0, otherwise it is a tuple containing 1 and a cumulative product of the first N-1 sizes

function _defaultstride(a::AbstractArray, i)
if i > ndims(a)
return length(a)
end
Expand Down
2 changes: 1 addition & 1 deletion base/linalg/dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ true
isposdef(A::AbstractMatrix) = ishermitian(A) && isposdef(cholfact(Hermitian(A)))
isposdef(x::Number) = imag(x)==0 && real(x) > 0

stride(A::Union{DenseArray,StridedReshapedArray,StridedReinterpretArray}, i::Int) = Base._cumsumprodsizes(A, i)
stride(A::Union{DenseArray,StridedReshapedArray,StridedReinterpretArray}, i::Int) = Base._defaultstride(A, i)
strides(A::Union{DenseArray,StridedReshapedArray,StridedReinterpretArray}) = size_to_strides(1, size(A)...)

function norm(x::StridedVector{T}, rx::Union{UnitRange{TI},AbstractRange{TI}}) where {T<:BlasFloat,TI<:Integer}
Expand Down
6 changes: 3 additions & 3 deletions doc/src/manual/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,12 +399,12 @@ perhaps range-types `Ind` of your own design. For more information, see [Arrays
| `Base.unsafe_convert(::Type{Ptr{T}}, A)` |   | Return the native address of an array. |


A strided array is a sub-type of `AbstractArray` whose entries are stored in memory with fixed strides.
A strided array is a subtype of `AbstractArray` whose entries are stored in memory with fixed strides.
Provided the element type of the array is compatible with BLAS, a strided array can utilize BLAS and LAPACK routines
for more efficient linear algebra routines.

A typical example of a user defined strided array is one that wraps a standard `Array`
with additional structure.
A typical example of a user-defined strided array is one that wraps a standard `Array`
with additional structure.


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a warning here too about how dangerous it is to implement these methods if the underlying storage is not actually strided. Otherwise the following might happen:

  • user calls a function. Gets a MethodError due to missing implementation of strides
  • "helpfully" implements strides to fix the method error

It might be useful to give some concrete examples of arrays and categorize them as to whether they have strided memory representation. Examples:

1:5   # not strided (there is no storage associated with this array, could segfault if implemented `strides`)
collect(1:5)  # is strided
A = [1 5; 2 6; 3 7; 4 8]  # is strided
V = view(A, 1:2, :)   # is strided
V = view(A, 1:2:4, :)   # is strided
V = view(A, [1,2,4], :)   # is not strided


Expand Down