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

Add BFloat16 #98643

Open
wants to merge 77 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
589afe0
Add api for BFloat16
huoyaoyuan Feb 18, 2024
312d051
Creating
huoyaoyuan Feb 18, 2024
5e1c981
Equals and GetHashCode
huoyaoyuan Feb 18, 2024
1fb4765
Comparison
huoyaoyuan Feb 18, 2024
fc05d3b
Constants and comment
huoyaoyuan Feb 18, 2024
152fe99
Xml doc
huoyaoyuan Feb 18, 2024
25a16e7
Using rounding for cast
huoyaoyuan Feb 18, 2024
50d90aa
Ref source
huoyaoyuan Feb 18, 2024
559f2e0
Simple tests
huoyaoyuan Feb 18, 2024
b24839c
Conversion tests
huoyaoyuan Feb 19, 2024
8284526
Stripping sign is redundant
huoyaoyuan Feb 19, 2024
8e32e71
Fix test copied from Half
huoyaoyuan Feb 19, 2024
4bd266e
Fix conversion test cases
huoyaoyuan Feb 19, 2024
6df00e6
Constants and well-known values
huoyaoyuan Feb 21, 2024
ff295fd
Categorizing methods
huoyaoyuan Feb 21, 2024
09af2b2
Reorder conversion members
huoyaoyuan Feb 21, 2024
1a8f0ad
Operators batch 1
huoyaoyuan Feb 21, 2024
c9fc867
Operators batch 2
huoyaoyuan Feb 21, 2024
e9fc0f8
TryConvert
huoyaoyuan Feb 21, 2024
c967aa5
Operators batch 3
huoyaoyuan Feb 21, 2024
17c13c0
Parsing and formatting
huoyaoyuan Feb 21, 2024
ad780a0
Add comments about how to determine parse and format info
huoyaoyuan Feb 21, 2024
c01949f
Add missing interface implementations
huoyaoyuan Feb 21, 2024
b63c1df
NumberBufferLength
huoyaoyuan Feb 21, 2024
754a3c8
Add more comment
huoyaoyuan Feb 22, 2024
bcc260f
Correct MinFastFloatDecimalExponent
huoyaoyuan Feb 24, 2024
5a3d200
Add explicit conversion to
huoyaoyuan Feb 24, 2024
c420dd3
Explicit convert from
huoyaoyuan Feb 24, 2024
13e65d1
Fullfill casting operators
huoyaoyuan Feb 24, 2024
8c5f546
Fullfill some formatting
huoyaoyuan Feb 24, 2024
0cb3932
Apply suggestions from code review
huoyaoyuan Apr 6, 2024
b615e68
Merge branch 'main' into BFloat16
huoyaoyuan Apr 6, 2024
8f70d91
Generic DiyFp
huoyaoyuan Feb 24, 2024
2458dd8
Generic Grisu3
huoyaoyuan Feb 24, 2024
a8bb94b
Generic Dragon4
huoyaoyuan Feb 24, 2024
9644914
Add MaxRoundTripDigits to MaxPrecisionCustomFormat to FormatInfo
huoyaoyuan Feb 25, 2024
a29db5c
Generic FormatFloat
huoyaoyuan Feb 25, 2024
a8a8a49
Adapt with existing FP types
huoyaoyuan Feb 25, 2024
2fd392f
Merge branch 'fp-formatting-generic' into BFloat16
huoyaoyuan Apr 6, 2024
f1582e7
Adapt formatting traits
huoyaoyuan Apr 6, 2024
eace3a6
Use generic format and delete Number.BFloat16
huoyaoyuan Apr 6, 2024
abd1e80
Update ref source
huoyaoyuan Apr 6, 2024
62156c9
Merge branch 'main'
huoyaoyuan May 3, 2024
e8012c9
Enable constant value tests
huoyaoyuan May 3, 2024
f711f8d
IsFinite/IsNaN
huoyaoyuan May 3, 2024
08168ff
IsPositive/IsNegative/IsSubnormal
huoyaoyuan May 3, 2024
d59a8c5
ToDouble
huoyaoyuan May 3, 2024
eb6dc47
Merge branch 'main' into BFloat16
huoyaoyuan May 23, 2024
25b7684
Merge branch 'main'
huoyaoyuan Jun 4, 2024
832651e
Merge branch 'main' into BFloat16
huoyaoyuan Jun 9, 2024
a07fe96
Fix test case
huoyaoyuan Jun 9, 2024
f9c35d3
Add double conversion test
huoyaoyuan Jun 9, 2024
4059b66
Parse tests
huoyaoyuan Jun 9, 2024
4b4d1a5
Formatting tests
huoyaoyuan Jun 9, 2024
6ed52f5
RoundTripping tests
huoyaoyuan Jun 9, 2024
14b0d85
Port float->Half conversion algorithm to double->BFloat16 to handle U…
huoyaoyuan Jun 10, 2024
ea1dd5f
Port function tests from Half
huoyaoyuan Jun 10, 2024
dfd49c8
Convert the precesion of test cases.
huoyaoyuan Jun 10, 2024
f5461ac
Merge branch 'main' into BFloat16
danmoseley Dec 2, 2024
daaec69
Merge branch 'main' into BFloat16
huoyaoyuan Dec 29, 2024
9938e8b
Align with TryWriteBig/LittleEndian
huoyaoyuan Dec 29, 2024
b889417
Remove redundant 'partial'
huoyaoyuan Dec 31, 2024
1282c85
Merge branch 'main' into BFloat16
tannergooding Jan 27, 2025
e6dd118
Merge branch 'main' into BFloat16
huoyaoyuan Feb 6, 2025
922f411
Use DefaultParseStyle
huoyaoyuan Feb 6, 2025
86dce2d
Fill conversion in signed integer
huoyaoyuan Feb 6, 2025
9f729a3
Fill conversion in unsigned integer and floating point
huoyaoyuan Feb 6, 2025
6baf940
Add conversion for S.R.Numerics
huoyaoyuan Feb 6, 2025
fb88f8e
Use float member function instead of MathF
huoyaoyuan Feb 6, 2025
d697344
Fill conversion in decimal
huoyaoyuan Feb 7, 2025
4e83ad9
Add conversion for NFloat
huoyaoyuan Feb 7, 2025
d58c80a
Use soft rounding for uint->bf16
huoyaoyuan Feb 9, 2025
8639fa3
Generic math rounding from unsigned and signed integer
huoyaoyuan Feb 10, 2025
34b1d07
Cleanup helper methods
huoyaoyuan Feb 10, 2025
8adbeb2
Add integer rounding tests
huoyaoyuan Feb 10, 2025
1f2653f
Move helpers and fix comment
huoyaoyuan Feb 11, 2025
9046622
Update comment
huoyaoyuan Feb 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
Expand Down Expand Up @@ -934,6 +935,10 @@ public static bool ToBoolean(ReadOnlySpan<byte> value)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Half Int16BitsToHalf(short value) => new Half((ushort)(value));

