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

Various fixes to make the package work with v0.5 #47

Merged
merged 4 commits into from
Feb 1, 2017
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
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ os:
- linux
- osx
julia:
- 0.3
- 0.4
- 0.5
- nightly
after_success:
- if [ $TRAVIS_JULIA_VERSION != "0.3" ]; then julia -e 'cd(Pkg.dir("ArrayViews")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'; fi
- julia -e 'cd(Pkg.dir("ArrayViews")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())';
notifications:
email: false
64 changes: 32 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,30 +51,31 @@ Reasons to prefer `ArrayViews`:

## Main Features

- An efficient ``view`` function that implements array views
- An efficient ``aview`` function that implements array views
- Support of arrays of arbitrary dimension and arbitrary combinations of indexers
- Support view composition (*i.e.* construct views over views)
- Support ``aview`` composition (*i.e.* construct views over views)
- Special attention to ensure type stability in most cases
- Efficient indexing (both cartesian and linear)
- Light weight view construction
- Light weight array view construction
- A systematic approach to detect contiguous views (statically)
- Views work with linear algebra functions


## Overview

The key function in this package is ``view``:
The key function in this package is ``aview``. This function is similar to ``sub`` in Julia Base, except that it returns an aview instance with more efficient representation:

```julia
a = rand(4, 5, 6)

view(a, :)
view(a, :, 2)
view(a, 1:2, 1:2:5, 4)
view(a, 2, :, 3:6)
aview(a, :)
aview(a, :, 2)
aview(a, 1:2, 1:2:5, 4)
aview(a, 2, :, 3:6)
```

The ``view`` function returns a view of type ``ArrayView``. Here, ``ArrayView`` is an abstract type with two derived types (``ContiguousView`` and ``StridedView``), defined as:
The ``aview`` function returns an array view of type ``ArrayView``.
Here, ``ArrayView`` is an abstract type with two derived types (``ContiguousView`` and ``StridedView``), defined as:

```julia
abstract ArrayView{T,N,M} <: DenseArray{T,N}
Expand All @@ -95,7 +96,7 @@ The *contiguous rank* plays an important role in determining (statically) the co
* * * * * *
. . . . . .
```
Here, ``*`` indicates a position covered by the view, and ``.`` otherwise. We can see that the columns are not contiguous.
Here, ``*`` indicates a position covered by the array view, and ``.`` otherwise. We can see that the columns are not contiguous.

**2D View with contiguous rank 1**

Expand All @@ -107,7 +108,7 @@ Here, ``*`` indicates a position covered by the view, and ``.`` otherwise. We ca
. . . . . .
. . . . . .
```
We can see that each column is contiguous, while the entire view is not.
We can see that each column is contiguous, while the entire array view is not.


**2D View with contiguous rank 2**
Expand All @@ -120,15 +121,15 @@ We can see that each column is contiguous, while the entire view is not.
* * * * * *
* * * * * *
```
The entire 2D view is contiguous.
The entire 2D array view is contiguous.


Formally, when ``v`` is a view with contiguous rank ``M``, then ``view(v, :, :, ..., :, 1)`` must be contiguous when the number of colons is less than or equal to ``M``.
Formally, when ``v`` is an array view with contiguous rank ``M``, then ``aview(v, :, :, ..., :, 1)`` must be contiguous when the number of colons is less than or equal to ``M``.


#### View Types

The package provide a hierarchy of view types (defined as follows):
The package provide a hierarchy of array view types (defined as follows):

```julia
# T: the element type
Expand All @@ -151,42 +152,41 @@ Here, an instance of ``ArrayView`` maintains a reference to the underlying array

#### View Types in Action

The following example illustrates how contiguous rank is used to determine view types in practice.
The following example illustrates how contiguous rank is used to determine aview types in practice.

```julia
a = rand(m, n)

# safe views

v0 = view(a, :) # of type ContiguousView{Float64, 1}
v0 = aview(a, :) # of type ContiguousView{Float64, 1}

