1#ifndef TATAMI_DELAYED_BIND_HPP
2#define TATAMI_DELAYED_BIND_HPP
10#include "../utils/Index_to_container.hpp"
32namespace DelayedBind_internal {
38template<
typename Index_,
class Initialize_>
39Index_ initialize_parallel_block(
40 const std::vector<Index_>& cumulative,
41 const std::vector<Index_>& mapping,
42 const Index_ block_start,
43 const Index_ block_length,
44 const Initialize_ init
46 if (mapping.empty()) {
50 const Index_ start_index = mapping[block_start];
51 Index_ actual_start = block_start - cumulative[start_index];
52 const Index_ block_end = block_start + block_length;
54 const Index_ nmats = cumulative.size() - 1;
55 for (Index_ index = start_index; index < nmats; ++index) {
56 const Index_ submat_end = cumulative[index + 1];
57 bool not_final = (block_end > submat_end);
58 const Index_ actual_end = (not_final ? submat_end : block_end) - cumulative[index];
59 init(index, actual_start, actual_end - actual_start);
69template<
typename Index_,
class Initialize_>
70void initialize_parallel_index(
71 const std::vector<Index_>& cumulative,
72 const std::vector<Index_>& mapping,
73 const std::vector<Index_>& indices,
74 const Initialize_ init
77 const Index_ il = indices.size();
78 while (counter < il) {
79 const Index_ first_index = indices[counter];
80 const Index_ bind_index = mapping[first_index];
81 const Index_ lower = cumulative[bind_index];
82 const Index_ upper = cumulative[bind_index + 1];
85 auto slice_ptr = std::make_shared<std::vector<Index_> >(1, first_index - lower);
88 while (counter < il && indices[counter] < upper) {
89 slice_ptr->push_back(indices[counter] - lower);
93 init(bind_index, std::move(slice_ptr));
97template<
bool oracle_,
typename Value_,
typename Index_>
98class ParallelDense final :
public DenseExtractor<oracle_, Value_, Index_> {
101 const std::vector<Index_>&,
102 const std::vector<Index_>&,
103 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
105 MaybeOracle<oracle_, Index_> oracle,
108 my_exts.reserve(matrices.size());
109 my_count.reserve(matrices.size());
110 for (
const auto& m : matrices) {
111 my_count.emplace_back(row ? m->ncol() : m->nrow());
112 my_exts.emplace_back(new_extractor<false, oracle_>(m.get(), row, oracle, opt));
117 const std::vector<Index_>& cumulative,
118 const std::vector<Index_>& mapping,
119 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
121 MaybeOracle<oracle_, Index_> oracle,
122 const Index_ block_start,
123 const Index_ block_length,
126 my_exts.reserve(matrices.size());
127 my_count.reserve(matrices.size());
128 initialize_parallel_block(
133 [&](
const Index_ i,
const Index_ sub_block_start,
const Index_ sub_block_length) ->
void {
134 my_count.emplace_back(sub_block_length);
135 my_exts.emplace_back(new_extractor<false, oracle_>(matrices[i].get(), row, oracle, sub_block_start, sub_block_length, opt));
141 const std::vector<Index_>& cumulative,
142 const std::vector<Index_>& mapping,
143 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
145 MaybeOracle<oracle_, Index_> oracle,
146 VectorPtr<Index_> indices_ptr,
149 my_exts.reserve(matrices.size());
150 my_count.reserve(matrices.size());
151 initialize_parallel_index(
155 [&](
const Index_ i, VectorPtr<Index_> sub_indices_ptr) ->
void {
156 my_count.emplace_back(sub_indices_ptr->size());
157 my_exts.emplace_back(new_extractor<false, oracle_>(matrices[i].get(), row, oracle, std::move(sub_indices_ptr), opt));
163 const Value_* fetch(
const Index_ i, Value_*
const buffer) {
165 const Index_ nmats = my_count.size();
166 for (Index_ x = 0; x < nmats; ++x) {
167 const auto ptr = my_exts[x]->fetch(i, copy);
168 const auto num = my_count[x];
176 std::vector<std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > > my_exts;
177 std::vector<Index_> my_count;
184template<
bool oracle_,
typename Value_,
typename Index_>
185class ParallelFullSparse final :
public SparseExtractor<oracle_, Value_, Index_> {
188 const std::vector<Index_>& cumulative,
189 const std::vector<Index_>&,
190 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
192 MaybeOracle<oracle_, Index_> oracle,
195 my_cumulative(cumulative),
196 my_needs_value(opt.sparse_extract_value),
197 my_needs_index(opt.sparse_extract_index)
199 my_exts.reserve(matrices.size());
200 for (
const auto& m : matrices) {
201 my_exts.emplace_back(new_extractor<true, oracle_>(m.get(), row, oracle, opt));
205 SparseRange<Value_, Index_> fetch(
const Index_ i, Value_*
const value_buffer, Index_*
const index_buffer) {
206 auto vcopy = value_buffer;
207 auto icopy = index_buffer;
208 Index_ accumulated = 0;
210 const Index_ nmats = my_exts.size();
211 for (Index_ x = 0; x < nmats; ++x) {
212 const auto range = my_exts[x]->fetch(i, vcopy, icopy);
213 accumulated += range.number;
214 if (my_needs_value) {
215 copy_n(range.value, range.number, vcopy);
216 vcopy += range.number;
218 if (my_needs_index) {
219 const auto offset = my_cumulative[x];
220 for (Index_ y = 0; y < range.number; ++y) {
221 icopy[y] = range.index[y] + offset;
223 icopy += range.number;
227 return SparseRange<Value_, Index_>(accumulated, (my_needs_value ? value_buffer : NULL), (my_needs_index ? index_buffer : NULL));
231 const std::vector<Index_>& my_cumulative;
232 bool my_needs_value, my_needs_index;
233 std::vector<std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > > my_exts;
236template<
bool oracle_,
typename Value_,
typename Index_>
237class ParallelBlockSparse final :
public SparseExtractor<oracle_, Value_, Index_> {
240 const std::vector<Index_>& cumulative,
241 const std::vector<Index_>& mapping,
242 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
244 MaybeOracle<oracle_, Index_> oracle,
245 const Index_ block_start,
246 const Index_ block_length,
249 my_cumulative(cumulative),
250 my_needs_value(opt.sparse_extract_value),
251 my_needs_index(opt.sparse_extract_index)
253 my_exts.reserve(matrices.size());
254 my_start_matrix = initialize_parallel_block(
259 [&](
const Index_ i,
const Index_ sub_block_start,
const Index_ sub_block_length) ->
void {
260 my_exts.emplace_back(new_extractor<true, oracle_>(matrices[i].get(), row, oracle, sub_block_start, sub_block_length, opt));
265 SparseRange<Value_, Index_> fetch(
const Index_ i, Value_*
const value_buffer, Index_*
const index_buffer) {
266 auto vcopy = value_buffer;
267 auto icopy = index_buffer;
270 const Index_ nmats = my_exts.size();
271 for (Index_ x = 0; x < nmats; ++x) {
272 const auto range = my_exts[x]->fetch(i, vcopy, icopy);
273 count += range.number;
274 if (my_needs_value) {
275 copy_n(range.value, range.number, vcopy);
276 vcopy += range.number;
278 if (my_needs_index) {
279 const Index_ offset = my_cumulative[x + my_start_matrix];
280 for (Index_ y = 0; y < range.number; ++y) {
281 icopy[y] = range.index[y] + offset;
283 icopy += range.number;
287 return SparseRange<Value_, Index_>(count, (my_needs_value ? value_buffer : NULL), (my_needs_index ? index_buffer : NULL));
291 const std::vector<Index_>& my_cumulative;
292 bool my_needs_value, my_needs_index;
293 std::vector<std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > > my_exts;
294 Index_ my_start_matrix;
297template<
bool oracle_,
typename Value_,
typename Index_>
298class ParallelIndexSparse final :
public SparseExtractor<oracle_, Value_, Index_> {
301 const std::vector<Index_>& cumulative,
302 const std::vector<Index_>& mapping,
303 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
305 MaybeOracle<oracle_, Index_> oracle,
306 VectorPtr<Index_> indices_ptr,
309 my_cumulative(cumulative),
310 my_needs_value(opt.sparse_extract_value),
311 my_needs_index(opt.sparse_extract_index)
313 my_exts.reserve(matrices.size());
314 my_which_matrix.reserve(matrices.size());
315 initialize_parallel_index(
319 [&](
const Index_ i, VectorPtr<Index_> sub_indices_ptr) ->
void {
320 my_which_matrix.emplace_back(i);
321 my_exts.emplace_back(new_extractor<true, oracle_>(matrices[i].get(), row, oracle, std::move(sub_indices_ptr), opt));
326 SparseRange<Value_, Index_> fetch(
const Index_ i, Value_*
const value_buffer, Index_*
const index_buffer) {
327 auto vcopy = value_buffer;
328 auto icopy = index_buffer;
331 const Index_ nmats = my_which_matrix.size();
332 for (Index_ x = 0; x < nmats; ++x) {
333 const auto range = my_exts[x]->fetch(i, vcopy, icopy);
334 count += range.number;
335 if (my_needs_value) {
336 copy_n(range.value, range.number, vcopy);
337 vcopy += range.number;
340 if (my_needs_index) {
341 const Index_ offset = my_cumulative[my_which_matrix[x]];
342 for (Index_ y = 0; y < range.number; ++y) {
343 icopy[y] = range.index[y] + offset;
345 icopy += range.number;
349 return SparseRange<Value_, Index_>(count, (my_needs_value ? value_buffer : NULL), (my_needs_index ? index_buffer : NULL));
353 const std::vector<Index_>& my_cumulative;
354 bool my_needs_value, my_needs_index;
355 std::vector<std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > > my_exts;
356 std::vector<Index_> my_which_matrix;
363template<
typename Value_,
typename Index_>
364class MyopicPerpendicularDense final :
public MyopicDenseExtractor<Value_, Index_> {
366 template<
typename ... Args_>
367 MyopicPerpendicularDense(
368 const std::vector<Index_>& cumulative,
369 const std::vector<Index_>& mapping,
370 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
372 const Args_& ... args
374 my_cumulative(cumulative),
377 my_exts.reserve(matrices.size());
378 for (
const auto& m : matrices) {
379 my_exts.emplace_back(m->dense(row, args...));
383 const Value_* fetch(
const Index_ i, Value_*
const buffer) {
384 const Index_ chosen = my_mapping[i];
385 return my_exts[chosen]->fetch(i - my_cumulative[chosen], buffer);
389 const std::vector<Index_>& my_cumulative;
390 const std::vector<Index_>& my_mapping;
391 std::vector<std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > > my_exts;
394template<
typename Value_,
typename Index_>
395class MyopicPerpendicularSparse final :
public MyopicSparseExtractor<Value_, Index_> {
397 template<
typename ... Args_>
398 MyopicPerpendicularSparse(
399 const std::vector<Index_>& cumulative,
400 const std::vector<Index_>& mapping,
401 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
403 const Args_& ... args
405 my_cumulative(cumulative),
408 my_exts.reserve(matrices.size());
409 for (
const auto& m : matrices) {
410 my_exts.emplace_back(m->sparse(row, args...));
414 SparseRange<Value_, Index_> fetch(
const Index_ i, Value_*
const vbuffer, Index_*
const ibuffer) {
415 const Index_ chosen = my_mapping[i];
416 return my_exts[chosen]->fetch(i - my_cumulative[chosen], vbuffer, ibuffer);
420 const std::vector<Index_>& my_cumulative;
421 const std::vector<Index_>& my_mapping;
422 std::vector<std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > > my_exts;
425template<
typename Index_,
class Initialize_>
426void initialize_perp_oracular(
427 const std::vector<Index_>& cumulative,
428 const std::vector<Index_>& mapping,
429 const Oracle<Index_>& oracle,
430 std::vector<Index_>& chosen,
433 const auto ntotal = oracle.total();
434 chosen.reserve(ntotal);
437 bool consecutive =
true;
440 std::vector<Index_> predictions;
442 void add(
const Index_ p) {
449 if (number + start == p) {
455 std::iota(predictions.begin(), predictions.end(), start);
458 predictions.push_back(p);
462 const auto nmats = cumulative.size() - 1;
463 auto predictions = create_container_of_Index_size<std::vector<Predictions> >(nmats);
464 for (I<
decltype(ntotal)> i = 0; i < ntotal; ++i) {
465 const auto prediction = oracle.get(i);
466 const Index_ choice = mapping[prediction];
467 chosen.push_back(choice);
468 predictions[choice].add(prediction - cumulative[choice]);
471 for (I<
decltype(nmats)> x = 0; x < nmats; ++x) {
472 auto& current = predictions[x];
473 if (current.consecutive) {
474 if (current.number) {
475 init(x, std::make_shared<ConsecutiveOracle<Index_> >(current.start, current.number));
478 if (!current.predictions.empty()) {
479 init(x, std::make_shared<FixedVectorOracle<Index_> >(std::move(current.predictions)));
485template<
typename Value_,
typename Index_>
486class OracularPerpendicularDense final :
public OracularDenseExtractor<Value_, Index_> {
488 template<
typename ... Args_>
489 OracularPerpendicularDense(
490 const std::vector<Index_>& cumulative,
491 const std::vector<Index_>& mapping,
492 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
494 std::shared_ptr<
const Oracle<Index_> > ora,
495 const Args_& ... args
498 initialize_perp_oracular(
503 [&](
const Index_ x, std::shared_ptr<
const Oracle<Index_> > subora) ->
void {
504 my_exts[x] = matrices[x]->dense(row, std::move(subora), args...);
509 const Value_* fetch(
const Index_ i, Value_*
const buffer) {
510 const auto chosen = my_segments[my_used];
511 const auto output = my_exts[chosen]->fetch(i, buffer);
517 std::vector<Index_> my_segments;
518 std::vector<std::unique_ptr<OracularDenseExtractor<Value_, Index_> > > my_exts;
522template<
typename Value_,
typename Index_>
523class OracularPerpendicularSparse final :
public OracularSparseExtractor<Value_, Index_> {
525 template<
typename ... Args_>
526 OracularPerpendicularSparse(
527 const std::vector<Index_>& cumulative,
528 const std::vector<Index_>& mapping,
529 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
531 std::shared_ptr<
const Oracle<Index_> > ora,
532 const Args_& ... args
535 initialize_perp_oracular(
540 [&](
const Index_ x, std::shared_ptr<
const Oracle<Index_> > subora) ->
void {
541 my_exts[x] = matrices[x]->sparse(row, std::move(subora), args...);
546 SparseRange<Value_, Index_> fetch(Index_ i, Value_* vbuffer, Index_* ibuffer) {
547 const auto chosen = my_segments[my_used];
548 const auto output = my_exts[chosen]->fetch(i, vbuffer, ibuffer);
554 std::vector<Index_> my_segments;
555 std::vector<std::unique_ptr<OracularSparseExtractor<Value_, Index_> > > my_exts;
573template<
typename Value_,
typename Index_>
583 my_matrices(std::move(matrices)), my_by_row(by_row)
585 auto nmats = my_matrices.size();
586 my_cumulative.reserve(sanisizer::sum<I<
decltype(my_cumulative.size())> >(nmats, 1));
587 I<
decltype(nmats)> sofar = 0;
588 my_cumulative.push_back(0);
590 for (I<
decltype(nmats)> i = 0; i < nmats; ++i) {
591 auto& current = my_matrices[i];
592 Index_ primary, secondary;
594 primary = current->nrow();
595 secondary = current->ncol();
597 primary = current->ncol();
598 secondary = current->nrow();
602 my_otherdim = secondary;
603 }
else if (my_otherdim != secondary) {
604 throw std::runtime_error(
"all 'my_matrices' should have the same number of " + (my_by_row ? std::string(
"columns") : std::string(
"rows")));
611 my_matrices[sofar] = std::move(current);
613 my_cumulative.push_back(sanisizer::sum<Index_>(my_cumulative.back(), primary));
618 my_matrices.resize(sofar);
625 my_mapping.reserve(my_cumulative.back());
626 for (I<
decltype(nmats)> i = 0; i < nmats; ++i) {
627 my_mapping.insert(my_mapping.end(), (my_by_row ? my_matrices[i]->nrow() : my_matrices[i]->ncol()), i);
631 for (
const auto& x : my_matrices) {
632 const double total =
static_cast<double>(x->nrow()) *
static_cast<double>(x->ncol());
634 my_sparse_prop += total * x->is_sparse_proportion();
635 my_by_row_prop += total * x->prefer_rows_proportion();
638 my_sparse_prop /= denom;
639 my_by_row_prop /= denom;
642 for (
int d = 0; d < 2; ++d) {
643 my_uses_oracle[d] =
false;
644 for (
const auto& x : my_matrices) {
645 if (x->uses_oracle(d)) {
646 my_uses_oracle[d] =
true;
660 DelayedBind(std::vector<std::shared_ptr<const
Matrix<Value_, Index_> > >(matrices.begin(), matrices.end()), by_row) {}
663 std::vector<std::shared_ptr<const Matrix<Value_, Index_> > > my_matrices;
666 Index_ my_otherdim = 0;
667 std::vector<Index_> my_cumulative;
668 std::vector<Index_> my_mapping;
670 double my_sparse_prop = 0, my_by_row_prop = 0;
671 std::array<bool, 2> my_uses_oracle;
676 return my_cumulative.back();
686 return my_cumulative.back();
691 return my_sparse_prop > 0.5;
695 return my_sparse_prop;
699 return my_by_row_prop > 0.5;
703 return my_by_row_prop;
707 return my_uses_oracle[row];
712 using Matrix<Value_, Index_>::sparse;
718 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> >
dense(
722 if (my_matrices.size() == 1) {
723 return my_matrices[0]->dense(row, opt);
724 }
else if (row == my_by_row) {
725 return std::make_unique<DelayedBind_internal::MyopicPerpendicularDense<Value_, Index_> >(
733 return std::make_unique<DelayedBind_internal::ParallelDense<false, Value_, Index_> >(
744 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> >
dense(
746 const Index_ block_start,
747 const Index_ block_length,
750 if (my_matrices.size() == 1) {
751 return my_matrices[0]->dense(row, block_start, block_length, opt);
752 }
else if (row == my_by_row) {
753 return std::make_unique<DelayedBind_internal::MyopicPerpendicularDense<Value_, Index_> >(
763 return std::make_unique<DelayedBind_internal::ParallelDense<false, Value_, Index_> >(
776 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> >
dense(
781 if (my_matrices.size() == 1) {
782 return my_matrices[0]->dense(row, std::move(indices_ptr), opt);
783 }
else if (row == my_by_row) {
784 return std::make_unique<DelayedBind_internal::MyopicPerpendicularDense<Value_, Index_> >(
789 std::move(indices_ptr),
793 return std::make_unique<DelayedBind_internal::ParallelDense<false, Value_, Index_> >(
799 std::move(indices_ptr),
809 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
813 if (my_matrices.size() == 1) {
814 return my_matrices[0]->sparse(row, opt);
815 }
else if (row == my_by_row) {
816 return std::make_unique<DelayedBind_internal::MyopicPerpendicularSparse<Value_, Index_> >(
824 return std::make_unique<DelayedBind_internal::ParallelFullSparse<false, Value_, Index_> >(
835 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
837 const Index_ block_start,
838 const Index_ block_length,
841 if (my_matrices.size() == 1) {
842 return my_matrices[0]->sparse(row, block_start, block_length, opt);
843 }
else if (row == my_by_row) {
844 return std::make_unique<DelayedBind_internal::MyopicPerpendicularSparse<Value_, Index_> >(
854 return std::make_unique<DelayedBind_internal::ParallelBlockSparse<false, Value_, Index_> >(
867 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
872 if (my_matrices.size() == 1) {
873 return my_matrices[0]->sparse(row, std::move(indices_ptr), opt);
874 }
else if (row == my_by_row) {
875 return std::make_unique<DelayedBind_internal::MyopicPerpendicularSparse<Value_, Index_> >(
880 std::move(indices_ptr),
884 return std::make_unique<DelayedBind_internal::ParallelIndexSparse<false, Value_, Index_> >(
890 std::move(indices_ptr),
900 std::unique_ptr<OracularDenseExtractor<Value_, Index_> >
dense(
905 if (my_matrices.size() == 1) {
906 return my_matrices[0]->dense(row, std::move(oracle), opt);
907 }
else if (!my_uses_oracle[row]) {
908 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(
912 }
else if (row == my_by_row) {
913 return std::make_unique<DelayedBind_internal::OracularPerpendicularDense<Value_, Index_> >(
922 return std::make_unique<DelayedBind_internal::ParallelDense<true, Value_, Index_> >(
933 std::unique_ptr<OracularDenseExtractor<Value_, Index_> >
dense(
936 const Index_ block_start,
937 const Index_ block_length,
940 if (my_matrices.size() == 1) {
941 return my_matrices[0]->dense(row, std::move(oracle), block_start, block_length, opt);
942 }
else if (!my_uses_oracle[row]) {
943 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(
945 dense(row, block_start, block_length, opt)
947 }
else if (row == my_by_row) {
948 return std::make_unique<DelayedBind_internal::OracularPerpendicularDense<Value_, Index_> >(
959 return std::make_unique<DelayedBind_internal::ParallelDense<true, Value_, Index_> >(
972 std::unique_ptr<OracularDenseExtractor<Value_, Index_> >
dense(
978 if (my_matrices.size() == 1) {
979 return my_matrices[0]->dense(row, std::move(oracle), std::move(indices_ptr), opt);
980 }
else if (!my_uses_oracle[row]) {
981 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(
983 dense(row, std::move(indices_ptr), opt)
985 }
else if (row == my_by_row) {
986 return std::make_unique<DelayedBind_internal::OracularPerpendicularDense<Value_, Index_> >(
992 std::move(indices_ptr),
996 return std::make_unique<DelayedBind_internal::ParallelDense<true, Value_, Index_> >(
1002 std::move(indices_ptr),
1012 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
1017 if (my_matrices.size() == 1) {
1018 return my_matrices[0]->sparse(row, std::move(oracle), opt);
1019 }
else if (!my_uses_oracle[row]) {
1020 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(
1024 }
else if (row == my_by_row) {
1025 return std::make_unique<DelayedBind_internal::OracularPerpendicularSparse<Value_, Index_> >(
1034 return std::make_unique<DelayedBind_internal::ParallelFullSparse<true, Value_, Index_> >(
1045 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
1047 std::shared_ptr<
const Oracle<Index_> > oracle,
1048 const Index_ block_start,
1049 const Index_ block_length,
1052 if (my_matrices.size() == 1) {
1053 return my_matrices[0]->sparse(row, std::move(oracle), block_start, block_length, opt);
1054 }
else if (!my_uses_oracle[row]) {
1055 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(
1057 sparse(row, block_start, block_length, opt)
1059 }
else if (row == my_by_row) {
1060 return std::make_unique<DelayedBind_internal::OracularPerpendicularSparse<Value_, Index_> >(
1071 return std::make_unique<DelayedBind_internal::ParallelBlockSparse<true, Value_, Index_> >(
1084 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
1086 std::shared_ptr<
const Oracle<Index_> > oracle,
1090 if (my_matrices.size() == 1) {
1091 return my_matrices[0]->sparse(row, std::move(oracle), std::move(indices_ptr), opt);
1092 }
else if (!my_uses_oracle[row]) {
1093 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(
1095 sparse(row, std::move(indices_ptr), opt)
1097 }
else if (row == my_by_row) {
1098 return std::make_unique<DelayedBind_internal::OracularPerpendicularSparse<Value_, Index_> >(
1104 std::move(indices_ptr),
1108 return std::make_unique<DelayedBind_internal::ParallelIndexSparse<true, Value_, Index_> >(
1114 std::move(indices_ptr),
1125template<
typename Value_,
typename Index_>
1126std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > > matrices,
bool row) {
1127 return std::shared_ptr<Matrix<Value_, Index_> >(
new DelayedBind<Value_, Index_>(std::move(matrices), row));
1130template<
typename Value_,
typename Index_>
1131std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<Matrix<Value_, Index_> > > matrices,
bool row) {
1132 return std::shared_ptr<Matrix<Value_, Index_> >(
new DelayedBind<Value_, Index_>(std::move(matrices), row));
1135template<
int margin_,
typename Value_,
typename Index_>
1136std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > > matrices) {
1137 return make_DelayedBind(std::move(matrices), margin_ == 0);
1140template<
int margin_,
typename Value_,
typename Index_>
1141std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<Matrix<Value_, Index_> > > matrices) {
1142 return make_DelayedBind(std::move(matrices), margin_ == 0);
Iterate across consecutive elements of the target dimension.
Iterate across a fixed sequence of elements on the target dimension.
Virtual class for a matrix of some numeric type.
Delayed combining of a matrix.
Definition DelayedBind.hpp:574
bool uses_oracle(const bool row) const
Definition DelayedBind.hpp:706
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedBind.hpp:972
DelayedBind(std::vector< std::shared_ptr< const Matrix< Value_, Index_ > > > matrices, const bool by_row)
Definition DelayedBind.hpp:582
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, const Options &opt) const
Definition DelayedBind.hpp:718
double is_sparse_proportion() const
Definition DelayedBind.hpp:694
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedBind.hpp:744
Index_ nrow() const
Definition DelayedBind.hpp:674
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedBind.hpp:776
DelayedBind(const std::vector< std::shared_ptr< Matrix< Value_, Index_ > > > &matrices, const bool by_row)
Definition DelayedBind.hpp:659
bool is_sparse() const
Definition DelayedBind.hpp:690
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedBind.hpp:900
Index_ ncol() const
Definition DelayedBind.hpp:682
bool prefer_rows() const
Definition DelayedBind.hpp:698
double prefer_rows_proportion() const
Definition DelayedBind.hpp:702
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedBind.hpp:933
Virtual class for a matrix.
Definition Matrix.hpp:59
Predict future access requests on the target dimension.
Definition Oracle.hpp:29
Copy data from one buffer to another.
Flexible representations for matrix data.
Definition Extractor.hpp:15
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
void resize_container_to_Index_size(Container_ &container, const Index_ x, Args_ &&... args)
Definition Index_to_container.hpp:92
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:273
Value_ * copy_n(const Value_ *const input, const Size_ n, Value_ *const output)
Definition copy.hpp:37
std::size_t PredictionIndex
Definition Oracle.hpp:18
Options for accessing data from a Matrix instance.
Definition Options.hpp:30