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
23 changes: 23 additions & 0 deletions src/h5cpp/dataspace/hyperslab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,29 @@ void Hyperslab::apply(const Dataspace &space, SelectionOperation ops) const {
}
}

SelectionType Hyperslab::type() const {
return SelectionType::Hyperslab;
}

size_t Hyperslab::size() const {
if(rank() == 0)
return 0;
size_t size = 1ul;
Dimensions dims = block();
Dimensions cnt = count();
for(Dimensions::size_type i = 0; i != dims.size(); i++)
size *= dims[i] * cnt[i];
return size;
}

Dimensions Hyperslab::dimensions() const {
Dimensions dims = block();
Dimensions cnt = count();
for(Dimensions::size_type i = 0; i != dims.size(); i++)
dims[i] *= cnt[i];
return dims;
}

Dataspace operator||(const Dataspace &space, const Hyperslab &selection) {
Dataspace new_space(space);
new_space.selection(SelectionOperation::Set, selection);
Expand Down
32 changes: 32 additions & 0 deletions src/h5cpp/dataspace/hyperslab.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,38 @@ class DLL_EXPORT Hyperslab : public Selection {
virtual void apply(const Dataspace &space,
SelectionOperation ops) const override;

//!
//! \brief get current dimensions
//!
//! Get a number of elements along each dimension a selection spans
//! this is particularly useful in the case of a Hyperslab
//!
//! \throws std::runtime_error in case of a failure
//!
//! \return the selection dimentsions
//!
virtual Dimensions dimensions() const override;

//!
//! \brief get the selection size
//!
//! Get the total number of elements adressed by an individual selection
//!
//! \throws std::runtime_error in case of a failure
//!
//! \return the selection type enumerator
//!
virtual size_t size() const override;

//!
//! \brief get the selection type
//!
//! Get the type of the selection
//!
//! \return the selection type enumerator
//!
virtual SelectionType type() const override;

private:
inline void check_dimension_index(size_t index, const std::string &what) const {
if (index >= rank()) {
Expand Down
23 changes: 23 additions & 0 deletions src/h5cpp/dataspace/points.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <h5cpp/dataspace/points.hpp>
#include <h5cpp/error/error.hpp>
#include <sstream>
#include <set>

namespace hdf5
{
Expand Down Expand Up @@ -88,5 +89,27 @@ void Points::apply(const Dataspace& space,

}

SelectionType Points::type() const {
return SelectionType::Points;
}

size_t Points::size() const {
return points();
}

Dimensions Points::dimensions() const {
size_t rnk = rank();
if(rnk == 0)
throw std::runtime_error("Cannot get coordinates for empty Points selection");
Dimensions dims(rnk);
std::vector<std::set<hsize_t>> uniqdim(rnk);

for(size_t j = 0; j != coordinates_.size(); j++)
uniqdim[j % rnk].insert(coordinates_[j]);
for(Dimensions::size_type i = 0; i != dims.size(); i++)
dims[i] = uniqdim[i].size();
return dims;
}

} // namespace dataspace
} // namespace hdf5
32 changes: 32 additions & 0 deletions src/h5cpp/dataspace/points.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,38 @@ class DLL_EXPORT Points : public Selection
//!
void apply (const Dataspace &space, SelectionOperation ops) const override;

//!
//! \brief get the selection size
//!
//! Get the total number of elements adressed by an individual selection
//!
//! \throws std::runtime_error in case of a failure
//!
//! \return the selection type enumerator
//!
virtual size_t size() const override;

//!
//! \brief get the selection type
//!
//! Get the type of the selection
//!
//! \return the selection type enumerator
//!
virtual SelectionType type() const override;

//!
//! \brief get current dimensions
//!
//! Get a number of elements along each dimension a selection spans
//! this is particularly useful in the case of a Hyperslab
//!
//! \throws std::runtime_error in case of a failure
//!
//! \return the selection dimentsions
//!
virtual Dimensions dimensions() const override;

private:
size_t rank_{ 0 };
#ifdef _MSC_VER
Expand Down
31 changes: 31 additions & 0 deletions src/h5cpp/dataspace/selection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,37 @@ class DLL_EXPORT Selection {
//! \param ops operator for the selection
virtual void apply(const Dataspace &space,
SelectionOperation ops) const = 0;
//!
//! \brief get current dimensions
//!
//! Get a number of elements along each dimension a selection spans
//! this is particularly useful in the case of a Hyperslab
//!
//! \throws std::runtime_error in case of a failure
//!
//! \return the selection dimentsions
//!
virtual Dimensions dimensions() const = 0;

//!
//! \brief get the selection size
//!
//! Get the total number of elements adressed by an individual selection
//!
//! \throws std::runtime_error in case of a failure
//!
//! \return the selection type enumerator
//!
virtual size_t size() const = 0;

//!
//! \brief get the selection type
//!
//! Get the type of the selection
//!
//! \return the selection type enumerator
//!
virtual SelectionType type() const = 0;
};

struct OperationWithSelection {
Expand Down
48 changes: 19 additions & 29 deletions src/h5cpp/node/dataset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1078,15 +1078,12 @@ void Dataset::read_reshape(T &data,
{
dataspace::Dataspace file_space = dataspace();
file_space.selection(dataspace::SelectionOperation::Set,selection);
if (selection.type() != dataspace::SelectionType::Hyperslab)
return read(data,mem_type,mem_space,file_space,dtpl);
try{
const dataspace::Hyperslab & hyper = dynamic_cast<const dataspace::Hyperslab &>(selection);
auto dims = hyper.block();
if(dims.size() > 1) {
auto count = hyper.count();
for(Dimensions::size_type i = 0; i != dims.size(); i++)
dims[i] *= count[i];

dataspace::Simple selected_space(dims);
if(hyper.rank() > 1) {
dataspace::Simple selected_space(hyper.dimensions());
if (selected_space.size() == mem_space.size()) {
// reads to the reshaped memory data buffer
return read(data,mem_type,selected_space,file_space,dtpl);
Expand Down Expand Up @@ -1147,31 +1144,24 @@ void Dataset::write_reshape(const T &data,
{
dataspace::Dataspace file_space = dataspace();
file_space.selection(dataspace::SelectionOperation::Set,selection);
if (mem_space.type() != dataspace::Type::Simple) {
write(data,mem_type,mem_space,file_space,dtpl);
}
else{
try{
const dataspace::Hyperslab & hyper = dynamic_cast<const dataspace::Hyperslab &>(selection);
auto dims = hyper.block();
if(dims.size() > 1) {
const dataspace::Simple & mem_simple_space = dataspace::Simple(mem_space);
auto count = hyper.count();
for(Dimensions::size_type i = 0; i != dims.size(); i++)
dims[i] *= count[i];

dataspace::Simple selected_space(dims);
if(selected_space.rank() > 1 &&
mem_simple_space.rank() == 1 &&
selected_space.size() == mem_space.size()) {
// writes from the reshaped memory data buffer
return write(data,mem_type,selected_space,file_space,dtpl);
}
if (mem_space.type() != dataspace::Type::Simple
|| selection.type() != dataspace::SelectionType::Hyperslab)
return write(data,mem_type,mem_space,file_space,dtpl);
try{
const dataspace::Hyperslab & hyper = dynamic_cast<const dataspace::Hyperslab &>(selection);
if(hyper.rank() > 1) {
const dataspace::Simple & mem_simple_space = dataspace::Simple(mem_space);
dataspace::Simple selected_space(hyper.dimensions());
if(selected_space.rank() > 1 &&
mem_simple_space.rank() == 1 &&
selected_space.size() == mem_space.size()) {
// writes from the reshaped memory data buffer
return write(data,mem_type,selected_space,file_space,dtpl);
}
}
catch(const std::bad_cast&) { }
write(data,mem_type,mem_space,file_space,dtpl);
}
catch(const std::bad_cast&) { }
write(data,mem_type,mem_space,file_space,dtpl);
}


Expand Down
47 changes: 45 additions & 2 deletions test/dataspace/hyperslab_simple_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ SCENARIO("Hyperslab construction") {
GIVEN("a default constructed hyperslab") {
dataspace::Hyperslab h;
THEN("the rank would be 0") { REQUIRE(h.rank() == 0ul); }
THEN("the size must be 0") { REQUIRE(h.size() == 0ul); }
THEN("the type must be Hyperslab") {
REQUIRE(h.type() == hdf5::dataspace::SelectionType::Hyperslab);
}
THEN("dimensions access must fail") {
REQUIRE_THROWS_AS(h.dimensions(), std::runtime_error);
}
THEN("offset access must fail") {
REQUIRE_THROWS_AS(h.offset(), std::runtime_error);
}
Expand All @@ -53,15 +60,27 @@ SCENARIO("Hyperslab construction") {
GIVEN("a hyperslab constructed from the number of dimensions") {
dataspace::Hyperslab hyperslab(2);
THEN("the rank must be 2") { REQUIRE(hyperslab.rank() == 2ul); }
THEN("the size must be 0") { REQUIRE(hyperslab.size() == 0ul); }
THEN("the type must be Hyperslab") {
REQUIRE(hyperslab.type() == hdf5::dataspace::SelectionType::Hyperslab);
}
THEN("dimensions access be 0") {
REQUIRE_THAT(hyperslab.dimensions(),
Catch::Matchers::Equals(Dimensions{0, 0}));
}
THEN("all offset must be 0") {
REQUIRE_THAT(hyperslab.offset(),
Catch::Matchers::Equals(Dimensions{0, 0}));
}
THEN("all strides must be 1") {
REQUIRE_THAT(hyperslab.stride(),
Catch::Matchers::Equals(Dimensions{1, 1}));
}
THEN("all counts must be 1") {
THEN("all counts must be 0") {
REQUIRE_THAT(hyperslab.count(),
Catch::Matchers::Equals(Dimensions{0, 0}));
}
THEN("all blocks must be 1") {
THEN("all blocks must be 0") {
REQUIRE_THAT(hyperslab.block(),
Catch::Matchers::Equals(Dimensions{0, 0}));
}
Expand All @@ -74,6 +93,14 @@ SCENARIO("Hyperslab construction") {
THEN("a hyperslab can be constructed") {
dataspace::Hyperslab h(offset, block);
AND_THEN("the rank will be 2") { REQUIRE(h.rank() == 2); }
AND_THEN("the size must be 12") { REQUIRE(h.size() == 12ul); }
AND_THEN("the type must be Hyperslab") {
REQUIRE(h.type() == hdf5::dataspace::SelectionType::Hyperslab);
}
AND_THEN("dimensions access be {3,4}") {
REQUIRE_THAT(h.dimensions(),
Catch::Matchers::Equals(Dimensions{3, 4}));
}
AND_THEN("the offset will be {1,2}") {
REQUIRE_THAT(h.offset(), Catch::Matchers::Equals(Dimensions{1, 2}));
}
Expand All @@ -95,6 +122,14 @@ SCENARIO("Hyperslab construction") {
THEN("a hyperslab can be constructed") {
dataspace::Hyperslab h(offset, count, stride);
AND_THEN("the ranke will be 2") { REQUIRE(h.rank() == 2); }
AND_THEN("the size must be 12") { REQUIRE(h.size() == 12ul); }
AND_THEN("the type must be Hyperslab") {
REQUIRE(h.type() == hdf5::dataspace::SelectionType::Hyperslab);
}
AND_THEN("dimensions access be {3,4} ") {
REQUIRE_THAT(h.dimensions(),
Catch::Matchers::Equals(Dimensions{3, 4}));
}
AND_THEN("the offset will be {1,2}") {
REQUIRE_THAT(h.offset(), Catch::Matchers::Equals(Dimensions{1, 2}));
}
Expand All @@ -119,6 +154,14 @@ SCENARIO("Hyperslab construction") {
THEN("a hyperslab can be constructed with") {
dataspace::Hyperslab h(offset, block, count, stride);
AND_THEN("the rank will be 2") { REQUIRE(h.rank() == 2); }
AND_THEN("the size must be 360") { REQUIRE(h.size() == 360ul); }
AND_THEN("the type must be Hyperslab") {
REQUIRE(h.type() == hdf5::dataspace::SelectionType::Hyperslab);
}
AND_THEN("dimensions access be {15,24} ") {
REQUIRE_THAT(h.dimensions(),
Catch::Matchers::Equals(Dimensions{15, 24}));
}
AND_THEN("the offset will be {1,2}") {
REQUIRE_THAT(h.offset(),
Catch::Matchers::Equals(Dimensions{1, 2}));
Expand Down
23 changes: 23 additions & 0 deletions test/dataspace/points_simple_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,40 @@ SCENARIO("construction of point selections") {
GIVEN("a default constructed Points") {
dataspace::Points h;
THEN("the rank must be 0") { REQUIRE(h.rank() == 0); }
THEN("the size must be 0") { REQUIRE(h.size() == 0ul); }
THEN("the type must be Points") {
REQUIRE(h.type() == hdf5::dataspace::SelectionType::Points);
}
THEN("dimensions access must fail") {
REQUIRE_THROWS_AS(h.dimensions(), std::runtime_error);
}
}

GIVEN("a Point selection constructed for a rank 2") {
dataspace::Points h(2);
THEN("the rank must be 2") { REQUIRE(h.rank() == 2); }
THEN("the size must be 0") { REQUIRE(h.size() == 0ul); }
THEN("the type must be Points") {
REQUIRE(h.type() == hdf5::dataspace::SelectionType::Points);
}
THEN("dimensions access be 0") {
REQUIRE_THAT(h.dimensions(),
Catch::Matchers::Equals(Dimensions{0, 0}));
}
}

GIVEN("a Point selection constructed from a list of points") {
dataspace::Points points({{1, 1}, {2, 2}});
THEN("the rank must be 2") { REQUIRE(points.rank() == 2u); }
THEN("the number of points must be 2") { REQUIRE(points.points() == 2u); }
THEN("the size must be 2") { REQUIRE(points.size() == 2ul); }
THEN("the type must be Points") {
REQUIRE(points.type() == hdf5::dataspace::SelectionType::Points);
}
THEN("dimensions access be {2,2}") {
REQUIRE_THAT(points.dimensions(),
Catch::Matchers::Equals(Dimensions{2, 2}));
}
}

GIVEN("a list of points of different rank") {
Expand Down