u1 = view(a, a:b, :) # of type StridedView{Float64, 2, 1}
u2 = view(u1, :, i) # of type ContiguousView{Float64, 1}
u1 = aview(a, a:b, :) # of type StridedView{Float64, 2, 1}
u2 = aview(u1, :, i) # of type ContiguousView{Float64, 1}

v1 = view(a, a:2:b, :) # of type StridedView{Float64, 2, 0}
v2 = view(v1, :, i) # of type StridedView{Float64, 1, 0}
v1 = aview(a, a:2:b, :) # of type StridedView{Float64, 2, 0}
v2 = aview(v1, :, i) # of type StridedView{Float64, 1, 0}

# unsafe views

v0 = unsafe_view(a, :) # of type UnsafeContiguousView{Float64, 1}
v0 = unsafe_aview(a, :) # of type UnsafeContiguousView{Float64, 1}

u1 = unsafe_view(a, a:b, :) # of type UnsafeStridedView{Float64, 2, 1}
u2 = unsafe_view(u1, :, i) # of type UnsafeContiguousView{Float64, 1}
u1 = unsafe_aview(a, a:b, :) # of type UnsafeStridedView{Float64, 2, 1}
u2 = unsafe_aview(u1, :, i) # of type UnsafeContiguousView{Float64, 1}

v1 = unsafe_view(a, a:2:b, :) # of type UnsafeStridedView{Float64, 2, 0}
v2 = unsafe_view(v1, :, i) # of type UnsafeStridedView{Float64, 1, 0}
v1 = unsafe_aview(a, a:2:b, :) # of type UnsafeStridedView{Float64, 2, 0}
v2 = unsafe_aview(v1, :, i) # of type UnsafeStridedView{Float64, 1, 0}
```

Four kinds of indexers are supported, integer, range (*e.g.* ``a:b``), stepped range (*e.g.* ``a:b:c``), and colon (*i.e.*, ``:``).


## View Construction

The procedure of constructing a view consists of several steps:
The procedure of constructing a aview consists of several steps:

1. Compute the shape of a view. This is done by an internal function ``vshape``.
1. Compute the shape of an array view. This is done by an internal function ``vshape``.

2. Compute the offset of a view. This is done by an internal function ``aoffset``. The computation is based on the following formula:
2. Compute the offset of an array view. This is done by an internal function ``aoffset``. The computation is based on the following formula:

```
offset(v(I1, I2, ..., Im)) = (first(I1) - 1) * stride(v, 1)
Expand All @@ -197,7 +197,7 @@ The procedure of constructing a view consists of several steps:

3. Compute the contiguous rank, based on both view shape and the combination of indexer types. A type ``ContRank{M}`` is introduced for static computation of contiguous rank (please refer to ``src/contrank.jl`` for details).

4. Construct a view, where the view type is determined by both the number of dimensions and the value of contiguous rank (which is determined statically).
4. Construct a aview, where the array view type is determined by both the number of dimensions and the value of contiguous rank (which is determined statically).

For runtime efficiency, specialized methods of these functions are implemented for views of 1D, 2D, and 3D. These methods are extensively tested.

Expand All @@ -221,6 +221,6 @@ rowvec_view(a, i) # make a view of `a[i,:]` as a strided vector.
# `a` needs to be a matrix here (contiguous or strided)

