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

Preserve the input element type in unique #23208

Merged
merged 2 commits into from
Aug 24, 2017
Merged

Conversation

ararslan
Copy link
Member

Previously the element type of the output was the smallest type that would fit the union of the input's individual element types. Now the output has an identical element type to the input.

Fixes #22696.

@nanosoldier runbenchmarks(ALL, vs=":master")

@ararslan ararslan added breaking This change will break code collections Data structures holding multiple items, e.g. sets labels Aug 10, 2017
@ararslan
Copy link
Member Author

Uh, what happened to AppVeyor?

Copy link
Member

@Sacha0 Sacha0 left a comment

Choose a reason for hiding this comment

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

:) !

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan

@StefanKarpinski
Copy link
Sponsor Member

Looks good to me – @JeffBezanson do you remember why it worked like this originally? Do we still want that logic for iterators or something, i.e. the case where we don't know the element type?

@ararslan
Copy link
Member Author

Bump @JeffBezanson

test/sets.jl Outdated
@test unique(x for x in Any[1,1.0])::Vector{Real} == [1]
@test unique(x for x in Any[1,1.0])::Vector{Any} == [1]
@test unique(x for x in Real[1,1.0])::Vector{Real} == [1]
@test eltype(unique(Integer[1,1,2])) === Integer
Copy link
Member

Choose a reason for hiding this comment

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

@test unique(Integer[1,1,2])::Vector{Integer} == [1,2] to test type and result? :)

Copy link
Member

@Sacha0 Sacha0 left a comment

Choose a reason for hiding this comment

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

lgtm for the touch ups! :)

@JeffBezanson
Copy link
Sponsor Member

This should call Base.iteratoreltype(itr) and use the old code if it returns EltypeUnknown().

@ararslan
Copy link
Member Author

Will do, thanks Jeff. Should that check be in place of the !isleaftype(T) or should I work it into dispatch?

@JeffBezanson
Copy link
Sponsor Member

The check can be !isleaftype(T) && iteratoreltype....

@ararslan
Copy link
Member Author

Timeouts and ProcessExitedExceptions across the board? That's more than a little concerning, but I don't see how it could be related, unless I'm missing something.

@ararslan
Copy link
Member Author

Anyone have advice on the CI failures?

@ararslan
Copy link
Member Author

Hmm, I can reproduce the stalling locally.

@ararslan
Copy link
Member Author

When running in LLDB, I'm getting a SIGINT in the core tests built from this branch. LLDB session here: https://gist.github.com/ararslan/da7e7e0cfc2adb9ca40777d17cf75b9e.

@ararslan
Copy link
Member Author

Okay, I've figured out what's happening now.

julia> U = Union{Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128}
Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}

julia> F = Base.uniontypes(U)[2]
Int16

julia> A = U[rand(F(1):F(10)) for i = 1:10]
10-element Array{Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8},1}:
 6
 5
 7
 5
 1
 1
 9
 1
 2
 1

julia> unique(A) # freezes

It freezes because now it hits a different code path. In this PR, !isleaftype(U) && iteratoreltype(A) == EltypeUnknown() is false, but the check prior to this PR, !isleaftype(U), is true. In this PR, it now tries to push! to a Set{U}() where U is that nasty Union type above. That kind of pushing explodes on 0.6, master, and this PR, but it isn't a problem on 0.6 and master since that code path doesn't get hit.

@quinnj
Copy link
Member

quinnj commented Aug 24, 2017

Luckily, we seem to already have a fix for this over on #23367

julia> U = Union{Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128}
Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}

julia> F = Base.uniontypes(U)[2]
Int16

julia> A = U[rand(F(1):F(10)) for i = 1:10]
10-element Array{Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8},1}:
  3
 10
  2
  7
 10
  5
  9
  9
  2
  1

julia> unique(A)
7-element Array{Int16,1}:
  3
 10
  2
  7
  5
  9
  1

@ararslan
Copy link
Member Author

Thanks, Jacob! In your example, is unique defined as it is here? Otherwise it won't be hitting the code that makes it freeze: pushing to a Set{Union{Nasty}}.

@ararslan
Copy link
Member Author

ararslan commented Aug 24, 2017

I checked out your jq/bitsunions branch, merged in aa/unique-eltype, built, and tried the above example again. It appears unique still chokes on the crazy Union.

Previously the element type of the output was the smallest type that
would fit the union of the input's individual element types. Now the
output has an identical element type to the input. Fixes #22696.
@ararslan
Copy link
Member Author

Jacob has noted that the issue is likely #22688

@ararslan
Copy link
Member Author

Okay, I've worked around the issue causing the core test to choke. Is this okay now?

@StefanKarpinski StefanKarpinski merged commit b46c74c into master Aug 24, 2017
@StefanKarpinski StefanKarpinski deleted the aa/unique-eltype branch August 24, 2017 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking This change will break code collections Data structures holding multiple items, e.g. sets
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants