1#ifndef TATAMI_DELAYED_BIND_HPP
2#define TATAMI_DELAYED_BIND_HPP
34namespace DelayedBind_internal {
49template<
typename Index_>
50class CompressedMapping {
52 CompressedMapping() =
default;
54 CompressedMapping(Index_ min_size,
const std::vector<Index_>& cumulative) {
57 while (min_size > 1) {
61 assert(sanisizer::is_less_than(min_size, std::numeric_limits<Index_>::digits));
62 const auto bin_size =
static_cast<Index_
>(1) << my_shift;
63 my_mask = (bin_size - 1);
65 const auto total_dim = cumulative.back();
66 assert(min_size <= total_dim);
67 const auto total_bins = (total_dim >> my_shift) + ((total_dim & my_mask) > 0);
68 my_bins.reserve(total_bins);
71 for (I<
decltype(total_bins)> b = 0; b < total_bins; ++b) {
74 Index_ lower = b << my_shift;
75 while (cumulative[pos] <= lower) {
81 const auto until_next = sanisizer::min(cumulative[pos] - lower, bin_size);
96 const Index_ encoding = (
static_cast<Index_
>(pos - 1) << my_shift) |
static_cast<Index_
>(until_next - 1);
97 my_bins.push_back(encoding);
101 Index_ operator[](
const Index_ i)
const {
102 const auto encoded = my_bins[i >> my_shift];
106 return sanisizer::sum_unsafe<Index_>(encoded >> my_shift, sanisizer::is_greater_than(i & my_mask, encoded & my_mask));
110 std::vector<Index_> my_bins;
119template<
typename Index_,
class Initialize_>
120Index_ initialize_parallel_block(
121 const std::vector<Index_>& cumulative,
122 const CompressedMapping<Index_>& mapping,
123 const Index_ block_start,
124 const Index_ block_length,
125 const Initialize_ init
127 const Index_ nmats = cumulative.size() - 1;
132 const Index_ start_index = mapping[block_start];
133 Index_ actual_start = block_start - cumulative[start_index];
134 const Index_ block_end = block_start + block_length;
136 for (Index_ index = start_index; index < nmats; ++index) {
137 const Index_ submat_end = cumulative[index + 1];
138 bool not_final = (block_end > submat_end);
139 const Index_ actual_end = (not_final ? submat_end : block_end) - cumulative[index];
140 init(index, actual_start, actual_end - actual_start);
150template<
typename Index_,
class Initialize_>
151void initialize_parallel_index(
152 const std::vector<Index_>& cumulative,
153 const CompressedMapping<Index_>& mapping,
154 const std::vector<Index_>& indices,
155 const Initialize_ init
158 const Index_ il = indices.size();
159 while (counter < il) {
160 const Index_ first_index = indices[counter];
161 const Index_ bind_index = mapping[first_index];
162 const Index_ lower = cumulative[bind_index];
163 const Index_ upper = cumulative[bind_index + 1];
166 auto slice_ptr = std::make_shared<std::vector<Index_> >(1, first_index - lower);
169 while (counter < il && indices[counter] < upper) {
170 slice_ptr->push_back(indices[counter] - lower);
174 init(bind_index, std::move(slice_ptr));
178template<
bool oracle_,
typename Value_,
typename Index_>
179class ParallelDense final :
public DenseExtractor<oracle_, Value_, Index_> {
182 const std::vector<Index_>&,
183 const CompressedMapping<Index_>&,
184 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
186 MaybeOracle<oracle_, Index_> oracle,
189 my_exts.reserve(matrices.size());
190 my_count.reserve(matrices.size());
191 for (
const auto& m : matrices) {
192 my_count.emplace_back(row ? m->ncol() : m->nrow());
193 my_exts.emplace_back(new_extractor<false, oracle_>(m.get(), row, oracle, opt));
198 const std::vector<Index_>& cumulative,
199 const CompressedMapping<Index_>& mapping,
200 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
202 MaybeOracle<oracle_, Index_> oracle,
203 const Index_ block_start,
204 const Index_ block_length,
207 my_exts.reserve(matrices.size());
208 my_count.reserve(matrices.size());
209 initialize_parallel_block(
214 [&](
const Index_ i,
const Index_ sub_block_start,
const Index_ sub_block_length) ->
void {
215 my_count.emplace_back(sub_block_length);
216 my_exts.emplace_back(new_extractor<false, oracle_>(matrices[i].get(), row, oracle, sub_block_start, sub_block_length, opt));
222 const std::vector<Index_>& cumulative,
223 const CompressedMapping<Index_>& mapping,
224 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
226 MaybeOracle<oracle_, Index_> oracle,
227 VectorPtr<Index_> indices_ptr,
230 my_exts.reserve(matrices.size());
231 my_count.reserve(matrices.size());
232 initialize_parallel_index(
236 [&](
const Index_ i, VectorPtr<Index_> sub_indices_ptr) ->
void {
237 my_count.emplace_back(sub_indices_ptr->size());
238 my_exts.emplace_back(new_extractor<false, oracle_>(matrices[i].get(), row, oracle, std::move(sub_indices_ptr), opt));
244 const Value_* fetch(
const Index_ i, Value_*
const buffer) {
246 const Index_ nmats = my_count.size();
247 for (Index_ x = 0; x < nmats; ++x) {
248 const auto ptr = my_exts[x]->fetch(i, copy);
249 const auto num = my_count[x];
257 std::vector<std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > > my_exts;
258 std::vector<Index_> my_count;
265template<
bool oracle_,
typename Value_,
typename Index_>
266class ParallelFullSparse final :
public SparseExtractor<oracle_, Value_, Index_> {
269 const std::vector<Index_>& cumulative,
270 const CompressedMapping<Index_>&,
271 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
273 MaybeOracle<oracle_, Index_> oracle,
276 my_cumulative(cumulative),
277 my_needs_value(opt.sparse_extract_value),
278 my_needs_index(opt.sparse_extract_index)
280 my_exts.reserve(matrices.size());
281 for (
const auto& m : matrices) {
282 my_exts.emplace_back(new_extractor<true, oracle_>(m.get(), row, oracle, opt));
286 SparseRange<Value_, Index_> fetch(
const Index_ i, Value_*
const value_buffer, Index_*
const index_buffer) {
287 auto vcopy = value_buffer;
288 auto icopy = index_buffer;
289 Index_ accumulated = 0;
291 const Index_ nmats = my_exts.size();
292 for (Index_ x = 0; x < nmats; ++x) {
293 const auto range = my_exts[x]->fetch(i, vcopy, icopy);
294 accumulated += range.number;
295 if (my_needs_value) {
296 copy_n(range.value, range.number, vcopy);
297 vcopy += range.number;
299 if (my_needs_index) {
300 const auto offset = my_cumulative[x];
301 for (Index_ y = 0; y < range.number; ++y) {
302 icopy[y] = range.index[y] + offset;
304 icopy += range.number;
308 return SparseRange<Value_, Index_>(accumulated, (my_needs_value ? value_buffer : NULL), (my_needs_index ? index_buffer : NULL));
312 const std::vector<Index_>& my_cumulative;
313 bool my_needs_value, my_needs_index;
314 std::vector<std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > > my_exts;
317template<
bool oracle_,
typename Value_,
typename Index_>
318class ParallelBlockSparse final :
public SparseExtractor<oracle_, Value_, Index_> {
321 const std::vector<Index_>& cumulative,
322 const CompressedMapping<Index_>& mapping,
323 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
325 MaybeOracle<oracle_, Index_> oracle,
326 const Index_ block_start,
327 const Index_ block_length,
330 my_cumulative(cumulative),
331 my_needs_value(opt.sparse_extract_value),
332 my_needs_index(opt.sparse_extract_index)
334 my_exts.reserve(matrices.size());
335 my_start_matrix = initialize_parallel_block(
340 [&](
const Index_ i,
const Index_ sub_block_start,
const Index_ sub_block_length) ->
void {
341 my_exts.emplace_back(new_extractor<true, oracle_>(matrices[i].get(), row, oracle, sub_block_start, sub_block_length, opt));
346 SparseRange<Value_, Index_> fetch(
const Index_ i, Value_*
const value_buffer, Index_*
const index_buffer) {
347 auto vcopy = value_buffer;
348 auto icopy = index_buffer;
351 const Index_ nmats = my_exts.size();
352 for (Index_ x = 0; x < nmats; ++x) {
353 const auto range = my_exts[x]->fetch(i, vcopy, icopy);
354 count += range.number;
355 if (my_needs_value) {
356 copy_n(range.value, range.number, vcopy);
357 vcopy += range.number;
359 if (my_needs_index) {
360 const Index_ offset = my_cumulative[x + my_start_matrix];
361 for (Index_ y = 0; y < range.number; ++y) {
362 icopy[y] = range.index[y] + offset;
364 icopy += range.number;
368 return SparseRange<Value_, Index_>(count, (my_needs_value ? value_buffer : NULL), (my_needs_index ? index_buffer : NULL));
372 const std::vector<Index_>& my_cumulative;
373 bool my_needs_value, my_needs_index;
374 std::vector<std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > > my_exts;
375 Index_ my_start_matrix;
378template<
bool oracle_,
typename Value_,
typename Index_>
379class ParallelIndexSparse final :
public SparseExtractor<oracle_, Value_, Index_> {
382 const std::vector<Index_>& cumulative,
383 const CompressedMapping<Index_>& mapping,
384 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
386 MaybeOracle<oracle_, Index_> oracle,
387 VectorPtr<Index_> indices_ptr,
390 my_cumulative(cumulative),
391 my_needs_value(opt.sparse_extract_value),
392 my_needs_index(opt.sparse_extract_index)
394 my_exts.reserve(matrices.size());
395 my_which_matrix.reserve(matrices.size());
396 initialize_parallel_index(
400 [&](
const Index_ i, VectorPtr<Index_> sub_indices_ptr) ->
void {
401 my_which_matrix.emplace_back(i);
402 my_exts.emplace_back(new_extractor<true, oracle_>(matrices[i].get(), row, oracle, std::move(sub_indices_ptr), opt));
407 SparseRange<Value_, Index_> fetch(
const Index_ i, Value_*
const value_buffer, Index_*
const index_buffer) {
408 auto vcopy = value_buffer;
409 auto icopy = index_buffer;
412 const Index_ nmats = my_which_matrix.size();
413 for (Index_ x = 0; x < nmats; ++x) {
414 const auto range = my_exts[x]->fetch(i, vcopy, icopy);
415 count += range.number;
416 if (my_needs_value) {
417 copy_n(range.value, range.number, vcopy);
418 vcopy += range.number;
421 if (my_needs_index) {
422 const Index_ offset = my_cumulative[my_which_matrix[x]];
423 for (Index_ y = 0; y < range.number; ++y) {
424 icopy[y] = range.index[y] + offset;
426 icopy += range.number;
430 return SparseRange<Value_, Index_>(count, (my_needs_value ? value_buffer : NULL), (my_needs_index ? index_buffer : NULL));
434 const std::vector<Index_>& my_cumulative;
435 bool my_needs_value, my_needs_index;
436 std::vector<std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > > my_exts;
437 std::vector<Index_> my_which_matrix;
444template<
typename Value_,
typename Index_>
445class MyopicPerpendicularDense final :
public MyopicDenseExtractor<Value_, Index_> {
447 template<
typename ... Args_>
448 MyopicPerpendicularDense(
449 const std::vector<Index_>& cumulative,
450 const CompressedMapping<Index_>& mapping,
451 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
453 const Args_& ... args
455 my_cumulative(cumulative),
458 my_exts.reserve(matrices.size());
459 for (
const auto& m : matrices) {
460 my_exts.emplace_back(m->dense(row, args...));
464 const Value_* fetch(
const Index_ i, Value_*
const buffer) {
465 const Index_ chosen = my_mapping[i];
466 return my_exts[chosen]->fetch(i - my_cumulative[chosen], buffer);
470 const std::vector<Index_>& my_cumulative;
471 const CompressedMapping<Index_>& my_mapping;
472 std::vector<std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > > my_exts;
475template<
typename Value_,
typename Index_>
476class MyopicPerpendicularSparse final :
public MyopicSparseExtractor<Value_, Index_> {
478 template<
typename ... Args_>
479 MyopicPerpendicularSparse(
480 const std::vector<Index_>& cumulative,
481 const CompressedMapping<Index_>& mapping,
482 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
484 const Args_& ... args
486 my_cumulative(cumulative),
489 my_exts.reserve(matrices.size());
490 for (
const auto& m : matrices) {
491 my_exts.emplace_back(m->sparse(row, args...));
495 SparseRange<Value_, Index_> fetch(
const Index_ i, Value_*
const vbuffer, Index_*
const ibuffer) {
496 const Index_ chosen = my_mapping[i];
497 return my_exts[chosen]->fetch(i - my_cumulative[chosen], vbuffer, ibuffer);
501 const std::vector<Index_>& my_cumulative;
502 const CompressedMapping<Index_>& my_mapping;
503 std::vector<std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > > my_exts;
506template<
typename Index_,
class Initialize_>
507void initialize_perp_oracular(
508 const std::vector<Index_>& cumulative,
509 const CompressedMapping<Index_>& mapping,
510 const Oracle<Index_>& oracle,
511 std::vector<Index_>& chosen,
514 const auto ntotal = oracle.total();
515 chosen.reserve(ntotal);
518 bool consecutive =
true;
521 std::vector<Index_> predictions;
523 void add(
const Index_ p) {
530 if (number + start == p) {
536 std::iota(predictions.begin(), predictions.end(), start);
539 predictions.push_back(p);
543 const auto nmats = cumulative.size() - 1;
544 auto predictions = create_container_of_Index_size<std::vector<Predictions> >(nmats);
545 for (I<
decltype(ntotal)> i = 0; i < ntotal; ++i) {
546 const auto prediction = oracle.get(i);
547 const Index_ choice = mapping[prediction];
548 chosen.push_back(choice);
549 predictions[choice].add(prediction - cumulative[choice]);
552 for (I<
decltype(nmats)> x = 0; x < nmats; ++x) {
553 auto& current = predictions[x];
554 if (current.consecutive) {
555 if (current.number) {
556 init(x, std::make_shared<ConsecutiveOracle<Index_> >(current.start, current.number));
559 if (!current.predictions.empty()) {
560 init(x, std::make_shared<FixedVectorOracle<Index_> >(std::move(current.predictions)));
566template<
typename Value_,
typename Index_>
567class OracularPerpendicularDense final :
public OracularDenseExtractor<Value_, Index_> {
569 template<
typename ... Args_>
570 OracularPerpendicularDense(
571 const std::vector<Index_>& cumulative,
572 const CompressedMapping<Index_>& mapping,
573 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
575 std::shared_ptr<
const Oracle<Index_> > ora,
576 const Args_& ... args
579 initialize_perp_oracular(
584 [&](
const Index_ x, std::shared_ptr<
const Oracle<Index_> > subora) ->
void {
585 my_exts[x] = matrices[x]->dense(row, std::move(subora), args...);
590 const Value_* fetch(
const Index_ i, Value_*
const buffer) {
591 const auto chosen = my_segments[my_used];
592 const auto output = my_exts[chosen]->fetch(i, buffer);
598 std::vector<Index_> my_segments;
599 std::vector<std::unique_ptr<OracularDenseExtractor<Value_, Index_> > > my_exts;
603template<
typename Value_,
typename Index_>
604class OracularPerpendicularSparse final :
public OracularSparseExtractor<Value_, Index_> {
606 template<
typename ... Args_>
607 OracularPerpendicularSparse(
608 const std::vector<Index_>& cumulative,
609 const CompressedMapping<Index_>& mapping,
610 const std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > >& matrices,
612 std::shared_ptr<
const Oracle<Index_> > ora,
613 const Args_& ... args
616 initialize_perp_oracular(
621 [&](
const Index_ x, std::shared_ptr<
const Oracle<Index_> > subora) ->
void {
622 my_exts[x] = matrices[x]->sparse(row, std::move(subora), args...);
627 SparseRange<Value_, Index_> fetch(Index_ i, Value_* vbuffer, Index_* ibuffer) {
628 const auto chosen = my_segments[my_used];
629 const auto output = my_exts[chosen]->fetch(i, vbuffer, ibuffer);
635 std::vector<Index_> my_segments;
636 std::vector<std::unique_ptr<OracularSparseExtractor<Value_, Index_> > > my_exts;
654template<
typename Value_,
typename Index_>
664 my_matrices(std::move(matrices)), my_by_row(by_row)
666 auto nmats = my_matrices.size();
667 my_cumulative.reserve(sanisizer::sum<I<
decltype(my_cumulative.size())> >(nmats, 1));
668 I<
decltype(nmats)> sofar = 0;
669 my_cumulative.push_back(0);
670 Index_ min_extent = std::numeric_limits<Index_>::max();
672 for (I<
decltype(nmats)> i = 0; i < nmats; ++i) {
673 auto& current = my_matrices[i];
674 Index_ primary, secondary;
676 primary = current->nrow();
677 secondary = current->ncol();
679 primary = current->ncol();
680 secondary = current->nrow();
684 my_otherdim = secondary;
685 }
else if (my_otherdim != secondary) {
686 throw std::runtime_error(
"all 'matrices' should have the same number of " + (my_by_row ? std::string(
"columns") : std::string(
"rows")));
693 my_matrices[sofar] = std::move(current);
695 my_cumulative.push_back(sanisizer::sum<Index_>(attest_for_Index(my_cumulative.back()), attest_for_Index(primary)));
696 min_extent = std::min(min_extent, primary);
701 my_matrices.resize(sofar);
707 my_mapping = DelayedBind_internal::CompressedMapping(min_extent, my_cumulative);
710 for (
const auto& x : my_matrices) {
711 const double total =
static_cast<double>(x->nrow()) *
static_cast<double>(x->ncol());
713 my_sparse_prop += total * x->is_sparse_proportion();
714 my_by_row_prop += total * x->prefer_rows_proportion();
717 my_sparse_prop /= denom;
718 my_by_row_prop /= denom;
721 for (
int d = 0; d < 2; ++d) {
722 my_uses_oracle[d] =
false;
723 for (
const auto& x : my_matrices) {
724 if (x->uses_oracle(d)) {
725 my_uses_oracle[d] =
true;
737 DelayedBind(std::vector<std::shared_ptr<const
Matrix<Value_, Index_> > >(matrices.begin(), matrices.end()), by_row) {}
743 std::vector<std::shared_ptr<const Matrix<Value_, Index_> > > my_matrices;
746 Index_ my_otherdim = 0;
747 std::vector<Index_> my_cumulative;
748 DelayedBind_internal::CompressedMapping<Index_> my_mapping;
750 double my_sparse_prop = 0, my_by_row_prop = 0;
751 std::array<bool, 2> my_uses_oracle;
756 return my_cumulative.back();
766 return my_cumulative.back();
771 return my_sparse_prop > 0.5;
775 return my_sparse_prop;
779 return my_by_row_prop > 0.5;
783 return my_by_row_prop;
787 return my_uses_oracle[row];
792 using Matrix<Value_, Index_>::sparse;
798 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> >
dense(
802 if (my_matrices.size() == 1) {
803 return my_matrices[0]->dense(row, opt);
804 }
else if (row == my_by_row) {
805 return std::make_unique<DelayedBind_internal::MyopicPerpendicularDense<Value_, Index_> >(
813 return std::make_unique<DelayedBind_internal::ParallelDense<false, Value_, Index_> >(
824 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> >
dense(
826 const Index_ block_start,
827 const Index_ block_length,
830 if (my_matrices.size() == 1) {
831 return my_matrices[0]->dense(row, block_start, block_length, opt);
832 }
else if (row == my_by_row) {
833 return std::make_unique<DelayedBind_internal::MyopicPerpendicularDense<Value_, Index_> >(
843 return std::make_unique<DelayedBind_internal::ParallelDense<false, Value_, Index_> >(
856 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> >
dense(
861 if (my_matrices.size() == 1) {
862 return my_matrices[0]->dense(row, std::move(indices_ptr), opt);
863 }
else if (row == my_by_row) {
864 return std::make_unique<DelayedBind_internal::MyopicPerpendicularDense<Value_, Index_> >(
869 std::move(indices_ptr),
873 return std::make_unique<DelayedBind_internal::ParallelDense<false, Value_, Index_> >(
879 std::move(indices_ptr),
889 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
893 if (my_matrices.size() == 1) {
894 return my_matrices[0]->sparse(row, opt);
895 }
else if (row == my_by_row) {
896 return std::make_unique<DelayedBind_internal::MyopicPerpendicularSparse<Value_, Index_> >(
904 return std::make_unique<DelayedBind_internal::ParallelFullSparse<false, Value_, Index_> >(
915 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
917 const Index_ block_start,
918 const Index_ block_length,
921 if (my_matrices.size() == 1) {
922 return my_matrices[0]->sparse(row, block_start, block_length, opt);
923 }
else if (row == my_by_row) {
924 return std::make_unique<DelayedBind_internal::MyopicPerpendicularSparse<Value_, Index_> >(
934 return std::make_unique<DelayedBind_internal::ParallelBlockSparse<false, Value_, Index_> >(
947 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
952 if (my_matrices.size() == 1) {
953 return my_matrices[0]->sparse(row, std::move(indices_ptr), opt);
954 }
else if (row == my_by_row) {
955 return std::make_unique<DelayedBind_internal::MyopicPerpendicularSparse<Value_, Index_> >(
960 std::move(indices_ptr),
964 return std::make_unique<DelayedBind_internal::ParallelIndexSparse<false, Value_, Index_> >(
970 std::move(indices_ptr),
980 std::unique_ptr<OracularDenseExtractor<Value_, Index_> >
dense(
985 if (my_matrices.size() == 1) {
986 return my_matrices[0]->dense(row, std::move(oracle), opt);
987 }
else if (!my_uses_oracle[row]) {
988 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(
992 }
else if (row == my_by_row) {
993 return std::make_unique<DelayedBind_internal::OracularPerpendicularDense<Value_, Index_> >(
1002 return std::make_unique<DelayedBind_internal::ParallelDense<true, Value_, Index_> >(
1013 std::unique_ptr<OracularDenseExtractor<Value_, Index_> >
dense(
1016 const Index_ block_start,
1017 const Index_ block_length,
1020 if (my_matrices.size() == 1) {
1021 return my_matrices[0]->dense(row, std::move(oracle), block_start, block_length, opt);
1022 }
else if (!my_uses_oracle[row]) {
1023 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(
1025 dense(row, block_start, block_length, opt)
1027 }
else if (row == my_by_row) {
1028 return std::make_unique<DelayedBind_internal::OracularPerpendicularDense<Value_, Index_> >(
1039 return std::make_unique<DelayedBind_internal::ParallelDense<true, Value_, Index_> >(
1052 std::unique_ptr<OracularDenseExtractor<Value_, Index_> >
dense(
1058 if (my_matrices.size() == 1) {
1059 return my_matrices[0]->dense(row, std::move(oracle), std::move(indices_ptr), opt);
1060 }
else if (!my_uses_oracle[row]) {
1061 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(
1063 dense(row, std::move(indices_ptr), opt)
1065 }
else if (row == my_by_row) {
1066 return std::make_unique<DelayedBind_internal::OracularPerpendicularDense<Value_, Index_> >(
1072 std::move(indices_ptr),
1076 return std::make_unique<DelayedBind_internal::ParallelDense<true, Value_, Index_> >(
1082 std::move(indices_ptr),
1092 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
1097 if (my_matrices.size() == 1) {
1098 return my_matrices[0]->sparse(row, std::move(oracle), opt);
1099 }
else if (!my_uses_oracle[row]) {
1100 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(
1104 }
else if (row == my_by_row) {
1105 return std::make_unique<DelayedBind_internal::OracularPerpendicularSparse<Value_, Index_> >(
1114 return std::make_unique<DelayedBind_internal::ParallelFullSparse<true, Value_, Index_> >(
1125 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
1127 std::shared_ptr<
const Oracle<Index_> > oracle,
1128 const Index_ block_start,
1129 const Index_ block_length,
1132 if (my_matrices.size() == 1) {
1133 return my_matrices[0]->sparse(row, std::move(oracle), block_start, block_length, opt);
1134 }
else if (!my_uses_oracle[row]) {
1135 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(
1137 sparse(row, block_start, block_length, opt)
1139 }
else if (row == my_by_row) {
1140 return std::make_unique<DelayedBind_internal::OracularPerpendicularSparse<Value_, Index_> >(
1151 return std::make_unique<DelayedBind_internal::ParallelBlockSparse<true, Value_, Index_> >(
1164 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
1166 std::shared_ptr<
const Oracle<Index_> > oracle,
1170 if (my_matrices.size() == 1) {
1171 return my_matrices[0]->sparse(row, std::move(oracle), std::move(indices_ptr), opt);
1172 }
else if (!my_uses_oracle[row]) {
1173 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(
1175 sparse(row, std::move(indices_ptr), opt)
1177 }
else if (row == my_by_row) {
1178 return std::make_unique<DelayedBind_internal::OracularPerpendicularSparse<Value_, Index_> >(
1184 std::move(indices_ptr),
1188 return std::make_unique<DelayedBind_internal::ParallelIndexSparse<true, Value_, Index_> >(
1194 std::move(indices_ptr),
1205template<
typename Value_,
typename Index_>
1206std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > > matrices,
bool row) {
1207 return std::shared_ptr<Matrix<Value_, Index_> >(
new DelayedBind<Value_, Index_>(std::move(matrices), row));
1210template<
typename Value_,
typename Index_>
1211std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<Matrix<Value_, Index_> > > matrices,
bool row) {
1212 return std::shared_ptr<Matrix<Value_, Index_> >(
new DelayedBind<Value_, Index_>(std::move(matrices), row));
1215template<
int margin_,
typename Value_,
typename Index_>
1216std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<
const Matrix<Value_, Index_> > > matrices) {
1217 return make_DelayedBind(std::move(matrices), margin_ == 0);
1220template<
int margin_,
typename Value_,
typename Index_>
1221std::shared_ptr<Matrix<Value_, Index_> > make_DelayedBind(std::vector<std::shared_ptr<Matrix<Value_, Index_> > > matrices) {
1222 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.
Convert index type to container size.
Virtual class for a matrix of some numeric type.
Delayed combining of a matrix.
Definition DelayedBind.hpp:655
bool uses_oracle(const bool row) const
Definition DelayedBind.hpp:786
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:1052
DelayedBind(std::vector< std::shared_ptr< const Matrix< Value_, Index_ > > > matrices, const bool by_row)
Definition DelayedBind.hpp:663
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, const Options &opt) const
Definition DelayedBind.hpp:798
double is_sparse_proportion() const
Definition DelayedBind.hpp:774
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:824
Index_ nrow() const
Definition DelayedBind.hpp:754
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedBind.hpp:856
bool is_sparse() const
Definition DelayedBind.hpp:770
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedBind.hpp:980
Index_ ncol() const
Definition DelayedBind.hpp:762
bool prefer_rows() const
Definition DelayedBind.hpp:778
double prefer_rows_proportion() const
Definition DelayedBind.hpp:782
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:1013
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:99
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:302
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