Skip to content

[DNM] Implement Float16 #21738

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

Closed
wants to merge 2,630 commits into from
Closed

Conversation

stephentyrone
Copy link
Contributor

@stephentyrone stephentyrone commented Jan 9, 2019

Implement IEEE 754 binary16 as Float16 in the stdlib conforming to BinaryFloatingPoint and SIMDScalar. This PR does not include availability tags to make it easier for people to experiment, but all of this API will be marked available(9999) in the final PR.

Evolution proposal: swiftlang/swift-evolution#1120
Pitch thread: https://forums.swift.org/t/add-float16/33019/25

@stephentyrone
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Jan 9, 2019

Build failed
Swift Test Linux Platform
Git Sha - 5df25f561616d995499dbd3ecac442b634739421

@swift-ci
Copy link
Contributor

swift-ci commented Jan 9, 2019

Build failed
Swift Test OS X Platform
Git Sha - 5df25f561616d995499dbd3ecac442b634739421

@beccadax beccadax added the swift evolution pending discussion Flag → feature: A feature that has a Swift evolution proposal currently in review label Jan 11, 2019
@Azoy
Copy link
Contributor

Azoy commented Jan 21, 2019

@stephentyrone I tried out Float16 locally and I have to say that constructing literals is painful:

func x() {
  var x: Float16 = 1.0
}

results in the following SIL: https://gist.github.com/Azoy/12c131dd50b9d3610ac98e290123f8a8 .
I'm no floating point expert, but I tested going through float32 first then to float16 for literals to see if we could hit the constant folding pass in SIL:

% if bits == 16:
// Trunc to Float then trunc to Float16
self = ${Self}(Float(_builtinFloatLiteral: value))
% elif ...

which thankfully did get picked up by constant folding, but required adding float16 semantics:

// lib/SILOptimizer/Utils/ConstantFolding.cpp Line: 963
case BuiltinFloatType::IEEE16:
  return IEESemantics(16, 5, 10, false);

this resulted in some very pleasing SIL: https://gist.github.com/Azoy/e9f644508454befd21c4b8cb1bfd99f0
which is lowered as a simple store half 0xH3C00, half* %x._value, align 2 in LLVM IR.

We'd have to keep the workaround for the init(_ other: Float80) initializer, but I wanted to ask if it's feasible to make this change for the init(_builtinFloatLiteral value: Builtin.FPIEEE80) initializer so that literals don't have to go through this workaround.

@Azoy
Copy link
Contributor

Azoy commented Jan 21, 2019

@rjmccall I also wanted to ask if it was at all feasible if floating point types could take advantage of a Builtin.FloatLiteral type like you did for integers. I'm not too sure how we would lower this type specifically in LLVM, but all occurrences of the float literal type should get replaced by one of the Builtin.FPIEEE{bits} types eventually which makes me think that this might be somewhat feasible. Although, at this point during the release cycle is seems very unlikely that such change would go through as it affects some of the stdlib API.

@stephentyrone
Copy link
Contributor Author

I wanted to ask if it's feasible to make this change for the init(_builtinFloatLiteral value: Builtin.FPIEEE80) initializer so that literals don't have to go through this workaround.

No, because that results in a double-rounding and gets some values wrong because of it. This is a temporary fix to get things working correctly, we can easily improve on it in the future.

@stephentyrone
Copy link
Contributor Author

@rjmccall I also wanted to ask if it was at all feasible if floating point types could take advantage of a Builtin.FloatLiteral type like you did for integers.

Yes, we can (and will) do this at some future point. In order to work efficiently and maintain ABI stability, it will probably be a bit more complex than the integer literals are, but it's on the radar.

@rjmccall
Copy link
Contributor

The biggest complexity with arbitrary-precision floating-point literals is that we cannot losslessly change the base of the source literal: if the user wrote 0.1, our representation has to be 1 × 10^-1. That's true even if we have no intention of ever supporting non-binary FP types (and I'd to, eventually). We wouldn't necessarily need to support bases other than 2 and 10, but we'd need to support at least those.