internal static short BFloat16BitsToInt16(BFloat16 value) => (short)value._value;

internal static BFloat16 Int16BitsToBFloat16(short value) => new BFloat16((ushort)(value));

/// <summary>
/// Converts the specified double-precision floating point number to a 64-bit unsigned integer.
/// </summary>
Expand Down Expand Up @@ -987,5 +992,9 @@ public static bool ToBoolean(ReadOnlySpan<byte> value)
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Half UInt16BitsToHalf(ushort value) => new Half(value);

internal static ushort BFloat16BitsToUInt16(BFloat16 value) => value._value;

internal static BFloat16 UInt16BitsToBFloat16(ushort value) => new BFloat16(value);
}
}
12 changes: 12 additions & 0 deletions src/libraries/System.Private.CoreLib/src/System/Decimal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1660,6 +1660,12 @@ static bool INumberBase<decimal>.TryConvertToChecked<TOther>(decimal value, [May
result = (TOther)(object)actualResult;
return true;
}
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualResult = checked((BFloat16)value);
result = (TOther)(object)actualResult;
return true;
}
else if (typeof(TOther) == typeof(short))
{
short actualResult = checked((short)value);
Expand Down Expand Up @@ -1748,6 +1754,12 @@ private static bool TryConvertTo<TOther>(decimal value, [MaybeNullWhen(false)] o
result = (TOther)(object)actualResult;
return true;
}
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualResult = (BFloat16)value;
result = (TOther)(object)actualResult;
return true;
}
else if (typeof(TOther) == typeof(short))
{
short actualResult = (value >= short.MaxValue) ? short.MaxValue :
Expand Down
2 changes: 1 addition & 1 deletion src/libraries/System.Private.CoreLib/src/System/Double.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1248,7 +1248,7 @@ private static bool TryConvertFrom<TOther>(TOther value, out double result)
result = (double)actualValue;
return true;
}
if (typeof(TOther) == typeof(BFloat16))
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualValue = (BFloat16)(object)value;
result = (double)actualValue;
Expand Down
6 changes: 1 addition & 5 deletions src/libraries/System.Private.CoreLib/src/System/Half.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1015,7 +1015,7 @@ public static explicit operator double(Half value)
exp -= 1;
}

