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();
96 tatami::process_consecutive_indices<Index_>(indices.data(), indices.size(),
97 [&](Index_ start, Index_ length) {
98 offset[non_target_dim] = start;
99 count[non_target_dim] = length;
100 comp.dataspace.selectHyperslab(H5S_SELECT_OR, count, offset);
105 count[non_target_dim] = indices.size();
106 comp.memspace.setExtentSimple(2, count);
107 comp.memspace.selectAll();
109 comp.dataset.read(buffer, define_mem_type<OutputValue_>(), comp.memspace, comp.dataspace);
119inline void initialize(
const std::string& file_name,
const std::string& dataset_name, std::unique_ptr<Components>& h5comp) {
121 h5comp.reset(
new Components);
127 H5::FileAccPropList fapl(H5::FileAccPropList::DEFAULT.getId());
128 fapl.setCache(0, 0, 0, 0);
130 h5comp->file.openFile(file_name, H5F_ACC_RDONLY, fapl);
131 h5comp->dataset = h5comp->file.openDataSet(dataset_name);
132 h5comp->dataspace = h5comp->dataset.getSpace();
136inline void destroy(std::unique_ptr<Components>& h5comp) {
142template<
bool oracle_,
bool by_h5_row_,
typename Index_>
146 const std::string& file_name,
147 const std::string& dataset_name,
148 [[maybe_unused]] tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
150 [[maybe_unused]]
const tatami_chunked::SlabCacheStats& slab_stats) :
151 my_oracle(std::move(oracle))
153 initialize(file_name, dataset_name, my_h5comp);
161 std::unique_ptr<Components> my_h5comp;
163 typename std::conditional<oracle_, size_t, bool>::type my_counter = 0;
166 template<
typename Value_>
167 const Value_* fetch_block(Index_ i, Index_ block_start, Index_ block_length, Value_* buffer) {
168 if constexpr(oracle_) {
169 i = my_oracle->get(my_counter++);
172 extract_block(by_h5_row_, i,
static_cast<Index_
>(1), block_start, block_length, buffer, *my_h5comp);
177 template<
typename Value_>
178 const Value_* fetch_indices(Index_ i,
const std::vector<Index_>& indices, Value_* buffer) {
179 if constexpr(oracle_) {
180 i = my_oracle->get(my_counter++);
183 extract_indices(by_h5_row_, i,
static_cast<Index_
>(1), indices, buffer, *my_h5comp);
189template<
bool by_h5_row_,
typename Index_,
typename CachedValue_>
193 const std::string& file_name,
194 const std::string& dataset_name,
195 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
197 const tatami_chunked::SlabCacheStats& slab_stats) :
198 my_dim_stats(std::move(target_dim_stats)),
199 my_factory(slab_stats),
200 my_cache(slab_stats.max_slabs_in_cache)
202 initialize(file_name, dataset_name, my_h5comp);
203 if constexpr(!by_h5_row_) {
204 my_transposition_buffer.resize(slab_stats.slab_size_in_elements);
213 std::unique_ptr<Components> my_h5comp;
214 tatami_chunked::ChunkDimensionStats<Index_> my_dim_stats;
216 tatami_chunked::DenseSlabFactory<CachedValue_> my_factory;
217 typedef typename decltype(my_factory)::Slab Slab;
218 tatami_chunked::LruSlabCache<Index_, Slab> my_cache;
220 typename std::conditional<by_h5_row_, bool, std::vector<CachedValue_> >::type my_transposition_buffer;
223 template<
typename Value_,
class Extract_>
224 void fetch_raw(Index_ i, Value_* buffer,
size_t non_target_length, Extract_ extract) {
225 Index_ chunk = i / my_dim_stats.chunk_length;
226 Index_ index = i % my_dim_stats.chunk_length;
228 const auto& info = my_cache.find(
231 return my_factory.create();
233 [&](Index_ id, Slab& contents) ->
void {
234 auto curdim = tatami_chunked::get_chunk_length(my_dim_stats,
id);
236 if constexpr(by_h5_row_) {
238 extract(
id * my_dim_stats.chunk_length, curdim, contents.data);
243 auto tptr = my_transposition_buffer.data();
245 extract(
id * my_dim_stats.chunk_length, curdim, tptr);
252 auto ptr = info.data + non_target_length *
static_cast<size_t>(index);
253 std::copy_n(ptr, non_target_length, buffer);
257 template<
typename Value_>
258 const Value_* fetch_block(Index_ i, Index_ block_start, Index_ block_length, Value_* buffer) {
259 fetch_raw(i, buffer, block_length, [&](Index_ start, Index_ length, CachedValue_* buf) {
260 extract_block(by_h5_row_, start, length, block_start, block_length, buf, *my_h5comp);
265 template<
typename Value_>
266 const Value_* fetch_indices(Index_ i,
const std::vector<Index_>& indices, Value_* buffer) {
267 fetch_raw(i, buffer, indices.size(), [&](Index_ start, Index_ length, CachedValue_* buf) {
268 extract_indices(by_h5_row_, start, length, indices, buf, *my_h5comp);
276template<
typename Index_,
typename CachedValue_>
277class OracularCoreNormal {
280 const std::string& file_name,
281 const std::string& dataset_name,
282 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
284 const tatami_chunked::SlabCacheStats& slab_stats) :
285 my_dim_stats(std::move(target_dim_stats)),
286 my_cache(std::move(oracle), slab_stats.max_slabs_in_cache),
287 my_slab_size(slab_stats.slab_size_in_elements),
288 my_memory_pool(slab_stats.max_slabs_in_cache * my_slab_size)
290 initialize(file_name, dataset_name, my_h5comp);
293 ~OracularCoreNormal() {
298 std::unique_ptr<Components> my_h5comp;
299 tatami_chunked::ChunkDimensionStats<Index_> my_dim_stats;
305 tatami_chunked::OracularSlabCache<Index_, Index_, Slab, true> my_cache;
307 std::vector<CachedValue_> my_memory_pool;
308 size_t my_offset = 0;
311 template<
class Function_>
312 static void sort_by_field(std::vector<std::pair<Index_, Slab*> >& indices, Function_ field) {
313 auto comp = [&field](
const std::pair<Index_, Slab*>& l,
const std::pair<Index_, Slab*>& r) ->
bool {
314 return field(l) < field(r);
316 if (!std::is_sorted(indices.begin(), indices.end(), comp)) {
317 std::sort(indices.begin(), indices.end(), comp);
321 template<
typename Value_,
class Unionize_>
322 void fetch_raw([[maybe_unused]] Index_ i, Value_* buffer,
size_t non_target_length, Unionize_ unionize) {
323 auto info = my_cache.next(
324 [&](Index_ current) -> std::pair<Index_, Index_> {
325 return std::pair<Index_, Index_>(current / my_dim_stats.chunk_length, current % my_dim_stats.chunk_length);
329 output.offset = my_offset;
330 my_offset += my_slab_size;
333 [&](std::vector<std::pair<Index_, Slab*> >& chunks, std::vector<std::pair<Index_, Slab*> >& to_reuse) {
336 sort_by_field(to_reuse, [](
const std::pair<Index_, Slab*>& x) ->
size_t {
return x.second->offset; });
338 auto dest = my_memory_pool.data();
339 size_t running_offset = 0;
340 for (
auto& x : to_reuse) {
341 auto& cur_offset = x.second->offset;
342 if (cur_offset != running_offset) {
343 std::copy_n(dest + cur_offset, my_slab_size, dest + running_offset);
344 cur_offset = running_offset;
346 running_offset += my_slab_size;
354 sort_by_field(chunks, [](
const std::pair<Index_, Slab*>& x) -> Index_ {
return x.first; });
357 auto& components = *my_h5comp;
358 auto& dspace = my_h5comp->dataspace;
366 Index_ run_chunk_id = chunks.front().first;
367 Index_ chunk_length = tatami_chunked::get_chunk_length(my_dim_stats, run_chunk_id);
368 Index_ run_length = chunk_length;
369 Index_ total_length = chunk_length;
370 chunks.front().second->offset = running_offset;
371 auto start_offset = running_offset;
372 running_offset += my_slab_size;
374 for (
size_t ci = 1, cend = chunks.size(); ci < cend; ++ci) {
375 auto& current_chunk = chunks[ci];
376 Index_ current_chunk_id = current_chunk.first;
378 if (current_chunk_id - run_chunk_id > 1) {
379 unionize(dspace, run_chunk_id * my_dim_stats.chunk_length, run_length);
380 run_chunk_id = current_chunk_id;
384 Index_ current_length = tatami_chunked::get_chunk_length(my_dim_stats, current_chunk_id);
385 run_length += current_length;
386 total_length += current_length;
387 current_chunk.second->offset = running_offset;
388 running_offset += my_slab_size;
391 unionize(dspace, run_chunk_id * my_dim_stats.chunk_length, run_length);
394 count[0] = total_length;
395 count[1] = non_target_length;
396 components.memspace.setExtentSimple(2, count);
397 components.memspace.selectAll();
398 components.dataset.read(dest + start_offset, define_mem_type<CachedValue_>(), components.memspace, dspace);
403 auto ptr = my_memory_pool.data() + info.first->offset + non_target_length *
static_cast<size_t>(info.second);
404 std::copy_n(ptr, non_target_length, buffer);
408 template<
typename Value_>
409 const Value_* fetch_block(Index_ i, Index_ block_start, Index_ block_length, Value_* buffer) {
410 fetch_raw(i, buffer, block_length, [&](H5::DataSpace& dspace, Index_ run_start, Index_ run_length) {
413 offset[0] = run_start;
414 offset[1] = block_start;
415 count[0] = run_length;
416 count[1] = block_length;
417 dspace.selectHyperslab(H5S_SELECT_OR, count, offset);
422 template<
typename Value_>
423 const Value_* fetch_indices(Index_ i,
const std::vector<Index_>& indices, Value_* buffer) {
424 fetch_raw(i, buffer, indices.size(), [&](H5::DataSpace& dspace, Index_ run_start, Index_ run_length) {
427 offset[0] = run_start;
428 count[0] = run_length;
431 tatami::process_consecutive_indices<Index_>(indices.data(), indices.size(),
432 [&](Index_ start, Index_ length) {
435 dspace.selectHyperslab(H5S_SELECT_OR, count, offset);
445template<
typename Index_,
typename CachedValue_>
446class OracularCoreTransposed {
448 OracularCoreTransposed(
449 const std::string& file_name,
450 const std::string& dataset_name,
451 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
453 const tatami_chunked::SlabCacheStats& slab_stats) :
454 my_dim_stats(std::move(target_dim_stats)),
455 my_factory(slab_stats),
456 my_cache(std::move(oracle), slab_stats.max_slabs_in_cache),
457 my_transposition_buffer(slab_stats.slab_size_in_elements),
458 my_transposition_buffer_ptr(my_transposition_buffer.data())
460 initialize(file_name, dataset_name, my_h5comp);
461 my_cache_transpose_info.reserve(slab_stats.max_slabs_in_cache);
464 ~OracularCoreTransposed() {
469 std::unique_ptr<Components> my_h5comp;
470 tatami_chunked::ChunkDimensionStats<Index_> my_dim_stats;
472 tatami_chunked::DenseSlabFactory<CachedValue_> my_factory;
473 typedef typename decltype(my_factory)::Slab Slab;
474 tatami_chunked::OracularSlabCache<Index_, Index_, Slab> my_cache;
476 std::vector<CachedValue_> my_transposition_buffer;
477 CachedValue_* my_transposition_buffer_ptr;
478 std::vector<std::pair<Slab*, Index_> > my_cache_transpose_info;
481 template<
typename Value_,
class Extract_>
482 void fetch_raw([[maybe_unused]] Index_ i, Value_* buffer,
size_t non_target_length, Extract_ extract) {
483 auto info = my_cache.next(
484 [&](Index_ current) -> std::pair<Index_, Index_> {
485 return std::pair<Index_, Index_>(current / my_dim_stats.chunk_length, current % my_dim_stats.chunk_length);
488 return my_factory.create();
490 [&](std::vector<std::pair<Index_, Slab*> >& chunks) {
491 my_cache_transpose_info.clear();
494 for (
const auto& c : chunks) {
495 auto curdim = tatami_chunked::get_chunk_length(my_dim_stats, c.first);
496 extract(c.first * my_dim_stats.chunk_length, curdim, c.second->data);
497 my_cache_transpose_info.emplace_back(c.second, curdim);
503 if (non_target_length != 1) {
504 for (
const auto& c : my_cache_transpose_info) {
506 tatami::transpose(c.first->data, non_target_length, c.second, my_transposition_buffer_ptr);
511 std::swap(c.first->data, my_transposition_buffer_ptr);
518 auto ptr = info.first->data + non_target_length *
static_cast<size_t>(info.second);
519 std::copy_n(ptr, non_target_length, buffer);
523 template<
typename Value_>
524 const Value_* fetch_block(Index_ i, Index_ block_start, Index_ block_length, Value_* buffer) {
525 fetch_raw(i, buffer, block_length, [&](Index_ start, Index_ length, CachedValue_* buf) {
526 extract_block(
false, start, length, block_start, block_length, buf, *my_h5comp);
531 template<
typename Value_>
532 const Value_* fetch_indices(Index_ i,
const std::vector<Index_>& indices, Value_* buffer) {
533 fetch_raw(i, buffer, indices.size(), [&](Index_ start, Index_ length, CachedValue_* buf) {
534 extract_indices(false, start, length, indices, buf, *my_h5comp);
547template<
bool solo_,
bool oracle_,
bool by_h5_row_,
typename Index_,
typename CachedValue_>
548using DenseCore =
typename std::conditional<solo_,
549 SoloCore<oracle_, by_h5_row_, Index_>,
550 typename std::conditional<!oracle_,
551 MyopicCore<by_h5_row_, Index_, CachedValue_>,
552 typename std::conditional<by_h5_row_,
553 OracularCoreNormal<Index_, CachedValue_>,
554 OracularCoreTransposed<Index_, CachedValue_>
563template<
bool solo_,
bool oracle_,
bool by_h5_row_,
typename Value_,
typename Index_,
typename CachedValue_>
567 const std::string& file_name,
568 const std::string& dataset_name,
569 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
571 Index_ non_target_dim,
572 const tatami_chunked::SlabCacheStats& slab_stats) :
576 std::move(target_dim_stats),
580 my_non_target_dim(non_target_dim)
583 const Value_* fetch(Index_ i, Value_* buffer) {
584 return my_core.fetch_block(i, 0, my_non_target_dim, buffer);
588 DenseCore<solo_, oracle_, by_h5_row_, Index_, CachedValue_> my_core;
589 Index_ my_non_target_dim;
592template<
bool solo_,
bool oracle_,
bool by_h5_row_,
typename Value_,
typename Index_,
typename CachedValue_>
596 const std::string& file_name,
597 const std::string& dataset_name,
598 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
602 const tatami_chunked::SlabCacheStats& slab_stats) :
606 std::move(target_dim_stats),
610 my_block_start(block_start),
611 my_block_length(block_length)
614 const Value_* fetch(Index_ i, Value_* buffer) {
615 return my_core.fetch_block(i, my_block_start, my_block_length, buffer);
619 DenseCore<solo_, oracle_, by_h5_row_, Index_, CachedValue_> my_core;
620 Index_ my_block_start, my_block_length;
623template<
bool solo_,
bool oracle_,
bool by_h5_row_,
typename Value_,
typename Index_,
typename CachedValue_>
627 const std::string& file_name,
628 const std::string& dataset_name,
629 tatami_chunked::ChunkDimensionStats<Index_> target_dim_stats,
632 const tatami_chunked::SlabCacheStats& slab_stats) :
636 std::move(target_dim_stats),
640 my_indices_ptr(std::move(indices_ptr))
643 const Value_* fetch(Index_ i, Value_* buffer) {
644 return my_core.fetch_indices(i, *my_indices_ptr, buffer);
648 DenseCore<solo_, oracle_, by_h5_row_, Index_, CachedValue_> my_core;
681template<
typename Value_,
typename Index_,
typename CachedValue_ = Value_>
683 std::string my_file_name, my_dataset_name;
686 size_t my_cache_size_in_elements;
687 bool my_require_minimum_cache;
689 tatami_chunked::ChunkDimensionStats<Index_> my_firstdim_stats, my_seconddim_stats;
690 bool my_prefer_firstdim;
702 my_file_name(std::move(file)),
703 my_dataset_name(std::move(name)),
704 my_transpose(transpose),
705 my_cache_size_in_elements(options.maximum_cache_size / sizeof(CachedValue_)),
706 my_require_minimum_cache(options.require_minimum_cache)
709 H5::H5File fhandle(my_file_name, H5F_ACC_RDONLY);
710 auto dhandle = open_and_check_dataset<false>(fhandle, my_dataset_name);
711 auto dims = get_array_dimensions<2>(dhandle, my_dataset_name);
713 hsize_t chunk_dims[2];
714 auto dparms = dhandle.getCreatePlist();
715 if (dparms.getLayout() != H5D_CHUNKED) {
718 chunk_dims[1] = dims[1];
720 dparms.getChunk(2, chunk_dims);
723 my_firstdim_stats = tatami_chunked::ChunkDimensionStats<Index_>(dims[0], chunk_dims[0]);
724 my_seconddim_stats = tatami_chunked::ChunkDimensionStats<Index_>(dims[1], chunk_dims[1]);
732 my_prefer_firstdim = (my_firstdim_stats.num_chunks > my_seconddim_stats.num_chunks);
745 bool prefer_rows_internal()
const {
747 return !my_prefer_firstdim;
749 return my_prefer_firstdim;
753 Index_ nrow_internal()
const {
755 return my_seconddim_stats.dimension_extent;
757 return my_firstdim_stats.dimension_extent;
761 Index_ ncol_internal()
const {
763 return my_firstdim_stats.dimension_extent;
765 return my_seconddim_stats.dimension_extent;
770 Index_ nrow()
const {
771 return nrow_internal();
774 Index_ ncol()
const {
775 return ncol_internal();
786 return prefer_rows_internal();
789 double prefer_rows_proportion()
const {
790 return static_cast<double>(prefer_rows_internal());
793 bool uses_oracle(
bool)
const {
797 bool is_sparse()
const {
801 double is_sparse_proportion()
const {
810 template<
bool oracle_,
template<
bool,
bool,
bool,
typename,
typename,
typename>
class Extractor_,
typename ... Args_>
811 std::unique_ptr<tatami::DenseExtractor<oracle_, Value_, Index_> > populate(
bool row, Index_ non_target_length,
tatami::MaybeOracle<oracle_, Index_> oracle, Args_&& ... args)
const {
812 bool by_h5_row = (row != my_transpose);
813 const auto& dim_stats = (by_h5_row ? my_firstdim_stats : my_seconddim_stats);
815 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);
816 if (slab_stats.max_slabs_in_cache > 0) {
818 return std::make_unique<Extractor_<false, oracle_, true, Value_, Index_, CachedValue_> >(
819 my_file_name, my_dataset_name, dim_stats, std::move(oracle), std::forward<Args_>(args)..., slab_stats
822 return std::make_unique<Extractor_<false, oracle_, false, Value_, Index_, CachedValue_> >(
823 my_file_name, my_dataset_name, dim_stats, std::move(oracle), std::forward<Args_>(args)..., slab_stats
829 return std::make_unique<Extractor_<true, oracle_, true, Value_, Index_, CachedValue_> >(
830 my_file_name, my_dataset_name, dim_stats, std::move(oracle), std::forward<Args_>(args)..., slab_stats
833 return std::make_unique<Extractor_<true, oracle_, false, Value_, Index_, CachedValue_> >(
834 my_file_name, my_dataset_name, dim_stats, std::move(oracle), std::forward<Args_>(args)..., slab_stats
844 std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(
bool row,
const tatami::Options&)
const {
845 Index_ full_non_target = (row ? ncol_internal() : nrow_internal());
846 return populate<false, DenseMatrix_internal::Full>(row, full_non_target,
false, full_non_target);
849 std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(
bool row, Index_ block_start, Index_ block_length,
const tatami::Options&)
const {
850 return populate<false, DenseMatrix_internal::Block>(row, block_length,
false, block_start, block_length);
854 auto nidx = indices_ptr->size();
855 return populate<false, DenseMatrix_internal::Index>(row, nidx,
false, std::move(indices_ptr));
862 std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(
bool row,
const tatami::Options& opt)
const {
863 Index_ full_non_target = (row ? ncol_internal() : nrow_internal());
864 return std::make_unique<tatami::FullSparsifiedWrapper<false, Value_, Index_> >(dense(row, opt), full_non_target, opt);
867 std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(
bool row, Index_ block_start, Index_ block_length,
const tatami::Options& opt)
const {
868 return std::make_unique<tatami::BlockSparsifiedWrapper<false, Value_, Index_> >(dense(row, block_start, block_length, opt), block_start, block_length, opt);
872 auto ptr = dense(row, indices_ptr, opt);
873 return std::make_unique<tatami::IndexSparsifiedWrapper<false, Value_, Index_> >(std::move(ptr), std::move(indices_ptr), opt);
880 std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
885 Index_ full_non_target = (row ? ncol_internal() : nrow_internal());
886 return populate<true, DenseMatrix_internal::Full>(row, full_non_target, std::move(oracle), full_non_target);
889 std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
896 return populate<true, DenseMatrix_internal::Block>(row, block_length, std::move(oracle), block_start, block_length);
899 std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
905 auto nidx = indices_ptr->size();
906 return populate<true, DenseMatrix_internal::Index>(row, nidx, std::move(oracle), std::move(indices_ptr));
913 std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
918 Index_ full_non_target = (row ? ncol_internal() : nrow_internal());
919 return std::make_unique<tatami::FullSparsifiedWrapper<true, Value_, Index_> >(dense(row, std::move(oracle), opt), full_non_target, opt);
922 std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
929 return std::make_unique<tatami::BlockSparsifiedWrapper<true, Value_, Index_> >(dense(row, std::move(oracle), block_start, block_length, opt), block_start, block_length, opt);
932 std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
938 auto ptr = dense(row, std::move(oracle), indices_ptr, opt);
939 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:682
DenseMatrix(std::string file, std::string name, bool transpose)
Definition DenseMatrix.hpp:741
bool prefer_rows() const
Definition DenseMatrix.hpp:785
DenseMatrix(std::string file, std::string name, bool transpose, const DenseMatrixOptions &options)
Definition DenseMatrix.hpp:701
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)
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
typename std::conditional< oracle_, std::shared_ptr< const Oracle< Index_ > >, bool >::type MaybeOracle
std::shared_ptr< const std::vector< Index_ > > VectorPtr
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.