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

8339494: Porting HalfFloatVector classes. #1233

Draft
wants to merge 1 commit into
base: lworld+fp16
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
50 changes: 43 additions & 7 deletions src/java.base/share/classes/java/lang/Float16.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,19 @@
// Enhanced Primitive Boxes described by JEP-402 (https://openjdk.org/jeps/402)
@jdk.internal.MigratedValueClass
@jdk.internal.ValueBased
@SuppressWarnings("serial")
public final class Float16
extends Number
implements Comparable<Float16> {
private final short value;
private static final long serialVersionUID = 16; // Not needed for a value class?

// Functionality for future consideration:
// float16ToShortBits that normalizes NaNs, c.f. floatToIntBits vs floatToRawIntBits
// copysign
// scalb
// nextUp / nextDown
// IEEEremainder / remainder operator remainder
// signum
// valueOf(BigDecimal) -- main implementation could be package private in BigDecimal

/**
* Returns a {@code Float16} instance wrapping IEEE 754 binary16
* encoded {@code short} value.
Expand Down Expand Up @@ -281,11 +279,11 @@ public static Float16 valueOf(int value) {
* @param value a {@code long} value.
*/
public static Float16 valueOf(long value) {
if (value < -65_504L) {
if (value <= -65_520L) { // -(Float16.MAX_VALUE + Float16.ulp(Float16.MAX_VALUE) / 2)
return NEGATIVE_INFINITY;
} else {
if (value > 65_504L) {
return NEGATIVE_INFINITY;
if (value >= 65_520L) { // Float16.MAX_VALUE + Float16.ulp(Float16.MAX_VALUE) / 2
return POSITIVE_INFINITY;
}
// Remaining range of long, the integers in approx. +/-
// 2^16, all fit in a float so the correct conversion can
Expand Down Expand Up @@ -572,6 +570,45 @@ public double doubleValue() {
return (double)floatValue();
}

/**
* Returns a representation of the specified floating-point value
* according to the IEEE 754 floating-point "binary16" bit
* layout.
*
* <p>Bit 15 (the bit that is selected by the mask
* {@code 0x80000000}) represents the sign of the floating-point
* number.
* Bits 14-10 (the bits that are selected by the mask
* {@code 0x7f800000}) represent the exponent.
* Bits 9-0 (the bits that are selected by the mask
* {@code 0x007fffff}) represent the significand (sometimes called
* the mantissa) of the floating-point number.
*
* <p>If the argument is positive infinity, the result is
* {@code 0x7C00}.
*
* <p>If the argument is negative infinity, the result is
* {@code 0xfC00}.
*
* <p>If the argument is NaN, the result is {@code 0x7E00}.
*
* <p>In all cases, the result is a short that, when given to the
* {@link #shortBitsToFloat16(short)} method, will produce a floating-point
* value the same as the argument to {@code float16ToShortBits}
* (except all NaN values are collapsed to a single
* "canonical" NaN value).
*
* @param f16 an IEEE 754 binary16 floating-point number.
* @return the bits that represent the floating-point number.
*/
//@IntrinsicCandidate
public static short float16ToShortBits(Float16 f16) {
if (!isNaN(f16)) {
return float16ToRawShortBits(f16);
}
return 0x7E00;
}

// Skipping for now:
// public int hashCode()
// public static int hashCode(Float16 value)
Expand Down Expand Up @@ -855,7 +892,6 @@ public static Float16 divide(Float16 dividend, Float16 divisor) {
*
* @param radicand the argument to have its square root taken
*
* @see Math#sqrt(float)
* @see Math#sqrt(double)
*/
// @IntrinsicCandidate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ public class VectorSupport {

// BasicType codes, for primitives only:
public static final int
T_FLOAT16 = 5,
T_FLOAT = 6,
T_DOUBLE = 7,
T_BYTE = 8,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,18 +406,26 @@ final IllegalArgumentException badArrayBits(Object iv,
Object iotaArray() {
// Create an iota array. It's OK if this is really slow,
// because it happens only once per species.
Object ia = Array.newInstance(laneType.elementType,
laneCount);
assert(ia.getClass() == laneType.arrayType);
Object ia = Array.newInstance(laneType.elementType, laneCount);
checkValue(laneCount-1); // worst case
for (int i = 0; i < laneCount; i++) {
if ((byte)i == i)
Array.setByte(ia, i, (byte)i);
else if ((short)i == i)
Array.setShort(ia, i, (short)i);
else
Array.setInt(ia, i, i);
assert(Array.getDouble(ia, i) == i);
assert(ia.getClass() == laneType.arrayType);
if (elementType() == Float16.class) {
Float16 [] f16arr = (Float16[])ia;
for (int i = 0; i < laneCount; i++) {
// Note: All the numbers in the range [0:2049) are directly
// representable in FP16 format without the precision loss.
f16arr[i] = Float16.valueOf((float)i);
}
} else {
for (int i = 0; i < laneCount; i++) {
if ((byte)i == i)
Array.setByte(ia, i, (byte)i);
else if ((short)i == i)
Array.setShort(ia, i, (short)i);
else
Array.setInt(ia, i, i);
assert(Array.getDouble(ia, i) == i);
}
}
return ia;
}
Expand Down Expand Up @@ -615,6 +623,8 @@ AbstractSpecies<?> computeSpecies(LaneType laneType,
s = IntVector.species(shape); break;
case LaneType.SK_LONG:
s = LongVector.species(shape); break;
case LaneType.SK_FLOAT16:
s = HalffloatVector.species(shape); break;
}
if (s == null) {
// NOTE: The result of this method is guaranteed to be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,15 @@ public DoubleVector reinterpretAsDoubles() {
return (DoubleVector) asVectorRaw(LaneType.DOUBLE);
}

/**
* {@inheritDoc} <!--workaround-->
*/
@Override
@ForceInline
public HalffloatVector reinterpretAsHalffloats() {
return (HalffloatVector) asVectorRaw(LaneType.FLOAT16);
}

/**
* {@inheritDoc} <!--workaround-->
*/
Expand Down Expand Up @@ -533,6 +542,8 @@ AbstractVector<F> defaultReinterpret(AbstractSpecies<F> rsp) {
return FloatVector.fromMemorySegment(rsp.check(float.class), ms, 0, bo, m.check(float.class)).check0(rsp);
case LaneType.SK_DOUBLE:
return DoubleVector.fromMemorySegment(rsp.check(double.class), ms, 0, bo, m.check(double.class)).check0(rsp);
case LaneType.SK_FLOAT16:
return HalffloatVector.fromMemorySegment(rsp.check(Float16.class), ms, 0, bo, m.check(Float16.class)).check0(rsp);
default:
throw new AssertionError(rsp.toString());
}
Expand Down Expand Up @@ -595,6 +606,13 @@ AbstractVector<F> defaultCast(AbstractSpecies<F> dsp) {
}
return DoubleVector.fromArray(dsp.check(double.class), a, 0).check0(dsp);
}
case LaneType.SK_FLOAT16: {
Float16[] a = new Float16[rlength];
for (int i = 0; i < limit; i++) {
a[i] = Float16.valueOf(lanes[i]);
}
return HalffloatVector.fromArray(dsp.check(Float16.class), a, 0).check0(dsp);
}
default: break;
}
} else {
Expand Down Expand Up @@ -645,6 +663,13 @@ AbstractVector<F> defaultCast(AbstractSpecies<F> dsp) {
}
return DoubleVector.fromArray(dsp.check(double.class), a, 0).check0(dsp);
}
case LaneType.SK_FLOAT16: {
Float16[] a = new Float16[rlength];
for (int i = 0; i < limit; i++) {
a[i] = Float16.valueOf(lanes[i]);
}
return HalffloatVector.fromArray(dsp.check(Float16.class), a, 0).check0(dsp);
}
default: break;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -347,14 +347,16 @@ public final byte reduceLanes(VectorOperators.Associative op,
@Override
@ForceInline
public final long reduceLanesToLong(VectorOperators.Associative op) {
return (long) super.reduceLanesTemplate(op); // specialized
byte res = super.reduceLanesTemplate(op); // specialized
return (long) res;
}

@Override
@ForceInline
public final long reduceLanesToLong(VectorOperators.Associative op,
VectorMask<Byte> m) {
return (long) super.reduceLanesTemplate(op, Byte128Mask.class, (Byte128Mask) m); // specialized
byte res = super.reduceLanesTemplate(op, Byte128Mask.class, (Byte128Mask) m); // specialized
return (long) res;
}

@ForceInline
Expand Down Expand Up @@ -682,7 +684,7 @@ public <E> VectorMask<E> cast(VectorSpecies<E> dsp) {
/*package-private*/
Byte128Mask indexPartiallyInUpperRange(long offset, long limit) {
return (Byte128Mask) VectorSupport.indexPartiallyInUpperRange(
Byte128Mask.class, byte.class, VLENGTH, offset, limit,
Byte128Mask.class, ETYPE, VLENGTH, offset, limit,
(o, l) -> (Byte128Mask) TRUE_MASK.indexPartiallyInRange(o, l));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -347,14 +347,16 @@ public final byte reduceLanes(VectorOperators.Associative op,
@Override
@ForceInline
public final long reduceLanesToLong(VectorOperators.Associative op) {
return (long) super.reduceLanesTemplate(op); // specialized
byte res = super.reduceLanesTemplate(op); // specialized
return (long) res;
}

@Override
@ForceInline
public final long reduceLanesToLong(VectorOperators.Associative op,
VectorMask<Byte> m) {
return (long) super.reduceLanesTemplate(op, Byte256Mask.class, (Byte256Mask) m); // specialized
byte res = super.reduceLanesTemplate(op, Byte256Mask.class, (Byte256Mask) m); // specialized
return (long) res;
}

@ForceInline
Expand Down Expand Up @@ -714,7 +716,7 @@ public <E> VectorMask<E> cast(VectorSpecies<E> dsp) {
/*package-private*/
Byte256Mask indexPartiallyInUpperRange(long offset, long limit) {
return (Byte256Mask) VectorSupport.indexPartiallyInUpperRange(
Byte256Mask.class, byte.class, VLENGTH, offset, limit,
Byte256Mask.class, ETYPE, VLENGTH, offset, limit,
(o, l) -> (Byte256Mask) TRUE_MASK.indexPartiallyInRange(o, l));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -347,14 +347,16 @@ public final byte reduceLanes(VectorOperators.Associative op,
@Override
@ForceInline
public final long reduceLanesToLong(VectorOperators.Associative op) {
return (long) super.reduceLanesTemplate(op); // specialized
byte res = super.reduceLanesTemplate(op); // specialized
return (long) res;
}

@Override
@ForceInline
public final long reduceLanesToLong(VectorOperators.Associative op,
VectorMask<Byte> m) {
return (long) super.reduceLanesTemplate(op, Byte512Mask.class, (Byte512Mask) m); // specialized
byte res = super.reduceLanesTemplate(op, Byte512Mask.class, (Byte512Mask) m); // specialized
return (long) res;
}

@ForceInline
Expand Down Expand Up @@ -778,7 +780,7 @@ public <E> VectorMask<E> cast(VectorSpecies<E> dsp) {
/*package-private*/
Byte512Mask indexPartiallyInUpperRange(long offset, long limit) {
return (Byte512Mask) VectorSupport.indexPartiallyInUpperRange(
Byte512Mask.class, byte.class, VLENGTH, offset, limit,
Byte512Mask.class, ETYPE, VLENGTH, offset, limit,
(o, l) -> (Byte512Mask) TRUE_MASK.indexPartiallyInRange(o, l));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -347,14 +347,16 @@ public final byte reduceLanes(VectorOperators.Associative op,
@Override
@ForceInline
public final long reduceLanesToLong(VectorOperators.Associative op) {
return (long) super.reduceLanesTemplate(op); // specialized
byte res = super.reduceLanesTemplate(op); // specialized
return (long) res;
}

@Override
@ForceInline
public final long reduceLanesToLong(VectorOperators.Associative op,
VectorMask<Byte> m) {
return (long) super.reduceLanesTemplate(op, Byte64Mask.class, (Byte64Mask) m); // specialized
byte res = super.reduceLanesTemplate(op, Byte64Mask.class, (Byte64Mask) m); // specialized
return (long) res;
}

@ForceInline
Expand Down Expand Up @@ -666,7 +668,7 @@ public <E> VectorMask<E> cast(VectorSpecies<E> dsp) {
/*package-private*/
Byte64Mask indexPartiallyInUpperRange(long offset, long limit) {
return (Byte64Mask) VectorSupport.indexPartiallyInUpperRange(
Byte64Mask.class, byte.class, VLENGTH, offset, limit,
Byte64Mask.class, ETYPE, VLENGTH, offset, limit,
(o, l) -> (Byte64Mask) TRUE_MASK.indexPartiallyInRange(o, l));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -347,14 +347,16 @@ public final byte reduceLanes(VectorOperators.Associative op,
@Override
@ForceInline
public final long reduceLanesToLong(VectorOperators.Associative op) {
return (long) super.reduceLanesTemplate(op); // specialized
byte res = super.reduceLanesTemplate(op); // specialized
return (long) res;
}

@Override
@ForceInline
public final long reduceLanesToLong(VectorOperators.Associative op,
VectorMask<Byte> m) {
return (long) super.reduceLanesTemplate(op, ByteMaxMask.class, (ByteMaxMask) m); // specialized
byte res = super.reduceLanesTemplate(op, ByteMaxMask.class, (ByteMaxMask) m); // specialized
return (long) res;
}

@ForceInline
Expand Down Expand Up @@ -652,7 +654,7 @@ public <E> VectorMask<E> cast(VectorSpecies<E> dsp) {
/*package-private*/
ByteMaxMask indexPartiallyInUpperRange(long offset, long limit) {
return (ByteMaxMask) VectorSupport.indexPartiallyInUpperRange(
ByteMaxMask.class, byte.class, VLENGTH, offset, limit,
ByteMaxMask.class, ETYPE, VLENGTH, offset, limit,
(o, l) -> (ByteMaxMask) TRUE_MASK.indexPartiallyInRange(o, l));
}

Expand Down
Loading
Loading