From 95251bc15782302d3f50e4b4a7e8e00205f1a05d Mon Sep 17 00:00:00 2001 From: Nader Rahhal <107228500+Nader-Rahhal@users.noreply.github.com> Date: Wed, 13 May 2026 17:26:53 -0500 Subject: [PATCH 01/10] hdf5 bindings --- lib/legate_jl_wrapper/include/wrapper.inl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/legate_jl_wrapper/include/wrapper.inl b/lib/legate_jl_wrapper/include/wrapper.inl index f1c9610d..90e865e4 100644 --- a/lib/legate_jl_wrapper/include/wrapper.inl +++ b/lib/legate_jl_wrapper/include/wrapper.inl @@ -330,4 +330,18 @@ inline uint64_t time_nanoseconds() { return legate::timing::measure_nanoseconds().value(); } } // namespace time + + +namespace hdf5 { +inline LogicalArray read_h5(const std::filesystem::path& file_path, std::string_view dataset_name) { + return legate::io::hdf5::from_file(file_path, dataset_name); +} + +inline void write_h5(const LogicalArray& array, std::filesystem::path file_path, std::string_view dataset_name) { + legate::io::hdf5::to_file(array, file_path, dataset_name); +} +} // namespace hdf5s + } // namespace legate_wrapper + + From 5e342a4bc54151647169d1288ca26d92e681e1e0 Mon Sep 17 00:00:00 2001 From: Nader Rahhal <107228500+Nader-Rahhal@users.noreply.github.com> Date: Thu, 14 May 2026 12:01:50 -0500 Subject: [PATCH 02/10] add hdf5 --- lib/legate_jl_wrapper/include/wrapper.inl | 1 + lib/legate_jl_wrapper/src/module.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/lib/legate_jl_wrapper/include/wrapper.inl b/lib/legate_jl_wrapper/include/wrapper.inl index 90e865e4..47748110 100644 --- a/lib/legate_jl_wrapper/include/wrapper.inl +++ b/lib/legate_jl_wrapper/include/wrapper.inl @@ -21,6 +21,7 @@ #include "legate/mapping/machine.h" #include "legate/runtime/runtime.h" #include "legate/timing/timing.h" +#include "legate/io/hdf5/interface.h" #include "legion.h" #include "legion/legion_config.h" diff --git a/lib/legate_jl_wrapper/src/module.cpp b/lib/legate_jl_wrapper/src/module.cpp index 2e216c5f..dc018814 100644 --- a/lib/legate_jl_wrapper/src/module.cpp +++ b/lib/legate_jl_wrapper/src/module.cpp @@ -234,5 +234,9 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& mod) { mod.method("time_microseconds", &legate_wrapper::time::time_microseconds); mod.method("time_nanoseconds", &legate_wrapper::time::time_nanoseconds); + /* hdf5 */ + mod.method("read_h5", &legate_wrapper::hdf5::read_h5); + mod.method("write_h5", &legate_wrapper::hdf5::write_h5); + wrap_ufi(mod); } From 7c996c0be3bc88aa672491b02fae47d941404b5b Mon Sep 17 00:00:00 2001 From: Nader Rahhal <107228500+Nader-Rahhal@users.noreply.github.com> Date: Thu, 14 May 2026 12:10:41 -0500 Subject: [PATCH 03/10] julia side --- src/api/data.jl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/api/data.jl b/src/api/data.jl index 092b002c..6785c063 100644 --- a/src/api/data.jl +++ b/src/api/data.jl @@ -284,3 +284,30 @@ function get_ptr(arr::PhysicalStore) # PhysicalStore -> Ptr return _get_ptr(CxxWrap.CxxPtr(arr)) # cxxwrap call end + +""" + read_h5(path::String, dataset::String) -> LogicalArray + +Read a dataset from an HDF5 file into a LogicalArray. + +# Arguments +- `path`: Path to the HDF5 file. +- `dataset`: Name of the dataset to read. +""" +function read_h5(path::String, dataset::String) + return read_h5(path, dataset) +end + +""" + write_h5(array::LogicalArray, path::String, dataset::String) + +Write a LogicalArray to a dataset in an HDF5 file. + +# Arguments +- `array`: The array to write. +- `path`: Path to the HDF5 file. +- `dataset`: Name of the dataset to write. +""" +function write_h5(array::LogicalArray, path::String, dataset::String) + write_h5(array.handle, path, dataset) +end From eab0bf4e29668bf33808ff3e4bfb9fac39cb1a03 Mon Sep 17 00:00:00 2001 From: Nader Rahhal <107228500+Nader-Rahhal@users.noreply.github.com> Date: Thu, 14 May 2026 13:31:51 -0500 Subject: [PATCH 04/10] finish hdf5 --- lib/legate_jl_wrapper/include/wrapper.inl | 10 +++++----- lib/legate_jl_wrapper/src/module.cpp | 8 +++++++- src/api/data.jl | 13 +++++++++---- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/lib/legate_jl_wrapper/include/wrapper.inl b/lib/legate_jl_wrapper/include/wrapper.inl index 47748110..8a407ae5 100644 --- a/lib/legate_jl_wrapper/include/wrapper.inl +++ b/lib/legate_jl_wrapper/include/wrapper.inl @@ -334,14 +334,14 @@ inline uint64_t time_nanoseconds() { namespace hdf5 { -inline LogicalArray read_h5(const std::filesystem::path& file_path, std::string_view dataset_name) { - return legate::io::hdf5::from_file(file_path, dataset_name); +inline LogicalArray read_h5(const std::string& file_path, const std::string& dataset_name) { + return legate::io::hdf5::from_file(std::filesystem::path(file_path), dataset_name); } -inline void write_h5(const LogicalArray& array, std::filesystem::path file_path, std::string_view dataset_name) { - legate::io::hdf5::to_file(array, file_path, dataset_name); +inline void write_h5(const LogicalArray& array, const std::string& file_path, const std::string& dataset_name) { + legate::io::hdf5::to_file(array, std::filesystem::path(file_path), dataset_name); } -} // namespace hdf5s +} // namespace hdf5 } // namespace legate_wrapper diff --git a/lib/legate_jl_wrapper/src/module.cpp b/lib/legate_jl_wrapper/src/module.cpp index dc018814..a6c75afd 100644 --- a/lib/legate_jl_wrapper/src/module.cpp +++ b/lib/legate_jl_wrapper/src/module.cpp @@ -172,7 +172,13 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& mod) { .method("data", &LogicalArray::data) // returns LogicalStore .method("get_physical_array", &LogicalArray::get_physical_array) // return PhysicalArray - .method("unbound", &LogicalArray::unbound); + .method("unbound", &LogicalArray::unbound) + .method("shape", [](const LogicalArray& arr) { + auto s = arr.data().shape(); + std::vector result; + for (int i = 0; i < arr.dim(); i++) result.push_back(s[i]); + return result; + }); mod.add_type("AutoTask") .method("add_input", static_cast( diff --git a/src/api/data.jl b/src/api/data.jl index 6785c063..a8fc89ba 100644 --- a/src/api/data.jl +++ b/src/api/data.jl @@ -294,10 +294,15 @@ Read a dataset from an HDF5 file into a LogicalArray. - `path`: Path to the HDF5 file. - `dataset`: Name of the dataset to read. """ -function read_h5(path::String, dataset::String) - return read_h5(path, dataset) +function read_hdf5(path::String, dataset::String) + impl = read_h5(path, dataset) # cxxwrap call + ndim = Int(dim(impl)) + shp = Tuple(Int.(shape(impl))) + T = code_type_map[Int(code(type(impl)))] + return LogicalArray{T, ndim}(impl, shp) end + """ write_h5(array::LogicalArray, path::String, dataset::String) @@ -308,6 +313,6 @@ Write a LogicalArray to a dataset in an HDF5 file. - `path`: Path to the HDF5 file. - `dataset`: Name of the dataset to write. """ -function write_h5(array::LogicalArray, path::String, dataset::String) +function write_hdf5(array::LogicalArray, path::String, dataset::String) write_h5(array.handle, path, dataset) -end +end \ No newline at end of file From 24414386f0fba7afa938a453b97d3b602b2f6cd7 Mon Sep 17 00:00:00 2001 From: Nader Rahhal <107228500+Nader-Rahhal@users.noreply.github.com> Date: Thu, 14 May 2026 15:55:55 -0500 Subject: [PATCH 05/10] versioning --- Project.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index 42cc5a98..f7bd95f2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "Legate" uuid = "1238f2cf-6593-4d60-9aca-2f5364e49909" -version = "0.1.2" +version = "0.1.3" [deps] CxxWrap = "1f15a43c-97ca-5a2a-ae31-89f07a497df4" @@ -27,6 +27,6 @@ FunctionWrappers = "1.1.3" JuliaFormatter = "2.2.0" LegatePreferences = "0.1.6" julia = "1.10" -legate_jl_wrapper_jll = "25.10.4" +legate_jl_wrapper_jll = "25.10.5" legate_jll = "25.10.2" -Preferences = "1" +Preferences = "1" \ No newline at end of file From ceb1576025cffa33302889f489e7da6867cf9713 Mon Sep 17 00:00:00 2001 From: David Krasowska Date: Sun, 17 May 2026 10:16:12 -0500 Subject: [PATCH 06/10] update VERSION --- lib/legate_jl_wrapper/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/legate_jl_wrapper/VERSION b/lib/legate_jl_wrapper/VERSION index 3252f073..e3082644 100644 --- a/lib/legate_jl_wrapper/VERSION +++ b/lib/legate_jl_wrapper/VERSION @@ -1 +1 @@ -25.10.3 \ No newline at end of file +25.10.5 \ No newline at end of file From 6e85265d0c67a8bc7c28f50fdc8a872a174b8726 Mon Sep 17 00:00:00 2001 From: krasow Date: Mon, 18 May 2026 11:55:21 -0500 Subject: [PATCH 07/10] hdf5 testing and fixing --- Project.toml | 4 +- lib/legate_jl_wrapper/include/wrapper.inl | 27 ++++++--- lib/legate_jl_wrapper/src/module.cpp | 3 +- src/api/data.jl | 22 +++++-- src/api/runtime.jl | 9 +++ src/utilities/attach.jl | 4 +- test/Project.toml | 2 + test/runtests.jl | 3 + test/tests/hdf5.jl | 73 +++++++++++++++++++++++ 9 files changed, 128 insertions(+), 19 deletions(-) create mode 100644 test/tests/hdf5.jl diff --git a/Project.toml b/Project.toml index f7bd95f2..483879ee 100644 --- a/Project.toml +++ b/Project.toml @@ -27,6 +27,6 @@ FunctionWrappers = "1.1.3" JuliaFormatter = "2.2.0" LegatePreferences = "0.1.6" julia = "1.10" -legate_jl_wrapper_jll = "25.10.5" +legate_jl_wrapper_jll = "25.10.4" legate_jll = "25.10.2" -Preferences = "1" \ No newline at end of file +Preferences = "1" diff --git a/lib/legate_jl_wrapper/include/wrapper.inl b/lib/legate_jl_wrapper/include/wrapper.inl index 8a407ae5..23cb59f2 100644 --- a/lib/legate_jl_wrapper/include/wrapper.inl +++ b/lib/legate_jl_wrapper/include/wrapper.inl @@ -18,10 +18,10 @@ */ #include "legate.h" +#include "legate/io/hdf5/interface.h" #include "legate/mapping/machine.h" #include "legate/runtime/runtime.h" #include "legate/timing/timing.h" -#include "legate/io/hdf5/interface.h" #include "legion.h" #include "legion/legion_config.h" @@ -64,6 +64,14 @@ inline bool has_started() { return legate::has_started(); } * @brief Check whether the Legate runtime has finished. */ inline bool has_finished() { return legate::has_finished(); } + +/** + * @ingroup legate_wrapper + * @brief Block until all pending Legate tasks have completed. + */ +inline void runtime_sync() { + Runtime::get_runtime()->issue_execution_fence(true); +} } // namespace runtime namespace tasking { @@ -332,17 +340,18 @@ inline uint64_t time_nanoseconds() { } } // namespace time - namespace hdf5 { -inline LogicalArray read_h5(const std::string& file_path, const std::string& dataset_name) { - return legate::io::hdf5::from_file(std::filesystem::path(file_path), dataset_name); +inline LogicalArray read_h5(const std::string& file_path, + const std::string& dataset_name) { + return legate::io::hdf5::from_file(std::filesystem::path(file_path), + dataset_name); } -inline void write_h5(const LogicalArray& array, const std::string& file_path, const std::string& dataset_name) { - legate::io::hdf5::to_file(array, std::filesystem::path(file_path), dataset_name); +inline void write_h5(const LogicalArray& array, const std::string& file_path, + const std::string& dataset_name) { + legate::io::hdf5::to_file(array, std::filesystem::path(file_path), + dataset_name); } -} // namespace hdf5 +} // namespace hdf5 } // namespace legate_wrapper - - diff --git a/lib/legate_jl_wrapper/src/module.cpp b/lib/legate_jl_wrapper/src/module.cpp index a6c75afd..042527b1 100644 --- a/lib/legate_jl_wrapper/src/module.cpp +++ b/lib/legate_jl_wrapper/src/module.cpp @@ -178,7 +178,7 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& mod) { std::vector result; for (int i = 0; i < arr.dim(); i++) result.push_back(s[i]); return result; - }); + }); mod.add_type("AutoTask") .method("add_input", static_cast( @@ -212,6 +212,7 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& mod) { mod.method("get_runtime", &legate_wrapper::runtime::get_runtime); mod.method("has_started", &legate_wrapper::runtime::has_started); mod.method("has_finished", &legate_wrapper::runtime::has_finished); + mod.method("runtime_sync", &legate_wrapper::runtime::runtime_sync); /* tasking */ mod.method("align", &legate_wrapper::tasking::align); mod.method("domain_from_shape", &legate_wrapper::tasking::domain_from_shape); diff --git a/src/api/data.jl b/src/api/data.jl index a8fc89ba..1f5b2e09 100644 --- a/src/api/data.jl +++ b/src/api/data.jl @@ -297,12 +297,14 @@ Read a dataset from an HDF5 file into a LogicalArray. function read_hdf5(path::String, dataset::String) impl = read_h5(path, dataset) # cxxwrap call ndim = Int(dim(impl)) - shp = Tuple(Int.(shape(impl))) + shp_h5 = Tuple(Int.(shape(impl))) + # HDF5 stores in C (row-major) order; Julia is column-major. + # HDF5.jl bridges this by reversing dimensions, so we do the same. + shp_jl = ndim > 1 ? reverse(shp_h5) : shp_h5 T = code_type_map[Int(code(type(impl)))] - return LogicalArray{T, ndim}(impl, shp) + return LogicalArray{T,ndim}(impl, shp_jl) end - """ write_h5(array::LogicalArray, path::String, dataset::String) @@ -313,6 +315,16 @@ Write a LogicalArray to a dataset in an HDF5 file. - `path`: Path to the HDF5 file. - `dataset`: Name of the dataset to write. """ -function write_hdf5(array::LogicalArray, path::String, dataset::String) +function write_hdf5(array::LogicalArray{T,1}, path::String, dataset::String) where {T} write_h5(array.handle, path, dataset) -end \ No newline at end of file +end + +# HDF5.jl bridges Julia's column-major and HDF5's C-order by reversing dimensions +# while keeping the raw bytes unchanged. We do the same: reshape the Julia array +# to the reversed shape (same bytes, different interpretation) before handing it +# to Legate's write_h5 so the on-disk shape matches what HDF5.jl expects. +function write_hdf5(array::LogicalArray{T,N}, path::String, dataset::String) where {T,N} + arr = Array{T,N}(array) + la_rev = LogicalArray(reshape(arr, reverse(size(arr)))) + write_h5(la_rev.handle, path, dataset) +end diff --git a/src/api/runtime.jl b/src/api/runtime.jl index 056a3f4b..6da0924d 100644 --- a/src/api/runtime.jl +++ b/src/api/runtime.jl @@ -40,6 +40,15 @@ Check whether the Legate runtime has finished. """ has_finished +""" + runtime_sync() + +Block until all pending Legate tasks have completed. + +Useful before reading files written by `write_hdf5` or other async operations. +""" +runtime_sync + """ create_library(name::String) -> Library diff --git a/src/utilities/attach.jl b/src/utilities/attach.jl index 897a619b..1d2b3025 100644 --- a/src/utilities/attach.jl +++ b/src/utilities/attach.jl @@ -78,7 +78,7 @@ end # conversion from Base Julia array to LogicalArray function (::Type{<:LogicalArray{A}})(arr::Array{B}) where {A,B} dims = Base.size(arr) - out = Legate.create_array(A, dims) + out = Legate.create_array(collect(Int64, dims), A) attached = Legate.attach_external(arr) copyto!(out, attached) return out @@ -86,7 +86,7 @@ end function (::Type{<:LogicalArray})(arr::Array{B}) where {B} dims = Base.size(arr) - out = Legate.create_array(B, dims) + out = Legate.create_array(collect(Int64, dims), B) attached = Legate.attach_external(arr) copyto!(out, attached) return out diff --git a/test/Project.toml b/test/Project.toml index 92aa2989..63f2137a 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,5 +1,7 @@ [deps] CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" +HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" +Legate = "1238f2cf-6593-4d60-9aca-2f5364e49909" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [extras] diff --git a/test/runtests.jl b/test/runtests.jl index df4ef3d1..faafbdca 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,6 @@ using Legate using Test +using HDF5 const VERBOSE = get(ENV, "VERBOSE", "1") != "0" const run_gpu_tests = (get(ENV, "GPUTESTS", "1") != "0") && (get(ENV, "NO_CUDA", "OFF") != "ON") @@ -15,6 +16,8 @@ if run_gpu_tests end end +include("tests/hdf5.jl") + # include("tests/tasking.jl") # if run_gpu_tests # include("tests/tasking_gpu.jl") diff --git a/test/tests/hdf5.jl b/test/tests/hdf5.jl new file mode 100644 index 00000000..3b86f562 --- /dev/null +++ b/test/tests/hdf5.jl @@ -0,0 +1,73 @@ +using HDF5 + +# Write a Julia array to HDF5 using HDF5.jl, read it back with Legate, and compare. +function test_hdf5_read(T::Type, shape::Tuple) + path = tempname() * ".h5" + dataset = "data" + original = rand(T, shape) + + h5open(path, "w") do f + write(f, dataset, original) + end + + legate_arr = Legate.read_hdf5(path, dataset) + result = Array(legate_arr) + + rm(path; force=true) + return result == original +end + +# Write a LogicalArray with Legate.write_hdf5, read it back with HDF5.jl, and compare. +function test_hdf5_write(T::Type, shape::Tuple) + path = tempname() * ".h5" + dataset = "data" + original = rand(T, shape...) + + legate_arr = Legate.LogicalArray(original) + Legate.write_hdf5(legate_arr, path, dataset) + Legate.runtime_sync() + + result = h5open(path, "r") do f + read(f, dataset) + end + + rm(path; force=true) + return result == original +end + +# Write with Legate, read back with Legate (roundtrip). +function test_hdf5_roundtrip(T::Type, shape::Tuple) + path = tempname() * ".h5" + dataset = "data" + original = rand(T, shape...) + + legate_arr = Legate.LogicalArray(original) + Legate.write_hdf5(legate_arr, path, dataset) + Legate.runtime_sync() + + result_arr = Legate.read_hdf5(path, dataset) + result = Array(result_arr) + + rm(path; force=true) + return result == original +end + +@testset verbose = true "HDF5 Interoperability" begin + for T in Base.uniontypes(Legate.SUPPORTED_NUMERIC_TYPES) + @testset "Type: $T" begin + for shape in [(10,), (4, 5), (3, 4, 5)] + @testset "Shape: $shape" begin + @testset "HDF5.jl write → Legate read" begin + @test test_hdf5_read(T, shape) + end + @testset "Legate write → HDF5.jl read" begin + @test test_hdf5_write(T, shape) + end + @testset "Legate roundtrip" begin + @test test_hdf5_roundtrip(T, shape) + end + end + end + end + end +end From d0f78243ef7556b21f10d093f8e8d204bb1ea69d Mon Sep 17 00:00:00 2001 From: krasow Date: Mon, 18 May 2026 12:01:19 -0500 Subject: [PATCH 08/10] address naming and argument ordering to mimic HDF5.jl --- src/api/data.jl | 22 +++++++++++----------- src/api/runtime.jl | 2 +- test/tests/hdf5.jl | 10 +++++----- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/api/data.jl b/src/api/data.jl index 1f5b2e09..babfa596 100644 --- a/src/api/data.jl +++ b/src/api/data.jl @@ -286,16 +286,16 @@ function get_ptr(arr::PhysicalStore) end """ - read_h5(path::String, dataset::String) -> LogicalArray + h5read(path::String, name::String) -> LogicalArray Read a dataset from an HDF5 file into a LogicalArray. # Arguments - `path`: Path to the HDF5 file. -- `dataset`: Name of the dataset to read. +- `name`: Name of the dataset to read. """ -function read_hdf5(path::String, dataset::String) - impl = read_h5(path, dataset) # cxxwrap call +function h5read(path::String, name::String) + impl = read_h5(path, name) # cxxwrap call ndim = Int(dim(impl)) shp_h5 = Tuple(Int.(shape(impl))) # HDF5 stores in C (row-major) order; Julia is column-major. @@ -306,25 +306,25 @@ function read_hdf5(path::String, dataset::String) end """ - write_h5(array::LogicalArray, path::String, dataset::String) + h5write(path::String, name::String, array::LogicalArray) Write a LogicalArray to a dataset in an HDF5 file. # Arguments -- `array`: The array to write. - `path`: Path to the HDF5 file. -- `dataset`: Name of the dataset to write. +- `name`: Name of the dataset to write. +- `array`: The array to write. """ -function write_hdf5(array::LogicalArray{T,1}, path::String, dataset::String) where {T} - write_h5(array.handle, path, dataset) +function h5write(path::String, name::String, array::LogicalArray{T,1}) where {T} + write_h5(array.handle, path, name) end # HDF5.jl bridges Julia's column-major and HDF5's C-order by reversing dimensions # while keeping the raw bytes unchanged. We do the same: reshape the Julia array # to the reversed shape (same bytes, different interpretation) before handing it # to Legate's write_h5 so the on-disk shape matches what HDF5.jl expects. -function write_hdf5(array::LogicalArray{T,N}, path::String, dataset::String) where {T,N} +function h5write(path::String, name::String, array::LogicalArray{T,N}) where {T,N} arr = Array{T,N}(array) la_rev = LogicalArray(reshape(arr, reverse(size(arr)))) - write_h5(la_rev.handle, path, dataset) + write_h5(la_rev.handle, path, name) end diff --git a/src/api/runtime.jl b/src/api/runtime.jl index 6da0924d..48bc43cd 100644 --- a/src/api/runtime.jl +++ b/src/api/runtime.jl @@ -45,7 +45,7 @@ has_finished Block until all pending Legate tasks have completed. -Useful before reading files written by `write_hdf5` or other async operations. +Useful before reading files written by `h5write` or other async operations. """ runtime_sync diff --git a/test/tests/hdf5.jl b/test/tests/hdf5.jl index 3b86f562..65f13bca 100644 --- a/test/tests/hdf5.jl +++ b/test/tests/hdf5.jl @@ -10,21 +10,21 @@ function test_hdf5_read(T::Type, shape::Tuple) write(f, dataset, original) end - legate_arr = Legate.read_hdf5(path, dataset) + legate_arr = Legate.h5read(path, dataset) result = Array(legate_arr) rm(path; force=true) return result == original end -# Write a LogicalArray with Legate.write_hdf5, read it back with HDF5.jl, and compare. +# Write a LogicalArray with Legate.h5write, read it back with HDF5.jl, and compare. function test_hdf5_write(T::Type, shape::Tuple) path = tempname() * ".h5" dataset = "data" original = rand(T, shape...) legate_arr = Legate.LogicalArray(original) - Legate.write_hdf5(legate_arr, path, dataset) + Legate.h5write(path, dataset, legate_arr) Legate.runtime_sync() result = h5open(path, "r") do f @@ -42,10 +42,10 @@ function test_hdf5_roundtrip(T::Type, shape::Tuple) original = rand(T, shape...) legate_arr = Legate.LogicalArray(original) - Legate.write_hdf5(legate_arr, path, dataset) + Legate.h5write(path, dataset, legate_arr) Legate.runtime_sync() - result_arr = Legate.read_hdf5(path, dataset) + result_arr = Legate.h5read(path, dataset) result = Array(result_arr) rm(path; force=true) From edb2365c8c9c6fbec897a2cbf3c32f53f257fe09 Mon Sep 17 00:00:00 2001 From: krasow Date: Mon, 18 May 2026 12:05:46 -0500 Subject: [PATCH 09/10] update comment --- src/api/data.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/api/data.jl b/src/api/data.jl index babfa596..fdf70d2b 100644 --- a/src/api/data.jl +++ b/src/api/data.jl @@ -319,10 +319,8 @@ function h5write(path::String, name::String, array::LogicalArray{T,1}) where {T} write_h5(array.handle, path, name) end -# HDF5.jl bridges Julia's column-major and HDF5's C-order by reversing dimensions -# while keeping the raw bytes unchanged. We do the same: reshape the Julia array -# to the reversed shape (same bytes, different interpretation) before handing it -# to Legate's write_h5 so the on-disk shape matches what HDF5.jl expects. +# mimic HDF5.jl ordering. Julia -> column-major && HDF5 -> c-order +# reshape Legate array keeping bytes same function h5write(path::String, name::String, array::LogicalArray{T,N}) where {T,N} arr = Array{T,N}(array) la_rev = LogicalArray(reshape(arr, reverse(size(arr)))) From 5cd818c88c22e0d42d1e2707b21e4842da65aca4 Mon Sep 17 00:00:00 2001 From: krasow Date: Mon, 18 May 2026 12:13:04 -0500 Subject: [PATCH 10/10] clean up global name space --- lib/legate_jl_wrapper/src/module.cpp | 4 ++-- src/api/data.jl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/legate_jl_wrapper/src/module.cpp b/lib/legate_jl_wrapper/src/module.cpp index 042527b1..d405387a 100644 --- a/lib/legate_jl_wrapper/src/module.cpp +++ b/lib/legate_jl_wrapper/src/module.cpp @@ -242,8 +242,8 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& mod) { mod.method("time_nanoseconds", &legate_wrapper::time::time_nanoseconds); /* hdf5 */ - mod.method("read_h5", &legate_wrapper::hdf5::read_h5); - mod.method("write_h5", &legate_wrapper::hdf5::write_h5); + mod.method("_read_h5", &legate_wrapper::hdf5::read_h5); + mod.method("_write_h5", &legate_wrapper::hdf5::write_h5); wrap_ufi(mod); } diff --git a/src/api/data.jl b/src/api/data.jl index fdf70d2b..f26ef42b 100644 --- a/src/api/data.jl +++ b/src/api/data.jl @@ -295,7 +295,7 @@ Read a dataset from an HDF5 file into a LogicalArray. - `name`: Name of the dataset to read. """ function h5read(path::String, name::String) - impl = read_h5(path, name) # cxxwrap call + impl = _read_h5(path, name) # cxxwrap call ndim = Int(dim(impl)) shp_h5 = Tuple(Int.(shape(impl))) # HDF5 stores in C (row-major) order; Julia is column-major. @@ -316,7 +316,7 @@ Write a LogicalArray to a dataset in an HDF5 file. - `array`: The array to write. """ function h5write(path::String, name::String, array::LogicalArray{T,1}) where {T} - write_h5(array.handle, path, name) + _write_h5(array.handle, path, name) end # mimic HDF5.jl ordering. Julia -> column-major && HDF5 -> c-order @@ -324,5 +324,5 @@ end function h5write(path::String, name::String, array::LogicalArray{T,N}) where {T,N} arr = Array{T,N}(array) la_rev = LogicalArray(reshape(arr, reverse(size(arr)))) - write_h5(la_rev.handle, path, name) + _write_h5(la_rev.handle, path, name) end