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

Initial implementation of float16 support #10342

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

eschnett
Copy link
Contributor

This implements support for the float16 datatype as proposed in #10146.

Copy link
Member

@rouault rouault left a comment

Choose a reason for hiding this comment

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

Thanks for tackling this. One major adjustment will be to introduce #ifdef at all places where we reference _Float16

There will be also the question on how to deal with Float16 datasets on environments where this is not a native data type. We should probably continue to expose them as Float32 as done for example by the GTiff, HDF5 or Zarr driver in current master. Otherwise we'll have to make sure that RasterIO() / GDALCopyWords() can work for Float16 <--> Float32 conversions even if _Float16 is not a native data type (using the functions of port/cpl_float.h)
Same issue with the VRT driver: what if a user creates/reads a VRT file referencing Float16 on a system without _Float16 support.

If you could rebase on top of latest master to solve a conflict, that would enable to have CI to trigger

}

// The generic function above does not work for _Float16 because
// std::numeric_limits<float>::epsilon() is the wrong choice
#ifndef SWIGPYTHON
Copy link
Member

Choose a reason for hiding this comment

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

Why testing for SWIGPYTHON outside of swig/include? That doesn't seem appropriate

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SWIG examines this file and is getting confused because it does not know _Float16. Is there a different way to tell SWIG to ignore this function? (I'm not a SWIG expert.)

Copy link
Member

Choose a reason for hiding this comment

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

ok I see. Perhaps use #ifndef SWIG to be more general then

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The error is

In file included from extensions/gdal_array_wrap.cpp:3395:
/localhome/eschnett/src/gdal/gcore/gdal_priv.h:4414:28: error: ‘bool ARE_REAL_EQUAL’ redeclared as different kind of entity
 4414 | inline bool ARE_REAL_EQUAL(_Float16 hfVal1, _Float16 hfVal2, int ulp = 2)
      |                            ^~~~~~~~
@@ -1692,6 +1695,9 @@ bool GDALExtendedDataType::CopyValue(const void *pSrc,
static_cast<GIntBig>(
*static_cast<const std::int64_t *>(pSrc)));
break;
case GDT_Float16:
str = CPLSPrintf("%.9g", *static_cast<const _Float16 *>(pSrc));
Copy link
Member

Choose a reason for hiding this comment

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

I would expect float16 requires less than 9 significant digits. Same below for CFloat16

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, it requires 5 digits.

I notice that double values are output with 18 digits. 17 would suffice.

@@ -1155,9 +1155,11 @@ static GDALExtendedDataType ParseDtype(const CPLJSONObject &obj,
}
else if (chType == 'f' && nBytes == 2)
{
// elt.nativeType = DtypeElt::NativeType::IEEEFP;
Copy link
Member

Choose a reason for hiding this comment

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

exposing has Float32 will still be needed for environments without native Float16 support

@@ -375,6 +375,10 @@ CPLErr GTIFFBuildOverviewsEx(const char *pszFilename, int nBands,
nBandFormat = SAMPLEFORMAT_INT;
break;

case GDT_Float16:
CPLAssert(false);
Copy link
Member

Choose a reason for hiding this comment

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

The assertion is inappropriate, as this could happen. We should error out with a proper CPLError(CE_Failure, CPLE_NotSupported, ...) error. Same remark for CFloat16 below. Actually we could potentially support Float16. There's for example support for it in frmts/gtiff/gtiffoddbitsband.cpp

@@ -105,6 +105,9 @@ static PyObject *GDALCreateNumpyArray(PyObject *pCreateArray, void *pBuffer,
case GDT_UInt64:
pszDataType = "uint64";
break;
case GDT_Float16:
CPLAssert(FALSE);
Copy link
Member

Choose a reason for hiding this comment

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

this assert should be converted to a CPLError(), or implemented

@@ -59,6 +59,8 @@ inline double GetSrcVal(const void *pSource, GDALDataType eSrcType, T ii)
case GDT_Int64:
return static_cast<double>(
static_cast<const int64_t *>(pSource)[ii]);
case GDT_Float16:
Copy link
Member

Choose a reason for hiding this comment

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

The data type enumeration in frmts/vrt/data/gdalvrt.xsd will need to be extended

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I assume you refer to DataTypeType. I assume the datatypes there are essentially unordered and do not have to have the same order as enum GDALDataType. I also added Int8 which seemed to be missing.

@eschnett
Copy link
Contributor Author

eschnett commented Jul 9, 2024

I am planning to use #ifdef SIZEOF__FLOAT16 to check whether _Float16 is available. Would you prefer a different mechanism?

@rouault
Copy link
Member

rouault commented Jul 9, 2024

I am planning to use #ifdef SIZEOF__FLOAT16 to check whether _Float16 is available.

that sounds reasonable. We should make sure that this is set in cmake/template/cpl_config.h.in so that code like out-of-tree drivers has also access to that define when building against GDAL headers

@eschnett
Copy link
Contributor Author

eschnett commented Jul 9, 2024

Should GetSrcVal in pixelfunctions.cpp return 0 for float16, or report an error if unsupported?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants