68 const RightColumns_ right_columns,
69 GetRightRow_ get_right_row,
70 Output_*
const output,
73 const auto left_NR = left.
nrow();
74 const auto common_dim = left.
ncol();
83 std::vector<LeftIndex_> left_empty;
85 for (LeftIndex_ lr = 0; lr < length; ++lr) {
86 const auto range = ext->fetch(vbuffer.data(), ibuffer.data());
87 if (range.number == 0) {
88 left_empty.push_back(lr);
92 for (LeftIndex_ x = 0; x < range.number; ++x) {
93 const auto rightrow = get_right_row(range.index[x]);
94 const Output_ mult = range.value[x];
95 for (RightColumns_ rc = 0; rc < right_columns; ++rc) {
96 tmp_output[rc] += mult *
static_cast<Output_
>(rightrow[rc]);
100 for (RightColumns_ rc = 0; rc < right_columns; ++rc) {
101 output[sanisizer::nd_offset<std::size_t>(start + lr, left_NR, rc)] = tmp_output[rc];
103 std::fill(tmp_output.begin(), tmp_output.end(), 0);
106 if (left_empty.size()) {
109 for (RightColumns_ rc = 0; rc < right_columns; ++rc) {
110 for (
const auto lr : left_empty) {
111 output[sanisizer::nd_offset<std::size_t>(start + lr, left_NR, rc)] = 0;
117 const auto max_block_rows = sanisizer::min(length, options.
block_size);
118 std::vector<Output_> tmp_output(sanisizer::product<
typename std::vector<Output_>::size_type>(max_block_rows, right_columns));
121 while (lr < length) {
122 const LeftIndex_ lrnum = sanisizer::min(options.
block_size, length - lr);
123 bool any_non_empty =
false;
124 for (LeftIndex_ lrcopy = 0; lrcopy < lrnum; ++lrcopy) {
125 const auto range = ext->fetch(vbuffer.data(), ibuffer.data());
126 if (range.number == 0) {
129 any_non_empty =
true;
131 for (LeftIndex_ x = 0; x < range.number; ++x) {
132 const auto rightrow = get_right_row(range.index[x]);
133 const Output_ mult = range.value[x];
134 for (RightColumns_ rc = 0; rc < right_columns; ++rc) {
135 tmp_output[sanisizer::nd_offset<std::size_t>(rc, right_columns, lrcopy)] += mult *
static_cast<Output_
>(rightrow[rc]);
143 RightColumns_ rc = 0;
144 while (rc < right_columns) {
145 const RightColumns_ rcend = rc + sanisizer::min(options.
block_size, right_columns - rc);
146 for (LeftIndex_ lrcopy = 0; lrcopy < lrnum; ++lrcopy) {
147 for (
auto rcopy = rc; rcopy < rcend; ++rcopy) {
148 const auto val = tmp_output[sanisizer::nd_offset<std::size_t>(rcopy, right_columns, lrcopy)];
149 output[sanisizer::nd_offset<std::size_t>(start + lr + lrcopy, left_NR, rcopy)] = val;
158 std::fill_n(tmp_output.begin(), sanisizer::product_unsafe<std::size_t>(right_columns, lrnum), 0);
void multiply_sparse_row_with_dense_row_matrix_to_column_output(const tatami::Matrix< LeftValue_, LeftIndex_ > &left, const RightColumns_ right_columns, GetRightRow_ get_right_row, Output_ *const output, const MultiplySparseRowWithDenseRowMatrixToColumnOutputOptions &options)
Definition row_to_column.hpp:66
auto consecutive_extractor(const Matrix< Value_, Index_ > &matrix, const bool row, const Index_ iter_start, const Index_ iter_length, Args_ &&... args)