The representation would therefore need to include:

  • a sign
  • a base (possibly just a 2 vs. 10 flag)
  • an exponent (a fixed-width Int32 would probably be fine for real use cases, but maybe we'd want this to be arbitrary-precision as well just because)
  • an arbitrary-precision integer as the "significand"
  • some way of expressing the infinities and various NaNs (maybe using the significand as a payload?)

And then maybe you'd also throw in a pre-computed Double, because it is not otherwise going to be efficient to turn one of these into an IEEE format.

@stephentyrone
Copy link
Contributor Author

@rjmccall Right. We want to have good support for radix 2 and 10, and nothing else really matters. There are some details to work out, but supporting those radices efficiently isn't too bad (and yes, one option is including a pre-computed Double and Float, though it's not the only option).

xedin and others added 18 commits February 17, 2020 16:09
…ions inside

Problem(s) which caused `ErrorExpr` to be added to AST should be
diagnosed already and solver wouldn't be able to produce a viable
solution in such case anyway.
The Android CI machines cannot execute the test in the target devices. Marking the test as executable makes the test filtering know that this test needs to be executed in the target device.
…-sillyness

Runtime: Less eager instantiation of type metadata in the conformance cache
Tests seem to pass without these.

Two calls still remain, in ModuleDecl::addFiles() and removeFiles().
It will take a bit more refactoring to eliminate those.
…a8a3deb651d2dd2fc3f8ad6

[ownership] Implement movable guaranteed scopes in ossa.
This fixes a recent source break. We need to perform the normal
unqualified lookup before we handle the special case of 'Self',
because there might be a type named Self defined in an outer
context.

Fixes <https://bugs.swift.org/browse/SR-12133> / <rdar://problem/59216636>
…gnostics

Use single quotes instead of backticks in diagnostics
…g terminators when fed by load [copy], copy_value.

This extends the (copy (guaranteed x)) -> (guaranteed x) optimization to handle
transforming terminator arguments. This will begin to enable us to eliminate RC ops
around optionals or casts.

I still need to add support for eliminating copies that forward through br args and phis.

<rdar://problem/56720436>
<rdar://problem/56720519>
The implementation was done quite a while ago.
Now, that we have support in lldb (swiftlang/llvm-project#773), we can enable it by default in the compiler.

LLDB now shows the runtime failure reason, for example:

* thread swiftlang#1, queue = 'com.apple.main-thread', stop reason = Swift runtime failure: arithmetic overflow
    frame swiftlang#1: 0x0000000100000f0d a.out`testit(a=127) at trap_message.swift:4
   1
   2   	@inline(never)
   3   	func testit(_ a: Int8) -> Int8 {
-> 4   	  return a + 1
   5   	}
   6

For details, see swiftlang#25978

rdar://problem/51278690
swift-ci and others added 18 commits February 22, 2020 22:50
[docs] Updating doc list for the diagnostics ported to new framework
…-hacks

[Constraint solver] Remove performance hacks for pattern type computation
build: bifurcate `_add_swift_executable_single`
[NFC] Minimize uses of 'fileprivate' after SE-0169
This isn't quite right, because it introduces double-rounding, but it will do in the short-term.
@xwu xwu added swift evolution approved Flag → feature: A feature that was approved through the Swift evolution process and removed swift evolution pending discussion Flag → feature: A feature that has a Swift evolution proposal currently in review labels Feb 27, 2020
@stephentyrone
Copy link
Contributor Author

Hmm, that's a merge gone wrong. Let's try that again.

@Azoy
Copy link
Contributor

Azoy commented Feb 28, 2020

2630 commits to implement Float16? I knew IEEE754 was tough but I didn’t know it was that tough.

@stephentyrone
Copy link
Contributor Author

Look, I just take "keep commits small" really seriously. One character max.

@Azoy
Copy link
Contributor

Azoy commented Feb 28, 2020

Easier for code review I see 😆

@stephentyrone
Copy link
Contributor Author

Real PR: #30130

@stephentyrone stephentyrone deleted the add-float16 branch March 9, 2020 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
swift evolution approved Flag → feature: A feature that was approved through the Swift evolution process
Projects
None yet
Development

Successfully merging this pull request may close these issues.