63 const RightColumns_ right_columns,
64 GetRightColumn_ get_right_column,
65 Output_*
const output,
68 const auto left_NR = left.
nrow();
69 const auto common_dim = left.
ncol();
77 for (LeftIndex_ lr = 0; lr < length; ++lr) {
78 const auto range = ext->fetch(vbuffer.data(), ibuffer.data());
79 for (RightColumns_ rc = 0; rc < right_columns; ++rc) {
80 output[sanisizer::nd_offset<std::size_t>(rc, right_columns, start + lr)] = sparse_dot_product<accumulators_>(
85 static_cast<Output_
>(0)
96 std::vector<std::vector<LeftValue_> > left_vbuffers;
97 std::vector<std::vector<LeftIndex_> > left_ibuffers;
98 std::vector<tatami::SparseRange<LeftValue_, LeftIndex_> > left_ranges;
99 std::vector<LeftIndex_> left_non_empty;
101 const LeftIndex_ max_block_rows = sanisizer::min(length, options.
block_size);
102 left_vbuffers.reserve(max_block_rows);
103 left_ibuffers.reserve(max_block_rows);
104 for (LeftIndex_ lr = 0; lr < max_block_rows; ++lr) {
108 sanisizer::resize(left_ranges, max_block_rows);
109 left_non_empty.reserve(max_block_rows);
113 while (lr < length) {
117 const auto left_block_info = fetch_non_empty_sparse_block(
126 [&](
const LeftIndex_ lr_copy) ->
void {
127 std::fill_n(output + sanisizer::product_unsafe<std::size_t>(start + lr_copy, right_columns), right_columns, 0);
130 const auto lr_num = left_block_info.num_non_empty;
134 if (left_block_info.all_non_empty) {
135 const auto lr_base = lr + start;
139 for (RightColumns_ rc = 0; rc < right_columns; ++rc) {
140 const auto rcol = get_right_column(rc);
141 for (LeftIndex_ lr_counter = 0; lr_counter < lr_num; ++lr_counter) {
142 const auto& currange = left_ranges[lr_counter];
143 output[sanisizer::nd_offset<std::size_t>(rc, right_columns, lr_base + lr_counter)] = sparse_dot_product<accumulators_>(
148 static_cast<Output_
>(0)
154 for (
auto& lrne : left_non_empty) {
157 for (RightColumns_ rc = 0; rc < right_columns; ++rc) {
158 const auto rcol = get_right_column(rc);
159 for (LeftIndex_ lr_counter = 0; lr_counter < lr_num; ++lr_counter) {
160 const auto& currange = left_ranges[lr_counter];
161 output[sanisizer::nd_offset<std::size_t>(rc, right_columns, left_non_empty[lr_counter])] = sparse_dot_product<accumulators_>(
166 static_cast<Output_
>(0)
172 lr = left_block_info.position;
void multiply_sparse_row_with_dense_column_matrix_to_row_output(const tatami::Matrix< LeftValue_, LeftIndex_ > &left, const RightColumns_ right_columns, GetRightColumn_ get_right_column, Output_ *const output, const MultiplySparseRowWithDenseColumnMatrixToRowOutputOptions &options)
Definition column_to_row.hpp:61
auto consecutive_extractor(const Matrix< Value_, Index_ > &matrix, const bool row, const Index_ iter_start, const Index_ iter_length, Args_ &&... args)