1#ifndef TATAMI_HDF5_DENSE_MATRIX_HPP
2#define TATAMI_HDF5_DENSE_MATRIX_HPP
13#include "tatami_chunked/tatami_chunked.hpp"
49namespace DenseMatrix_internal {
55 H5::DataSpace dataspace;
56 H5::DataSpace memspace;
59template<
typename Index_,
typename OutputValue_>
60void extract_block(
bool h5_row_is_target, Index_ cache_start, Index_ cache_length, Index_ block_start, Index_ block_length, OutputValue_* buffer, Components& comp) {
64 int target_dim = 1 - h5_row_is_target;
65 offset[target_dim] = cache_start;
66 count[target_dim] = cache_length;
68 int non_target_dim = h5_row_is_target;
69 offset[non_target_dim] = block_start;
70 count[non_target_dim] = block_length;
71 comp.dataspace.selectHyperslab(H5S_SELECT_SET, count, offset);
75 comp.memspace.setExtentSimple(2, count);
76 comp.memspace.selectAll();
78 comp.dataset.read(buffer, define_mem_type<OutputValue_>(), comp.memspace, comp.dataspace);
81template<
typename Index_,
typename OutputValue_>
82void extract_indices(
bool h5_row_is_target, Index_ cache_start, Index_ cache_length,
const std::vector<Index_>& indices, OutputValue_* buffer, Components& comp) {
86 int target_dim = 1 - h5_row_is_target;
87 offset[target_dim] = cache_start;
88 count[target_dim] = cache_length;
90 int non_target_dim = h5_row_is_target;
95 comp.dataspace.selectNone();
99 [&](Index_ start, Index_ length) ->
void {
100 offset[non_target_dim] = start;
101 count[non_target_dim] = length;
102 comp.dataspace.selectHyperslab(H5S_SELECT_OR, count, offset);
107 count[non_target_dim] = indices.size();
108 comp.memspace.setExtentSimple(2, count);
109 comp.memspace.selectAll();
111 comp.dataset.read(buffer, define_mem_type<OutputValue_>(), comp.memspace, comp.dataspace);
121inline void initialize(
const std::string& file_name,
const std::string& dataset_name, std::unique_ptr<Components>& h5comp) {
123 h5comp.reset(
new Components);
129 H5::FileAccPropList fapl(H5::FileAccPropList::DEFAULT.getId());
130 fapl.setCache(0, 0, 0, 0);
132 h5comp->file.openFile(file_name, H5F_ACC_RDONLY, fapl);
133 h5comp->dataset = h5comp->file.openDataSet(dataset_name);
134 h5comp->dataspace = h5comp->dataset.getSpace();
138inline void destroy(std::unique_ptr<Components>& h5comp) {
144template<
bool oracle_,
bool by_h5_row_,
typename Index_>
148 const std::string& file_name,
149 const std::string& dataset_name,
150 [[maybe_unused]] tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
152 [[maybe_unused]]
const tatami_chunked::SlabCacheStats& slab_stats) :
153 my_oracle(std::move(oracle))
155 initialize(file_name, dataset_name, my_h5comp);
163 std::unique_ptr<Components> my_h5comp;
165 typename std::conditional<oracle_, size_t, bool>::type my_counter = 0;
168 template<
typename Value_>
169 const Value_* fetch_block(Index_ i, Index_ block_start, Index_ block_length, Value_* buffer) {
170 if constexpr(oracle_) {
171 i = my_oracle->get(my_counter++);
174 extract_block(by_h5_row_, i,
static_cast<Index_
>(1), block_start, block_length, buffer, *my_h5comp);
179 template<
typename Value_>
180 const Value_* fetch_indices(Index_ i,
const std::vector<Index_>& indices, Value_* buffer) {
181 if constexpr(oracle_) {
182 i = my_oracle->get(my_counter++);
185 extract_indices(by_h5_row_, i,
static_cast<Index_
>(1), indices, buffer, *my_h5comp);
191template<
bool by_h5_row_,
typename Index_,
typename CachedValue_>
195 const std::string& file_name,
196 const std::string& dataset_name,
197 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
199 const tatami_chunked::SlabCacheStats& slab_stats) :
200 my_dim_stats(std::move(target_dim_stats)),
201 my_factory(slab_stats),
202 my_cache(slab_stats.max_slabs_in_cache)
204 initialize(file_name, dataset_name, my_h5comp);
205 if constexpr(!by_h5_row_) {
206 my_transposition_buffer.resize(slab_stats.slab_size_in_elements);
215 std::unique_ptr<Components> my_h5comp;
216 tatami_chunked::ChunkDimensionStats<Index_> my_dim_stats;
218 tatami_chunked::DenseSlabFactory<CachedValue_> my_factory;
219 typedef typename decltype(my_factory)::Slab Slab;
220 tatami_chunked::LruSlabCache<Index_, Slab> my_cache;
222 typename std::conditional<by_h5_row_, bool, std::vector<CachedValue_> >::type my_transposition_buffer;
225 template<
typename Value_,
class Extract_>
226 void fetch_raw(Index_ i, Value_* buffer,
size_t non_target_length, Extract_ extract) {
227 Index_ chunk = i / my_dim_stats.chunk_length;
228 Index_ index = i % my_dim_stats.chunk_length;
230 const auto& info = my_cache.find(
233 return my_factory.create();
235 [&](Index_ id, Slab& contents) ->
void {
236 auto curdim = tatami_chunked::get_chunk_length(my_dim_stats,
id);
238 if constexpr(by_h5_row_) {
240 extract(
id * my_dim_stats.chunk_length, curdim, contents.data);
245 auto tptr = my_transposition_buffer.data();
247 extract(
id * my_dim_stats.chunk_length, curdim, tptr);
254 auto ptr = info.data + non_target_length *
static_cast<size_t>(index);
255 std::copy_n(ptr, non_target_length, buffer);
259 template<
typename Value_>
260 const Value_* fetch_block(Index_ i, Index_ block_start, Index_ block_length, Value_* buffer) {
265 [&](Index_ start, Index_ length, CachedValue_* buf) ->
void {
266 extract_block(by_h5_row_, start, length, block_start, block_length, buf, *my_h5comp);
272 template<
typename Value_>
273 const Value_* fetch_indices(Index_ i,
const std::vector<Index_>& indices, Value_* buffer) {
278 [&](Index_ start, Index_ length, CachedValue_* buf) ->
void {
279 extract_indices(by_h5_row_, start, length, indices, buf, *my_h5comp);
288template<
typename Index_,
typename CachedValue_>
289class OracularCoreNormal {
292 const std::string& file_name,
293 const std::string& dataset_name,
294 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
296 const tatami_chunked::SlabCacheStats& slab_stats) :
297 my_dim_stats(std::move(target_dim_stats)),
298 my_cache(std::move(oracle), slab_stats.max_slabs_in_cache),
299 my_slab_size(slab_stats.slab_size_in_elements),
300 my_memory_pool(slab_stats.max_slabs_in_cache * my_slab_size)
302 initialize(file_name, dataset_name, my_h5comp);
305 ~OracularCoreNormal() {
310 std::unique_ptr<Components> my_h5comp;
311 tatami_chunked::ChunkDimensionStats<Index_> my_dim_stats;
317 tatami_chunked::OracularSlabCache<Index_, Index_, Slab, true> my_cache;
319 std::vector<CachedValue_> my_memory_pool;
320 size_t my_offset = 0;
323 template<
class Function_>
324 static void sort_by_field(std::vector<std::pair<Index_, Slab*> >& indices, Function_ field) {
325 auto comp = [&field](
const std::pair<Index_, Slab*>& l,
const std::pair<Index_, Slab*>& r) ->
bool {
326 return field(l) < field(r);
328 if (!std::is_sorted(indices.begin(), indices.end(), comp)) {
329 std::sort(indices.begin(), indices.end(), comp);
333 template<
typename Value_,
class Unionize_>
334 void fetch_raw([[maybe_unused]] Index_ i, Value_* buffer,
size_t non_target_length, Unionize_ unionize) {
335 auto info = my_cache.next(
336 [&](Index_ current) -> std::pair<Index_, Index_> {
337 return std::pair<Index_, Index_>(current / my_dim_stats.chunk_length, current % my_dim_stats.chunk_length);
341 output.offset = my_offset;
342 my_offset += my_slab_size;
345 [&](std::vector<std::pair<Index_, Slab*> >& chunks, std::vector<std::pair<Index_, Slab*> >& to_reuse) ->
void {
348 sort_by_field(to_reuse, [](
const std::pair<Index_, Slab*>& x) ->
size_t {
return x.second->offset; });
350 auto dest = my_memory_pool.data();
351 size_t running_offset = 0;
352 for (
auto& x : to_reuse) {
353 auto& cur_offset = x.second->offset;
354 if (cur_offset != running_offset) {
355 std::copy_n(dest + cur_offset, my_slab_size, dest + running_offset);
356 cur_offset = running_offset;
358 running_offset += my_slab_size;
366 sort_by_field(chunks, [](
const std::pair<Index_, Slab*>& x) -> Index_ {
return x.first; });
369 auto& components = *my_h5comp;
370 auto& dspace = my_h5comp->dataspace;
378 Index_ run_chunk_id = chunks.front().first;
379 Index_ chunk_length = tatami_chunked::get_chunk_length(my_dim_stats, run_chunk_id);
380 Index_ run_length = chunk_length;
381 Index_ total_length = chunk_length;
382 chunks.front().second->offset = running_offset;
383 auto start_offset = running_offset;
384 running_offset += my_slab_size;
386 for (
size_t ci = 1, cend = chunks.size(); ci < cend; ++ci) {
387 auto& current_chunk = chunks[ci];
388 Index_ current_chunk_id = current_chunk.first;
390 if (current_chunk_id - run_chunk_id > 1) {
391 unionize(dspace, run_chunk_id * my_dim_stats.chunk_length, run_length);
392 run_chunk_id = current_chunk_id;
396 Index_ current_length = tatami_chunked::get_chunk_length(my_dim_stats, current_chunk_id);
397 run_length += current_length;
398 total_length += current_length;
399 current_chunk.second->offset = running_offset;
400 running_offset += my_slab_size;
403 unionize(dspace, run_chunk_id * my_dim_stats.chunk_length, run_length);
406 count[0] = total_length;
407 count[1] = non_target_length;
408 components.memspace.setExtentSimple(2, count);
409 components.memspace.selectAll();
410 components.dataset.read(dest + start_offset, define_mem_type<CachedValue_>(), components.memspace, dspace);
415 auto ptr = my_memory_pool.data() + info.first->offset + non_target_length *
static_cast<size_t>(info.second);
416 std::copy_n(ptr, non_target_length, buffer);
420 template<
typename Value_>
421 const Value_* fetch_block(Index_ i, Index_ block_start, Index_ block_length, Value_* buffer) {
426 [&](H5::DataSpace& dspace, Index_ run_start, Index_ run_length) ->
void {
429 offset[0] = run_start;
430 offset[1] = block_start;
431 count[0] = run_length;
432 count[1] = block_length;
433 dspace.selectHyperslab(H5S_SELECT_OR, count, offset);
439 template<
typename Value_>
440 const Value_* fetch_indices(Index_ i,
const std::vector<Index_>& indices, Value_* buffer) {
445 [&](H5::DataSpace& dspace, Index_ run_start, Index_ run_length) ->
void {
448 offset[0] = run_start;
449 count[0] = run_length;
452 tatami::process_consecutive_indices<Index_>(
455 [&](Index_ start, Index_ length) -> void {
458 dspace.selectHyperslab(H5S_SELECT_OR, count, offset);
469template<
typename Index_,
typename CachedValue_>
470class OracularCoreTransposed {
472 OracularCoreTransposed(
473 const std::string& file_name,
474 const std::string& dataset_name,
475 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
477 const tatami_chunked::SlabCacheStats& slab_stats) :
478 my_dim_stats(std::move(target_dim_stats)),
479 my_factory(slab_stats),
480 my_cache(std::move(oracle), slab_stats.max_slabs_in_cache),
481 my_transposition_buffer(slab_stats.slab_size_in_elements),
482 my_transposition_buffer_ptr(my_transposition_buffer.data())
484 initialize(file_name, dataset_name, my_h5comp);
485 my_cache_transpose_info.reserve(slab_stats.max_slabs_in_cache);
488 ~OracularCoreTransposed() {
493 std::unique_ptr<Components> my_h5comp;
494 tatami_chunked::ChunkDimensionStats<Index_> my_dim_stats;
496 tatami_chunked::DenseSlabFactory<CachedValue_> my_factory;
497 typedef typename decltype(my_factory)::Slab Slab;
498 tatami_chunked::OracularSlabCache<Index_, Index_, Slab> my_cache;
500 std::vector<CachedValue_> my_transposition_buffer;
501 CachedValue_* my_transposition_buffer_ptr;
502 std::vector<std::pair<Slab*, Index_> > my_cache_transpose_info;
505 template<
typename Value_,
class Extract_>
506 void fetch_raw([[maybe_unused]] Index_ i, Value_* buffer,
size_t non_target_length, Extract_ extract) {
507 auto info = my_cache.next(
508 [&](Index_ current) -> std::pair<Index_, Index_> {
509 return std::pair<Index_, Index_>(current / my_dim_stats.chunk_length, current % my_dim_stats.chunk_length);
512 return my_factory.create();
514 [&](std::vector<std::pair<Index_, Slab*> >& chunks) ->
void {
515 my_cache_transpose_info.clear();
518 for (
const auto& c : chunks) {
519 auto curdim = tatami_chunked::get_chunk_length(my_dim_stats, c.first);
520 extract(c.first * my_dim_stats.chunk_length, curdim, c.second->data);
521 my_cache_transpose_info.emplace_back(c.second, curdim);
527 if (non_target_length != 1) {
528 for (
const auto& c : my_cache_transpose_info) {
530 tatami::transpose(c.first->data, non_target_length, c.second, my_transposition_buffer_ptr);
535 std::swap(c.first->data, my_transposition_buffer_ptr);
542 auto ptr = info.first->data + non_target_length *
static_cast<size_t>(info.second);
543 std::copy_n(ptr, non_target_length, buffer);
547 template<
typename Value_>
548 const Value_* fetch_block(Index_ i, Index_ block_start, Index_ block_length, Value_* buffer) {
553 [&](Index_ start, Index_ length, CachedValue_* buf) ->
void {
554 extract_block(
false, start, length, block_start, block_length, buf, *my_h5comp);
560 template<
typename Value_>
561 const Value_* fetch_indices(Index_ i,
const std::vector<Index_>& indices, Value_* buffer) {
566 [&](Index_ start, Index_ length, CachedValue_* buf) ->
void {
567 extract_indices(false, start, length, indices, buf, *my_h5comp);
581template<
bool solo_,
bool oracle_,
bool by_h5_row_,
typename Index_,
typename CachedValue_>
582using DenseCore =
typename std::conditional<solo_,
583 SoloCore<oracle_, by_h5_row_, Index_>,
584 typename std::conditional<!oracle_,
585 MyopicCore<by_h5_row_, Index_, CachedValue_>,
586 typename std::conditional<by_h5_row_,
587 OracularCoreNormal<Index_, CachedValue_>,
588 OracularCoreTransposed<Index_, CachedValue_>
597template<
bool solo_,
bool oracle_,
bool by_h5_row_,
typename Value_,
typename Index_,
typename CachedValue_>
601 const std::string& file_name,
602 const std::string& dataset_name,
603 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
605 Index_ non_target_dim,
606 const tatami_chunked::SlabCacheStats& slab_stats) :
610 std::move(target_dim_stats),
614 my_non_target_dim(non_target_dim)
617 const Value_* fetch(Index_ i, Value_* buffer) {
618 return my_core.fetch_block(i, 0, my_non_target_dim, buffer);
622 DenseCore<solo_, oracle_, by_h5_row_, Index_, CachedValue_> my_core;
623 Index_ my_non_target_dim;
626template<
bool solo_,
bool oracle_,
bool by_h5_row_,
typename Value_,
typename Index_,
typename CachedValue_>
630 const std::string& file_name,
631 const std::string& dataset_name,
632 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
636 const tatami_chunked::SlabCacheStats& slab_stats) :
640 std::move(target_dim_stats),
644 my_block_start(block_start),
645 my_block_length(block_length)
648 const Value_* fetch(Index_ i, Value_* buffer) {
649 return my_core.fetch_block(i, my_block_start, my_block_length, buffer);
653 DenseCore<solo_, oracle_, by_h5_row_, Index_, CachedValue_> my_core;
654 Index_ my_block_start, my_block_length;
657template<
bool solo_,
bool oracle_,
bool by_h5_row_,
typename Value_,
typename Index_,
typename CachedValue_>
661 const std::string& file_name,
662 const std::string& dataset_name,
663 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
666 const tatami_chunked::SlabCacheStats& slab_stats) :
670 std::move(target_dim_stats),
674 my_indices_ptr(std::move(indices_ptr))
677 const Value_* fetch(Index_ i, Value_* buffer) {
678 return my_core.fetch_indices(i, *my_indices_ptr, buffer);
682 DenseCore<solo_, oracle_, by_h5_row_, Index_, CachedValue_> my_core;
715template<
typename Value_,
typename Index_,
typename CachedValue_ = Value_>
717 std::string my_file_name, my_dataset_name;
720 size_t my_cache_size_in_elements;
721 bool my_require_minimum_cache;
723 tatami_chunked::ChunkDimensionStats<Index_> my_firstdim_stats, my_seconddim_stats;
724 bool my_prefer_firstdim;
736 my_file_name(std::move(file)),
737 my_dataset_name(std::move(name)),
738 my_transpose(transpose),
739 my_cache_size_in_elements(options.maximum_cache_size / sizeof(CachedValue_)),
740 my_require_minimum_cache(options.require_minimum_cache)
743 H5::H5File fhandle(my_file_name, H5F_ACC_RDONLY);
744 auto dhandle = open_and_check_dataset<false>(fhandle, my_dataset_name);
745 auto dims = get_array_dimensions<2>(dhandle, my_dataset_name);
747 hsize_t chunk_dims[2];
748 auto dparms = dhandle.getCreatePlist();
749 if (dparms.getLayout() != H5D_CHUNKED) {
752 chunk_dims[1] = dims[1];
754 dparms.getChunk(2, chunk_dims);
757 my_firstdim_stats = tatami_chunked::ChunkDimensionStats<Index_>(dims[0], chunk_dims[0]);
758 my_seconddim_stats = tatami_chunked::ChunkDimensionStats<Index_>(dims[1], chunk_dims[1]);
766 my_prefer_firstdim = (my_firstdim_stats.num_chunks > my_seconddim_stats.num_chunks);
779 bool prefer_rows_internal()
const {
781 return !my_prefer_firstdim;
783 return my_prefer_firstdim;
787 Index_ nrow_internal()
const {
789 return my_seconddim_stats.dimension_extent;
791 return my_firstdim_stats.dimension_extent;
795 Index_ ncol_internal()
const {
797 return my_firstdim_stats.dimension_extent;
799 return my_seconddim_stats.dimension_extent;
804 Index_ nrow()
const {
805 return nrow_internal();
808 Index_ ncol()
const {
809 return ncol_internal();
820 return prefer_rows_internal();
823 double prefer_rows_proportion()
const {
824 return static_cast<double>(prefer_rows_internal());
827 bool uses_oracle(
bool)
const {
831 bool is_sparse()
const {
835 double is_sparse_proportion()
const {
844 template<
bool oracle_,
template<
bool,
bool,
bool,
typename,
typename,
typename>
class Extractor_,
typename ... Args_>
845 std::unique_ptr<tatami::DenseExtractor<oracle_, Value_, Index_> > populate(
bool row, Index_ non_target_length,
tatami::MaybeOracle<oracle_, Index_> oracle, Args_&& ... args)
const {
846 bool by_h5_row = (row != my_transpose);
847 const auto& dim_stats = (by_h5_row ? my_firstdim_stats : my_seconddim_stats);
849 tatami_chunked::SlabCacheStats slab_stats(dim_stats.chunk_length, non_target_length, dim_stats.num_chunks, my_cache_size_in_elements, my_require_minimum_cache);
850 if (slab_stats.max_slabs_in_cache > 0) {
852 return std::make_unique<Extractor_<false, oracle_, true, Value_, Index_, CachedValue_> >(
853 my_file_name, my_dataset_name, dim_stats, std::move(oracle), std::forward<Args_>(args)..., slab_stats
856 return std::make_unique<Extractor_<false, oracle_, false, Value_, Index_, CachedValue_> >(
857 my_file_name, my_dataset_name, dim_stats, std::move(oracle), std::forward<Args_>(args)..., slab_stats
863 return std::make_unique<Extractor_<true, oracle_, true, Value_, Index_, CachedValue_> >(
864 my_file_name, my_dataset_name, dim_stats, std::move(oracle), std::forward<Args_>(args)..., slab_stats
867 return std::make_unique<Extractor_<true, oracle_, false, Value_, Index_, CachedValue_> >(
868 my_file_name, my_dataset_name, dim_stats, std::move(oracle), std::forward<Args_>(args)..., slab_stats
878 std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(
bool row,
const tatami::Options&)
const {
879 Index_ full_non_target = (row ? ncol_internal() : nrow_internal());
880 return populate<false, DenseMatrix_internal::Full>(row, full_non_target,
false, full_non_target);
883 std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(
bool row, Index_ block_start, Index_ block_length,
const tatami::Options&)
const {
884 return populate<false, DenseMatrix_internal::Block>(row, block_length,
false, block_start, block_length);
888 auto nidx = indices_ptr->size();
889 return populate<false, DenseMatrix_internal::Index>(row, nidx,
false, std::move(indices_ptr));
896 std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(
bool row,
const tatami::Options& opt)
const {
897 Index_ full_non_target = (row ? ncol_internal() : nrow_internal());
898 return std::make_unique<tatami::FullSparsifiedWrapper<false, Value_, Index_> >(dense(row, opt), full_non_target, opt);
901 std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(
bool row, Index_ block_start, Index_ block_length,
const tatami::Options& opt)
const {
902 return std::make_unique<tatami::BlockSparsifiedWrapper<false, Value_, Index_> >(dense(row, block_start, block_length, opt), block_start, block_length, opt);
906 auto ptr = dense(row, indices_ptr, opt);
907 return std::make_unique<tatami::IndexSparsifiedWrapper<false, Value_, Index_> >(std::move(ptr), std::move(indices_ptr), opt);
914 std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
919 Index_ full_non_target = (row ? ncol_internal() : nrow_internal());
920 return populate<true, DenseMatrix_internal::Full>(row, full_non_target, std::move(oracle), full_non_target);
923 std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
930 return populate<true, DenseMatrix_internal::Block>(row, block_length, std::move(oracle), block_start, block_length);
933 std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
939 auto nidx = indices_ptr->size();
940 return populate<true, DenseMatrix_internal::Index>(row, nidx, std::move(oracle), std::move(indices_ptr));
947 std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
952 Index_ full_non_target = (row ? ncol_internal() : nrow_internal());
953 return std::make_unique<tatami::FullSparsifiedWrapper<true, Value_, Index_> >(dense(row, std::move(oracle), opt), full_non_target, opt);
956 std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
963 return std::make_unique<tatami::BlockSparsifiedWrapper<true, Value_, Index_> >(dense(row, std::move(oracle), block_start, block_length, opt), block_start, block_length, opt);
966 std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
972 auto ptr = dense(row, std::move(oracle), indices_ptr, opt);
973 return std::make_unique<tatami::IndexSparsifiedWrapper<true, Value_, Index_> >(std::move(ptr), std::move(indices_ptr), opt);
Dense matrix backed by a DataSet in a HDF5 file.
Definition DenseMatrix.hpp:716
DenseMatrix(std::string file, std::string name, bool transpose)
Definition DenseMatrix.hpp:775
bool prefer_rows() const
Definition DenseMatrix.hpp:819
DenseMatrix(std::string file, std::string name, bool transpose, const DenseMatrixOptions &options)
Definition DenseMatrix.hpp:735
Representations for matrix data in HDF5 files.
Definition CompressedSparseMatrix.hpp:23
void serialize(Function_ f)
Definition serialize.hpp:45
void transpose(const Input_ *input, size_t nrow, size_t ncol, size_t input_stride, Output_ *output, size_t output_stride)
std::shared_ptr< const std::vector< Index_ > > VectorPtr
typename std::conditional< oracle_, std::shared_ptr< const Oracle< Index_ > >, bool >::type MaybeOracle
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
void process_consecutive_indices(const Index_ *indices, Index_ length, Function_ fun)
Default locking for serial access.
Options for DenseMatrix extraction.
Definition DenseMatrix.hpp:26
bool require_minimum_cache
Definition DenseMatrix.hpp:43
size_t maximum_cache_size
Definition DenseMatrix.hpp:36
Utilities for HDF5 extraction.