Skip to content

Commit

Permalink
Rename allocate_for -> similar. Fixes #17124.
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy committed Jul 7, 2016
1 parent 05c0528 commit 97b3e9a
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 44 deletions.
33 changes: 11 additions & 22 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,6 @@ different element type it will create a regular `Array` instead:
2.18425e-314 2.18425e-314 2.18425e-314 2.18425e-314
2.18425e-314 2.18425e-314 2.18425e-314 2.18425e-314
See also `allocate_for`.
"""
similar{T}(a::AbstractArray{T}) = similar(a, T)
similar( a::AbstractArray, T::Type) = similar(a, T, to_shape(indices(a)))
Expand All @@ -347,44 +346,34 @@ to_shape(r::OneTo) = Int(last(r))
to_shape(r::UnitRange) = convert(UnitRange{Int}, r)

"""
allocate_for(storagetype, referencearray, [shape])
similar(storagetype, indices)
Create an uninitialized mutable array analogous to that specified by
`storagetype`, but with type and shape specified by the final two
arguments. The main purpose of this function is to support allocation
of arrays that may have unconventional indexing (starting at other
than 1), as determined by `referencearray` and the optional `shape`
information.
`storagetype`, but with `indices` specified by the last
argument. `storagetype` might be a type or a function.
**Examples**:
allocate_for(Array{Int}, A)
similar(Array{Int}, indices(A))
creates an array that "acts like" an `Array{Int}` (and might indeed be
backed by one), but which is indexed identically to `A`. If `A` has
conventional indexing, this will likely just call
conventional indexing, this will be identical to
`Array{Int}(size(A))`, but if `A` has unconventional indexing then the
indices of the result will match `A`.
allocate_for(BitArray, A, (indices(A, 2),))
similar(BitArray, (indices(A, 2),))
would create a 1-dimensional logical array whose indices match those
of the columns of `A`.
The main purpose of the `referencearray` argument is to select a
particular array type supporting unconventional indexing (as it is
possible that several different ones will be simultaneously in use).
similar(dims->zeros(Int, dims), indices(A))
See also `similar`.
would create an array of `Int`, initialized to zero, matching the
indices of `A`.
"""
allocate_for(f, a, shape::Union{DimOrInd,DimsOrInds}) = f(to_shape(shape))
allocate_for(f, a) = allocate_for(f, a, indices(a))
# allocate_for when passed multiple arrays. Necessary for broadcast, etc.
function allocate_for(f, as::Tuple, shape::Union{DimOrInd,DimsOrInds})
@_inline_meta
a = promote_indices(as...)
allocate_for(f, a, shape)
end
similar(f, shape::Tuple) = f(to_shape(shape))
similar(f, dims::DimOrInd...) = similar(f, dims)

promote_indices(a) = a
function promote_indices(a, b, c...)
Expand Down
12 changes: 6 additions & 6 deletions base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Broadcast

using Base.Cartesian
using Base: promote_op, promote_eltype, promote_eltype_op, @get!, _msk_end, unsafe_bitgetindex, linearindices, to_shape, allocate_for, tail, dimlength, OneTo
using Base: promote_op, promote_eltype, promote_eltype_op, @get!, _msk_end, unsafe_bitgetindex, linearindices, to_shape, tail, dimlength, OneTo
import Base: .+, .-, .*, ./, .\, .//, .==, .<, .!=, .<=, , .%, .<<, .>>, .^
export broadcast, broadcast!, bitbroadcast
export broadcast_getindex, broadcast_setindex!
Expand Down Expand Up @@ -181,20 +181,20 @@ function broadcast_t(f, ::Type{Any}, As...)
shp = broadcast_shape(As...)
iter = CartesianRange(shp)
if isempty(iter)
return allocate_for(Array{Union{}}, As, shp)
return similar(Array{Union{}}, shp)
end
nargs = length(As)
sz = size(iter)
indexmaps = map(x->newindexer(sz, x), As)
st = start(iter)
I, st = next(iter, st)
val = f([ As[i][newindex(I, indexmaps[i])] for i=1:nargs ]...)
B = allocate_for(Array{typeof(val)}, As, shp)
B = similar(Array{typeof(val)}, shp)
B[I] = val
return _broadcast!(f, B, indexmaps, As, Val{nargs}, iter, st, 1)
end

@inline broadcast_t(f, T, As...) = broadcast!(f, allocate_for(Array{T}, As, broadcast_shape(As...)), As...)
@inline broadcast_t(f, T, As...) = broadcast!(f, similar(Array{T}, broadcast_shape(As...)), As...)

@inline broadcast(f, As...) = broadcast_t(f, promote_eltype_op(f, As...), As...)

Expand All @@ -217,7 +217,7 @@ function broadcast(f, As...)
end
=#

@inline bitbroadcast(f, As...) = broadcast!(f, allocate_for(BitArray, As, broadcast_shape(As...)), As...)
@inline bitbroadcast(f, As...) = broadcast!(f, similar(BitArray, broadcast_shape(As...)), As...)

broadcast_getindex(src::AbstractArray, I::AbstractArray...) = broadcast_getindex!(Array{eltype(src)}(to_shape(broadcast_shape(I...))), src, I...)
@generated function broadcast_getindex!(dest::AbstractArray, src::AbstractArray, I::AbstractArray...)
Expand Down Expand Up @@ -368,7 +368,7 @@ for (f, scalarf) in ((:.==, :(==)),
shape = :(indices($active))
@eval begin
function ($f)(A::$sigA, B::$sigB)
P = allocate_for(BitArray, $active, $shape)
P = similar(BitArray, $shape)
F = parent(P)
l = length(F)
l == 0 && return F
Expand Down
1 change: 0 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,6 @@ export
zeta,

# arrays
allocate_for,
bitbroadcast,
broadcast!,
broadcast,
Expand Down
8 changes: 4 additions & 4 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ If `dim` is specified, returns unique regions of the array `itr` along `dim`.
@generated function unique{T,N}(A::AbstractArray{T,N}, dim::Int)
quote
1 <= dim <= $N || return copy(A)
hashes = allocate_for(inds->zeros(UInt, inds), A, indices(A, dim))
hashes = similar(inds->zeros(UInt, inds), indices(A, dim))

# Compute hash for each row
k = 0
Expand All @@ -791,15 +791,15 @@ If `dim` is specified, returns unique regions of the array `itr` along `dim`.
end

# Collect index of first row for each hash
uniquerow = allocate_for(Array{Int}, A, indices(A, dim))
uniquerow = similar(Array{Int}, indices(A, dim))
firstrow = Dict{Prehashed,Int}()
for k = indices(A, dim)
uniquerow[k] = get!(firstrow, Prehashed(hashes[k]), k)
end
uniquerows = collect(values(firstrow))

# Check for collisions
collided = allocate_for(falses, A, indices(A, dim))
collided = similar(falses, indices(A, dim))
@inbounds begin
@nloops $N i A d->(if d == dim
k = i_d
Expand All @@ -814,7 +814,7 @@ If `dim` is specified, returns unique regions of the array `itr` along `dim`.
end

if any(collided)
nowcollided = allocate_for(BitArray, A, indices(A, dim))
nowcollided = similar(BitArray, indices(A, dim))
while any(collided)
# Collect index of first row for each collided hash
empty!(firstrow)
Expand Down
8 changes: 4 additions & 4 deletions base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module Sort

using Base: Order, copymutable, linearindices, allocate_for, linearindexing, viewindexing, LinearFast
using Base: Order, copymutable, linearindices, linearindexing, viewindexing, LinearFast

import
Base.sort,
Expand Down Expand Up @@ -447,7 +447,7 @@ function sortperm(v::AbstractVector;
by=identity,
rev::Bool=false,
order::Ordering=Forward)
p = Base.allocate_for(Vector{Int}, v, indices(v, 1))
p = similar(Vector{Int}, indices(v, 1))
for (i,ind) in zip(eachindex(p), indices(v, 1))
p[i] = ind
end
Expand Down Expand Up @@ -507,7 +507,7 @@ end
function sortrows(A::AbstractMatrix; kws...)
inds = indices(A,1)
T = slicetypeof(A, inds, :)
rows = allocate_for(Vector{T}, A, indices(A, 1))
rows = similar(Vector{T}, indices(A, 1))
for i in inds
rows[i] = view(A, i, :)
end
Expand All @@ -518,7 +518,7 @@ end
function sortcols(A::AbstractMatrix; kws...)
inds = indices(A,2)
T = slicetypeof(A, :, inds)
cols = allocate_for(Vector{T}, A, indices(A, 2))
cols = similar(Vector{T}, indices(A, 2))
for i in inds
cols[i] = view(A, :, i)
end
Expand Down
13 changes: 6 additions & 7 deletions test/offsetarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

module OAs

using Base: DimOrInd, Indices, LinearSlow, LinearFast
using Base: DimOrInd, DimsOrInds, Indices, LinearSlow, LinearFast

export OffsetArray

Expand Down Expand Up @@ -46,16 +46,15 @@ Base.indices1{T}(A::OffsetArray{T,0}) = 1:1
function Base.similar(A::OffsetArray, T::Type, dims::Dims)
B = similar(parent(A), T, dims)
end
function Base.similar(A::AbstractArray, T::Type, inds::Tuple{Vararg{DimOrInd}})
function Base.similar(A::AbstractArray, T::Type, inds::Tuple{UnitRange,Vararg{UnitRange}})
B = similar(A, T, map(Base.dimlength, inds))
OffsetArray(B, map(indsoffset, inds))
end

Base.allocate_for(f, A::OffsetArray, shape::DimOrInd) = OffsetArray(f(Base.dimlength(shape)), (indsoffset(shape),))
Base.allocate_for(f, A::OffsetArray, shape::Tuple{Vararg{DimOrInd}}) = OffsetArray(f(map(Base.dimlength, shape)), map(indsoffset, shape))
Base.similar(f::Union{Function,Type}, shape::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(f(map(Base.dimlength, shape)), map(indsoffset, shape))
Base.promote_indices(a::OffsetArray, b::OffsetArray) = a

Base.reshape(A::AbstractArray, inds::Indices) = OffsetArray(reshape(A, map(Base.dimlength, inds)), map(indsoffset, inds))
Base.reshape(A::AbstractArray, inds::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(reshape(A, map(Base.dimlength, inds)), map(indsoffset, inds))

@inline function Base.getindex{T,N}(A::OffsetArray{T,N}, I::Vararg{Int,N})
@boundscheck checkbounds(A, I...)
Expand Down Expand Up @@ -207,10 +206,10 @@ B = similar(A, (3,4))
@test isa(B, Array{Int,2})
@test size(B) == (3,4)
@test indices(B) == (1:3, 1:4)
B = similar(A, (-3:3,4))
B = similar(A, (-3:3,1:4))
@test isa(B, OffsetArray{Int,2})
@test indices(B) == (-3:3, 1:4)
B = similar(parent(A), (-3:3,4))
B = similar(parent(A), (-3:3,1:4))
@test isa(B, OffsetArray{Int,2})
@test indices(B) == (-3:3, 1:4)

Expand Down

0 comments on commit 97b3e9a

Please sign in to comment.