-
-
Notifications
You must be signed in to change notification settings - Fork 16
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 support for float16 datatypes #179
Changes from 2 commits
e3d2604
55f8b2b
d400999
af49dd3
d94f8db
7ab8c4d
3fd3303
4d65adc
06b420b
eba8d7c
0ca1e57
68ddb7c
94b691f
0f0d9bb
db4a741
640ca0e
af44070
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,6 +94,7 @@ private static final HDFDataProvider getDataProvider(final Datatype dtype, final | |
final boolean dataTransposed) throws Exception | ||
{ | ||
HDFDataProvider dataProvider = null; | ||
log.debug("getDataProvider(): Datatype is {}", dtype.getDescription()); | ||
|
||
try { | ||
if (dtype.isCompound()) | ||
|
@@ -1623,7 +1624,7 @@ private static class NumericalDataProvider extends HDFDataProvider { | |
private static final Logger log = LoggerFactory.getLogger(NumericalDataProvider.class); | ||
|
||
private final boolean isUINT64; | ||
|
||
private final boolean isFLT16; | ||
private final long typeSize; | ||
|
||
NumericalDataProvider(final Datatype dtype, final Object dataBuf, final boolean dataTransposed) | ||
|
@@ -1633,6 +1634,7 @@ private static class NumericalDataProvider extends HDFDataProvider { | |
|
||
typeSize = dtype.getDatatypeSize(); | ||
isUINT64 = dtype.isUnsigned() && (typeSize == 8); | ||
isFLT16 = dtype.isFloat() && (typeSize == 2); | ||
} | ||
|
||
@Override | ||
|
@@ -1641,7 +1643,9 @@ public Object getDataValue(int columnIndex, int rowIndex) | |
super.getDataValue(columnIndex, rowIndex); | ||
|
||
try { | ||
if (isUINT64) | ||
if (isFLT16) | ||
theValue = Float.toString(Float.float16ToFloat((short)theValue)); | ||
else if (isUINT64) | ||
theValue = Tools.convertUINT64toBigInt(Long.valueOf((long)theValue)); | ||
} | ||
catch (Exception ex) { | ||
|
@@ -1660,7 +1664,9 @@ public Object getDataValue(Object obj, int index) | |
super.getDataValue(obj, index); | ||
|
||
try { | ||
if (isUINT64) | ||
if (isFLT16) | ||
theValue = Float.toString(Float.float16ToFloat((short)theValue)); | ||
else if (isUINT64) | ||
theValue = Tools.convertUINT64toBigInt(Long.valueOf((long)theValue)); | ||
} | ||
catch (Exception ex) { | ||
|
@@ -1672,6 +1678,79 @@ public Object getDataValue(Object obj, int index) | |
|
||
return theValue; | ||
} | ||
|
||
/** | ||
* update the data value of a compound type. | ||
* | ||
* @param columnIndex the column | ||
* @param rowIndex the row | ||
* @param newValue the new data value object | ||
*/ | ||
@Override | ||
public void setDataValue(int columnIndex, int rowIndex, Object newValue) | ||
{ | ||
Object theValue = newValue; | ||
if (isFLT16) | ||
theValue = Short.toString(Float.floatToFloat16(Float.parseFloat((String)newValue))); | ||
|
||
super.setDataValue(columnIndex, rowIndex, theValue); | ||
} | ||
|
||
/** | ||
* When a CompoundDataProvider wants to pass a List of data down to a nested CompoundDataProvider, or | ||
* when a top-level container DataProvider (such as an ArrayDataProvider) wants to hand data down to a | ||
* base CompoundDataProvider, we need to pass down a List of data and the new value, plus a field and | ||
* row index. This method is for facilitating this behavior. | ||
* | ||
* In general, all "container" DataProviders that have a "container" base DataProvider should call | ||
* down into their base DataProvider(s) using this{}, method, in order to ensure that buried | ||
* CompoundDataProviders get handled correctly. When their base DataProvider is not a "container" | ||
* type, the method setDataValue(index, Object, Object) should be used instead. | ||
* | ||
* For atomic type DataProviders, we treat this method as directly calling into setDataValue(index, | ||
* Object, Object) using the passed rowIndex. However, this method should, in general, not be called | ||
* by atomic type DataProviders. | ||
* | ||
* @param columnIndex the column | ||
* @param rowIndex the row | ||
* @param bufObject the data object | ||
* @param newValue the new data object | ||
*/ | ||
public void setDataValue(int columnIndex, int rowIndex, Object bufObject, Object newValue) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure that we actually need to implement this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe, but container types will need the same method if I'm correct. Will need a test file. |
||
{ | ||
Object newbufObject = bufObject; | ||
if (isFLT16) | ||
newbufObject = Float.float16ToFloat((short)bufObject); | ||
setDataValue(rowIndex, newbufObject, newValue); | ||
} | ||
|
||
/** | ||
* When a parent HDFDataProvider (such as an ArrayDataProvider) wants to set a data value by routing | ||
* the operation through its base HDFDataProvider, the parent HDFDataProvider will generally know the | ||
* direct index to have the base provider use. This method is to facilitate this kind of behavior. | ||
* | ||
* Note that this method takes two Object parameters, one which is the object that the method should | ||
* set its data inside of and one which is the new value to set. This is to be able to nicely support | ||
* nested compound DataProviders. | ||
* | ||
* @param index the index into the data array | ||
* @param bufObject the data object | ||
* @param newValue the new data object | ||
*/ | ||
public void setDataValue(int index, Object bufObject, Object newValue) | ||
{ | ||
Object newbufObject = bufObject; | ||
if (isFLT16) | ||
newbufObject = Float.float16ToFloat((short)bufObject); | ||
try { | ||
setDataValue(index, newbufObject, newValue); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, exactly what happened. |
||
} | ||
catch (Exception ex) { | ||
log.debug("setDataValue({}, {})=({}): updateAtomicValue failure: ", index, newbufObject, | ||
newValue, ex); | ||
} | ||
log.trace("setDataValue({}, {})=({}): finish", index, newbufObject, newValue); | ||
} | ||
} | ||
|
||
private static class EnumDataProvider extends HDFDataProvider { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this set as a string here rather than a real data value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be an artifact before the Display/Converter changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be. I never created one, but it'd be useful to have a test file with a float16 member inside a compound, since this seems like editing one of those values would convert it to a String and either fail on write or cause weird issues later during read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did test a change value and it worked - will need to check into container types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can see the other
setDataValue
calls below returnFloat.float16ToFloat((short)bufObject)
rather than a string. This almost certainly doesn't need theShort.toString(
part and I'm surprised it doesn't cause problems.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe - I know not having it failed the first time I tried - will try again since changing other code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs to be a string - fails without it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then something is wrong elsewhere. For numerical values the DataProvider should be setting actual values and not strings. The only time numerical data should be working on a String is when converting to displayable formats in the DataDisplayConverters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trouble is that float16 is a Short underneath and everything was triggering on that type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I understand, but it shouldn't be a string. It's unfortunate that the implementation chose to encode the value in a
short
, because it forces us to implement "wrapper"setDataValue
functions just to check if a value is a float16 value so that we can convert it from ashort
to a real float type, but I suppose it is what it is. But, the data array we work with should always be in terms of eithershort
orfloat
and then converted toString
in the DataDisplayConverters andfloat
elsewhere where we need a real value (if we didn't already choose to convert it to afloat
for the data array).