-
Notifications
You must be signed in to change notification settings - Fork 15
Avoid dynamic allocation with H5Sselect_hyperslab
#101
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -229,18 +229,18 @@ inline Selection SliceTraits<Derivate>::select(const HyperSlab& hyper_slab, | |
| } | ||
|
|
||
| template <typename Derivate> | ||
| inline Selection SliceTraits<Derivate>::select(const HyperSlab& hyper_slab) const { | ||
| template <typename Impl> | ||
| inline Selection SliceTraits<Derivate>::select(const HyperSlabInterface<Impl>& hyper_slab) const { | ||
| const auto& slice = static_cast<const Derivate&>(*this); | ||
| auto filespace = slice.getSpace(); | ||
| filespace = hyper_slab.apply(filespace); | ||
|
|
||
| auto n_elements = detail::h5s_get_select_npoints(filespace.getId()); | ||
| auto memspace = DataSpace(std::array<size_t, 1>{size_t(n_elements)}); | ||
| const auto n_elements = detail::h5s_get_select_npoints(filespace.getId()); | ||
| auto memspace = DataSpace{static_cast<size_t>(n_elements)}; | ||
|
|
||
| return detail::make_selection(memspace, filespace, details::get_dataset(slice)); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As you might have noticed I'm not so keen on having both a statically sized version and fixed-sized version. Especially, because it's currently not done for performance reasons and HighFive is very consistent about using Now for the good news: we could use SFINAE for @antonysigma Would this work for you? The SFINAE part isn't strictly needed, in a first version an unconstrained template parameter would suffice. That way if you don't feel like fighting SFINAE, I can take care of it later.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Re: moving Re: SFINAE for
Yes, help wanted to tighten the constraints eventually.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll first try with |
||
|
|
||
|
|
||
| template <typename Derivate> | ||
| inline Selection SliceTraits<Derivate>::select(const std::vector<size_t>& offset, | ||
| const std::vector<size_t>& count, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| /* | ||
| * Copyright (c), 2025, Antony Chan | ||
| * | ||
| * Distributed under the Boost Software License, Version 1.0. | ||
| * (See accompanying file LICENSE_1_0.txt or copy at | ||
| * http://www.boost.org/LICENSE_1_0.txt) | ||
| * | ||
| */ | ||
| #include <functional> | ||
| #include <iostream> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| #include <highfive/highfive.hpp> | ||
|
|
||
| namespace { | ||
| template <size_t Rank> | ||
| struct RegularHyperSlabNoMalloc | ||
| : public HighFive::HyperSlabInterface<RegularHyperSlabNoMalloc<Rank>> { | ||
| RegularHyperSlabNoMalloc(const std::array<hsize_t, Rank>& offset_, | ||
| const std::array<hsize_t, Rank>& count_) | ||
| : offset(offset_) | ||
| , count(count_) {} | ||
|
|
||
| HighFive::DataSpace apply(const HighFive::DataSpace& space_) const { | ||
| auto space = space_.clone(); | ||
| const auto error_code = H5Sselect_hyperslab( | ||
| space.getId(), H5S_SELECT_SET, offset.data(), nullptr, count.data(), nullptr); | ||
|
|
||
| if (error_code < 0) { | ||
| HighFive::HDF5ErrMapper::ToException<HighFive::DataSpaceException>( | ||
| "Unable to select hyperslab"); | ||
| } | ||
| return space; | ||
| } | ||
|
|
||
| std::array<hsize_t, Rank> offset{}; | ||
| std::array<hsize_t, Rank> count{}; | ||
| }; | ||
| } // namespace | ||
|
|
||
| int main(void) { | ||
| using namespace HighFive; | ||
|
|
||
| // Create a new file using the default property lists. | ||
| File file{"select_partial_example_no_alloc.h5", File::Truncate}; | ||
|
|
||
| // Example values in a 2x5 array. This might cause one allocation. | ||
| const std::vector<std::array<double, 5>> values{ | ||
| std::array<double, 5>{1.0, 2.0, 4.0, 8.0, 16.0}, | ||
| std::array<double, 5>{32.0, 64.0, 128.0, 256.0, 512.0}}; | ||
|
|
||
| // Might cause allocations in HDF5 and for std::string if "dset" is too long for | ||
| // short-string optimization. | ||
| DataSet dataset = file.createDataSet<double>("dset", DataSpace::From(values)); | ||
|
|
||
| // ------------------------------------------- | ||
| // From here on: no allocations are permitted. | ||
| dataset.write(values); | ||
|
|
||
| // Select the 2x2 values after an offset of 0x2. | ||
| std::array<std::array<double, 2>, 2> result; | ||
|
|
||
| // Specify the selection without any memory allocations. | ||
| dataset.select(RegularHyperSlabNoMalloc<2>{{0, 2}, {2, 2}}).read_raw(result.front().data()); | ||
|
|
||
| // Print out the 4 values. | ||
| for (auto i: result) { | ||
| for (auto j: i) { | ||
| std::cout << ' ' << j; | ||
| } | ||
| std::cout << '\n'; | ||
| } | ||
|
|
||
| return 0; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.