From eeda30a076830ef7f3c3c98e8d4b3acec13e5a8f Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Fri, 16 Feb 2018 13:37:08 -0600 Subject: [PATCH 1/3] Array docs: Clarify DenseArray vs. "strided" Dense Arrays absolutely must be contiguously arranged in memory. This attempts to make documentation match the current reality. --- doc/src/manual/arrays.md | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/doc/src/manual/arrays.md b/doc/src/manual/arrays.md index f7432063cd774..7746884137225 100644 --- a/doc/src/manual/arrays.md +++ b/doc/src/manual/arrays.md @@ -697,21 +697,13 @@ object returned by *integer* indexing (`A[1, ..., 1]`, when `A` is not empty) an the length of the tuple returned by [`size`](@ref). For more details on defining custom `AbstractArray` implementations, see the [array interface guide in the interfaces chapter](@ref man-interface-array). -`DenseArray` is an abstract subtype of `AbstractArray` intended to include all arrays that are -laid out at regular offsets in memory, and which can therefore be passed to external C and Fortran -functions expecting this memory layout. Subtypes should provide a [`strides(A)`](@ref) method -that returns a tuple of "strides" for each dimension; a provided [`stride(A,k)`](@ref) method accesses -the `k`th element within this tuple. Increasing the index of dimension `k` by `1` should -increase the index `i` of [`getindex(A,i)`](@ref) by [`stride(A,k)`](@ref). If a pointer conversion -method [`Base.unsafe_convert(Ptr{T}, A)`](@ref) is provided, the memory layout should correspond -in the same way to these strides. More concrete examples can be found within the [interface guide -for strided arrays](@ref man-interface-strided-arrays). - -The [`Array`](@ref) type is a specific instance of `DenseArray` where elements are stored in column-major -order (see additional notes in [Performance Tips](@ref man-performance-tips)). [`Vector`](@ref) and [`Matrix`](@ref) are aliases for -the 1-d and 2-d cases. Specific operations such as scalar indexing, assignment, and a few other -basic storage-specific operations are all that have to be implemented for [`Array`](@ref), so -that the rest of the array library can be implemented in a generic manner. +`DenseArray` is an abstract subtype of `AbstractArray` intended to include all arrays where +elements are stored contiguously in column-major order (see additional notes in +[Performance Tips](@ref man-performance-tips)). The [`Array`](@ref) type is a specific instance +of `DenseArray` [`Vector`](@ref) and [`Matrix`](@ref) are aliases for the 1-d and 2-d cases. +Very few operations are implemented specifically for `Array` beyond those that are required +for all `AbstractArrays`s; much of the array library is implemented in a generic +manner that allows all custom arrays to behave similarly. `SubArray` is a specialization of `AbstractArray` that performs indexing by reference rather than by copying. A `SubArray` is created with the [`view`](@ref) function, which is called the same @@ -722,9 +714,19 @@ array indirectly. By putting the [`@views`](@ref) macro in front of an expressi block of code, any `array[...]` slice in that expression will be converted to create a `SubArray` view instead. -`StridedVector` and `StridedMatrix` are convenient aliases defined to make it possible for Julia -to call a wider range of BLAS and LAPACK functions by passing them either [`Array`](@ref) or -`SubArray` objects, and thus saving inefficiencies from memory allocation and copying. +A "strided" array is stored in memory and has its elements are laid out in regular offsets such that +it can be passed to external C and Fortran functions that expect this memory layout. Strided arrays +must define a [`strides(A)`](@ref) method that returns a tuple of "strides" for each dimension; a +provided [`stride(A,k)`](@ref) method accesses the `k`th element within this tuple. Increasing the +index of dimension `k` by `1` should increase the index `i` of [`getindex(A,i)`](@ref) by +[`stride(A,k)`](@ref). If a pointer conversion method [`Base.unsafe_convert(Ptr{T}, A)`](@ref) is +provided, the memory layout must correspond in the same way to these strides. `DenseArray` is a +very specific example of a strided array where the elements are arranged contiguously, thus it +provides its subtypes with the approporiate definition of `strides`. More concrete examples +can be found within the [interface guide for strided arrays](@ref man-interface-strided-arrays). +`StridedVector` and `StridedMatrix` are convenient aliases for many of the builtin array types that +are considered strided arrays, allowing them to dispatch to select specialized implementations that +call highly tuned and optimized BLAS and LAPACK functions using just the pointer and strides. The following example computes the QR decomposition of a small section of a larger array, without creating any temporaries, and by calling the appropriate LAPACK function with the right leading From bb84b87627f13790e84e7a2ff608b318665a0691 Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Sat, 17 Feb 2018 15:56:29 -0600 Subject: [PATCH 2/3] Add note about requiring a support `isbits` eltype We can tackle more general definitions later. --- doc/src/manual/arrays.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/src/manual/arrays.md b/doc/src/manual/arrays.md index 7746884137225..98b34078fe04f 100644 --- a/doc/src/manual/arrays.md +++ b/doc/src/manual/arrays.md @@ -715,7 +715,8 @@ block of code, any `array[...]` slice in that expression will be converted to create a `SubArray` view instead. A "strided" array is stored in memory and has its elements are laid out in regular offsets such that -it can be passed to external C and Fortran functions that expect this memory layout. Strided arrays +an instance with a supported `isbits` element type can be passed to +external C and Fortran functions that expect this memory layout. Strided arrays must define a [`strides(A)`](@ref) method that returns a tuple of "strides" for each dimension; a provided [`stride(A,k)`](@ref) method accesses the `k`th element within this tuple. Increasing the index of dimension `k` by `1` should increase the index `i` of [`getindex(A,i)`](@ref) by From 8769486ecb65fb30a74d2c2c8f6a8c2b3ac62f1c Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Sun, 18 Feb 2018 12:45:25 -0600 Subject: [PATCH 3/3] Fixup bad grammer --- doc/src/manual/arrays.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/manual/arrays.md b/doc/src/manual/arrays.md index 98b34078fe04f..09ca6a3af90b1 100644 --- a/doc/src/manual/arrays.md +++ b/doc/src/manual/arrays.md @@ -714,7 +714,7 @@ array indirectly. By putting the [`@views`](@ref) macro in front of an expressi block of code, any `array[...]` slice in that expression will be converted to create a `SubArray` view instead. -A "strided" array is stored in memory and has its elements are laid out in regular offsets such that +A "strided" array is stored in memory with elements laid out in regular offsets such that an instance with a supported `isbits` element type can be passed to external C and Fortran functions that expect this memory layout. Strided arrays must define a [`strides(A)`](@ref) method that returns a tuple of "strides" for each dimension; a