70 const RightColumns_ right_columns,
71 GetRightRow_ get_right_row,
72 Output_*
const output,
75 const auto left_NR = left.
nrow();
76 const auto common_dim = left.
ncol();
82 std::fill_n(output, sanisizer::product_unsafe<std::size_t>(right_columns, left_NR), 0);
93 std::optional<std::vector<Output_> > tmp_output;
98 for (LeftIndex_ lr = 0; lr < length; ++lr) {
99 const auto left_ptr = ext->fetch(buffer.data());
100 const auto optr = output + sanisizer::product_unsafe<std::size_t>(start + lr, right_columns);
106 tmp_optr = tmp_output->data();
109 for (LeftIndex_ cd = 0; cd < common_dim; ++cd) {
110 const Output_ mult = left_ptr[cd];
111 const auto rightrow = get_right_row(cd);
112 for (RightColumns_ rc = 0; rc < right_columns; ++rc) {
113 tmp_optr[rc] +=
static_cast<Output_
>(rightrow[rc]) * mult;
118 std::copy_n(tmp_optr, right_columns, optr);
119 std::fill_n(tmp_optr, right_columns, 0);
127 std::vector<std::vector<LeftValue_> > left_buffers;
128 std::vector<const LeftValue_*> left_ptrs;
130 std::optional<std::vector<Output_> > tmp_output;
133 left_buffers.reserve(max_block_rows);
134 for (LeftIndex_ b = 0; b < max_block_rows ; ++b) {
137 sanisizer::resize(left_ptrs, max_block_rows);
143 tmp_output.emplace(sanisizer::product<I<
decltype(tmp_output->size())> >(max_block_rows, right_columns));
148 while (lr < length) {
150 for (LeftIndex_ lr_counter = 0; lr_counter < lr_num; ++lr_counter) {
151 left_ptrs[lr_counter] = left_ext->fetch(left_buffers[lr_counter].data());
154 Output_*
const optr = output + sanisizer::product_unsafe<std::size_t>(start + lr, right_columns);
159 tmp_optr = tmp_output->data();
163 while (cd < common_dim) {
164 const LeftIndex_ cd_end = cd + sanisizer::min(options.
primary_block_size, common_dim - cd);
165 RightColumns_ rc = 0;
166 while (rc < right_columns) {
167 const RightColumns_ rc_end = rc + sanisizer::min(options.
secondary_block_size, right_columns - rc);
169 for (LeftIndex_ lr_counter = 0; lr_counter < lr_num; ++lr_counter) {
170 const auto matrow = left_ptrs[lr_counter];
171 const auto prod = tmp_optr + sanisizer::product_unsafe<std::size_t>(lr_counter, right_columns);
172 for (
auto ccopy = cd; ccopy < cd_end; ++ccopy) {
173 const auto mult = matrow[ccopy];
174 const auto& rightrow = get_right_row(ccopy);
175 for (
auto rc_copy = rc; rc_copy < rc_end; ++rc_copy) {
176 prod[rc_copy] += mult * rightrow[rc_copy];
187 const auto out_space = sanisizer::product_unsafe<std::size_t>(lr_num, right_columns);
188 std::copy_n(tmp_optr, out_space, optr);
189 std::fill_n(tmp_optr, out_space, 0);
void multiply_dense_row_with_dense_row_matrix_to_row_output(const tatami::Matrix< LeftValue_, LeftIndex_ > &left, const RightColumns_ right_columns, GetRightRow_ get_right_row, Output_ *const output, const MultiplyDenseRowWithDenseRowMatrixToRowOutputOptions &options)
Definition row_to_row.hpp:68