tatami
C++ API for different matrix representations
Loading...
Searching...
No Matches
convert_to_fragmented_sparse.hpp
Go to the documentation of this file.
1#ifndef TATAMI_CONVERT_TO_FRAGMENTED_SPARSE_H
2#define TATAMI_CONVERT_TO_FRAGMENTED_SPARSE_H
3
7
8#include <memory>
9#include <vector>
10
17namespace tatami {
18
29template<typename Value_, typename Index_>
34 FragmentedSparseContents(size_t n) : value(n), index(n) {}
43 std::vector<std::vector<Value_> > value;
44
50 std::vector<std::vector<Index_> > index;
51};
52
62
75template<typename StoredValue_, typename StoredIndex_, typename InputValue_, typename InputIndex_>
78 bool row,
80{
81 InputIndex_ NR = matrix.nrow();
82 InputIndex_ NC = matrix.ncol();
83 InputIndex_ primary = (row ? NR : NC);
84 InputIndex_ secondary = (row ? NC : NR);
85
87 auto& store_v = output.value;
88 auto& store_i = output.index;
89
90 if (row == matrix.prefer_rows()) {
91 if (matrix.is_sparse()) {
92 parallelize([&](int, InputIndex_ start, InputIndex_ length) -> void {
93 std::vector<InputValue_> buffer_v(secondary);
94 std::vector<InputIndex_> buffer_i(secondary);
95 auto wrk = consecutive_extractor<true>(matrix, row, start, length);
96
97 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
98 auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
99 auto& sv = store_v[p];
100 auto& si = store_i[p];
101 sv.reserve(range.number);
102 si.reserve(range.number);
103
104 for (InputIndex_ i = 0; i < range.number; ++i, ++range.value, ++range.index) {
105 if (*range.value) {
106 sv.push_back(*range.value);
107 si.push_back(*range.index);
108 }
109 }
110 }
111 }, primary, options.num_threads);
112
113 } else {
114 parallelize([&](int, InputIndex_ start, InputIndex_ length) -> void {
115 std::vector<InputValue_> buffer_v(secondary);
116 auto wrk = consecutive_extractor<false>(matrix, row, start, length);
117
118 // Special conversion from dense to save ourselves from having to make
119 // indices that we aren't really interested in.
120 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
121 auto ptr = wrk->fetch(buffer_v.data());
122 auto& sv = store_v[p];
123 auto& si = store_i[p];
124
125 for (InputIndex_ s = 0; s < secondary; ++s, ++ptr) {
126 if (*ptr) {
127 sv.push_back(*ptr);
128 si.push_back(s);
129 }
130 }
131 }
132 }, primary, options.num_threads);
133 }
134
135 } else {
136 // We iterate on the matrix matrix's preferred dimension, under the
137 // assumption that it may be arbitrarily costly to extract in the
138 // non-preferred dim; it is thus cheaper to do cache-unfriendly inserts
139 // into the output buffers.
140
141 if (matrix.is_sparse()) {
142 parallelize([&](int, InputIndex_ start, InputIndex_ length) -> void {
143 std::vector<InputValue_> buffer_v(primary);
144 std::vector<InputIndex_> buffer_i(primary);
145 auto wrk = consecutive_extractor<true>(matrix, !row, static_cast<InputIndex_>(0), secondary, start, length);
146
147 for (InputIndex_ x = 0; x < secondary; ++x) {
148 auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
149 for (InputIndex_ i = 0; i < range.number; ++i, ++range.value, ++range.index) {
150 if (*range.value) {
151 store_v[*range.index].push_back(*range.value);
152 store_i[*range.index].push_back(x);
153 }
154 }
155 }
156 }, primary, options.num_threads);
157
158 } else {
159 parallelize([&](int, InputIndex_ start, InputIndex_ length) -> void {
160 auto wrk = consecutive_extractor<false>(matrix, !row, static_cast<InputIndex_>(0), secondary, start, length);
161 std::vector<InputValue_> buffer_v(length);
162
163 for (InputIndex_ x = 0; x < secondary; ++x) {
164 auto ptr = wrk->fetch(buffer_v.data());
165 for (InputIndex_ p = start, pe = start + length; p < pe; ++p, ++ptr) {
166 if (*ptr) {
167 store_v[p].push_back(*ptr);
168 store_i[p].push_back(x);
169 }
170 }
171 }
172 }, primary, options.num_threads);
173 }
174 }
175
176 return output;
177}
178
188
204template<
205 typename Value_,
206 typename Index_,
207 typename StoredValue_ = Value_,
208 typename StoredIndex_ = Index_,
209 typename InputValue_,
210 typename InputIndex_
211>
212std::shared_ptr<Matrix<Value_, Index_> > convert_to_fragmented_sparse(
214 bool row,
216{
218 matrix,
219 row,
220 [&]{
222 ropt.num_threads = options.num_threads;
223 return ropt;
224 }()
225 );
226 return std::shared_ptr<Matrix<Value_, Index_> >(
228 Value_,
229 Index_,
230 std::vector<std::vector<StoredValue_> >,
231 std::vector<std::vector<StoredIndex_> >
232 >(
233 matrix.nrow(),
234 matrix.ncol(),
235 std::move(frag.value),
236 std::move(frag.index),
237 row,
238 []{
239 FragmentedSparseMatrixOptions fopt;
240 fopt.check = false; // no need for checks, as we guarantee correctness.
241 return fopt;
242 }()
243 )
244 );
245}
246
250// Backwards compatbility.
251template<typename Value_, typename Index_, typename StoredValue_ = Value_, typename StoredIndex_ = Index_, typename InputValue_, typename InputIndex_>
252std::shared_ptr<Matrix<Value_, Index_> > convert_to_fragmented_sparse(const Matrix<InputValue_, InputIndex_>* matrix, bool row, int threads = 1) {
254 *matrix,
255 row,
256 [&]{
257 ConvertToFragmentedSparseOptions opt;
258 opt.num_threads = threads;
259 return opt;
260 }()
261 );
262}
263
264template<typename StoredValue_, typename StoredIndex_, typename InputValue_, typename InputIndex_>
265FragmentedSparseContents<StoredValue_, StoredIndex_> retrieve_fragmented_sparse_contents(const Matrix<InputValue_, InputIndex_>* matrix, bool row, int threads = 1) {
267 *matrix,
268 row,
269 [&]{
270 RetrieveFragmentedSparseContentsOptions opt;
271 opt.num_threads = threads;
272 return opt;
273 }()
274 );
275}
276
277template <bool row_, typename StoredValue_, typename StoredIndex_, typename InputValue_, typename InputIndex_>
278FragmentedSparseContents<StoredValue_, StoredIndex_> retrieve_fragmented_sparse_contents(const Matrix<InputValue_, InputIndex_>* matrix, int threads = 1) {
280}
281
282template <bool row_, typename Value_, typename Index_, typename StoredValue_ = Value_, typename StoredIndex_ = Index_, typename InputValue_, typename InputIndex_>
283std::shared_ptr<Matrix<Value_, Index_> > convert_to_fragmented_sparse(const Matrix<InputValue_, InputIndex_>* matrix, int threads = 1) {
285}
290}
291
292#endif
Fragmented sparse matrix representation.
Fragmented sparse matrix representation.
Definition FragmentedSparseMatrix.hpp:465
Virtual class for a matrix.
Definition Matrix.hpp:59
virtual Index_ ncol() const =0
virtual Index_ nrow() const =0
virtual bool prefer_rows() const =0
virtual bool is_sparse() const =0
Templated construction of a new consecutive extractor.
Flexible representations for matrix data.
Definition Extractor.hpp:15
void parallelize(Function_ fun, Index_ tasks, int threads)
Definition parallelize.hpp:42
FragmentedSparseContents< StoredValue_, StoredIndex_ > retrieve_fragmented_sparse_contents(const Matrix< InputValue_, InputIndex_ > &matrix, bool row, const RetrieveFragmentedSparseContentsOptions &options)
Definition convert_to_fragmented_sparse.hpp:76
std::shared_ptr< Matrix< Value_, Index_ > > convert_to_fragmented_sparse(const Matrix< InputValue_, InputIndex_ > &matrix, bool row, const ConvertToFragmentedSparseOptions &options)
Definition convert_to_fragmented_sparse.hpp:212
auto consecutive_extractor(const Matrix< Value_, Index_ > &matrix, bool row, Index_ iter_start, Index_ iter_length, Args_ &&... args)
Definition consecutive_extractor.hpp:35
Parallelized iteration over a tatami::Matrix.
Options for convert_to_fragmented_sparse().
Definition convert_to_fragmented_sparse.hpp:182
int num_threads
Definition convert_to_fragmented_sparse.hpp:186
Fragmented sparse contents.
Definition convert_to_fragmented_sparse.hpp:30
std::vector< std::vector< Value_ > > value
Definition convert_to_fragmented_sparse.hpp:43
std::vector< std::vector< Index_ > > index
Definition convert_to_fragmented_sparse.hpp:50
Options for retrieve_fragmented_sparse_contents().
Definition convert_to_fragmented_sparse.hpp:56
int num_threads
Definition convert_to_fragmented_sparse.hpp:60