Skip to content
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
56 changes: 34 additions & 22 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
# - uses: julia-actions/julia-runtest@v1

HDF5:
name: julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
name: julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ matrix.hdf5_jll }}
runs-on: ${{ matrix.os }}
timeout-minutes: 20
strategy:
Expand All @@ -57,27 +57,31 @@ jobs:
# We need to keep the association between OS and ARCH, and
# there is no good way to express this as a matrix. Hence we
# duplicate for all Julia versions.
- {version: '1.10', os: ubuntu-24.04, arch: x64}
- {version: '1.10', os: ubuntu-24.04, arch: x86}
- {version: '1.10', os: ubuntu-24.04-arm, arch: aarch64}
- {version: '1.10', os: macOS-15-intel, arch: x64}
- {version: '1.10', os: macOS-26, arch: aarch64}
- {version: '1.10', os: windows-2025, arch: x64}
- {version: '1.10', os: windows-2025, arch: x86}
- {version: '1', os: ubuntu-24.04, arch: x64}
- {version: '1', os: ubuntu-24.04, arch: x86}
- {version: '1', os: ubuntu-24.04-arm, arch: aarch64}
- {version: '1', os: macOS-15-intel, arch: x64}
- {version: '1', os: macOS-26, arch: aarch64}
- {version: '1', os: windows-2025, arch: x64}
- {version: '1', os: windows-2025, arch: x86}
- {version: 'nightly', os: ubuntu-24.04, arch: x64}
- {version: 'nightly', os: ubuntu-24.04, arch: x86}
- {version: 'nightly', os: ubuntu-24.04-arm, arch: aarch64}
- {version: 'nightly', os: macOS-15-intel, arch: x64}
- {version: 'nightly', os: macOS-26, arch: aarch64}
- {version: 'nightly', os: windows-2025, arch: x64}
- {version: 'nightly', os: windows-2025, arch: x86}
# Keep coverage for Julia 1.10 with HDF5_jll 1.12
# The known-bad combination is Julia 1.12 or later with HDF5_jll 1.12
- {version: '1.10', os: ubuntu-24.04, arch: x64, hdf5_jll: '1.12'}
- {version: '1.10', os: ubuntu-24.04, arch: x64, hdf5_jll: 'latest'}
- {version: '1.10', os: ubuntu-24.04, arch: x86, hdf5_jll: 'latest'}
- {version: '1.10', os: ubuntu-24.04-arm, arch: aarch64, hdf5_jll: 'latest'}
- {version: '1.10', os: macOS-15-intel, arch: x64, hdf5_jll: 'latest'}
- {version: '1.10', os: macOS-26, arch: aarch64, hdf5_jll: 'latest'}
- {version: '1.10', os: windows-2025, arch: x64, hdf5_jll: 'latest'}
- {version: '1.10', os: windows-2025, arch: x86, hdf5_jll: 'latest'}
- {version: '1', os: ubuntu-24.04, arch: x64, hdf5_jll: '1.14'}
- {version: '1', os: ubuntu-24.04, arch: x64, hdf5_jll: 'latest'}
- {version: '1', os: ubuntu-24.04, arch: x86, hdf5_jll: 'latest'}
- {version: '1', os: ubuntu-24.04-arm, arch: aarch64, hdf5_jll: 'latest'}
- {version: '1', os: macOS-15-intel, arch: x64, hdf5_jll: 'latest'}
- {version: '1', os: macOS-26, arch: aarch64, hdf5_jll: 'latest'}
- {version: '1', os: windows-2025, arch: x64, hdf5_jll: 'latest'}
- {version: '1', os: windows-2025, arch: x86, hdf5_jll: 'latest'}
- {version: 'nightly', os: ubuntu-24.04, arch: x64, hdf5_jll: 'latest'}
- {version: 'nightly', os: ubuntu-24.04, arch: x86, hdf5_jll: 'latest'}
- {version: 'nightly', os: ubuntu-24.04-arm, arch: aarch64, hdf5_jll: 'latest'}
- {version: 'nightly', os: macOS-15-intel, arch: x64, hdf5_jll: 'latest'}
- {version: 'nightly', os: macOS-26, arch: aarch64, hdf5_jll: 'latest'}
- {version: 'nightly', os: windows-2025, arch: x64, hdf5_jll: 'latest'}
- {version: 'nightly', os: windows-2025, arch: x86, hdf5_jll: 'latest'}
steps:
- uses: actions/checkout@v6
- uses: julia-actions/cache@v3
Expand All @@ -86,6 +90,14 @@ jobs:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: julia-actions/julia-buildpkg@v1
- name: Pin HDF5_jll to ${{ matrix.hdf5_jll }}
if: ${{ matrix.hdf5_jll != 'latest' }}
shell: julia --project=@. {0}
run: |
using Pkg
Pkg.pin(PackageSpec(name="HDF5_jll", version="${{ matrix.hdf5_jll }}"))
Pkg.instantiate() # ensures Manifest/artifacts match the pin

