H5Easy::dump() with xt::xarray results in failed static_assert
I am trying to dump an n-dimensional xt::xarray to an HDF file.
xt::xarray<double> arr({2, 2}, {1, 2, 3, 4});
H5Easy::dump(file, "myDataset", arr);
This results in:
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Inspector_misc.hpp(194): error C2338: static_assert failed: 'The type is not trivially copyable'
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Inspector_misc.hpp(194): note: the template instantiation context (the oldest one first) is
%{srcPath}Interpolation\Interpolant.cpp(375): note: see reference to function template instantiation 'HighFive::DataSet H5Easy::dump<xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>>(HighFive::File &,const std::string &,const T &,H5Easy::DumpMode)' being compiled
with
[
T=xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>
]
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\h5easy_bits/H5Easy_public.hpp(100): note: see reference to class template instantiation 'H5Easy::detail::io_impl<xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>,void>' being compiled
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\h5easy_bits\H5Easy_scalar.hpp(24): note: while compiling class template member function 'HighFive::DataSet H5Easy::detail::io_impl<xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>,void>::dump(HighFive::File &,const std::string &,const T &,const H5Easy::DumpOptions &)'
with
[
T=xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>
]
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\h5easy_bits/H5Easy_public.hpp(100): note: see the first reference to 'H5Easy::detail::io_impl<xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>,void>::dump' in 'H5Easy::dump'
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\h5easy_bits\H5Easy_scalar.hpp(28): note: see reference to function template instantiation 'HighFive::DataSet H5Easy::detail::initScalarDataset<T>(HighFive::File &,const std::string &,const T &,const H5Easy::DumpOptions &)' being compiled
with
[
T=xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>
]
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\h5easy_bits\H5Easy_misc.hpp(83): note: while compiling class template member function 'HighFive::DataSet HighFive::NodeTraits<HighFive::File>::createDataSet(const std::string &,const HighFive::DataSpace &,const HighFive::DataSetCreateProps &,const HighFive::DataSetAccessProps &,bool)'
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\h5easy_bits\H5Easy_misc.hpp(83): note: while processing the default template argument of 'HighFive::DataSet HighFive::NodeTraits<HighFive::File>::createDataSet(const std::string &,const HighFive::DataSpace &,const HighFive::DataSetCreateProps &,const HighFive::DataSetAccessProps &,bool)'
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\bits/H5Node_traits.hpp(69): note: see reference to class template instantiation 'HighFive::details::inspector<T>' being compiled
with
[
T=xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>
]
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Inspector_misc.hpp(207): note: see reference to class template instantiation 'HighFive::details::type_helper<T>' being compiled
with
[
T=xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>
]
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Inspector_misc.hpp(193): note: while compiling class template member function 'void HighFive::details::type_helper<T>::serialize(const xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag> &,xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag> *)'
with
[
T=xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>
]
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Converter_misc.hpp(355): note: see the first reference to 'HighFive::details::type_helper<T>::serialize' in 'HighFive::details::Writer<T,void>::Writer'
with
[
T=xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>
]
%{buildPath}vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Converter_misc.hpp(406): note: see the first reference to 'HighFive::details::Writer<T,void>::Writer' in 'HighFive::details::data_converter::serialize'
with
[
T=xt::xarray_container<xt::uvector<double,std::allocator<double>>,xt::layout_type::row_major,xt::svector<size_t,4,std::allocator<size_t>,true>,xt::xtensor_expression_tag>
]
Version Information
- Compiler: MSVC
I am now getting this same error when trying to create a dataset from a dataspace.
HighFive::DataSpace ds({2, 2});
auto set = file.createDataSet("myData", ds);
${bld}\vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Inspector_misc.hpp(194): error C2338: static_assert failed: 'The type is not trivially copyable'
${bld}\vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Inspector_misc.hpp(194): note: the template instantiation context (the oldest one first) is
${src}\Interpolation\Interpolant.cpp(376): note: see reference to function template instantiation 'HighFive::DataSet HighFive::NodeTraits<HighFive::File>::createDataSet<HighFive::DataSpace>(const std::string &,const T &,const HighFive::DataSetCreateProps &,const HighFive::DataSetAccessProps &,bool)' being compiled
with
[
T=HighFive::DataSpace
]
${src}\Interpolation\Interpolant.cpp(376): note: see the first reference to 'HighFive::NodeTraits<HighFive::File>::createDataSet' in '`anonymous-namespace'::buildInterpolator'
${bld}\vcpkg_installed\x64-windows-digilens\include\highfive\bits/H5Node_traits_misc.hpp(96): note: see reference to class template instantiation 'HighFive::details::inspector<HighFive::DataSpace>' being compiled
${bld}\vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Inspector_misc.hpp(207): note: see reference to class template instantiation 'HighFive::details::type_helper<T>' being compiled
with
[
T=HighFive::DataSpace
]
${bld}\vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Inspector_misc.hpp(193): note: while compiling class template member function 'void HighFive::details::type_helper<T>::serialize(const HighFive::DataSpace &,HighFive::DataSpace *)'
with
[
T=HighFive::DataSpace
]
${bld}\vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Converter_misc.hpp(355): note: see the first reference to 'HighFive::details::type_helper<T>::serialize' in 'HighFive::details::Writer<T,void>::Writer'
with
[
T=HighFive::DataSpace
]
${bld}\vcpkg_installed\x64-windows-digilens\include\highfive\bits\H5Converter_misc.hpp(406): note: see the first reference to 'HighFive::details::Writer<T,void>::Writer' in 'HighFive::details::data_converter::serialize'
with
[
T=HighFive::DataSpace
]
ninja: build stopped: subcommand failed.
I tried with the pre-release for 3.0 using the following file:
$ cat issue-1045.cpp
#include <xtensor/xtensor.hpp>
#include <highfive/H5Easy.hpp>
int main() {
xt::xarray<double> array({2, 2}, {1, 2, 3, 4});
auto file = HighFive::File("foo.h5", HighFive::File::Truncate);
H5Easy::dump(file, "foo", array);
return 0;
}
and then compiled it using:
g++ -g -I $(spack location --install-dir xtensor)/include -I$(spack location --install-dir xtl)/include -I include issue-1045.cpp -o issue-1045 -lhdf5
(The spack commands can be replaced with the location of the xtensor libraries; and -I include is the path to HighFive.) The above compiles, and then fails with the following error:
$ ./issue-1045
terminate called after throwing an instance of 'std::runtime_error'
what(): Cannot resize with custom strides when layout() is != layout_type::dynamic.
[1] 4143 IOT instruction (core dumped) ./issue-1045
which is thrown from the ctor of xt::array:
...
#7 0x0000555555556222 in xt::xstrided_container<xt::xarray_container<xt::uvector<double, std::allocator<double> >, (xt::layout_type)1, xt::svector<unsigned long, 4ul, std::allocator<unsigned long>, true>, xt::xtensor_expression_tag> >::resize<xt::svector<unsigned long, 4ul, std::allocator<unsigned long>, true> const&> (this=0x7fffffffd4a0, shape=..., strides=...) ...
#8 0x00005555555559c8 in xt::xarray_container<xt::uvector<double, std::allocator<double> >, (xt::layout_type)1, xt::svector<unsigned long, 4ul, std::allocator<unsigned long>, true>, xt::xtensor_expression_tag>::xarray_container (this=0x7fffffffd4a0, shape=..., strides=...)
#9 0x00005555555552bc in main () at issue-1045.cpp:9
(likely xt::xarray<double> array({2, 2}, {1, 2, 3, 4}); doesn't do what you expect it to.)
A slight variation works:
xt::xarray<double> array = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
Here's a complete example that uses HighFive core (without Easy):
#include <highfive/highfive.hpp>
#include <highfive/xtensor.hpp>
int main() {
xt::xarray<double> array = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
auto file = HighFive::File("foo.h5", HighFive::File::Truncate);
file.createDataSet("foo", array);
return 0;
}
which creates:
$ h5dump foo.h5
HDF5 "foo.h5" {
GROUP "/" {
DATASET "foo" {
DATATYPE H5T_IEEE_F64LE
DATASPACE SIMPLE { ( 3, 2 ) / ( 3, 2 ) }
DATA {
(0,0): 1, 2,
(1,0): 3, 4,
(2,0): 5, 6
}
}
}
}
What I am running into is a compile-time error (a static_assert), so no matter how I initialize the xt::xarray it won't matter, HighFive is refusing to accept it as an argument to createDataSet. This appears to be because std::is_trivially_copyable_v<xt::xarray> is false.
Can't be reproduced on recent versions of HighFive; and since there's no details w.r.t. versions of the involved libraries there's nothing we can do.
Windows CI includes XTensor and when checking the logs of the most recent run we find it ran: https://github.com/BlueBrain/HighFive/actions/runs/10470198213/job/28994831492#step:5:1078