-
Notifications
You must be signed in to change notification settings - Fork 51
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
HDF5IOHandler: Support for float128 on ARM64/PPC64 #1364
HDF5IOHandler: Support for float128 on ARM64/PPC64 #1364
Conversation
846b8f7
to
f61263b
Compare
Figured to work around the heap corruption. Issue is that on macOS/ARM64, |
Hey Ulrik, |
Aaah, monday has caught me again. After using the correct branch, this also solves the issue on Summit/PPC64. |
Hmm, we'll probably also need complex 128bit double types then.. |
This is actually quite an interesting issue. I had completely forgotten that x86 uses 80bit precision for |
So, you would suggest instead to do something like |
I opened a PR with suggestions skalarproduktraum#1 |
src/IO/HDF5/HDF5IOHandler.cpp
Outdated
else if (H5Tequal(attr_type, m_H5T_LONG_DOUBLE_80_LE)) | ||
{ | ||
// worst case, sizeof(long double) is only 8, so allocate enough | ||
// memory to fit 16 bytes per member |
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.
We should maybe use malloc here to avoid running into aliasing issues?
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.
Yep, that makes much more sense. This was just my stop-gap solution for the prototype.
Yes, I think that generally cross-platform
So far, we did avoid converting (casting) data during I/O and kept it platform-specific. I am open to suggestions to enable platform-portability, but we need to check if that works on all platforms and is worth the performance hit (ideally, opt-in). |
src/IO/HDF5/HDF5IOHandler.cpp
Outdated
@@ -73,6 +73,8 @@ HDF5IOHandlerImpl::HDF5IOHandlerImpl( | |||
, m_H5T_CFLOAT{H5Tcreate(H5T_COMPOUND, sizeof(float) * 2)} | |||
, m_H5T_CDOUBLE{H5Tcreate(H5T_COMPOUND, sizeof(double) * 2)} | |||
, m_H5T_CLONG_DOUBLE{H5Tcreate(H5T_COMPOUND, sizeof(long double) * 2)} | |||
, m_H5T_LONG_DOUBLE_80_BE{H5Tcopy(H5T_IEEE_F64BE)} |
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.
BE is not really used: virtually all PPC machines in HPC use LE these days :)
3d1190b
to
223f2b3
Compare
d711f78
to
223f2b3
Compare
@ax3l I have reduced this to little endian and added a comment that this conversion fix specifically targets the AMD64 -> ARM64/PPC64 special case. The workaround is used only if the double type is not recognized as a native type, so I'd say that the opt-in criterium is sufficiently fulfilled. |
src/IO/HDF5/HDF5Auxiliary.cpp
Outdated
@@ -98,7 +98,7 @@ hid_t openPMD::GetH5DataType::operator()(Attribute const &att) | |||
return H5Tcopy(H5T_NATIVE_DOUBLE); | |||
case DT::LONG_DOUBLE: | |||
case DT::VEC_LONG_DOUBLE: | |||
return H5Tcopy(H5T_NATIVE_LDOUBLE); | |||
return H5Tcopy(m_userTypes.at(typeid(long double).name())); |
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.
return H5Tcopy(m_userTypes.at(typeid(long double).name())); | |
return H5Tcopy(H5T_NATIVE_LDOUBLE); |
I think that the change can be reverted again. In writing procedures, we can always use the native datatype anyway. In HDF5IOHandlerImpl::readDataset()
we need to manually check if the dataset can be read as native long double
anyway before attempting the workaround with the manually defined long double
. As a result, it's fine to return native long double
here in ::openDataset()
. Other reading procedures don't use this anyway.
88f9f9d
to
3aaecc0
Compare
for more information, see https://pre-commit.ci
3aaecc0
to
7f023fe
Compare
src/IO/HDF5/HDF5IOHandler.cpp
Outdated
auto *tmpBuffer = | ||
static_cast<long double *>(malloc(16 * 2 * dims[0])); |
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.
In C++, I would use new
and delete
over malloc
and free
.
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.
This will need a reinterpret_cast
then though, as you can't new
a void pointer. But I'll push a commit.
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.
We found today: can be new long double
😅
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.
It turns out, we cannot 🙃
This branch is active when sizeof(long double) == 8
, but the dataset on disk has 16-byte doubles. There is no way to allocate a correctly-sized buffer using native float types, so new char[]
it is.
ping @franzpoeschel @skalarproduktraum pls see review comments to finalize :) We would like to cut the 0.15.2 release soon, let me know if this works to be updated :) |
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.
Looks awesome, we just want to update the new long double
.
I added an update and made a comment a bit clearer |
Also, add a more explanative comment
cb44a14
to
0c53b05
Compare
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.
Excellent, good point!
This PR (hopefully) addresses #1363 by adding h5py-compatible float128 data types in HDF5IOHandler. The original issue seems to originate from a AMD64 vs. ARM64/PPC64 difference in the handling of
long double
types. While on AMD64, 128bit float with 80 bits of precision directly maps to H5T_NATIVE_LDOUBLE, it does not on ARM64/PPC64.For the time being, I have also added some more debug output to the else branch where an unknown type is encountered, such that the HDF5 type info can be more easily recovered.
The PR currently still has a
Heap corruption detected, free list is damaged
error, the attributes that failed to read correctly originally read correctly now, though. Maybe @franzpoeschel has an idea there 👍