- uses: julia-actions/julia-runtest@v1
env:
JULIA_DEBUG: Main
Expand Down
23 changes: 12 additions & 11 deletions src/api/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -523,17 +523,18 @@ const H5T_C_S1 = _read_const(:H5T_C_S1_g)
const H5T_STD_REF_OBJ = _read_const(:H5T_STD_REF_OBJ_g)
const H5T_STD_REF_DSETREG = _read_const(:H5T_STD_REF_DSETREG_g)
# Native types
const H5T_NATIVE_B8 = _read_const(:H5T_NATIVE_B8_g)
const H5T_NATIVE_INT8 = _read_const(:H5T_NATIVE_INT8_g)
const H5T_NATIVE_UINT8 = _read_const(:H5T_NATIVE_UINT8_g)
const H5T_NATIVE_INT16 = _read_const(:H5T_NATIVE_INT16_g)
const H5T_NATIVE_UINT16 = _read_const(:H5T_NATIVE_UINT16_g)
const H5T_NATIVE_INT32 = _read_const(:H5T_NATIVE_INT32_g)
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_FLOAT = _read_const(:H5T_NATIVE_FLOAT_g)
const H5T_NATIVE_DOUBLE = _read_const(:H5T_NATIVE_DOUBLE_g)
const H5T_NATIVE_B8 = _read_const(:H5T_NATIVE_B8_g)
const H5T_NATIVE_INT8 = _read_const(:H5T_NATIVE_INT8_g)
const H5T_NATIVE_UINT8 = _read_const(:H5T_NATIVE_UINT8_g)
const H5T_NATIVE_INT16 = _read_const(:H5T_NATIVE_INT16_g)
const H5T_NATIVE_UINT16 = _read_const(:H5T_NATIVE_UINT16_g)
const H5T_NATIVE_INT32 = _read_const(:H5T_NATIVE_INT32_g)
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 = _has_symbol(:H5T_NATIVE_FLOAT16_g) ? _read_const(:H5T_NATIVE_FLOAT16_g) : hid_t(-1)
const H5T_NATIVE_FLOAT = _read_const(:H5T_NATIVE_FLOAT_g)
const H5T_NATIVE_DOUBLE = _read_const(:H5T_NATIVE_DOUBLE_g)
# Other type constants
const H5T_VARIABLE = reinterpret(UInt, -1)

Expand Down
11 changes: 10 additions & 1 deletion src/typeconversions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ hdf5_type_id(::Type{Int32}) = API.H5T_NATIVE_INT32
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
function hdf5_type_id(::Type{Float16})
if hdf5_supports_Float16
return API.H5T_NATIVE_FLOAT16
else
throw(ArgumentError("Float16 HDF5 datatypes are not supported by the linked HDF5 library"))
end
end
hdf5_type_id(::Type{Float32}) = API.H5T_NATIVE_FLOAT
hdf5_type_id(::Type{Float64}) = API.H5T_NATIVE_DOUBLE
hdf5_type_id(::Type{Reference}) = API.H5T_STD_REF_OBJ
Expand Down Expand Up @@ -177,7 +184,9 @@ function _hdf5_type_map(class_id, is_signed, native_size)
end
end
else
return if native_size == 4
return if native_size == 2
Float16
elseif native_size == 4
Float32
elseif native_size == 8
Float64
Expand Down
14 changes: 13 additions & 1 deletion src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,20 @@ Base.cconvert(
::Type{Ptr{T}}, ref::Reference
) where {T<:Union{Reference,API.hobj_ref_t,Cvoid}} = Ref(ref)