ellipview(a, i) # make a view of the i-th slice of a
# e.g. `a` is a matrix => this is equiv. to `view(a, :, i)`
# `a` is a cube => this is equiv. to `view(a, :, :, i)`, etc.
# e.g. `a` is a matrix => this is equiv. to `aview(a, :, i)`
# `a` is a cube => this is equiv. to `aview(a, :, :, i)`, etc.
```
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
julia 0.3
julia 0.5
Compat
17 changes: 4 additions & 13 deletions src/ArrayViews.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION >= v"0.4.0-dev+6521" && __precompile__(true)
__precompile__(true)

module ArrayViews

Expand All @@ -7,16 +7,7 @@ using Compat
import Base: eltype, ndims, size, length, stride, strides
import Base: to_index, getindex, setindex!, parent, similar
import Base: Ptr, pointer

if VERSION >= v"0.4.0-dev+2085"
import Base: iscontiguous
end

if VERSION < v"0.4.0-dev+3768"
import Base: convert
else
import Base: unsafe_convert
end
import Base: iscontiguous, convert, unsafe_convert

export
StridedArrayView,
Expand All @@ -33,8 +24,8 @@ export

contiguous_view,
strided_view,
view,
unsafe_view,
aview,
unsafe_aview,
ellipview,
diagview,
rowvec_view,
Expand Down
4 changes: 2 additions & 2 deletions src/arrviews.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ ContiguousView(arr::Array, shp::Dims) = ContiguousView(arr, 0, shp)

immutable UnsafeContiguousView{T,N} <: UnsafeArrayView{T,N,N}
ptr::Ptr{T}
len::Int
shp::NTuple{N,Int}
len::Int
end

UnsafeContiguousView{T,N}(ptr::Ptr{T}, shp::NTuple{N,Int}) =
UnsafeContiguousView{T,N}(ptr, prod(shp), shp)
UnsafeContiguousView{T,N}(ptr, shp, prod(shp))

UnsafeContiguousView{T,N}(ptr::Ptr{T}, offset::Int, shp::NTuple{N,Int}) =
UnsafeContiguousView(ptr+offset*sizeof(T), shp)
Expand Down
14 changes: 7 additions & 7 deletions src/convenience.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# functions for convenience of use

## diagonal view
## diagonal aview

function diagview{T}(a::DenseArray{T,2})
m, n = size(a)
Expand All @@ -9,7 +9,7 @@ function diagview{T}(a::DenseArray{T,2})
StridedView(parent(a), offset(a), (len,), ContRank{0}, (s1 + s2,))
end

## row vector view
## row vector aview

function rowvec_view{T}(a::DenseArray{T,2}, i::Integer)
m, n = size(a)
Expand All @@ -32,8 +32,8 @@ end

## ellipview

@compat ellipview{T}(a::DenseArray{T,2}, i::Union{Integer, UnitRange}) = view(a, :, i)
@compat ellipview{T}(a::DenseArray{T,3}, i::Union{Integer, UnitRange}) = view(a, :, :, i)
@compat ellipview{T}(a::DenseArray{T,4}, i::Union{Integer, UnitRange}) = view(a, :, :, :, i)
@compat ellipview{T}(a::DenseArray{T,5}, i::Union{Integer, UnitRange}) = view(a, :, :, :, :, i)
@compat ellipview{T,N}(a::DenseArray{T,N}, i::Union{Integer, UnitRange}) = view(a, ntuple(i->Colon(),N-1)..., i)
@compat ellipview{T}(a::DenseArray{T,2}, i::Union{Integer, UnitRange}) = aview(a, :, i)
@compat ellipview{T}(a::DenseArray{T,3}, i::Union{Integer, UnitRange}) = aview(a, :, :, i)
@compat ellipview{T}(a::DenseArray{T,4}, i::Union{Integer, UnitRange}) = aview(a, :, :, :, i)
@compat ellipview{T}(a::DenseArray{T,5}, i::Union{Integer, UnitRange}) = aview(a, :, :, :, :, i)
@compat ellipview{T,N}(a::DenseArray{T,N}, i::Union{Integer, UnitRange}) = aview(a, ntuple(i->Colon(),N-1)..., i)
2 changes: 2 additions & 0 deletions src/deprecates.jl
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Base.@deprecate contiguous_view ContiguousView
Base.@deprecate strided_view StridedView
Base.@deprecate unsafe_aview unsafe_aview
Base.@deprecate view aview
Loading