71 const RightColumns_ right_columns,
72 GetRightColumn_ get_right_column,
73 Output_*
const output,
76 const auto left_NR = left.
nrow();
77 const auto common_dim = left.
ncol();
83 for (LeftIndex_ lr = 0; lr < length; ++lr) {
84 const auto lptr = lext->fetch(lbuffer.data());
85 for (RightColumns_ rc = 0; rc < right_columns; ++rc) {
86 output[sanisizer::nd_offset<std::size_t>(start + lr, left_NR, rc)] = dense_dot_product<accumulators_>(
90 static_cast<Output_
>(0)
102 std::fill_n(output, sanisizer::product_unsafe<std::size_t>(left_NR, right_columns), 0);
109 std::vector<std::vector<LeftValue_> > lbuffers;
110 lbuffers.reserve(max_block_rows);
111 for (LeftIndex_ b = 0; b < max_block_rows; ++b) {
116 std::optional<std::vector<Output_> > tmp_output;
123 const RightColumns_ max_block_cols = sanisizer::min(right_columns, options.
primary_block_size);
125 tmp_output.emplace(sanisizer::product<I<
decltype(tmp_output->size())> >(max_block_cols, max_block_rows));
126 optr = tmp_output->data();
132 while (lr < length) {
134 for (LeftIndex_ lr_counter = 0; lr_counter < lr_num; ++lr_counter) {
135 lptrs[lr_counter] = ext->fetch(lbuffers[lr_counter].data());
138 RightColumns_ rc = 0;
139 while (rc < right_columns) {
140 const RightColumns_ rc_num = sanisizer::min(options.
primary_block_size, right_columns - rc);
142 LeftIndex_ out_row_offset, out_stride;
143 RightColumns_ out_col_offset;
145 std::fill_n(optr, sanisizer::product_unsafe<std::size_t>(rc_num, lr_num), 0);
152 out_stride = left_NR;
156 while (cd < common_dim) {
158 for (RightColumns_ rc_counter = 0; rc_counter < rc_num; ++rc_counter) {
159 const auto& rightcol = get_right_column(rc + rc_counter);
160 for (LeftIndex_ lr_counter = 0; lr_counter < lr_num; ++lr_counter) {
161 auto& dest = optr[sanisizer::nd_offset<std::size_t>(out_row_offset + lr_counter, out_stride, out_col_offset + rc_counter)];
162 dest = dense_dot_product<accumulators_>(
165 lptrs[lr_counter] + cd,
174 for (RightColumns_ rc_counter = 0; rc_counter < rc_num; ++rc_counter) {
176 optr + sanisizer::product_unsafe<std::size_t>(lr_num, rc_counter),
178 output + sanisizer::nd_offset<std::size_t>(start + lr, left_NR, rc + rc_counter)
void multiply_dense_row_with_dense_column_matrix_to_column_output(const tatami::Matrix< LeftValue_, LeftIndex_ > &left, const RightColumns_ right_columns, GetRightColumn_ get_right_column, Output_ *const output, const MultiplyDenseRowWithDenseColumnMatrixToColumnOutputOptions &options)
Definition column_to_column.hpp:69
auto consecutive_extractor(const Matrix< Value_, Index_ > &matrix, const bool row, const Index_ iter_start, const Index_ iter_length, Args_ &&... args)