100 std::vector<std::size_t> dims;
104 auto shandle = group.openDataSet(
"shape");
105 auto sspace = shandle.getSpace();
106 if (sspace.getSimpleExtentNdims() != 1) {
107 throw std::runtime_error(
"'shape' dataset should be 1-dimensional");
110 sspace.getSimpleExtentDims(&len);
112 throw std::runtime_error(
"'shape' dataset should have length 2");
115 if (version.lt(1, 1, 0)) {
116 dims = load_non_negative_integer_vector_0_99<std::size_t>(shandle, 2);
118 if (ritsuko::hdf5::exceeds_integer_limit(shandle, 64,
false)) {
119 throw std::runtime_error(
"'shape' should have a datatype that can fit into a 64-bit unsigned integer");
121 dims = load_dimensions_from_uint64_contents<std::size_t>(shandle, 2);
127 auto dhandle = group.openDataSet(
"data");
128 auto dspace = dhandle.getSpace();
129 if (dspace.getSimpleExtentNdims() != 1) {
130 throw std::runtime_error(
"'data' dataset should be 1-dimensional");
132 dspace.getSimpleExtentDims(&nnz);
134 if (version.lt(1, 1, 0)) {
135 array_type = translate_type_0_99(dhandle.getTypeClass());
136 if (is_boolean_0_99(dhandle)) {
137 array_type = BOOLEAN;
140 auto type = load_scalar_string_attribute(dhandle,
"type");
141 array_type = translate_type_1_1(type);
143 check_type_1_1(dhandle, array_type);
148 if (array_type != INTEGER && array_type != BOOLEAN && array_type != FLOAT) {
149 throw std::runtime_error(
"dataset should be integer, float or boolean");
151 validate_missing_placeholder(dhandle, version);
157 if (!version.lt(1, 1, 0)) {
158 auto bhandle = group.openDataSet(
"by_column");
159 if (bhandle.getSpace().getSimpleExtentNdims() != 0) {
160 throw std::runtime_error(
"'by_column' dataset should be scalar");
162 if (ritsuko::hdf5::exceeds_integer_limit(bhandle, 8,
true)) {
163 throw std::runtime_error(
"datatype of the 'by_column' dataset should fit into an 8-bit signed integer");
166 bhandle.read(&val, H5::PredType::NATIVE_INT8);
170 const auto primary = (csc ? dims[1] : dims[0]);
171 const auto secondary = (csc ? dims[0] : dims[1]);
173 std::vector<std::uint64_t> indptrs;
175 auto iphandle = group.openDataSet(
"indptr");
176 auto ipspace = iphandle.getSpace();
177 if (ipspace.getSimpleExtentNdims() != 1) {
178 throw std::runtime_error(
"'indptr' dataset should be 1-dimensional");
181 ipspace.getSimpleExtentDims(&iplen);
184 throw std::runtime_error(
"'indptr' should have length equal to the number of " + (csc ? std::string(
"columns") : std::string(
"rows")) +
" plus 1");
187 if (version.lt(1, 1, 0)) {
188 if (iphandle.getTypeClass() != H5T_INTEGER) {
189 throw std::runtime_error(
"'indptr' should be integer");
191 indptrs = load_non_negative_integer_vector_0_99<std::uint64_t>(iphandle, iplen);
193 if (ritsuko::hdf5::exceeds_integer_limit(iphandle, 64,
false)) {
194 throw std::runtime_error(
"datatype of 'indptr' should fit into a 64-bit unsigned integer");
197 iphandle.read(indptrs.data(), H5::PredType::NATIVE_UINT64);
200 iphandle.read(indptrs.data(), H5::PredType::NATIVE_UINT64);
201 if (indptrs[0] != 0) {
202 throw std::runtime_error(
"first entry of 'indptr' should be 0");
205 throw std::runtime_error(
"last entry of 'indptr' should be equal to the length of 'data'");
210 auto ihandle = group.openDataSet(
"indices");
211 auto ispace = ihandle.getSpace();
212 if (ispace.getSimpleExtentNdims() != 1) {
213 throw std::runtime_error(
"'indices' dataset should be 1-dimensional");
216 ispace.getSimpleExtentDims(&inum);
218 throw std::runtime_error(
"'indices' and 'data' should have the same length");
221 if (version.lt(1, 1, 0)) {
222 if (!ritsuko::hdf5::exceeds_integer_limit(ihandle, 64,
true)) {
223 validate_sparse_indices<std::int64_t>(ihandle, indptrs, primary, secondary, csc, options.
contiguous_chunk_size);
224 }
else if (!ritsuko::hdf5::exceeds_integer_limit(ihandle, 64,
false)) {
225 validate_sparse_indices<std::uint64_t>(ihandle, indptrs, primary, secondary, csc, options.
contiguous_chunk_size);
227 throw std::runtime_error(
"'indices' should be integer");
231 if (ritsuko::hdf5::exceeds_integer_limit(ihandle, 64,
false)) {
232 throw std::runtime_error(
"datatype of 'indices' should fit into a 64-bit unsigned integer");
234 validate_sparse_indices<std::uint64_t>(ihandle, indptrs, primary, secondary, csc, options.
contiguous_chunk_size);
239 if (group.exists(
"dimnames")) {