1#ifndef TATAMI_DELAYED_BIND_HPP
2#define TATAMI_DELAYED_BIND_HPP
30namespace DelayedBind_internal {
36template<
typename Index_,
class Initialize_>
37Index_ initialize_parallel_block(
38 const std::vector<Index_>& cumulative,
39 const std::vector<Index_>& mapping,
44 if (mapping.empty()) {
48 Index_ start_index = mapping[block_start];
49 Index_ actual_start = block_start - cumulative[start_index];
50 Index_ block_end = block_start + block_length;
52 for (Index_ index = start_index, nmats = cumulative.size() - 1; index < nmats; ++index) {
53 Index_ submat_end = cumulative[index + 1];
54 bool not_final = (block_end > submat_end);
55 Index_ actual_end = (not_final ? submat_end : block_end) - cumulative[index];
56 init(index, actual_start, actual_end - actual_start);
66template<
typename Index_,
class Initialize_>
67void initialize_parallel_index(
68 const std::vector<Index_>& cumulative,
69 const std::vector<Index_>& mapping,
70 const std::vector<Index_>& indices,
73 Index_ counter = 0, il = indices.size();
74 while (counter < il) {
75 Index_ first_index = indices[counter];
76 Index_ bind_index = mapping[first_index];
77 Index_ lower = cumulative[bind_index];
78 Index_ upper = cumulative[bind_index + 1];
81 auto slice_ptr = std::make_shared<std::vector<Index_> >(1, first_index - lower);
84 while (counter < il && indices[counter] < upper) {
85 slice_ptr->push_back(indices[counter] - lower);
89 init(bind_index, std::move(slice_ptr));
93template<
bool oracle_,
typename Value_,
typename Index_>
94class ParallelDense :
public DenseExtractor<oracle_, Value_, Index_> {
97 const std::vector<Index_>&,
98 const std::vector<Index_>&,
99 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
101 MaybeOracle<oracle_, Index_> oracle,
104 my_exts.reserve(matrices.size());
105 my_count.reserve(matrices.size());
106 for (
const auto& m : matrices) {
107 my_count.emplace_back(row ? m->ncol() : m->nrow());
108 my_exts.emplace_back(new_extractor<false, oracle_>(m.get(), row, oracle, opt));
113 const std::vector<Index_>& cumulative,
114 const std::vector<Index_>& mapping,
115 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
117 MaybeOracle<oracle_, Index_> oracle,
122 my_exts.reserve(matrices.size());
123 my_count.reserve(matrices.size());
124 initialize_parallel_block(
129 [&](Index_ i, Index_ sub_block_start, Index_ sub_block_length) ->
void {
130 my_count.emplace_back(sub_block_length);
131 my_exts.emplace_back(new_extractor<false, oracle_>(matrices[i].get(), row, oracle, sub_block_start, sub_block_length, opt));
137 const std::vector<Index_>& cumulative,
138 const std::vector<Index_>& mapping,
139 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
141 MaybeOracle<oracle_, Index_> oracle,
142 VectorPtr<Index_> indices_ptr,
145 my_exts.reserve(matrices.size());
146 my_count.reserve(matrices.size());
147 initialize_parallel_index(
151 [&](Index_ i, VectorPtr<Index_> sub_indices_ptr) ->
void {
152 my_count.emplace_back(sub_indices_ptr->size());
153 my_exts.emplace_back(new_extractor<false, oracle_>(matrices[i].get(), row, oracle, std::move(sub_indices_ptr), opt));
159 const Value_* fetch(Index_ i, Value_* buffer) {
161 for (Index_ x = 0, end = my_count.size(); x < end; ++x) {
162 auto ptr = my_exts[x]->fetch(i, copy);
163 auto num = my_count[x];
171 std::vector<std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > > my_exts;
172 std::vector<Index_> my_count;
179template<
bool oracle_,
typename Value_,
typename Index_>
180class ParallelFullSparse :
public SparseExtractor<oracle_, Value_, Index_> {
183 const std::vector<Index_>& cumulative,
184 const std::vector<Index_>&,
185 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
187 MaybeOracle<oracle_, Index_> oracle,
188 const Options& opt) :
189 my_cumulative(cumulative),
190 my_needs_value(opt.sparse_extract_value),
191 my_needs_index(opt.sparse_extract_index)
193 my_exts.reserve(matrices.size());
194 for (
const auto& m : matrices) {
195 my_exts.emplace_back(new_extractor<true, oracle_>(m.get(), row, oracle, opt));
199 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
200 auto vcopy = value_buffer;
201 auto icopy = index_buffer;
202 Index_ accumulated = 0;
204 for (Index_ x = 0, end = my_cumulative.size() - 1; x < end; ++x) {
205 auto range = my_exts[x]->fetch(i, vcopy, icopy);
206 accumulated += range.number;
207 if (my_needs_value) {
208 copy_n(range.value, range.number, vcopy);
209 vcopy += range.number;
211 if (my_needs_index) {
212 auto offset = my_cumulative[x];
213 for (Index_ y = 0; y < range.number; ++y) {
214 icopy[y] = range.index[y] + offset;
216 icopy += range.number;
220 return SparseRange<Value_, Index_>(accumulated, (my_needs_value ? value_buffer : NULL), (my_needs_index ? index_buffer : NULL));
224 const std::vector<Index_>& my_cumulative;
225 bool my_needs_value, my_needs_index;
226 std::vector<std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > > my_exts;
229template<
bool oracle_,
typename Value_,
typename Index_>
230class ParallelBlockSparse :
public SparseExtractor<oracle_, Value_, Index_> {
233 const std::vector<Index_>& cumulative,
234 const std::vector<Index_>& mapping,
235 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
237 MaybeOracle<oracle_, Index_> oracle,
240 const Options& opt) :
241 my_cumulative(cumulative),
242 my_needs_value(opt.sparse_extract_value),
243 my_needs_index(opt.sparse_extract_index)
245 my_exts.reserve(matrices.size());
246 my_start_matrix = initialize_parallel_block(
251 [&](Index_ i, Index_ sub_block_start, Index_ sub_block_length) ->
void {
252 my_exts.emplace_back(new_extractor<true, oracle_>(matrices[i].get(), row, oracle, sub_block_start, sub_block_length, opt));
257 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
258 auto vcopy = value_buffer;
259 auto icopy = index_buffer;
262 for (Index_ x = 0, end = my_exts.size(); x < end; ++x) {
263 auto range = my_exts[x]->fetch(i, vcopy, icopy);
264 count += range.number;
265 if (my_needs_value) {
266 copy_n(range.value, range.number, vcopy);
267 vcopy += range.number;
269 if (my_needs_index) {
270 Index_ offset = my_cumulative[x + my_start_matrix];
271 for (Index_ y = 0; y < range.number; ++y) {
272 icopy[y] = range.index[y] + offset;
274 icopy += range.number;
278 return SparseRange<Value_, Index_>(count, (my_needs_value ? value_buffer : NULL), (my_needs_index ? index_buffer : NULL));
282 const std::vector<Index_>& my_cumulative;
283 bool my_needs_value, my_needs_index;
284 std::vector<std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > > my_exts;
285 Index_ my_start_matrix;
288template<
bool oracle_,
typename Value_,
typename Index_>
289class ParallelIndexSparse :
public SparseExtractor<oracle_, Value_, Index_> {
292 const std::vector<Index_>& cumulative,
293 const std::vector<Index_>& mapping,
294 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
296 MaybeOracle<oracle_, Index_> oracle,
297 VectorPtr<Index_> indices_ptr,
298 const Options& opt) :
299 my_cumulative(cumulative),
300 my_needs_value(opt.sparse_extract_value),
301 my_needs_index(opt.sparse_extract_index)
303 my_exts.reserve(matrices.size());
304 my_which_matrix.reserve(matrices.size());
305 initialize_parallel_index(
309 [&](Index_ i, VectorPtr<Index_> sub_indices_ptr) ->
void {
310 my_which_matrix.emplace_back(i);
311 my_exts.emplace_back(new_extractor<true, oracle_>(matrices[i].get(), row, oracle, std::move(sub_indices_ptr), opt));
316 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
317 auto vcopy = value_buffer;
318 auto icopy = index_buffer;
321 for (Index_ x = 0, end = my_which_matrix.size(); x < end; ++x) {
322 auto range = my_exts[x]->fetch(i, vcopy, icopy);
323 count += range.number;
324 if (my_needs_value) {
325 copy_n(range.value, range.number, vcopy);
326 vcopy += range.number;
329 if (my_needs_index) {
330 Index_ offset = my_cumulative[my_which_matrix[x]];
331 for (Index_ y = 0; y < range.number; ++y) {
332 icopy[y] = range.index[y] + offset;
334 icopy += range.number;
338 return SparseRange<Value_, Index_>(count, (my_needs_value ? value_buffer : NULL), (my_needs_index ? index_buffer : NULL));
342 const std::vector<Index_>& my_cumulative;
343 bool my_needs_value, my_needs_index;
344 std::vector<std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > > my_exts;
345 std::vector<Index_> my_which_matrix;
352template<
typename Value_,
typename Index_>
353class MyopicPerpendicularDense :
public MyopicDenseExtractor<Value_, Index_> {
355 template<
typename ... Args_>
356 MyopicPerpendicularDense(
357 const std::vector<Index_>& cumulative,
358 const std::vector<Index_>& mapping,
359 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
361 const Args_& ... args) :
362 my_cumulative(cumulative),
365 my_exts.reserve(matrices.size());
366 for (
const auto& m : matrices) {
367 my_exts.emplace_back(m->dense(row, args...));
371 const Value_* fetch(Index_ i, Value_* buffer) {
372 Index_ chosen = my_mapping[i];
373 return my_exts[chosen]->fetch(i - my_cumulative[chosen], buffer);
377 const std::vector<Index_>& my_cumulative;
378 const std::vector<Index_>& my_mapping;
379 std::vector<std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > > my_exts;
382template<
typename Value_,
typename Index_>
383class MyopicPerpendicularSparse :
public MyopicSparseExtractor<Value_, Index_> {
385 template<
typename ... Args_>
386 MyopicPerpendicularSparse(
387 const std::vector<Index_>& cumulative,
388 const std::vector<Index_>& mapping,
389 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
391 const Args_& ... args) :
392 my_cumulative(cumulative),
395 my_exts.reserve(matrices.size());
396 for (
const auto& m : matrices) {
397 my_exts.emplace_back(m->sparse(row, args...));
401 SparseRange<Value_, Index_> fetch(Index_ i, Value_* vbuffer, Index_* ibuffer) {
402 Index_ chosen = my_mapping[i];
403 return my_exts[chosen]->fetch(i - my_cumulative[chosen], vbuffer, ibuffer);
407 const std::vector<Index_>& my_cumulative;
408 const std::vector<Index_>& my_mapping;
409 std::vector<std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > > my_exts;
412template<
typename Index_,
class Initialize_>
413void initialize_perp_oracular(
414 const std::vector<Index_>& cumulative,
415 const std::vector<Index_>& mapping,
416 const Oracle<Index_>* oracle,
417 std::vector<Index_>& chosen,
420 size_t ntotal = oracle->total();
421 chosen.reserve(ntotal);
424 bool consecutive =
true;
427 std::vector<Index_> predictions;
436 if (number + start == p) {
441 predictions.resize(number);
442 std::iota(predictions.begin(), predictions.end(), start);
445 predictions.push_back(p);
449 Index_ nmats = cumulative.size() - 1;
450 std::vector<Predictions> predictions(nmats);
451 for (
size_t i = 0; i < ntotal; ++i) {
452 auto prediction = oracle->get(i);
453 Index_ choice = mapping[prediction];
454 chosen.push_back(choice);
455 predictions[choice].add(prediction - cumulative[choice]);
458 for (Index_ x = 0; x < nmats; ++x) {
459 auto& current = predictions[x];
460 if (current.consecutive) {
461 if (current.number) {
462 init(x, std::make_shared<ConsecutiveOracle<Index_> >(current.start, current.number));
465 if (!current.predictions.empty()) {
466 init(x, std::make_shared<FixedVectorOracle<Index_> >(std::move(current.predictions)));
472template<
typename Value_,
typename Index_>
473class OracularPerpendicularDense :
public OracularDenseExtractor<Value_, Index_> {
475 template<
typename ... Args_>
476 OracularPerpendicularDense(
477 const std::vector<Index_>& cumulative,
478 const std::vector<Index_>& mapping,
479 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
481 std::shared_ptr<
const Oracle<Index_> > ora,
482 const Args_& ... args)
484 my_exts.resize(matrices.size());
485 initialize_perp_oracular(
490 [&](Index_ x, std::shared_ptr<
const Oracle<Index_> > subora) ->
void {
491 my_exts[x] = matrices[x]->dense(row, std::move(subora), args...);
496 const Value_* fetch(Index_ i, Value_* buffer) {
497 auto chosen = segments[used];
498 auto output = my_exts[chosen]->fetch(i, buffer);
504 std::vector<Index_> segments;
505 std::vector<std::unique_ptr<OracularDenseExtractor<Value_, Index_> > > my_exts;
509template<
typename Value_,
typename Index_>
510class OracularPerpendicularSparse :
public OracularSparseExtractor<Value_, Index_> {
512 template<
typename ... Args_>
513 OracularPerpendicularSparse(
514 const std::vector<Index_>& cumulative,
515 const std::vector<Index_>& mapping,
516 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
518 std::shared_ptr<
const Oracle<Index_> > ora,
519 const Args_& ... args)
521 my_exts.resize(matrices.size());
522 initialize_perp_oracular(
527 [&](Index_ x, std::shared_ptr<
const Oracle<Index_> > subora) ->
void {
528 my_exts[x] = matrices[x]->sparse(row, std::move(subora), args...);
533 SparseRange<Value_, Index_> fetch(Index_ i, Value_* vbuffer, Index_* ibuffer) {
534 auto chosen = segments[used];
535 auto output = my_exts[chosen]->fetch(i, vbuffer, ibuffer);
541 std::vector<Index_> segments;
542 std::vector<std::unique_ptr<OracularSparseExtractor<Value_, Index_> > > my_exts;
560template<
typename Value_,
typename Index_>
570 my_matrices(std::move(matrices)), my_by_row(by_row), my_cumulative(my_matrices.size()+1)
573 for (
size_t i = 0, nmats = my_matrices.size(); i < nmats; ++i) {
574 auto& current = my_matrices[i];
575 Index_ primary, secondary;
577 primary = current->nrow();
578 secondary = current->ncol();
580 primary = current->ncol();
581 secondary = current->nrow();
585 my_otherdim = secondary;
586 }
else if (my_otherdim != secondary) {
587 throw std::runtime_error(
"all 'my_matrices' should have the same number of " + (my_by_row ? std::string(
"columns") : std::string(
"rows")));
594 my_matrices[sofar] = std::move(current);
596 my_cumulative[sofar + 1] = my_cumulative[sofar] + primary;
601 my_cumulative.resize(sofar + 1);
602 my_matrices.resize(sofar);
608 my_mapping.reserve(my_cumulative.back());
609 for (Index_ i = 0, nmats = my_matrices.size(); i < nmats; ++i) {
610 my_mapping.insert(my_mapping.end(), (my_by_row ? my_matrices[i]->nrow() : my_matrices[i]->ncol()), i);
614 for (
const auto& x : my_matrices) {
615 double total =
static_cast<double>(x->nrow()) *
static_cast<double>(x->ncol());
617 my_sparse_prop += total * x->is_sparse_proportion();
618 my_by_row_prop += total * x->prefer_rows_proportion();
621 my_sparse_prop /= denom;
622 my_by_row_prop /= denom;
625 for (
int d = 0; d < 2; ++d) {
626 my_uses_oracle[d] =
false;
627 for (
const auto& x : my_matrices) {
628 if (x->uses_oracle(d)) {
629 my_uses_oracle[d] =
true;
643 DelayedBind(std::vector<std::shared_ptr<const
Matrix<Value_, Index_> > >(matrices.begin(), matrices.end()), by_row) {}
646 std::vector<std::shared_ptr<const Matrix<Value_, Index_> > > my_matrices;
649 Index_ my_otherdim = 0;
650 std::vector<Index_> my_cumulative;
651 std::vector<Index_> my_mapping;
653 double my_sparse_prop = 0, my_by_row_prop = 0;
654 std::array<bool, 2> my_uses_oracle;
659 return my_cumulative.back();
669 return my_cumulative.back();
674 return my_sparse_prop > 0.5;
678 return my_sparse_prop;
682 return my_by_row_prop > 0.5;
686 return my_by_row_prop;
690 return my_uses_oracle[row];
693 using Matrix<Value_, Index_>::dense;
695 using Matrix<Value_, Index_>::sparse;
701 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> >
dense(
bool row,
const Options& opt)
const {
702 if (my_matrices.size() == 1) {
703 return my_matrices[0]->dense(row, opt);
704 }
else if (row == my_by_row) {
705 return std::make_unique<DelayedBind_internal::MyopicPerpendicularDense<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, opt);
707 return std::make_unique<DelayedBind_internal::ParallelDense<false, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row,
false, opt);
711 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> >
dense(
bool row, Index_ block_start, Index_ block_length,
const Options& opt)
const {
712 if (my_matrices.size() == 1) {
713 return my_matrices[0]->dense(row, block_start, block_length, opt);
714 }
else if (row == my_by_row) {
715 return std::make_unique<DelayedBind_internal::MyopicPerpendicularDense<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, block_start, block_length, opt);
717 return std::make_unique<DelayedBind_internal::ParallelDense<false, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row,
false, block_start, block_length, opt);
722 if (my_matrices.size() == 1) {
723 return my_matrices[0]->dense(row, std::move(indices_ptr), opt);
724 }
else if (row == my_by_row) {
725 return std::make_unique<DelayedBind_internal::MyopicPerpendicularDense<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(indices_ptr), opt);
727 return std::make_unique<DelayedBind_internal::ParallelDense<false, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row,
false, std::move(indices_ptr), opt);
735 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
bool row,
const Options& opt)
const {
736 if (my_matrices.size() == 1) {
737 return my_matrices[0]->sparse(row, opt);
738 }
else if (row == my_by_row) {
739 return std::make_unique<DelayedBind_internal::MyopicPerpendicularSparse<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, opt);
741 return std::make_unique<DelayedBind_internal::ParallelFullSparse<false, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row,
false, opt);
745 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
bool row, Index_ block_start, Index_ block_length,
const Options& opt)
const {
746 if (my_matrices.size() == 1) {
747 return my_matrices[0]->sparse(row, block_start, block_length, opt);
748 }
else if (row == my_by_row) {
749 return std::make_unique<DelayedBind_internal::MyopicPerpendicularSparse<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, block_start, block_length, opt);
751 return std::make_unique<DelayedBind_internal::ParallelBlockSparse<false, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row,
false, block_start, block_length, opt);
755 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
bool row,
VectorPtr<Index_> indices_ptr,
const Options& opt)
const {
756 if (my_matrices.size() == 1) {
757 return my_matrices[0]->sparse(row, std::move(indices_ptr), opt);
758 }
else if (row == my_by_row) {
759 return std::make_unique<DelayedBind_internal::MyopicPerpendicularSparse<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(indices_ptr), opt);
761 return std::make_unique<DelayedBind_internal::ParallelIndexSparse<false, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row,
false, std::move(indices_ptr), opt);
769 std::unique_ptr<OracularDenseExtractor<Value_, Index_> >
dense(
bool row, std::shared_ptr<
const Oracle<Index_> > oracle,
const Options& opt)
const {
770 if (my_matrices.size() == 1) {
771 return my_matrices[0]->dense(row, std::move(oracle), opt);
772 }
else if (!my_uses_oracle[row]) {
773 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, opt));
774 }
else if (row == my_by_row) {
775 return std::make_unique<DelayedBind_internal::OracularPerpendicularDense<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), opt);
777 return std::make_unique<DelayedBind_internal::ParallelDense<true, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), opt);
781 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 {
782 if (my_matrices.size() == 1) {
783 return my_matrices[0]->dense(row, std::move(oracle), block_start, block_length, opt);
784 }
else if (!my_uses_oracle[row]) {
785 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, block_start, block_length, opt));
786 }
else if (row == my_by_row) {
787 return std::make_unique<DelayedBind_internal::OracularPerpendicularDense<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), block_start, block_length, opt);
789 return std::make_unique<DelayedBind_internal::ParallelDense<true, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), block_start, block_length, opt);
794 if (my_matrices.size() == 1) {
795 return my_matrices[0]->dense(row, std::move(oracle), std::move(indices_ptr), opt);
796 }
else if (!my_uses_oracle[row]) {
797 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, std::move(indices_ptr), opt));
798 }
else if (row == my_by_row) {
799 return std::make_unique<DelayedBind_internal::OracularPerpendicularDense<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), std::move(indices_ptr), opt);
801 return std::make_unique<DelayedBind_internal::ParallelDense<true, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), std::move(indices_ptr), opt);
809 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
bool row, std::shared_ptr<
const Oracle<Index_> > oracle,
const Options& opt)
const {
810 if (my_matrices.size() == 1) {
811 return my_matrices[0]->sparse(row, std::move(oracle), opt);
812 }
else if (!my_uses_oracle[row]) {
813 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, opt));
814 }
else if (row == my_by_row) {
815 return std::make_unique<DelayedBind_internal::OracularPerpendicularSparse<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), opt);
817 return std::make_unique<DelayedBind_internal::ParallelFullSparse<true, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), opt);
821 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 {
822 if (my_matrices.size() == 1) {
823 return my_matrices[0]->sparse(row, std::move(oracle), block_start, block_length, opt);
824 }
else if (!my_uses_oracle[row]) {
825 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, block_start, block_length, opt));
826 }
else if (row == my_by_row) {
827 return std::make_unique<DelayedBind_internal::OracularPerpendicularSparse<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), block_start, block_length, opt);
829 return std::make_unique<DelayedBind_internal::ParallelBlockSparse<true, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), block_start, block_length, opt);
833 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
bool row, std::shared_ptr<
const Oracle<Index_> > oracle,
VectorPtr<Index_> indices_ptr,
const Options& opt)
const {
834 if (my_matrices.size() == 1) {
835 return my_matrices[0]->sparse(row, std::move(oracle), std::move(indices_ptr), opt);
836 }
else if (!my_uses_oracle[row]) {
837 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, std::move(indices_ptr), opt));
838 }
else if (row == my_by_row) {
839 return std::make_unique<DelayedBind_internal::OracularPerpendicularSparse<Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), std::move(indices_ptr), opt);
841 return std::make_unique<DelayedBind_internal::ParallelIndexSparse<true, Value_, Index_> >(my_cumulative, my_mapping, my_matrices, row, std::move(oracle), std::move(indices_ptr), opt);
850template<
typename Value_,
typename Index_>
851std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > > matrices,
bool row) {
852 return std::shared_ptr<Matrix<Value_, Index_> >(
new DelayedBind<Value_, Index_>(std::move(matrices), row));
855template<
typename Value_,
typename Index_>
856std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<Matrix<Value_, Index_> > > matrices,
bool row) {
857 return std::shared_ptr<Matrix<Value_, Index_> >(
new DelayedBind<Value_, Index_>(std::move(matrices), row));
860template<
int margin_,
typename Value_,
typename Index_>
861std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > > matrices) {
862 return make_DelayedBind(std::move(matrices), margin_ == 0);
865template<
int margin_,
typename Value_,
typename Index_>
866std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<Matrix<Value_, Index_> > > matrices) {
867 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:561
DelayedBind(const std::vector< std::shared_ptr< Matrix< Value_, Index_ > > > &matrices, bool by_row)
Definition DelayedBind.hpp:642
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedBind.hpp:793
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, const Options &opt) const
Definition DelayedBind.hpp:701
double is_sparse_proportion() const
Definition DelayedBind.hpp:677
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedBind.hpp:721
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedBind.hpp:769
Index_ nrow() const
Definition DelayedBind.hpp:657
bool is_sparse() const
Definition DelayedBind.hpp:673
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 DelayedBind.hpp:781
Index_ ncol() const
Definition DelayedBind.hpp:665
DelayedBind(std::vector< std::shared_ptr< const Matrix< Value_, Index_ > > > matrices, bool by_row)
Definition DelayedBind.hpp:569
bool prefer_rows() const
Definition DelayedBind.hpp:681
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedBind.hpp:711
double prefer_rows_proportion() const
Definition DelayedBind.hpp:685
bool uses_oracle(bool row) const
Definition DelayedBind.hpp:689
Virtual class for a matrix.
Definition Matrix.hpp:59
Predict future access requests on the target dimension.
Definition Oracle.hpp:21
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
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:273
Value_ * copy_n(const Value_ *input, Size_ n, Value_ *output)
Definition copy.hpp:25
Options for accessing data from a Matrix instance.
Definition Options.hpp:30