Skip to content

Commit

Permalink
Merge pull request #3 from N5N3/patch2
Browse files Browse the repository at this point in the history
second try
  • Loading branch information
N5N3 authored Jul 5, 2021
2 parents acbb8f4 + 996e272 commit b69943a
Show file tree
Hide file tree
Showing 40 changed files with 546 additions and 331 deletions.
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ New library features
Standard library changes
------------------------

* The `length` function on certain ranges of certain specific element types no longer checks for integer
overflow in most cases. The new function `checked_length` is now available, which will try to use checked
arithmetic to error if the result may be wrapping. Or use a package such as SaferIntegers.jl when
constructing the range. ([#40382])

#### Package Manager

#### LinearAlgebra
Expand Down
25 changes: 9 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@
Documentation:
[![version 1][docs-img]](https://docs.julialang.org)

Code coverage:
[![coveralls][coveralls-img]](https://coveralls.io/r/JuliaLang/julia?branch=master)
[![codecov][codecov-img]](https://codecov.io/github/JuliaLang/julia?branch=master)

Continuous integration: [![Build status](https://badge.buildkite.com/f28e0d28b345f9fad5856ce6a8d64fffc7c70df8f4f2685cd8.svg?branch=master)](https://buildkite.com/julialang/julia)

[docs-img]: https://img.shields.io/badge/docs-v1-blue.svg
[coveralls-img]: https://img.shields.io/coveralls/github/JuliaLang/julia/master.svg?label=coveralls
[codecov-img]: https://img.shields.io/codecov/c/github/JuliaLang/julia/master.svg?label=codecov


## The Julia Language

Expand Down Expand Up @@ -141,19 +150,3 @@ Supported IDEs include: [julia-vscode](https://github.com/JuliaEditorSupport/jul
Code plugin), [Juno](http://junolab.org/) (Atom plugin). [Jupyter](https://jupyter.org/)
notebooks are available through the [IJulia](https://github.com/JuliaLang/IJulia.jl) package, and
[Pluto](https://github.com/fonsp/Pluto.jl) notebooks through the Pluto.jl package.

## Continuous Integration (CI) Builders

Code coverage:
[![coveralls][coveralls-img]](https://coveralls.io/r/JuliaLang/julia?branch=master)
[![codecov][codecov-img]](https://codecov.io/github/JuliaLang/julia?branch=master)

| Builder | Status |
| ---------- | ------ |
| Overall | [![Build status](https://badge.buildkite.com/f28e0d28b345f9fad5856ce6a8d64fffc7c70df8f4f2685cd8.svg?branch=master)](https://buildkite.com/julialang/julia) |
| analyzegc | [![Build status](https://badge.buildkite.com/f28e0d28b345f9fad5856ce6a8d64fffc7c70df8f4f2685cd8.svg?branch=master&step=analyzegc)](https://buildkite.com/julialang/julia) |
| llvmpasses | [![Build status](https://badge.buildkite.com/f28e0d28b345f9fad5856ce6a8d64fffc7c70df8f4f2685cd8.svg?branch=master&step=llvmpasses)](https://buildkite.com/julialang/julia) |
| coverage | [![Build status](https://badge.buildkite.com/d5ae34dbbf6fefe615300c4f3118bf63cb4a5ae7fd962263c1.svg?branch=master)](https://buildkite.com/julialang/julia-coverage-linux64) |

[coveralls-img]: https://img.shields.io/coveralls/github/JuliaLang/julia/master.svg?label=coveralls
[codecov-img]: https://img.shields.io/codecov/c/github/JuliaLang/julia/master.svg?label=codecov
13 changes: 8 additions & 5 deletions base/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,6 @@ include("refpointer.jl")
include("checked.jl")
using .Checked

# SIMD loops
@pure sizeof(s::String) = Core.sizeof(s) # needed by gensym as called from simdloop
include("simdloop.jl")
using .SimdLoop

# array structures
include("indices.jl")
include("array.jl")
Expand Down Expand Up @@ -177,6 +172,14 @@ using .MultiplicativeInverses
include("abstractarraymath.jl")
include("arraymath.jl")

# SIMD loops
@pure sizeof(s::String) = Core.sizeof(s) # needed by gensym as called from simdloop
include("simdloop.jl")
using .SimdLoop

# functions for AbstractArray with @simd
include("abstractarraypatch.jl")

# map-reduce operators
include("reduce.jl")

Expand Down
124 changes: 34 additions & 90 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,6 @@ axes1(A::AbstractArray{<:Any,0}) = OneTo(1)
axes1(A::AbstractArray) = (@_inline_meta; axes(A)[1])
axes1(iter) = oneto(length(iter))

unsafe_indices(A) = axes(A)
unsafe_indices(r::AbstractRange) = (oneto(unsafe_length(r)),) # Ranges use checked_sub for size

"""
keys(a::AbstractArray)
Expand Down Expand Up @@ -580,14 +577,14 @@ end
function trailingsize(inds::Indices, n)
s = 1
for i=n:length(inds)
s *= unsafe_length(inds[i])
s *= length(inds[i])
end
return s
end
# This version is type-stable even if inds is heterogeneous
function trailingsize(inds::Indices)
@_inline_meta
prod(map(unsafe_length, inds))
prod(map(length, inds))
end

## Bounds checking ##
Expand Down Expand Up @@ -688,7 +685,7 @@ function checkbounds_indices(::Type{Bool}, ::Tuple{}, I::Tuple)
@_inline_meta
checkindex(Bool, OneTo(1), I[1])::Bool & checkbounds_indices(Bool, (), tail(I))
end
checkbounds_indices(::Type{Bool}, IA::Tuple, ::Tuple{}) = (@_inline_meta; all(x->unsafe_length(x)==1, IA))
checkbounds_indices(::Type{Bool}, IA::Tuple, ::Tuple{}) = (@_inline_meta; all(x->length(x)==1, IA))
checkbounds_indices(::Type{Bool}, ::Tuple{}, ::Tuple{}) = true

throw_boundserror(A, I) = (@_noinline_meta; throw(BoundsError(A, I)))
Expand Down Expand Up @@ -886,7 +883,35 @@ function copy!(dst::AbstractArray, src::AbstractArray)
end

## from general iterable to any array

"""
copyto!(dest::AbstractArray, src) -> dest
Copy all elements from collection `src` to array `dest`, whose length must be greater than
or equal to the length `n` of `src`. The first `n` elements of `dest` are overwritten,
the other elements are left untouched.
See also [`copy!`](@ref Base.copy!), [`copy`](@ref).
# Examples
```jldoctest
julia> x = [1., 0., 3., 0., 5.];
julia> y = zeros(7);
julia> copyto!(y, x);
julia> y
7-element Vector{Float64}:
1.0
0.0
3.0
0.0
5.0
0.0
0.0
```
"""
function copyto!(dest::AbstractArray, src)
destiter = eachindex(dest)
y = iterate(destiter)
Expand Down Expand Up @@ -964,87 +989,6 @@ function copyto!(dest::AbstractArray, dstart::Integer, src, sstart::Integer, n::
return dest
end

## copy between abstract arrays - generally more efficient
## since a single index variable can be used.

"""
copyto!(dest::AbstractArray, src) -> dest
Copy all elements from collection `src` to array `dest`, whose length must be greater than
or equal to the length `n` of `src`. The first `n` elements of `dest` are overwritten,
the other elements are left untouched.
See also [`copy!`](@ref Base.copy!), [`copy`](@ref).
# Examples
```jldoctest
julia> x = [1., 0., 3., 0., 5.];
julia> y = zeros(7);
julia> copyto!(y, x);
julia> y
7-element Vector{Float64}:
1.0
0.0
3.0
0.0
5.0
0.0
0.0
```
"""
function copyto!(dest::AbstractArray, src::AbstractArray)
isempty(src) && return dest
src′ = unalias(dest, src)
copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(src′), src′)
end

function copyto!(deststyle::IndexStyle, dest::AbstractArray, srcstyle::IndexStyle, src::AbstractArray)
isempty(src) && return dest
src′ = unalias(dest, src)
copyto_unaliased!(deststyle, dest, srcstyle, src′)
end

function copyto_unaliased!(deststyle::IndexStyle, dest::AbstractArray, srcstyle::IndexStyle, src::AbstractArray)
isempty(src) && return dest
length(dest) >= length(src) || throw(BoundsError(dest, LinearIndices(src)))
if deststyle isa IndexLinear
if srcstyle isa IndexLinear
Δi = firstindex(dest) - firstindex(src)
for i in eachindex(src)
@inbounds dest[i + Δi] = src[i]
end
else
j = firstindex(dest) - 1
@inbounds @simd for I in eachindex(src)
dest[j+=1] = src[I]
end
end
else
if srcstyle isa IndexLinear
i = firstindex(src) - 1
@inbounds @simd for J in eachindex(dest)
dest[J] = src[i+=1]
end
else
iterdest, itersrc = eachindex(dest), eachindex(src)
if iterdest == itersrc
# Shared-iterator implementation
@inbounds @simd for I in itersrc
dest[I] = src[I]
end
else
for (I,J) in zip(itersrc, iterdest)
@inbounds dest[J] = src[I]
end
end
end
end
return dest
end

function copyto!(dest::AbstractArray, dstart::Integer, src::AbstractArray)
copyto!(dest, dstart, src, first(LinearIndices(src)), length(src))
end
Expand Down Expand Up @@ -2497,8 +2441,8 @@ function _sub2ind_recurse(inds, L, ind, i::Integer, I::Integer...)
end

nextL(L, l::Integer) = L*l
nextL(L, r::AbstractUnitRange) = L*unsafe_length(r)
nextL(L, r::Slice) = L*unsafe_length(r.indices)
nextL(L, r::AbstractUnitRange) = L*length(r)
nextL(L, r::Slice) = L*length(r.indices)
offsetin(i, l::Integer) = i-1
offsetin(i, r::AbstractUnitRange) = i-first(r)

Expand All @@ -2524,7 +2468,7 @@ end
_lookup(ind, d::Integer) = ind+1
_lookup(ind, r::AbstractUnitRange) = ind+first(r)
_div(ind, d::Integer) = div(ind, d), 1, d
_div(ind, r::AbstractUnitRange) = (d = unsafe_length(r); (div(ind, d), first(r), d))
_div(ind, r::AbstractUnitRange) = (d = length(r); (div(ind, d), first(r), d))

# Vectorized forms
function _sub2ind(inds::Indices{1}, I1::AbstractVector{T}, I::AbstractVector{T}...) where T<:Integer
Expand Down
55 changes: 55 additions & 0 deletions base/abstractarraypatch.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

## copy between abstract arrays - generally more efficient
## since a single index variable can be used.
## copyto_unaliased! use @simd to speed up, so these definition is seperated from abstractarray.jl

function copyto!(dest::AbstractArray, src::AbstractArray)
isempty(src) && return dest
src′ = unalias(dest, src)
copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(src′), src′)
end

function copyto!(deststyle::IndexStyle, dest::AbstractArray, srcstyle::IndexStyle, src::AbstractArray)
isempty(src) && return dest
src′ = unalias(dest, src)
copyto_unaliased!(deststyle, dest, srcstyle, src′)
end

function copyto_unaliased!(deststyle::IndexStyle, dest::AbstractArray, srcstyle::IndexStyle, src::AbstractArray)
isempty(src) && return dest
length(dest) >= length(src) || throw(BoundsError(dest, LinearIndices(src)))
if deststyle isa IndexLinear
if srcstyle isa IndexLinear
Δi = firstindex(dest) - firstindex(src)
for i in eachindex(src)
@inbounds dest[i + Δi] = src[i]
end
else
j = firstindex(dest) - 1
@inbounds @simd for I in eachindex(src)
dest[j+=1] = src[I]
end
end
else
if srcstyle isa IndexLinear
i = firstindex(src) - 1
@inbounds @simd for J in eachindex(dest)
dest[J] = src[i+=1]
end
else
iterdest, itersrc = eachindex(dest), eachindex(src)
if iterdest == itersrc
# Shared-iterator implementation
@inbounds @simd for I in itersrc
dest[I] = src[I]
end
else
for (I,J) in zip(itersrc, iterdest)
@inbounds dest[J] = src[I]
end
end
end
end
return dest
end
2 changes: 1 addition & 1 deletion base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ an `Int`.
"""
Base.@propagate_inbounds newindex(arg, I::CartesianIndex) = CartesianIndex(_newindex(axes(arg), I.I))
Base.@propagate_inbounds newindex(arg, I::Integer) = CartesianIndex(_newindex(axes(arg), (I,)))
Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple) = (ifelse(Base.unsafe_length(ax[1])==1, ax[1][1], I[1]), _newindex(tail(ax), tail(I))...)
Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple) = (ifelse(length(ax[1]) == 1, ax[1][1], I[1]), _newindex(tail(ax), tail(I))...)
Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple) = ()
Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple{}) = (ax[1][1], _newindex(tail(ax), ())...)
Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple{}) = ()
Expand Down
12 changes: 10 additions & 2 deletions base/checked.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ module Checked

export checked_neg, checked_abs, checked_add, checked_sub, checked_mul,
checked_div, checked_rem, checked_fld, checked_mod, checked_cld,
add_with_overflow, sub_with_overflow, mul_with_overflow
checked_length, add_with_overflow, sub_with_overflow, mul_with_overflow

import Core.Intrinsics:
checked_sadd_int, checked_ssub_int, checked_smul_int, checked_sdiv_int,
checked_srem_int,
checked_uadd_int, checked_usub_int, checked_umul_int, checked_udiv_int,
checked_urem_int
import ..no_op_err, ..@_inline_meta, ..@_noinline_meta
import ..no_op_err, ..@_inline_meta, ..@_noinline_meta, ..checked_length

# define promotion behavior for checked operations
checked_add(x::Integer, y::Integer) = checked_add(promote(x,y)...)
Expand Down Expand Up @@ -349,4 +349,12 @@ The overflow protection may impose a perceptible performance penalty.
"""
checked_cld(x::T, y::T) where {T<:Integer} = cld(x, y) # Base.cld already checks

"""
Base.checked_length(r)
Calculates `length(r)`, but may check for overflow errors where applicable when
the result doesn't fit into `Union{Integer(eltype(r)),Int}`.
"""
checked_length(r) = length(r) # for most things, length doesn't error

end
5 changes: 0 additions & 5 deletions base/compiler/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,6 @@ add_with_overflow(x::T, y::T) where {T<:SignedInt} = checked_sadd_int(x, y)
add_with_overflow(x::T, y::T) where {T<:UnsignedInt} = checked_uadd_int(x, y)
add_with_overflow(x::Bool, y::Bool) = (x+y, false)

# SIMD loops (The new copyto_unalias! use @simd)
@pure sizeof(s::String) = Core.sizeof(s) # needed by gensym as called from simdloop
include("simdloop.jl")
using .SimdLoop

# core array operations
include("indices.jl")
include("array.jl")
Expand Down
3 changes: 3 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ end
@deprecate cat_shape(dims, shape::Tuple{}, shapes::Tuple...) cat_shape(dims, shapes) false
cat_shape(dims, shape::Tuple{}) = () # make sure `cat_shape(dims, ())` do not recursively calls itself

@deprecate unsafe_indices(A) axes(A) false
@deprecate unsafe_length(r) length(r) false

# END 1.6 deprecations

# BEGIN 1.7 deprecations
Expand Down
Loading

0 comments on commit b69943a

Please sign in to comment.