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

[WIP] fixes for julia 0.7 #37

Merged
merged 1 commit into from
Jan 13, 2018

Conversation

fredrikekre
Copy link
Member

@fredrikekre fredrikekre commented Dec 5, 2017

Split out from #34: This PR aims to just get things working on julia master, and then I will rebase #34 on top of this.

So after investigating a bit further regarding the similiar methods discussed in #34 there seem to be two problems:

  • With the new broadcasting interface, broadcast_similar used the fallback method. I fixed this by hooking into the broadcast machinery (excellent interface btw Tim 🎉)

  • The other problems show up in the tests I commented out for now. For instance:

    julia> A = OffsetArray(rand(4,4), (-3,5));
    
    julia> unique(A, 1)
    ERROR: MethodError: no method matching Array{Int64,N} where N(::Uninitialized, ::Tuple{UnitRange{Int64}})
    Stacktrace:
     [1] similar(::Type{Array{Int64,N} where N}, ::Tuple{UnitRange{Int64}}) at ./array.jl:254
     [2] similar(::Type, ::UnitRange{Int64}) at ./abstractarray.jl:567
     [3] @generated body at ./multidimensional.jl:1583 [inlined]
     [4] unique(::OffsetArray{Float64,2,Array{Float64,2}}, ::Int64) at ./multidimensional.jl:1571
     [5] top-level scope

which is because unique calls the similar(::Type{BitArray}, inds) method here: https://github.com/JuliaLang/julia/blob/c697415e5d665e2085846dc3a3313cff296ef98f/base/multidimensional.jl#L1606 which forces us to hijack that method.

Similarly, for sortcols / sortrows we end up here: https://github.com/JuliaLang/julia/blob/c697415e5d665e2085846dc3a3313cff296ef98f/base/sort.jl#L964 which forces us to hijack that method. sortcols / sortrows can be fixed, I think with the following patch to base:

diff --git a/base/sort.jl b/base/sort.jl
index 2c7a0ac..ca7bbf6 100644
--- a/base/sort.jl
+++ b/base/sort.jl
@@ -922,7 +922,7 @@ julia> sortrows([7 3 5; -1 6 4; 9 -2 8], rev=true)
 function sortrows(A::AbstractMatrix; kws...)
     inds = indices(A,1)
     T = slicetypeof(A, inds, :)
-    rows = similar(Vector{T}, indices(A, 1))
+    rows = similar(A, T, indices(A, 1))
     for i in inds
         rows[i] = view(A, i, :)
     end
@@ -961,7 +961,7 @@ julia> sortcols([7 3 5; 6 -1 -4; 9 -2 8], rev=true)
 function sortcols(A::AbstractMatrix; kws...)
     inds = indices(A,2)
     T = slicetypeof(A, :, inds)
-    cols = similar(Vector{T}, indices(A, 2))
+    cols = similar(A, T, indices(A, 2))
     for i in inds
         cols[i] = view(A, :, i)
     end

Copy link
Member

@timholy timholy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

# Broadcasting interface
@static if VERSION > v"0.7.0-DEV.2638" # https://github.com/JuliaLang/julia/pull/23939
struct OffsetArrayStyle <: Broadcast.BroadcastStyle end
Broadcast.BroadcastStyle(::Type{<:OffsetArray}) = OffsetArrayStyle()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can save several lines with

Broadcast.BroadcastStyle(::Type{<:OffsetArray}) = Broadcast.ArrayStyle{OffsetArray}()

You shouldn't need broadcast_indices or define the rule with respect to Scalar. More importantly, it should also successfully take precedence over, e.g., Array.

test/runtests.jl Outdated
@@ -312,12 +312,12 @@ seek(io, 0)
amin, amax = extrema(parent(A))
@test clamp.(A, (amax+amin)/2, amax) == OffsetArray(clamp.(parent(A), (amax+amin)/2, amax), indices(A))

@test unique(A, 1) == parent(A)
@test unique(A, 2) == parent(A)
# @test unique(A, 1) == parent(A)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do these need to be commented out?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry, I see you explained.

I'm less worried about the hijacking than you. To me similar(BitArray, inds) means "give me something that acts like a BitArray but has the following inds." If that's not a BitArray (generally, it will turn out to be a wrapped BitArray), that's fine.

