72 const RightVectors_ right_vectors,
73 GetRightVector_ get_right_vector,
74 GetOutputVector_ get_output_vector,
77 const auto left_NR = left.
nrow();
78 const auto common_dim = left.
ncol();
79 typedef I<
decltype(get_output_vector(0)[0])> Output;
85 for (LeftIndex_ lr = 0; lr < length; ++lr) {
86 const auto lptr = lext->fetch(lbuffer.data());
87 for (RightVectors_ rv = 0; rv < right_vectors; ++rv) {
88 get_output_vector(rv)[start + lr] = dense_dot_product<accumulators_>(
92 static_cast<Output
>(0)
105 std::vector<std::vector<LeftValue_> > left_buffers;
106 left_buffers.reserve(max_block_rows);
107 for (LeftIndex_ lr = 0; lr < max_block_rows; ++lr) {
115 for (RightVectors_ rc = 0; rc < right_vectors; ++rc) {
116 std::fill_n(get_output_vector(rc), length, 0);
120 while (lr < length) {
122 for (LeftIndex_ lr_counter = 0; lr_counter < lr_num; ++lr_counter) {
123 left_ptrs[lr_counter] = ext->fetch(left_buffers[lr_counter].data());
126 RightVectors_ rc = 0;
127 while (rc < right_vectors) {
128 const RightVectors_ rc_num = sanisizer::min(options.
primary_block_size, right_vectors - rc);
131 while (cd < common_dim) {
133 for (RightVectors_ rc_counter = 0; rc_counter < rc_num; ++rc_counter) {
134 const auto outvec = get_output_vector(rc + rc_counter) + start + lr;
135 const auto rightvec = get_right_vector(rc + rc_counter);
137 for (LeftIndex_ lr_counter = 0; lr_counter < lr_num; ++lr_counter) {
138 auto& dest = outvec[lr_counter];
139 dest = dense_dot_product<accumulators_>(
142 left_ptrs[lr_counter] + cd,
160 std::vector<std::vector<Output> > tmp_output;
162 const RightVectors_ max_block_cols = sanisizer::min(right_vectors, options.
primary_block_size);
163 tmp_output.reserve(max_block_cols);
164 for (RightVectors_ rc = 0; rc < max_block_cols; ++rc) {
170 while (lr < length) {
172 for (LeftIndex_ lr_counter = 0; lr_counter < lr_num; ++lr_counter) {
173 left_ptrs[lr_counter] = ext->fetch(left_buffers[lr_counter].data());
176 RightVectors_ rc = 0;
177 while (rc < right_vectors) {
178 const RightVectors_ rc_num = sanisizer::min(options.
primary_block_size, right_vectors - rc);
181 while (cd < common_dim) {
183 for (RightVectors_ rc_counter = 0; rc_counter < rc_num; ++rc_counter) {
184 const auto outvec = tmp_output[rc_counter].data();
185 const auto rightvec = get_right_vector(rc + rc_counter);
187 for (LeftIndex_ lr_counter = 0; lr_counter < lr_num; ++lr_counter) {
188 auto& dest = outvec[lr_counter];
189 dest = dense_dot_product<accumulators_>(
192 left_ptrs[lr_counter] + cd,
200 for (RightVectors_ rc_counter = 0; rc_counter < rc_num; ++rc_counter) {
201 auto& src = tmp_output[rc_counter];
202 std::copy_n(src.begin(), lr_num, get_output_vector(rc + rc_counter) + start + lr);
203 std::fill_n(src.begin(), lr_num, 0);
void multiply_dense_row_with_multiple_vectors(const tatami::Matrix< LeftValue_, LeftIndex_ > &left, const RightVectors_ right_vectors, GetRightVector_ get_right_vector, GetOutputVector_ get_output_vector, const MultiplyDenseRowWithMultipleVectorsOptions &options)
Definition dense_row.hpp:70