const hdf5_supports_Float16 = API.H5T_NATIVE_FLOAT16 != API.hid_t(-1)
const BitsType = Union{
Bool,Int8,UInt8,Int16,UInt16,Int32,UInt32,Int64,UInt64,Float32,Float64
Bool,
Int8,
UInt8,
Int16,
UInt16,
Int32,
UInt32,
Int64,
UInt64,
Float32,
Float64,
(hdf5_supports_Float16 ? Float16 : Union{})
}
const ScalarType = Union{BitsType,Reference}

Expand Down
27 changes: 27 additions & 0 deletions test/plain.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ using CRC32c
using H5Zblosc
using Test

const test_Float16 = HDF5.hdf5_supports_Float16

gatherf(dst_buf, dst_buf_bytes_used, op_data) = HDF5.API.herr_t(0)
gatherf_bad(dst_buf, dst_buf_bytes_used, op_data) = HDF5.API.herr_t(-1)
gatherf_data(dst_buf, dst_buf_bytes_used, op_data) = HDF5.API.herr_t((op_data == 9) - 1)
Expand Down Expand Up @@ -41,6 +43,9 @@ end
A = randn(3, 5)
write(f, "Afloat64", convert(Matrix{Float64}, A))
write(f, "Afloat32", convert(Matrix{Float32}, A))
if test_Float16
write(f, "Afloat16", convert(Matrix{Float16}, A))
end
Ai = rand(1:20, 2, 4)
write(f, "Aint8", convert(Matrix{Int8}, Ai))
f["Aint16"] = convert(Matrix{Int16}, Ai)
Expand Down Expand Up @@ -176,6 +181,11 @@ end
@test zerodim == 42 && isa(zerodim, Int32)
bloscempty = read(fr, "bloscempty")
@test bloscempty == Int64[] && isa(bloscempty, Vector{Int64})
if test_Float16
Af16 = read(fr, "Afloat16")
@test convert(Matrix{Float16}, A) == Af16
@test eltype(Af16) == Float16
end
Af32 = read(fr, "Afloat32")
@test convert(Matrix{Float32}, A) == Af32
@test eltype(Af32) == Float32
Expand Down Expand Up @@ -611,6 +621,9 @@ end # testset plain
Acmplx = rand(ComplexF64, 3, 5)
write(f, "Acmplx64", convert(Matrix{ComplexF64}, Acmplx))
write(f, "Acmplx32", convert(Matrix{ComplexF32}, Acmplx))
if test_Float16
write(f, "Acmplx16", convert(Matrix{ComplexF16}, Acmplx))
end

dset = create_dataset(
f, "Acmplx64_hyperslab", datatype(Complex{Float64}), dataspace(Acmplx)
Expand All @@ -623,6 +636,11 @@ end # testset plain
@test_throws ErrorException f["_ComplexF64"] = 1.0 + 2.0im
@test_throws ErrorException write(f, "_Acmplx64", convert(Matrix{ComplexF64}, Acmplx))
@test_throws ErrorException write(f, "_Acmplx32", convert(Matrix{ComplexF32}, Acmplx))
if test_Float16
@test_throws ErrorException write(
f, "_Acmplx16", convert(Matrix{ComplexF16}, Acmplx)
)
end
HDF5.enable_complex_support()

close(f)
Expand All @@ -633,6 +651,11 @@ end # testset plain
z_attrs = attributes(fr["ComplexF64"])
@test read(z_attrs["ComplexInt64"]) == 1im

if test_Float16
Acmplx16 = read(fr, "Acmplx16")
@test convert(Matrix{ComplexF16}, Acmplx) == Acmplx16
@test eltype(Acmplx16) == ComplexF16
end
Acmplx32 = read(fr, "Acmplx32")
@test convert(Matrix{ComplexF32}, Acmplx) == Acmplx32
@test eltype(Acmplx32) == ComplexF32
Expand All @@ -651,6 +674,10 @@ end # testset plain
z = read(fr, "ComplexF64")
@test isa(z, NamedTuple{(:r, :i),Tuple{Float64,Float64}})

if test_Float16
Acmplx16 = read(fr, "Acmplx16")
@test eltype(Acmplx16) == NamedTuple{(:r, :i),Tuple{Float16,Float16}}
end
Acmplx32 = read(fr, "Acmplx32")
@test eltype(Acmplx32) == NamedTuple{(:r, :i),Tuple{Float32,Float32}}
Acmplx64 = read(fr, "Acmplx64")
Expand Down
Loading