1#ifndef TATAMI_DELAYED_SUBSET_HPP
2#define TATAMI_DELAYED_SUBSET_HPP
23template<
typename Index_>
25 std::vector<Index_> collapsed;
26 std::vector<Index_> reindex;
29template<
typename Index_,
class SubsetStorage_,
class ToIndex_>
31 std::vector<std::pair<Index_, Index_> >
collected;
62template<
bool oracle_,
typename Value_,
typename Index_>
65 template<
class SubsetStorage_>
66 ParallelDense(
const Matrix<Value_, Index_>* matrix,
const SubsetStorage_& subset,
bool row, MaybeOracle<oracle_, Index_> oracle,
const Options& opt) {
67 auto processed = format_dense_parallel_base<Index_>(subset, subset.size(), [&](Index_ i) -> Index_ { return i; });
68 initialize(matrix, std::move(processed), row, std::move(oracle), opt);
71 template<
class SubsetStorage_>
72 ParallelDense(
const Matrix<Value_, Index_>* matrix,
const SubsetStorage_& subset,
bool row, MaybeOracle<oracle_, Index_> oracle, Index_ block_start, Index_ block_length,
const Options& opt) {
73 auto processed = format_dense_parallel_base<Index_>(subset, block_length, [&](Index_ i) -> Index_ {
return i + block_start; });
74 initialize(matrix, std::move(processed), row, std::move(oracle), opt);
77 template<
class SubsetStorage_>
78 ParallelDense(
const Matrix<Value_, Index_>* matrix,
const SubsetStorage_& subset,
bool row, MaybeOracle<oracle_, Index_> oracle, VectorPtr<Index_> indices_ptr,
const Options& opt) {
79 const auto& indices = *indices_ptr;
80 auto processed = format_dense_parallel_base<Index_>(subset, indices.size(), [&](Index_ i) -> Index_ { return indices[i]; });
81 initialize(matrix, std::move(processed), row, std::move(oracle), opt);
85 void initialize(
const Matrix<Value_, Index_>* matrix, DenseParallelResults<Index_> processed,
bool row, MaybeOracle<oracle_, Index_> oracle,
const Options& opt) {
86 my_holding_vbuffer.resize(processed.collapsed.size());
87 my_ext = new_extractor<false, oracle_>(matrix, row, std::move(oracle), std::move(processed.collapsed), opt);
88 my_reindex.swap(processed.reindex);
92 const Value_* fetch(Index_ i, Value_* buffer) {
93 auto src = my_ext->fetch(i, my_holding_vbuffer.data());
97 for (
auto p : my_reindex) {
106 std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > my_ext;
107 std::vector<Value_> my_holding_vbuffer;
108 std::vector<Index_> my_reindex;
111template<
typename Index_>
119 std::vector<Index_> pool_ptrs;
120 std::vector<Index_> pool_indices;
124template<
typename Index_>
126 std::vector<Index_> collapsed;
127 SparseParallelReindex<Index_> reindex;
130template<
typename Index_,
class SubsetStorage_,
class ToIndex_>
132 std::vector<std::pair<Index_, Index_> >
collected;
144 output.reindex.pool_indices.reserve(
len);
170 output.reindex.pool_indices.push_back(
pp.second);
179 output.reindex.pool_indices.push_back(
pp.second);
189template<
bool oracle_,
typename Value_,
typename Index_>
192 template<
class SubsetStorage_>
193 ParallelSparse(
const Matrix<Value_, Index_>* mat,
const SubsetStorage_& subset,
bool row, MaybeOracle<oracle_, Index_> oracle,
const Options& opt) {
194 auto processed = format_sparse_parallel_base<Index_>(subset, subset.size(), [](Index_ i) -> Index_ { return i; });
195 initialize(mat, std::move(processed), subset.size(), row, std::move(oracle), opt);
198 template<
class SubsetStorage_>
199 ParallelSparse(
const Matrix<Value_, Index_>* mat,
const SubsetStorage_& subset,
bool row, MaybeOracle<oracle_, Index_> oracle, Index_ block_start, Index_ block_length,
const Options& opt) {
200 auto processed = format_sparse_parallel_base<Index_>(subset, block_length, [&](Index_ i) -> Index_ {
return i + block_start; });
201 initialize(mat, std::move(processed), block_length, row, std::move(oracle), opt);
204 template<
class SubsetStorage_>
205 ParallelSparse(
const Matrix<Value_, Index_>* mat,
const SubsetStorage_& subset,
bool row, MaybeOracle<oracle_, Index_> oracle, VectorPtr<Index_> indices_ptr,
const Options& opt) {
206 const auto& indices = *indices_ptr;
207 auto processed = format_sparse_parallel_base<Index_>(subset, indices.size(), [&](Index_ i) -> Index_ { return indices[i]; });
208 initialize(mat, std::move(processed), indices.size(), row, std::move(oracle), opt);
212 void initialize(
const Matrix<Value_, Index_>* mat, SparseParallelResults<Index_> processed,
size_t extent,
bool row, MaybeOracle<oracle_, Index_> oracle, Options opt) {
213 my_shift = extent - processed.collapsed.size();
215 my_needs_value = opt.sparse_extract_value;
216 my_needs_index = opt.sparse_extract_index;
217 my_needs_sort = opt.sparse_ordered_index;
219 if (my_needs_sort && my_needs_value) {
220 my_sortspace.reserve(extent);
225 opt.sparse_extract_index =
true;
226 if (!my_needs_index) {
227 my_holding_ibuffer.resize(processed.collapsed.size());
230 my_ext = new_extractor<true, oracle_>(mat, row, std::move(oracle), std::move(processed.collapsed), opt);
231 my_reindex = std::move(processed.reindex);
235 SparseRange<Value_, Index_> fetch(Index_ i, Value_* vbuffer, Index_* ibuffer) {
236 auto vinit = (my_needs_value ? vbuffer + my_shift : NULL);
237 auto iinit = (my_needs_index ? ibuffer + my_shift : my_holding_ibuffer.data());
238 auto input = my_ext->fetch(i, vinit, iinit);
240 if (!my_needs_sort) {
249 auto vcopy = vbuffer;
250 auto icopy = ibuffer;
252 auto vsrc = input.value;
253 bool replace_value = my_needs_value && vsrc != vcopy;
255 for (Index_ i = 0; i < input.number; ++i) {
256 auto lookup = input.index[i] - my_reindex.offset;
257 auto start = my_reindex.pool_ptrs[lookup];
258 auto num = my_reindex.pool_ptrs[lookup + 1] - start;
263 std::fill_n(vcopy, num, val);
266 replace_value = (vcopy != vsrc);
269 if (my_needs_index) {
274 std::copy_n(my_reindex.pool_indices.begin() + start, num, icopy);
279 input.number = count;
280 if (my_needs_value) {
281 input.value = vbuffer;
283 if (my_needs_index) {
284 input.index = ibuffer;
289 }
else if (my_needs_value) {
293 my_sortspace.clear();
294 for (Index_ i = 0; i < input.number; ++i) {
295 auto val = input.value[i];
296 auto lookup = input.index[i] - my_reindex.offset;
297 auto start = my_reindex.pool_ptrs[lookup];
298 auto end = my_reindex.pool_ptrs[lookup + 1];
299 for (Index_ j = start; j < end; ++j) {
300 my_sortspace.emplace_back(my_reindex.pool_indices[j], val);
303 std::sort(my_sortspace.begin(), my_sortspace.end());
304 input.number = my_sortspace.size();
306 auto vcopy = vbuffer;
307 for (
const auto& ss : my_sortspace) {
311 input.value = vbuffer;
313 if (my_needs_index) {
314 auto icopy = ibuffer;
315 for (
const auto& ss : my_sortspace) {
319 input.index = ibuffer;
330 auto icopy = ibuffer;
332 for (Index_ i = 0; i < input.number; ++i) {
333 auto lookup = input.index[i] - my_reindex.offset;
334 auto start = my_reindex.pool_ptrs[lookup];
335 auto num = my_reindex.pool_ptrs[lookup + 1] - start;
338 if (my_needs_index) {
339 std::copy_n(my_reindex.pool_indices.begin() + start, num, icopy);
344 input.number = count;
345 if (my_needs_index) {
346 std::sort(ibuffer, ibuffer + count);
347 input.index = ibuffer;
357 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > my_ext;
358 bool my_needs_value, my_needs_index, my_needs_sort;
359 SparseParallelReindex<Index_> my_reindex;
360 std::vector<std::pair<Index_, Value_> > my_sortspace;
361 std::vector<Index_> my_holding_ibuffer;
381template<
typename Value_,
typename Index_,
class SubsetStorage_>
395 std::shared_ptr<const Matrix<Value_, Index_> > my_matrix;
402 return my_subset.size();
404 return my_matrix->nrow();
410 return my_matrix->ncol();
412 return my_subset.size();
417 return my_matrix->is_sparse();
421 return my_matrix->is_sparse_proportion();
425 return my_matrix->prefer_rows();
429 return my_matrix->prefer_rows_proportion();
433 return my_matrix->uses_oracle(
row);
444 template<
typename ...
Args_>
445 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > populate_myopic_dense(
bool row,
Args_&& ...
args)
const {
446 if (
row == my_by_row) {
447 return std::make_unique<subset_utils::MyopicPerpendicularDense<Value_, Index_, SubsetStorage_> >(my_matrix.get(), my_subset,
row, std::forward<Args_>(
args)...);
449 return std::make_unique<DelayedSubset_internal::ParallelDense<false, Value_, Index_> >(my_matrix.get(), my_subset,
row,
false, std::forward<Args_>(
args)...);
455 return populate_myopic_dense(
row,
opt);
470 template<
typename ...
Args_>
471 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > populate_myopic_sparse(
bool row,
Args_&& ...
args)
const {
472 if (
row == my_by_row) {
473 return std::make_unique<subset_utils::MyopicPerpendicularSparse<Value_, Index_, SubsetStorage_> >(my_matrix.get(), my_subset,
row, std::forward<Args_>(
args)...);
475 return std::make_unique<DelayedSubset_internal::ParallelSparse<false, Value_, Index_> >(my_matrix.get(), my_subset,
row,
false, std::forward<Args_>(
args)...);
481 return populate_myopic_sparse(
row,
opt);
496 template<
typename ...
Args_>
497 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > populate_oracular_dense(
bool row, std::shared_ptr<
const Oracle<Index_> >
oracle,
Args_&& ...
args)
const {
498 if (
row == my_by_row) {
499 return std::make_unique<subset_utils::OracularPerpendicularDense<Value_, Index_> >(my_matrix.get(), my_subset,
row, std::move(
oracle), std::forward<Args_>(
args)...);
501 return std::make_unique<DelayedSubset_internal::ParallelDense<true, Value_, Index_> >(my_matrix.get(), my_subset,
row, std::move(
oracle), std::forward<Args_>(
args)...);
507 return populate_oracular_dense(
row, std::move(
oracle),
opt);
522 template<
typename ...
Args_>
523 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > populate_oracular_sparse(
bool row, std::shared_ptr<
const Oracle<Index_> >
oracle,
Args_&& ...
args)
const {
524 if (
row == my_by_row) {
525 return std::make_unique<subset_utils::OracularPerpendicularSparse<Value_, Index_> >(my_matrix.get(), my_subset,
row, std::move(
oracle), std::forward<Args_>(
args)...);
527 return std::make_unique<DelayedSubset_internal::ParallelSparse<true, Value_, Index_> >(my_matrix.get(), my_subset,
row, std::move(
oracle), std::forward<Args_>(
args)...);
533 return populate_oracular_sparse(
row, std::move(
oracle),
opt);
Delayed subsetting of a matrix with general indices.
Definition DelayedSubset.hpp:382
bool uses_oracle(bool row) const
Definition DelayedSubset.hpp:432
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > my_subset_ptr, const Options &opt) const
Definition DelayedSubset.hpp:540
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubset.hpp:458
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubset.hpp:484
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubset.hpp:532
Index_ ncol() const
Definition DelayedSubset.hpp:408
bool prefer_rows() const
Definition DelayedSubset.hpp:424
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubset.hpp:510
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, VectorPtr< Index_ > my_subset_ptr, const Options &opt) const
Definition DelayedSubset.hpp:488
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, const Options &opt) const
Definition DelayedSubset.hpp:480
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubset.hpp:506
DelayedSubset(std::shared_ptr< const Matrix< Value_, Index_ > > matrix, SubsetStorage_ subset, bool by_row)
Definition DelayedSubset.hpp:391
double prefer_rows_proportion() const
Definition DelayedSubset.hpp:428
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > my_subset_ptr, const Options &opt) const
Definition DelayedSubset.hpp:514
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, const Options &opt) const
Definition DelayedSubset.hpp:454
Index_ nrow() const
Definition DelayedSubset.hpp:400
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubset.hpp:536
bool is_sparse() const
Definition DelayedSubset.hpp:416
double is_sparse_proportion() const
Definition DelayedSubset.hpp:420
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, VectorPtr< Index_ > my_subset_ptr, const Options &opt) const
Definition DelayedSubset.hpp:462
Virtual class for a matrix.
Definition Matrix.hpp:59
Predict future access requests on the target dimension.
Definition Oracle.hpp:21
Flexible representations for matrix data.
Definition Extractor.hpp:15
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:273
typename std::conditional< oracle_, OracularSparseExtractor< Value_, Index_ >, MyopicSparseExtractor< Value_, Index_ > >::type SparseExtractor
Definition Extractor.hpp:284
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
auto consecutive_extractor(const Matrix< Value_, Index_ > *mat, bool row, Index_ iter_start, Index_ iter_length, Args_ &&... args)
Definition consecutive_extractor.hpp:35
Options for accessing data from a Matrix instance.
Definition Options.hpp:30