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

Operations between Float16 and Integer now return Float16 #17297

Merged
merged 3 commits into from
Aug 6, 2016
Merged

Operations between Float16 and Integer now return Float16 #17297

merged 3 commits into from
Aug 6, 2016

Conversation

vchuravy
Copy link
Member

@vchuravy vchuravy commented Jul 6, 2016

Previously we would promote to Float32 leading to subtle type
instabilities when Float16 was used for computations instead of
a pure data-storage format.

Fixes #17261

@vchuravy
Copy link
Member Author

vchuravy commented Jul 6, 2016

By only defining promote_type(Float16, Integer) = Float16 this
would incur an overhead by first converting the Integer argument
to Float16 and then Float32. Since currently all mathematical
operations fall back to Float32 this converts the types as early
as possible.

This might be problematic for platforms that natively implement
Float16 support and maybe the AVX SIMD instructions that can
support Float16.

@kshyatt kshyatt added the types and dispatch Types, subtyping and method dispatch label Jul 6, 2016
@vchuravy
Copy link
Member Author

Removed the fancy optimizations so this will be consistent, but slower.

@vchuravy
Copy link
Member Author

This is the minimal change necessary to make this work or am I missing something?

I would be in favour of doing this now and making it fast later.

@StefanKarpinski
Copy link
Sponsor Member

👍

@@ -107,6 +107,8 @@ Breaking changes
* Juxtaposition of numeric literals ending in `.` (e.g. `1.x`) is no longer
allowed ([#15731]).

* Operations between `Float16` and `Integers` now return `Float16` instead of `Float32`. ([#17261])
Copy link
Contributor

Choose a reason for hiding this comment

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

Integers

@tkelman
Copy link
Contributor

tkelman commented Jul 14, 2016

@vchuravy I rebased this because of the Float16 inference issues (#17394), and turns out this introduced more failing cases. Hopefully one of the compiler gurus can fix that issue? #17313 passed its tests when they ran on CI after the most recent PR push a few days ago, but not after it was merged due to some intervening change on master that introduced an inference regression.

The failures after my commit here are an unrelated appveyor timeout and osx libgit2 segfault (problematic libgit2 change was reverted). I guess we could merge this unless someone knows how to fix the inference issue.

(S in (Int, Rational{Int})) ||
(S === Complex{Int} && op in (+, -, *, ^)) ||
(Complex{UInt} in (R, S) && op === ^) ||
(S <: Integer && op === ^)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is really messy and took more time to get passing than I should have spent on it. We should maybe comment out Float16 and Complex{Float16} from the loop if this is hard to fix, though we won't know when it gets fixed if we do that.

Copy link
Contributor

Choose a reason for hiding this comment

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

See #17389, that should fix all these.

@vchuravy
Copy link
Member Author

@tkelman Thanks for picking this up. I sadly don't know how to fix the test failures... I would like to see this in 0.5 so that we can work on #17440

@tkelman
Copy link
Contributor

tkelman commented Jul 18, 2016

This was a bit unconventional to bisect, had to apply the patch from https://github.com/JuliaLang/julia/commit/6b40f865f0f379babea6daa0729fc3afbfc5c301.patch at different points in the history to see where it would cause @code_warntype Float16(1)+true to start giving ANY output. Turns out it was cd35df5. Is there a comprehension somewhere in the promotion call chain for Float16 conversion?

@vchuravy
Copy link
Member Author

vchuravy commented Jul 18, 2016

Not as far as I can tell, but this makes the call-chain a lot longer and we
do a lot more conversions to Float16. I just stepped through the entire
chain with Gallium for

x = Float16(1.0)
y = Rational{Int64}(1, 2)
@enter x + y

and we convert a lot more and a lot earlier to and fromFloat16, but there
is no comprehension in sight.

@@ -160,7 +161,7 @@ end

ldexp(a::Float16, b::Integer) = Float16(ldexp(Float32(a), b))

^(x::Float16, y::Integer) = Float16(Float32(x)^y)
^(x::Float16, y::Float16) = Float16(Float32(x)^Float32(y))
Copy link
Member Author

Choose a reason for hiding this comment

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

This change is a mistake.

^(x::Float16, y::Integer) = Float16(Float32(x)^y) was correct.

@JeffBezanson
Copy link
Sponsor Member

Bump. Rebase and merge?

@tkelman
Copy link
Contributor

tkelman commented Jul 22, 2016

I think this would violate feature freeze. No more breaking changes until we branch.

@StefanKarpinski
Copy link
Sponsor Member

It's really a shame that this slipped through the cracks, but yes, at this point this violates feature freeze.

@ViralBShah
Copy link
Member

Would doing it in 0.5.x be possible - I guess this is strictly not a breaking change. If this is considered breaking and won't happen in 0.5.x, then we should try and get it in now rather than go a whole release with the old behaviour.

@tkelman
Copy link
Contributor

tkelman commented Jul 23, 2016

We wouldn't backport something that changes return types either. We need to stop putting anything other than bug fixes (or docs, or simple test additions) in this release, that's what feature freeze means.

@StefanKarpinski
Copy link
Sponsor Member

If this isn't in 0.5.0, it can't be in 0.5.x – it's very much a behavior change that is not a bug fix. Maybe we should just leave this and make a concerted effort in the next release to make sure that Float16s uniformly work just like Float32 and Float64. I suspect there are more behavioral differences than this.

Previously we would promote to Float32 leading to subtle type
instabilities when Float16 was used for computations instead of
a pure data-storage format.

By defining `promote_type(Float16, Integer) = Float16` this
incurs an overhead by first converting the `Integer` argument
to `Float16` and then `Float32` for mathematical operations,
that are performed in Float32.
@vchuravy
Copy link
Member Author

vchuravy commented Aug 5, 2016

Yeah! The tests pass.

@@ -160,6 +160,8 @@ This section lists changes that do not have deprecation warnings.
* `map` on a dictionary now expects a function that expects and returns a `Pair`.
The result is now another dictionary instead of an array ([#16622]).

* Operations between `Float16` and `Integers` now return `Float16` instead of `Float32`. ([#17261])
Copy link
Contributor

Choose a reason for hiding this comment

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

should be in 0.6 news section now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants