Skip to content

Add support for Float16#1229

Merged
mkitti merged 8 commits into
masterfrom
eschnett/float16
Apr 28, 2026
Merged

Add support for Float16#1229
mkitti merged 8 commits into
masterfrom
eschnett/float16

Conversation

@eschnett

Copy link
Copy Markdown
Contributor

Closes #1228.

@mkitti mkitti left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think some of these changes might make us dependent on HDF5_jll version 2. Could we detect the HDF5 version before trying to load a possibly non-existent constant?

Comment thread src/api/functions.jl
"""
function h5p_set_obj_track_times(plist_id, track_times)
lock(liblock)
@show :h5p_set_obj_track_times track_times

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this is probably unrelated.

Comment thread src/api/types.jl Outdated
const H5T_NATIVE_UINT32 = _read_const(:H5T_NATIVE_UINT32_g)
const H5T_NATIVE_INT64 = _read_const(:H5T_NATIVE_INT64_g)
const H5T_NATIVE_UINT64 = _read_const(:H5T_NATIVE_UINT64_g)
const H5T_NATIVE_FLOAT16 = _read_const(:H5T_NATIVE_FLOAT16_g)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we need something for earlier versions of HDF5 here (pre 2.0).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds Float16 (half-float) support to HDF5.jl’s Julia↔HDF5 type conversions to address failures when reading Float16 datasets (Issue #1228), and extends the test suite to cover Float16 and ComplexF16 roundtrips.

Changes:

  • Add Float16 to the scalar “bits” type set and map HDF5 float types of size 2 bytes to Julia Float16.
  • Introduce an API constant / type-id mapping for H5T_NATIVE_FLOAT16 to enable writing Float16 datasets.
  • Extend test/plain.jl to write/read Float16 and ComplexF16 datasets; remove a stray debug @show from an API wrapper.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/plain.jl Adds Float16 + ComplexF16 read/write test coverage.
src/types.jl Expands BitsType union to include Float16.
src/typeconversions.jl Adds Float16 HDF5 type-id mapping and Float16 size-based type inference on read.
src/api/types.jl Adds H5T_NATIVE_FLOAT16 constant binding.
src/api/functions.jl Removes a debug @show statement from a generated wrapper.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/api/types.jl Outdated
const H5T_NATIVE_UINT32 = _read_const(:H5T_NATIVE_UINT32_g)
const H5T_NATIVE_INT64 = _read_const(:H5T_NATIVE_INT64_g)
const H5T_NATIVE_UINT64 = _read_const(:H5T_NATIVE_UINT64_g)
const H5T_NATIVE_FLOAT16 = _read_const(:H5T_NATIVE_FLOAT16_g)

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

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

H5T_NATIVE_FLOAT16 is loaded unconditionally via _read_const(:H5T_NATIVE_FLOAT16_g). Since _read_const uses dlsym(...; throw_error=true) this will raise during module load if the linked libhdf5 (or the shim exporting *_g symbols) doesn’t provide that symbol. Please gate this with _has_symbol(:H5T_NATIVE_FLOAT16_g) (or a libversion check) and either provide a fallback type id or throw a clear runtime error when Float16 writes are attempted on unsupported HDF5 builds.

Suggested change
const H5T_NATIVE_FLOAT16 = _read_const(:H5T_NATIVE_FLOAT16_g)
const H5T_NATIVE_FLOAT16 = _has_symbol(:H5T_NATIVE_FLOAT16_g) ? _read_const(:H5T_NATIVE_FLOAT16_g) : hid_t(-1)

Copilot uses AI. Check for mistakes.
Comment thread src/typeconversions.jl Outdated
hdf5_type_id(::Type{UInt32}) = API.H5T_NATIVE_UINT32
hdf5_type_id(::Type{Int64}) = API.H5T_NATIVE_INT64
hdf5_type_id(::Type{UInt64}) = API.H5T_NATIVE_UINT64
hdf5_type_id(::Type{Float16}) = API.H5T_NATIVE_FLOAT16

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

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

hdf5_type_id(::Type{Float16}) = API.H5T_NATIVE_FLOAT16 will fail (at compile time or runtime) if the API constant can’t be loaded on some HDF5 versions/builds. Consider defining this method conditionally (based on API._has_symbol(:H5T_NATIVE_FLOAT16_g) / libversion) and raising a targeted error message when Float16 datatypes are not supported by the linked HDF5 library, or mapping to an available standard half-float type when present.

Suggested change
hdf5_type_id(::Type{Float16}) = API.H5T_NATIVE_FLOAT16
function hdf5_type_id(::Type{Float16})
if API._has_symbol(:H5T_NATIVE_FLOAT16_g)
return API.H5T_NATIVE_FLOAT16
end
throw(ArgumentError("Float16 HDF5 datatypes are not supported by the linked HDF5 library"))
end

Copilot uses AI. Check for mistakes.
Comment thread test/plain.jl Outdated
Comment on lines +180 to +182
Af16 = read(fr, "Afloat16")
@test convert(Matrix{Float16}, A) == Af16
@test eltype(Af16) == Float16

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

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

These Float16 read/write assertions are unconditional. If the linked HDF5 build doesn’t support half-float (e.g., older libhdf5 versions still allowed by this package’s compat), the tests may fail or even error during package load due to missing type IDs. Please guard this block behind a capability check (e.g., API._has_symbol(:H5T_NATIVE_FLOAT16_g) / a libversion check), or bump the minimum supported HDF5_jll/libhdf5 version accordingly.

Suggested change
Af16 = read(fr, "Afloat16")
@test convert(Matrix{Float16}, A) == Af16
@test eltype(Af16) == Float16
if HDF5.API._has_symbol(:H5T_NATIVE_FLOAT16_g)
Af16 = read(fr, "Afloat16")
@test convert(Matrix{Float16}, A) == Af16
@test eltype(Af16) == Float16
end

Copilot uses AI. Check for mistakes.
Comment thread test/plain.jl Outdated
Comment on lines +642 to +644
Acmplx16 = read(fr, "Acmplx16")
@test convert(Matrix{ComplexF16}, Acmplx) == Acmplx16
@test eltype(Acmplx16) == ComplexF16

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

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

ComplexF16 datasets are now written/read unconditionally. This will break on HDF5 builds that don’t support Float16 type IDs (since complex compound type creation relies on hdf5_type_id(Float16)). Please make these tests conditional on Float16 datatype support (or update the minimum supported HDF5 version) to avoid failures on older libhdf5 installations.

Copilot uses AI. Check for mistakes.
@eschnett

Copy link
Copy Markdown
Contributor Author

Which HDF5 library versions should we support? I might be a good idea to add respective CI tests. It would be straightforward to e.g. run a test with HDF5_jll @1 to test with the latest HDF5 1.x version.

@mkitti

mkitti commented Apr 28, 2026

Copy link
Copy Markdown
Member

Based on the available downloads I would say 1.14.6 and 2.1.0 at least. Maybe a 1.12 release would be useful as well if there is not a strong need to drop support.

Let me know if you start working on that. I will take a look.

https://support.hdfgroup.org/downloads/

@mkitti

mkitti commented Apr 28, 2026

Copy link
Copy Markdown
Member

We can drop HDF5 1.12. Thanks for trying.

@mkitti

mkitti commented Apr 28, 2026

Copy link
Copy Markdown
Member

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/CI.yml Outdated
Comment on lines +94 to +98
- name: Run ${{ matrix.package.repo }} tests with HDF5_jll ${{ matrix.hdf5_jll }}
env:
JULIA_DEBUG: Main
HDF5_jll: ${{ matrix.hdf5_jll }}
shell: julia --project=@. {0}

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

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

matrix.package.repo is not defined in the HDF5 job matrix, so this step name will expand to an empty string (and is confusing to read). Use a literal package name (e.g. HDF5.jl) or ${{ github.repository }}/${{ github.workflow }} instead.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good point.

Comment thread .github/workflows/CI.yml Outdated
- {version: 'nightly', os: macOS-26, arch: aarch64}
- {version: 'nightly', os: windows-2025, arch: x64}
- {version: 'nightly', os: windows-2025, arch: x86}
- {version: '1.10', os: ubuntu-24.04, arch: x64, hdf5_jll: '1.12'} # HDF5_jll 1.12 does not work with Julia 1.12

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

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

The inline comment mentions “Julia 1.12”, but this matrix entry is for Julia 1.10. If the note is still relevant, clarify what combination is known-bad (Julia vs HDF5_jll) to avoid misleading future maintainers.

Suggested change
- {version: '1.10', os: ubuntu-24.04, arch: x64, hdf5_jll: '1.12'} # HDF5_jll 1.12 does not work with Julia 1.12
- {version: '1.10', os: ubuntu-24.04, arch: x64, hdf5_jll: '1.12'} # Keep coverage for Julia 1.10 with HDF5_jll 1.12; the known-bad combination is Julia 1.12 with HDF5_jll 1.12

Copilot uses AI. Check for mistakes.
@mkitti

mkitti commented Apr 28, 2026

Copy link
Copy Markdown
Member

Looks pretty good to me.

To summarize the support for upstream HDF5_jll:

  • Support HDF5 1.12 for as long as we support Julia 1.10 LTS
  • Support last 1.14 release as the last of the HDF5 1.x series, until HDF Group drops that from Downloads page.
  • Support latest HDF5 2.x release

@mkitti

mkitti commented Apr 28, 2026

Copy link
Copy Markdown
Member

Both of Copilot's suggestions seem productive with the first one being a bug fix.

Comment thread .github/workflows/CI.yml Outdated
Comment thread .github/workflows/CI.yml Outdated
Try to keep julia-runtest action. Reformat and elaborate on comments.

Co-authored-by: Mark Kittisopikul <mkitti@users.noreply.github.com>
Comment thread .github/workflows/CI.yml Outdated
@mkitti

mkitti commented Apr 28, 2026

Copy link
Copy Markdown
Member

Would we want to add support for bfloat16 in the future perhaps as a package extension via https://github.com/JuliaMath/BFloat16s.jl?
https://www.hdfgroup.org/2025/11/10/release-of-hdf5-2-0-0-newsletter-207/

@mkitti mkitti merged commit 350d496 into master Apr 28, 2026
29 checks passed
@mkitti mkitti deleted the eschnett/float16 branch April 28, 2026 04:05
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.

KeyError when loading float16 data

3 participants