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

Added support for Float16 #341

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open

Conversation

andyferris
Copy link
Contributor

  • Saving and loading Float16 values is now supported
  • Float16 is no longer an "opaque" type.
  • Added some more wrapper functions relating to setting and getting
    floating-point datatype fields
  • H5T_FLOAT16 needs to be created dynamically. Attempts at making the
    list of natively supported types dynamically modifiable by the user
    is blocked by the fact that HDF5BitsKind is used for dispatch
    everywhere...
  • Unit test

CC @omriroames @r-chris

Note: There is a (rather small) caveat that all 2-byte floating point types will be loaded as Float16 (which may be lossy if people aren't using the IEEE conventional type).

@andyferris
Copy link
Contributor Author

CC @c42f

Copy link

@c42f c42f left a comment

Choose a reason for hiding this comment

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

I had a look. This all looks pretty reasonable, though I don't know a lot about the surrounding code.

src/plain.jl Outdated

# Set up Float16 (must occur at runtime)
eval(:(const H5T_FLOAT16 = make_float16()))
eval(:(hdf5_type_id(::Type{Float16}) = H5T_FLOAT16))
Copy link

Choose a reason for hiding this comment

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

I guess you can use @eval here? Slightly more readable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True! I always forget about @eval

src/plain.jl Outdated
error("Error getting fields of floating-point datatype")
end
return (spos[], epos[], esize[], mpos[], msize[])
end
Copy link

Choose a reason for hiding this comment

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

Was this function required for debugging? I can't see it used elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Seemed reasonable to define getters as I define the matching setters.

Copy link
Contributor Author

@andyferris andyferris Oct 26, 2016

Choose a reason for hiding this comment

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

And yes I did use it for debugging (same with h5t_get_ebias above)

Copy link

Choose a reason for hiding this comment

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

Makes sense.

src/plain.jl Outdated
is_signed = h5t_get_sign(native_type)
else
is_signed = nothing
# First look in the type last for a match
Copy link

Choose a reason for hiding this comment

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

spelling "last" ?

@andyferris
Copy link
Contributor Author

andyferris commented Oct 26, 2016

<begin cranky rant>

I'm noting that there have been several sensible and minimal PRs sitting around, some since July, and others since quite recently, with not even a comment. These include #317 and #318 (@eschnett), #331 (@r-chris), and #342 (@OmriRoames - obviously this one is much too recent for complaints) (plus 2 more recent ones from myself).

Can I ping whoever maintains this package a bit of general HDF5 community attention? Apologies in advance for being pushy, but I'm going start with @timholy, @simonster and @tkelman. Not sure who else might have merge permissions.

For obvious reasons, HDF5.jl is an important package for getting real work done. I completely understand that everyone here is a volunteer and is busy - and if the package needs more maintainers to share the workload, I'm sure there's a few of us willing to help out. And again, sorry for being cranky and pushy!!!

</end rant>

@c42f
Copy link

c42f commented Oct 26, 2016

@andyferris sorry about the mess on this branch, there were some crossed wires with a rebase!

I tried to fix it up - hope it looks good to you now?

@andyferris
Copy link
Contributor Author

I don't think I see any problems...

src/plain.jl Outdated
eval(:(const H5T_FLOAT16 = make_float16()))
eval(:(hdf5_type_id(::Type{Float16}) = H5T_FLOAT16))
@eval(const H5T_FLOAT16 = make_float16())
@eval(hdf5_type_id(::Type{Float16}) = H5T_FLOAT16)
Copy link

Choose a reason for hiding this comment

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

I don't think you even need the macro brackets here by the way.

@andyferris
Copy link
Contributor Author

bump

Andy Ferris and others added 2 commits March 16, 2017 15:03
 * Saving and loading Float16 values is now supported
 * Float16 is no longer an "opaque" type.
 * Added some more wrapper functions relating to setting and getting
   floating-point datatype fields
 * `H5T_FLOAT16` needs to be created dynamically. Attempts at making the
   list of natively supported types dynamically modifiable by the user
   is  blocked by the fact that `HDF5BitsKind` is used for dispatch
   everywhere...
 * Unit test
@andyferris
Copy link
Contributor Author

Rebased. bump.

@c42f
Copy link

c42f commented Mar 16, 2017

The CI errors here seem to be the issue in JuliaLang/julia#7669

I think you need

@eval hdf5_type_id(::Type{Float16})=H5T_FLOAT16

@musm
Copy link
Member

musm commented Mar 21, 2017

@simonster any reason not to support float16? Do you have any reservations here. The basic implementation looks fine I believe but im not an expert with the code base

@musm
Copy link
Member

musm commented Mar 23, 2017

tests now passing thanks @c42f for that! @andyferris hope you don't mind I pushed the fix for you

@andyferris
Copy link
Contributor Author

Of course - thanks @musm and @c42f :)

test/plain.jl Outdated

# Test Float16 support
arr_float16 = Float16[1.0, 0.25, 0.5, 8.0]
h5write("test_float16.h5", "x", arr_float16)
Copy link
Contributor

Choose a reason for hiding this comment

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

should clean this file up when the test is done, otherwise stale results from previous runs could give misleading results

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is it more robust to check for existence and delete it before the test?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess if you want it to stick around afterwards for debugging, maybe? But then it sticks around in the package dir (I think that's where Pkg.test will usually run from). It's not checked in so it wouldn't make the package dirty in the git sense, but it would be an untracked file.

Would be consistent with the earlier tests to put it under joinpath(tmpdir, "test_float16.h5") and move the rm(tmpdir, recursive=true) to after this test.

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

@andyferris
Copy link
Contributor Author

Thanks @musm for the patches. Is this good to go?

@simonster
Copy link
Member

It would be good to make sure that this doesn't change things for JLD, e.g. that Float16 values saved with JLD and the previous version of HDF5 can still be read after these changes. Otherwise we may need to tweak some things to accommodate this change.

h5t_lock(FLOAT16)
return FLOAT16
end
# const H5T_FLOAT16 = make_float16() (in `__init__()`)
Copy link
Member

Choose a reason for hiding this comment

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

I guess I don't really understand why this has to be in __init__ do you think you could please explain this to me?

Copy link

Choose a reason for hiding this comment

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

This is needed for the same reason that H5open() is called inside __init__: make_float16() is allocating new data structures inside the underlying hdf5 library and must be called each time the library is loaded.

Actually it's interesting that the rest of the code assumes the value of globals like H5T_NATIVE_FLOAT_g will be consistent between different runs of the julia program. Looking at the C library, these globals are allocated inside H5open(), so it seems this isn't really guaranteed.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks. I'm wondering of a way to trigger a bug to show that.
In matlab.jl we have references https://github.com/JuliaInterop/MATLAB.jl/blob/master/src/init.jl
that are filled in with the pointers in inside __init__ ref https://github.com/JuliaInterop/MATLAB.jl/blob/master/src/MATLAB.jl#L53
we might have to do the same here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have no idea if we can trigger a bug/make a test for this... would it happen if the HDF5 binary library was updated without this package being precompiled again? And yes, to me, filling references at run-time during __init__ seems the safest possible thing to do.

Copy link

Choose a reason for hiding this comment

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

To trigger this possible bug, it looks like you'd need to first load a library which creates a custom id dynamically (through a call to H5Iregister() I guess?), before H5open() is called. I don't know whether the libhdf5 API contract prevents this from happening.

After that, load HDF5.jl into the same process and the ids may be different from when HDF5.jl was loaded in build.jl.

Copy link
Contributor

Choose a reason for hiding this comment

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

This seems quite possible. Another library (e.g. PETSc) could depend on HDF5_jll so that HDF5_jll is loaded and initialized before HDF5.jl is initialized. It would be quite difficult to trigger this in a test case though.

@musm
Copy link
Member

musm commented Mar 2, 2020

It seems like a good idea to try to push this through once again.

@Iddingsite
Copy link

Hi, is there any news on Float16 support?

@mkitti
Copy link
Member

mkitti commented May 31, 2022

I'm thinking about resurrecting this, but making it lazy.

Instead of invoking it on __init__, we could have a constant Ref to hold this. make_float16 would just be invoked once on demand.

@musm
Copy link
Member

musm commented May 31, 2022

@mkitti that's what I was suggesting in https://github.com/JuliaIO/HDF5.jl/pull/341/files#r116400351

@Iddingsite
Copy link

Hi, is there some updates on that? Is there a reason that is preventing the changes from @musm to be merged? Would be really useful for one of my application.

@mkitti
Copy link
Member

mkitti commented Jan 18, 2024

Mainly it needs to rebased. The pull request is quite old now.

@Iddingsite
Copy link

I see. Doesn't seems so much work but sadly I don't have any expertise in this. I will have to wait for someone to pick this up!

@mkitti
Copy link
Member

mkitti commented Jan 22, 2024

What would be even better is if HDF Group added upstream support for Float16.

There's a related issue here:
HDFGroup/hdf5#2154

@Iddingsite
Copy link

I see, I was not aware of that one. Yeah, that would makes sense to wait for native support 👍 thx!

@eschnett
Copy link
Contributor

No, it doesn't make sense to wait. It would be really cool if we had that feature now.

@Iddingsite
Copy link

I've noticied that the last version from the hdfgroup is now supporting Float16 (https://www.hdfgroup.org/2024/04/release-of-hdf5-1-14-4-newsletter-202/). Is that now supported in the Julia wrapper?

@eschnett
Copy link
Contributor

eschnett commented Jul 2, 2024

Working on it JuliaPackaging/Yggdrasil#8588 ...

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

Successfully merging this pull request may close these issues.

8 participants