return CreateDouble(sign, (ushort)(exp + 0x3F0), (ulong)sig << 42);
return Math.CreateDouble(sign, (ushort)(exp + 0x3F0), (ulong)sig << 42);
Copy link
Member

Choose a reason for hiding this comment

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

nit: Math is basically "frozen" and not a place we want to find new methods, even internal ones

These would be "better" as internal double.Create and float.Create methods instead

}

/// <summary>Explicitly converts a half-precision floating-point value to its nearest representable <see cref="float" /> value.</summary>
Expand Down Expand Up @@ -1177,10 +1177,6 @@ private static double CreateDoubleNaN(bool sign, ulong significand)
return BitConverter.UInt64BitsToDouble(signInt | NaNBits | sigInt);
}

private static float CreateSingle(bool sign, byte exp, uint sig) => BitConverter.UInt32BitsToSingle(((sign ? 1U : 0U) << float.SignShift) + ((uint)exp << float.BiasedExponentShift) + sig);

private static double CreateDouble(bool sign, ushort exp, ulong sig) => BitConverter.UInt64BitsToDouble(((sign ? 1UL : 0UL) << double.SignShift) + ((ulong)exp << double.BiasedExponentShift) + sig);

#endregion

//
Expand Down
8 changes: 4 additions & 4 deletions src/libraries/System.Private.CoreLib/src/System/Int128.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1604,8 +1604,8 @@ private static bool TryConvertFromSaturating<TOther>(TOther value, out Int128 re
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualValue = (BFloat16)(object)value;
result = (actualValue >= new BFloat16(0x7F00)) ? MaxValue :
(actualValue <= new BFloat16(0xFF00)) ? MinValue : (Int128)actualValue;
result = (actualValue >= BitConverter.UInt16BitsToBFloat16(0x7F00)) ? MaxValue :
(actualValue <= BitConverter.UInt16BitsToBFloat16(0xFF00)) ? MinValue : (Int128)actualValue;
return true;
}
else if (typeof(TOther) == typeof(short))
Expand Down Expand Up @@ -1686,8 +1686,8 @@ private static bool TryConvertFromTruncating<TOther>(TOther value, out Int128 re
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualValue = (BFloat16)(object)value;
result = (actualValue >= new BFloat16(0x7F00)) ? MaxValue :
(actualValue <= new BFloat16(0xFF00)) ? MinValue : (Int128)actualValue;
result = (actualValue >= BitConverter.UInt16BitsToBFloat16(0x7F00)) ? MaxValue :
(actualValue <= BitConverter.UInt16BitsToBFloat16(0xFF00)) ? MinValue : (Int128)actualValue;
return true;
}
else if (typeof(TOther) == typeof(short))
Expand Down
8 changes: 4 additions & 4 deletions src/libraries/System.Private.CoreLib/src/System/Int16.cs
Original file line number Diff line number Diff line change
Expand Up @@ -981,8 +981,8 @@ private static bool TryConvertFromSaturating<TOther>(TOther value, out short res
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualValue = (BFloat16)(object)value;
result = (actualValue >= new BFloat16(0x4700)) ? MaxValue :
(actualValue <= new BFloat16(0xB700)) ? MinValue : (short)actualValue;
result = (actualValue >= BitConverter.UInt16BitsToBFloat16(0x4700)) ? MaxValue :
(actualValue <= BitConverter.UInt16BitsToBFloat16(0xB700)) ? MinValue : (short)actualValue;
return true;
}
else if (typeof(TOther) == typeof(int))
Expand Down Expand Up @@ -1067,8 +1067,8 @@ private static bool TryConvertFromTruncating<TOther>(TOther value, out short res
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualValue = (BFloat16)(object)value;
result = (actualValue >= new BFloat16(0x4700)) ? MaxValue :
(actualValue <= new BFloat16(0xB700)) ? MinValue : (short)actualValue;
result = (actualValue >= BitConverter.UInt16BitsToBFloat16(0x4700)) ? MaxValue :
(actualValue <= BitConverter.UInt16BitsToBFloat16(0xB700)) ? MinValue : (short)actualValue;
return true;
}
else if (typeof(TOther) == typeof(int))
Expand Down
8 changes: 4 additions & 4 deletions src/libraries/System.Private.CoreLib/src/System/Int32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1022,8 +1022,8 @@ private static bool TryConvertFromSaturating<TOther>(TOther value, out int resul
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualValue = (BFloat16)(object)value;
result = (actualValue >= new BFloat16(0x4F00)) ? MaxValue :
(actualValue <= new BFloat16(0xBF00)) ? MinValue : (int)actualValue;
result = (actualValue >= BitConverter.UInt16BitsToBFloat16(0x4F00)) ? MaxValue :
(actualValue <= BitConverter.UInt16BitsToBFloat16(0xBF00)) ? MinValue : (int)actualValue;
return true;
}
else if (typeof(TOther) == typeof(short))
Expand Down Expand Up @@ -1107,8 +1107,8 @@ private static bool TryConvertFromTruncating<TOther>(TOther value, out int resul
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualValue = (BFloat16)(object)value;
result = (actualValue >= new BFloat16(0x4F00)) ? MaxValue :
(actualValue <= new BFloat16(0xBF00)) ? MinValue : (int)actualValue;
result = (actualValue >= BitConverter.UInt16BitsToBFloat16(0x4F00)) ? MaxValue :
(actualValue <= BitConverter.UInt16BitsToBFloat16(0xBF00)) ? MinValue : (int)actualValue;
return true;
}
else if (typeof(TOther) == typeof(short))
Expand Down
8 changes: 4 additions & 4 deletions src/libraries/System.Private.CoreLib/src/System/Int64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1019,8 +1019,8 @@ private static bool TryConvertFromSaturating<TOther>(TOther value, out long resu
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualValue = (BFloat16)(object)value;
result = (actualValue >= new BFloat16(0x5F00)) ? MaxValue :
(actualValue <= new BFloat16(0xCF00)) ? MinValue : (long)actualValue;
result = (actualValue >= BitConverter.UInt16BitsToBFloat16(0x5F00)) ? MaxValue :
(actualValue <= BitConverter.UInt16BitsToBFloat16(0xCF00)) ? MinValue : (long)actualValue;
return true;
}
else if (typeof(TOther) == typeof(short))
Expand Down Expand Up @@ -1102,8 +1102,8 @@ private static bool TryConvertFromTruncating<TOther>(TOther value, out long resu
else if (typeof(TOther) == typeof(BFloat16))
{
BFloat16 actualValue = (BFloat16)(object)value;
result = (actualValue >= new BFloat16(0x5F00)) ? MaxValue :
(actualValue <= new BFloat16(0xCF00)) ? MinValue : (long)actualValue;
result = (actualValue >= BitConverter.UInt16BitsToBFloat16(0x5F00)) ? MaxValue :
(actualValue <= BitConverter.UInt16BitsToBFloat16(0xCF00)) ? MinValue : (long)actualValue;
return true;
}
else if (typeof(TOther) == typeof(short))
Expand Down
4 changes: 4 additions & 0 deletions src/libraries/System.Private.CoreLib/src/System/Math.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1707,5 +1707,9 @@ internal static ulong ConvertToUInt64Checked(double value)
ThrowHelper.ThrowOverflowException();
return 0;
}

internal static float CreateSingle(bool sign, byte exp, uint sig) => BitConverter.UInt32BitsToSingle(((sign ? 1U : 0U) << float.SignShift) + ((uint)exp << float.BiasedExponentShift) + sig);

internal static double CreateDouble(bool sign, ushort exp, ulong sig) => BitConverter.UInt64BitsToDouble(((sign ? 1UL : 0UL) << double.SignShift) + ((ulong)exp << double.BiasedExponentShift) + sig);
}
}
Loading
Loading