59 Output_*
const output,
62 const auto left_NR = left.
nrow();
63 const auto common_dim = left.
ncol();
64 const auto right_NC = right.
ncol();
72 auto right_non_empty = filter_non_empty_sparse(
74 [&](
const RightIndex_) ->
void {}
78 std::optional<std::vector<std::optional<std::vector<Output_> > > > tmp_results;
80 tmp_results.emplace(sanisizer::cast<I<
decltype(tmp_results->size())> >(options.
num_threads - 1));
83 std::fill_n(output, sanisizer::product_unsafe<std::size_t>(left_NR, right_NC), 0);
87 const LeftIndex_ cd_total = (right_non_empty.has_value() ?
static_cast<LeftIndex_
>(right_non_empty->size()) : common_dim);
88 const int num_used =
tatami::parallelize([&](
int t, LeftIndex_ start, LeftIndex_ length) ->
void {
89 std::optional<std::vector<Output_> > tmp_output;
91 if (!do_parallel || t == 0) {
94 tmp_output.emplace(sanisizer::product<I<
decltype(tmp_output->size())> >(left_NR, right_NC));
95 outptr = tmp_output->data();
100 auto task = [&](std::unique_ptr<tatami::OracularDenseExtractor<LeftValue_, LeftIndex_> >& ext,
auto converter) ->
void {
101 for (LeftIndex_ cd = 0; cd < length; ++cd) {
102 const auto lptr = ext->fetch(dbuffer.data());
103 const auto actual_cd = converter(cd);
104 const auto& right_values = rhs_data.value[actual_cd];
105 const auto& right_indices = rhs_data.index[actual_cd];
106 const RightIndex_ right_nnz = right_values.size();
107 for (RightIndex_ x = 0; x < right_nnz; ++x) {
108 const Output_ mult = right_values[x];
109 const auto idx = right_indices[x];
110 for (LeftIndex_ lr = 0; lr < left_NR; ++lr) {
111 outptr[sanisizer::nd_offset<std::size_t>(lr, left_NR, idx)] += mult *
static_cast<Output_
>(lptr[lr]);
117 if (right_non_empty.has_value()) {
121 [&](
const LeftIndex_ cd) -> LeftIndex_ {
122 return (*right_non_empty)[start + cd];
129 [&](
const LeftIndex_ cd) -> LeftIndex_ {
135 if (do_parallel && t > 0) {
136 (*tmp_results)[t - 1] = std::move(tmp_output);
141 for (
int u = 1; u < num_used; ++u) {
142 const auto& tmp = *((*tmp_results)[u - 1]);
143 const auto N = tmp.size();
144 for (I<
decltype(N)> x = 0; x < N; ++x) {
void multiply_dense_column_with_sparse_column_matrix_to_column_output(const tatami::Matrix< LeftValue_, LeftIndex_ > &left, const tatami::Matrix< RightValue_, RightIndex_ > &right, Output_ *const output, const MultiplyDenseColumnWithSparseColumnMatrixToColumnOutputOptions &options)
Definition column_to_column.hpp:56
auto new_extractor(const Matrix< Value_, Index_ > &matrix, const bool row, MaybeOracle< oracle_, Index_ > oracle, Args_ &&... args)
FragmentedSparseContents< StoredValue_, StoredIndex_ > retrieve_fragmented_sparse_contents(const Matrix< InputValue_, InputIndex_ > &matrix, const bool row, const RetrieveFragmentedSparseContentsOptions &options)
auto consecutive_extractor(const Matrix< Value_, Index_ > &matrix, const bool row, const Index_ iter_start, const Index_ iter_length, Args_ &&... args)