test/runtests.jl Outdated
v = OffsetArray(rand(8), (-2,))
@test sort(v) == OffsetArray(sort(parent(v)), v.offsets)
@test sortrows(A) == OffsetArray(sortrows(parent(A)), A.offsets)
@test sortcols(A) == OffsetArray(sortcols(parent(A)), A.offsets)
# @test sortrows(A) == OffsetArray(sortrows(parent(A)), A.offsets)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too?

@fredrikekre fredrikekre force-pushed the fe/fixes-for-julia-0.7 branch 2 times, most recently from f6b40d3 to ca511d6 Compare December 6, 2017 10:43
@fredrikekre
Copy link
Member Author

Alright, this just needs JuliaLang/Compat.jl#427 and JuliaLang/Compat.jl#429 now, then a new Compat version.

OffsetArray(T(uninitialized, map(length, shape)), map(indexoffset, shape))

# Broadcasting interface
@static if VERSION > v"0.7.0-DEV.2638" # https://github.com/JuliaLang/julia/pull/23939
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this anymore or is it handled by similar?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No 😞 But it was fun to try the new interface 😄

Base.similar(::Type{T}, shape::Tuple{UnitRange,Vararg{UnitRange}}) where {T<:Array} =
OffsetArray(T(uninitialized, map(length, shape)), map(indexoffset, shape))
Base.similar(::Type{T}, shape::Tuple{UnitRange,Vararg{UnitRange}}) where {T<:BitArray} =
OffsetArray(T(uninitialized, map(length, shape)), map(indexoffset, shape))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need all three of these specializations or would

Base.similar(::Type{T}, shape::Tuple{UnitRange,Vararg{UnitRange}}) where {T<:AbstractArray} =
    OffsetArray(T(map(length, shape)), map(indexoffset, shape))

be good enough? (OffsetArray being the defacto "owner" of UnitRange indices.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the are needed for ambiguity resolution with https://github.com/JuliaLang/julia/blob/7d7d81af41448aeaafb2dadedf54e831616c25cf/base/array.jl#L254 and https://github.com/JuliaLang/julia/blob/7d7d81af41448aeaafb2dadedf54e831616c25cf/base/bitarray.jl#L355. And we also need a separate for OffsetArray, which does not use the new uninitialized singleton for construction. I plan to implement that in a separate PR.

@fredrikekre fredrikekre force-pushed the fe/fixes-for-julia-0.7 branch from ca511d6 to 8c8f4f3 Compare December 6, 2017 11:52
@timholy
Copy link
Member

timholy commented Dec 12, 2017

This seems ready to go except for the 0.6 breakage.

@timholy timholy closed this Dec 12, 2017
@timholy timholy reopened this Dec 12, 2017
@fredrikekre
Copy link
Member Author

fredrikekre commented Dec 12, 2017

Yes, for 0.6 this needs a new Compat tag for the IOContext change (JuliaLang/Compat.jl#427), was waiting for JuliaLang/Compat.jl#428 before tagging.

@fredrikekre fredrikekre force-pushed the fe/fixes-for-julia-0.7 branch from 8c8f4f3 to 9d0e8c3 Compare December 21, 2017 12:18
@fredrikekre fredrikekre reopened this Dec 21, 2017
@fredrikekre fredrikekre force-pushed the fe/fixes-for-julia-0.7 branch 3 times, most recently from b06b453 to 1988cf2 Compare January 9, 2018 20:48
  - indices -> axes
  - ind2sub -> CartesianIndices
  - CartesianRange -> CartesianIndices
  - copy! -> copyto!
@fredrikekre fredrikekre force-pushed the fe/fixes-for-julia-0.7 branch from 1988cf2 to ce854a7 Compare January 9, 2018 20:53
@fredrikekre fredrikekre reopened this Jan 12, 2018
@fredrikekre
Copy link
Member Author

Looks like tests passes on both 0.6 and 0.7 now :)

@timholy timholy merged commit e0ec9ed into JuliaArrays:master Jan 13, 2018
@timholy
Copy link
Member

timholy commented Jan 13, 2018

Wonderful, many thanks for seeing this through.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants