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 support for float16 datatypes #179

Merged
merged 17 commits into from
May 3, 2024
Merged
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
12 changes: 6 additions & 6 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -831,11 +831,11 @@
</sequential>
</macrodef>

<target name="runauitest" description="Runs the test you specify on the command line with -Dtest=" depends="jar, clean-junit-uitest, compile-test, ensure-test5-name, ensure-test4-name, jacoco">
<target name="runauitest" description="Runs the test you specify on the command line with -Dtest=" depends="deploy,jar, clean-junit-uitest, compile-test, ensure-test5-name, ensure-test4-name, jacoco">
<mkdir dir="${report.dir}" />

<run-ui-junit
rootdir="${basedir}/${uitestclasses.dir}"
rootdir="${basedir}/${jar.dir}"
workdir="${basedir}/${uitestclasses.dir}/uitest"
propfile="${basedir}/${uitestclasses.dir}/.hdfview${app.version}"
includes="**/${uitestclasses.dir}/${test}.class"
Expand All @@ -851,7 +851,7 @@
<mkdir dir="${report.dir}" />

<run-ui-junit
rootdir="${basedir}/${uitestclasses.dir}"
rootdir="${basedir}/${jar.dir}"
workdir="${basedir}/${uitestclasses.dir}/uitest"
propfile="${basedir}/${uitestclasses.dir}/.hdfview${app.version}"
includes="**/${uitestclasses.dir}/${test}.class"
Expand All @@ -865,7 +865,7 @@

<!-- Run the top-level HDF4 UI tests -->
<run-ui-junit
rootdir="${basedir}/${hdf4uitestclasses.dir}"
rootdir="${basedir}/${jar.dir}"
workdir="${basedir}/${hdf4uitestclasses.dir}"
propfile="${basedir}/${uitestclasses.dir}/.hdfview${app.version}"
includes="**/${hdf4uitestclasses.dir}/${test}.class"
Expand All @@ -879,7 +879,7 @@

<!-- Run the top-level HDF5 UI tests -->
<run-ui-junit
rootdir="${basedir}/${hdf5uitestclasses.dir}"
rootdir="${basedir}/${jar.dir}"
workdir="${basedir}/${hdf5uitestclasses.dir}"
propfile="${basedir}/${uitestclasses.dir}/.hdfview${app.version}"
includes="${hdf5uitestclasses.dir}/${test}.class"
Expand All @@ -891,7 +891,7 @@
<mkdir dir="${report.dir}" />

<run-ui-junit
rootdir="${basedir}/${testclasses.dir}"
rootdir="${basedir}/${jar.dir}"
workdir="${basedir}/${testclasses.dir}/modules"
includes="**/modules/*Test*"
excludes="**/modules/*$*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@ private static class NumericalDataDisplayConverter extends HDFDisplayConverter {
private final StringBuilder buffer;
private final long typeSize;
private final boolean isUINT64;
private final boolean isFLT16;

NumericalDataDisplayConverter(final Datatype dtype) throws Exception
{
Expand All @@ -727,6 +728,7 @@ private static class NumericalDataDisplayConverter extends HDFDisplayConverter {

typeSize = dtype.getDatatypeSize();
isUINT64 = dtype.isUnsigned() && (typeSize == 8);
isFLT16 = dtype.isFloat() && (typeSize == 2);
}

@Override
Expand Down
112 changes: 88 additions & 24 deletions src/org.hdfgroup.hdfview/hdf/view/TableView/DataProviderFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -375,30 +376,24 @@ public void setDataValue(int columnIndex, int rowIndex, Object newValue)
}

/**
* 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.
* 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.
* 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.
* 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
* @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)
{
Expand Down Expand Up @@ -1623,7 +1618,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)
Expand All @@ -1633,6 +1628,7 @@ private static class NumericalDataProvider extends HDFDataProvider {

typeSize = dtype.getDatatypeSize();
isUINT64 = dtype.isUnsigned() && (typeSize == 8);
isFLT16 = dtype.isFloat() && (typeSize == 2);
}

@Override
Expand All @@ -1641,7 +1637,9 @@ public Object getDataValue(int columnIndex, int rowIndex)
super.getDataValue(columnIndex, rowIndex);

try {
if (isUINT64)
if (isFLT16)
theValue = Float.float16ToFloat((short)theValue);
else if (isUINT64)
theValue = Tools.convertUINT64toBigInt(Long.valueOf((long)theValue));
}
catch (Exception ex) {
Expand All @@ -1660,7 +1658,9 @@ public Object getDataValue(Object obj, int index)
super.getDataValue(obj, index);

try {
if (isUINT64)
if (isFLT16)
theValue = Float.float16ToFloat((short)theValue);
else if (isUINT64)
theValue = Tools.convertUINT64toBigInt(Long.valueOf((long)theValue));
}
catch (Exception ex) {
Expand All @@ -1672,6 +1672,70 @@ public Object getDataValue(Object obj, int index)

return theValue;
}

/**
* update the data value of a 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)
{
log.trace("setDataValue({}, {})=({}): start", rowIndex, columnIndex, newValue);
try {
if (isFLT16) {
// must convert string from float to short first
float fValue = Float.parseFloat((String)newValue);
short sValue = Float.floatToFloat16(fValue);
// setDataValue requires a String, so convert short to String
String strValue = Short.toString(sValue);
super.setDataValue(columnIndex, rowIndex, strValue);
}
else
super.setDataValue(columnIndex, rowIndex, newValue);
}
catch (Exception ex) {
log.debug("setDataValue({}, {})=({}): failure: ", rowIndex, columnIndex, newValue, ex);
theValue = DataFactoryUtils.errStr;
}
}

/**
* 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)
{
log.trace("setDataValue({}: {})=({}): start", index, bufObject, newValue);
try {
if (isFLT16) {
// must convert string from float to short first
float fValue = Float.parseFloat((String)newValue);
short sValue = Float.floatToFloat16(fValue);
// setDataValue requires a String, so convert short to String
String strValue = Short.toString(sValue);
super.setDataValue(index, bufObject, strValue);
}
else
super.setDataValue(index, bufObject, newValue);
}
catch (Exception ex) {
log.debug("setDataValue({}, {})=({}): updateAtomicValue failure: ", index, bufObject,
newValue, ex);
}
log.trace("setDataValue({}, {})=({}): finish", index, bufObject, newValue);
}
}

private static class EnumDataProvider extends HDFDataProvider {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -636,19 +636,27 @@ public boolean validate(int colIndex, int rowIndex, Object newValue)
break;

case 2:
if (datasetDatatype.isUnsigned()) {
/*
* First try to parse as a larger type in order to catch a NumberFormatException
*/
Integer intValue = Integer.parseInt((String)newValue);
if (intValue < 0)
throw new NumberFormatException("Invalid negative value for unsigned datatype");
if (datasetDatatype.isInteger()) {
if (datasetDatatype.isUnsigned()) {
/*
* First try to parse as a larger type in order to catch a NumberFormatException
*/
Integer intValue = Integer.parseInt((String)newValue);
if (intValue < 0)
throw new NumberFormatException(
"Invalid negative value for unsigned datatype");

if (intValue > (Short.MAX_VALUE * 2) + 1)
throw new NumberFormatException("Value out of range. Value:\"" + newValue + "\"");
if (intValue > (Short.MAX_VALUE * 2) + 1)
throw new NumberFormatException("Value out of range. Value:\"" + newValue +
"\"");
}
else {
Short.parseShort((String)newValue);
}
}
else {
Short.parseShort((String)newValue);
/* Floating-point type */
Float.parseFloat((String)newValue);
}
break;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ public class NewCompoundAttributeDialog extends NewDataObjectDialog {
"unsigned short (16-bit)", // 4
"unsigned int (32-bit)", // 5
"long (64-bit)", // 6
"float", // 7
"double", // 8
"float (32-bit)", // 7
"double (64-bit)", // 8
"string", // 9
"enum", // 10
"unsigned long (64-bit)" // 11
"unsigned long (64-bit)", // 11
"float16 (16-bit)", // 12
"long double (128-bit)" // 13
jhendersonHDF marked this conversation as resolved.
Show resolved Hide resolved
jhendersonHDF marked this conversation as resolved.
Show resolved Hide resolved
};

private Combo nFieldBox, templateChoice;
Expand Down Expand Up @@ -465,6 +467,14 @@ else if (DATATYPE_NAMES[11].equals(typeName)) {
type = fileFormat.createDatatype(Datatype.CLASS_INTEGER, 8, Datatype.NATIVE,
Datatype.SIGN_NONE);
}
else if (DATATYPE_NAMES[12].equals(typeName)) {
type =
fileFormat.createDatatype(Datatype.CLASS_FLOAT, 2, Datatype.NATIVE, Datatype.NATIVE);
}
else if (DATATYPE_NAMES[13].equals(typeName)) {
type =
fileFormat.createDatatype(Datatype.CLASS_FLOAT, 16, Datatype.NATIVE, Datatype.NATIVE);
}
else {
throw new IllegalArgumentException("Invalid data type.");
}
Expand Down
Loading
Loading