Skip to content

Commit 5fb4fba

Browse files
authored
Improve strided array docs (#59466)
This PR improves the docs for the strided array interface by clarifying that `elsize` is in bytes and not elements, and adding an example of how the functions fit together. XRef: #59435
1 parent 4987606 commit 5fb4fba

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

doc/src/manual/interfaces.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,9 @@ perhaps range-types `Ind` of your own design. For more information, see
401401
|:----------------------------------------------- |:-------------------------------------- |:------------------------------------------------------------------------------------- |
402402
| `strides(A)` | | Return the distance in memory (in number of elements) between adjacent elements in each dimension as a tuple. If `A` is an `AbstractArray{T,0}`, this should return an empty tuple. |
403403
| `Base.unsafe_convert(::Type{Ptr{T}}, A)` | | Return the native address of an array. |
404-
| `Base.elsize(::Type{<:A})` | | Return the stride between consecutive elements in the array. |
404+
| `Base.elsize(::Type{<:A})` | | Return the stride (in number of bytes) between consecutive elements in the array. |
405405
| **Optional methods** | **Default definition** | **Brief description** |
406-
| `stride(A, i::Int)` | `strides(A)[i]` | Return the distance in memory (in number of elements) between adjacent elements in dimension k. |
406+
| `stride(A, i::Int)` | `strides(A)[i]` | Return the distance in memory (in number of elements) between adjacent elements in dimension i. |
407407

408408
A strided array is a subtype of `AbstractArray` whose entries are stored in memory with fixed strides.
409409
Provided the element type of the array is compatible with BLAS, a strided array can utilize BLAS and LAPACK routines
@@ -413,6 +413,34 @@ that wraps a standard `Array` with additional structure.
413413
Warning: do not implement these methods if the underlying storage is not actually strided, as it
414414
may lead to incorrect results or segmentation faults.
415415

416+
The following function demonstrates how an element at indices `I` in a strided array `A` can be accessed.
417+
This function assumes the element type `isbitstype` and the indices are inbounds.
418+
419+
```jldoctest
420+
julia> function unsafe_strided_getindex(A::AbstractArray{T,N}, I::Vararg{Int, N})::T where {T, N}
421+
A_cconv = Base.cconvert(Ptr{T}, A)
422+
GC.@preserve A_cconv begin
423+
A_ptr = Base.unsafe_convert(Ptr{T}, A_cconv)
424+
for d in 1:N
425+
stride_in_bytes = stride(A, d) * Base.elsize(typeof(A))
426+
first_idx = first(axes(A, d))
427+
A_ptr += (I[d] - first_idx) * stride_in_bytes
428+
end
429+
unsafe_load(A_ptr)
430+
end
431+
end;
432+
433+
julia> A = [1 5; 2 6; 3 7; 4 8];
434+
435+
julia> unsafe_strided_getindex(A, 3, 2)
436+
7
437+
438+
julia> V = view(A, 1:2:3, 1:2);
439+
440+
julia> unsafe_strided_getindex(V, 2, 2)
441+
7
442+
```
443+
416444
Here are some examples to demonstrate which type of arrays are strided and which are not:
417445
```julia
418446
1:5 # not strided (there is no storage associated with this array.)

0 commit comments

Comments
 (0)