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

Make mapreduce also work with Range{BigInt} #8871

Closed
wants to merge 2 commits into from
Closed

Make mapreduce also work with Range{BigInt} #8871

wants to merge 2 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Nov 1, 2014

I noticed the following behavior: when calling one of

prod(1:big(16))
reduce(*, 1:big(16))

this results in

ERROR: `mapreduce_impl` has no method matching mapreduce_impl(::IdFun, ::MulFun, ::UnitRange{BigInt}, ::Int64, ::BigInt)
 in _mapreduce at reduce.jl:168
 in prod at reduce.jl:265

(On the other hand,

prod(1:big(15))
reduce(*, 1:big(15))
foldl(*, 1:big(16))
factorial(big(16))

all work fine.)

I propose this commit, which fixes that behavior, but should

mapreduce_pairwise_impl(f, op, A::AbstractArray, ifirst::Int, ilast::Int, blksize::Int)
mapreduce_seq_impl(f, op::AddFun, a::AbstractArray, ifirst::Int, ilast::Int)
mapreduce_impl(f, op::AddFun, A::AbstractArray, ifirst::Int, ilast::Int)
mapreduce_impl(f, op::MaxFun, A::AbstractArray, first::Int, last::Int)
mapreduce_impl(f, op::MinFun, A::AbstractArray, first::Int, last::Int)
mapreduce_impl(f, op::AndFun, A::AbstractArray, ifirst::Int, ilast::Int)
mapreduce_impl(f, op::OrFun, A::AbstractArray, ifirst::Int, ilast::Int)

possibly also be changed in the same way, even though their last arguments' being Int does not break anything (that I could find)?

@ivarne
Copy link
Sponsor Member

ivarne commented Nov 1, 2014

Looks reasonable and bonus for adding a test!

I feel that this is only fixing a symptom rather than a the general issue. AbstractArrays that can't use native Ints for indexing is kind of tricky. Not sure if we can really fix that tough.

@ivarne
Copy link
Sponsor Member

ivarne commented Nov 1, 2014

In case anyone else is confused why 15 works and not 16, it should be pretty obvious from the implementation of _mapreduce. It looks like we have some invalid assumptions there.

@ghost
Copy link
Author

ghost commented Nov 3, 2014

Given isa(1:(big(typemax(Int)) + 1), AbstractArray) == true, how else would one index all the data?

And is there any particular reason why AbstractArray is used in this case instead of the iterator interface, like in foldl? Is it because this is potentially meant to be computed in a distributed fashion? If so, where does this happen?

@ivarne
Copy link
Sponsor Member

ivarne commented Nov 3, 2014

I didn't say it was wrong for AbstractArrays to use larger types for indexing. I just said that I would like a better fix.

I looked at your code again now, and got a feeling that with your patch prod(big(typemax(Int)):big(typemax(Int))+16) will hang forever.

I think we have 3 good reasons to not use a foldl style implementation

  • Keep the associativity undefined so that we can utilize multithreading in the future.
  • It has better error accumulating behaviour for many FloatingPoint operations
  • It keeps BigInt working more with smaller (=faster) numbers.

@ivarne
Copy link
Sponsor Member

ivarne commented Nov 3, 2014

Sorry, I was wrong about the hang. You'd need a range with length(range) > typemax(Int) for the hang to occur, and a 3 GHz processor will spend 10 years doing that many clock cycles. Maybe we should just convert n to an Int in _mapreduce, with a overflow checking conversion?

ivarne added a commit that referenced this pull request Nov 3, 2014
Mapreduce didn't work with `Range{BigInt}`, because the length wasn't a
`Int`, because of potential overflow. This patch just converts the
length to Int with a checked conversion, because a mapreduce on larger
arrays will probably never finish anyway.
@@ -104,6 +104,8 @@ prod([3.0]) === 0.0
prod(z) === 120
prod(fz) === 120.0

prod(1:big(16)) == big(20922789888000)
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

NOT good to follow the style of broken tests from the previous lines!

We need to add @test in front of all of those. (I'm working on a fix)

ivarne added a commit that referenced this pull request Nov 3, 2014
Mapreduce didn't work with `Range{BigInt}`, because the length wasn't a
`Int`, because of potential overflow. This patch just converts the
length to Int with a checked conversion, because a mapreduce on larger
arrays will probably never finish anyway.

Also fix some broken test of prod
@ivarne ivarne mentioned this pull request Nov 3, 2014
@ghost
Copy link
Author

ghost commented Nov 3, 2014

Ah ok I did not notice your commit. Feel free to close this.

@ivarne
Copy link
Sponsor Member

ivarne commented Nov 3, 2014

Yeah! We crossed each other. I had guessed so much on this issue, that I had to actually try and see that I was not just speaking nonsense. Currently I think my PR is more complete, so unless you want to clean this PR up to get a commit in the history of Julia, I'll just merge mine and close this.

We love and value new contributors tough, and I don't want you to feel I "stole" your PR. Please ask if you have any trouble cleaning up the PR.

@ghost
Copy link
Author

ghost commented Nov 3, 2014

No problem ;)

@ghost ghost closed this Nov 3, 2014
@ghost ghost deleted the bug_reduce_types branch November 3, 2014 21:00
lindahua added a commit that referenced this pull request Nov 4, 2014
ivarne added a commit that referenced this pull request Nov 7, 2014
Mapreduce didn't work with `Range{BigInt}`, because the length wasn't a
`Int`, because of potential overflow. This patch just converts the
length to Int with a checked conversion, because a mapreduce on larger
arrays will probably never finish anyway.

Also fix some broken test of prod

(cherry picked from commit 9493465)

Fix test for 32 bit

The test added in #8893 shouldn't use typemax(Int), but typemax(Int64)

(cherry picked from commit 49083be)
waTeim pushed a commit to waTeim/julia that referenced this pull request Nov 23, 2014
Mapreduce didn't work with `Range{BigInt}`, because the length wasn't a
`Int`, because of potential overflow. This patch just converts the
length to Int with a checked conversion, because a mapreduce on larger
arrays will probably never finish anyway.

Also fix some broken test of prod
This pull request was closed.
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