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
4#include <memory>
5#include <vector>
6#include <cstddef>
7
10#include "../utils/copy.hpp"
12#include "../utils/Index_to_container.hpp"
13
20namespace tatami {
21
32template<typename Value_, typename Index_>
37 FragmentedSparseContents(Index_ n) :
38 value(cast_Index_to_container_size<I<decltype(value)> >(n)),
40 {}
49 std::vector<std::vector<Value_> > value;
50
56 std::vector<std::vector<Index_> > index;
57};
58
68
81template<typename StoredValue_, typename StoredIndex_, typename InputValue_, typename InputIndex_>
84 const bool row,
86{
87 const InputIndex_ NR = matrix.nrow();
88 const InputIndex_ NC = matrix.ncol();
89 const InputIndex_ primary = (row ? NR : NC);
90 const InputIndex_ secondary = (row ? NC : NR);
91
93 auto& store_v = output.value;
94 auto& store_i = output.index;
95
96 if (row == matrix.prefer_rows()) {
97 if (matrix.is_sparse()) {
98 parallelize([&](const int, const InputIndex_ start, const InputIndex_ length) -> void {
99 auto wrk = consecutive_extractor<true>(matrix, row, start, length);
102
103 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
104 const auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
105 auto& sv = store_v[p];
106 auto& si = store_i[p];
107 sv.reserve(range.number);
108 si.reserve(range.number);
109
110 for (InputIndex_ i = 0; i < range.number; ++i) {
111 const auto val = range.value[i];
112 if (val) {
113 sv.push_back(val);
114 si.push_back(range.index[i]);
115 }
116 }
117 }
118 }, primary, options.num_threads);
119
120 } else {
121 parallelize([&](const int, const InputIndex_ start, const InputIndex_ length) -> void {
122 auto wrk = consecutive_extractor<false>(matrix, row, start, length);
124
125 // Special conversion from dense to save ourselves from having to make
126 // indices that we aren't really interested in.
127 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
128 const auto ptr = wrk->fetch(buffer_v.data());
129 auto& sv = store_v[p];
130 auto& si = store_i[p];
131
132 for (InputIndex_ s = 0; s < secondary; ++s) {
133 const auto val = ptr[s];
134 if (val) {
135 sv.push_back(val);
136 si.push_back(s);
137 }
138 }
139 }
140 }, primary, options.num_threads);
141 }
142
143 } else {
144 // We iterate on the matrix matrix's preferred dimension, under the
145 // assumption that it may be arbitrarily costly to extract in the
146 // non-preferred dim; it is thus cheaper to do cache-unfriendly inserts
147 // into the output buffers.
148
149 if (matrix.is_sparse()) {
150 parallelize([&](const int, const InputIndex_ start, const InputIndex_ length) -> void {
151 auto wrk = consecutive_extractor<true>(matrix, !row, static_cast<InputIndex_>(0), secondary, start, length);
154
155 for (InputIndex_ x = 0; x < secondary; ++x) {
156 const auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
157 for (InputIndex_ i = 0; i < range.number; ++i) {
158 const auto val = range.value[i];
159 if (val) {
160 const auto idx = range.index[i];
161 store_v[idx].push_back(val);
162 store_i[idx].push_back(x);
163 }
164 }
165 }
166 }, primary, options.num_threads);
167
168 } else {
169 parallelize([&](const int, const InputIndex_ start, const InputIndex_ length) -> void {
170 auto wrk = consecutive_extractor<false>(matrix, !row, static_cast<InputIndex_>(0), secondary, start, length);
172
173 for (InputIndex_ x = 0; x < secondary; ++x) {
174 const auto ptr = wrk->fetch(buffer_v.data());
175 for (InputIndex_ p = 0; p < length; ++p) {
176 const auto val = ptr[p];
177 if (val) {
178 const auto idx = p + start;
179 store_v[idx].push_back(val);
180 store_i[idx].push_back(x);
181 }
182 }
183 }
184 }, primary, options.num_threads);
185 }
186 }
187
188 return output;
189}
190
200
216template<
217 typename Value_,
218 typename Index_,
219 typename StoredValue_ = Value_,
220 typename StoredIndex_ = Index_,
221 typename InputValue_,
222 typename InputIndex_
223>
224std::shared_ptr<Matrix<Value_, Index_> > convert_to_fragmented_sparse(
226 const bool row,
228{
230 matrix,
231 row,
232 [&]{
234 ropt.num_threads = options.num_threads;
235 return ropt;
236 }()
237 );
238 return std::shared_ptr<Matrix<Value_, Index_> >(
240 Value_,
241 Index_,
242 std::vector<std::vector<StoredValue_> >,
243 std::vector<std::vector<StoredIndex_> >
244 >(
245 matrix.nrow(),
246 matrix.ncol(),
247 std::move(frag.value),
248 std::move(frag.index),
249 row,
250 []{
251 FragmentedSparseMatrixOptions fopt;
252 fopt.check = false; // no need for checks, as we guarantee correctness.
253 return fopt;
254 }()
255 )
256 );
257}
258
262// Backwards compatbility.
263template<typename Value_, typename Index_, typename StoredValue_ = Value_, typename StoredIndex_ = Index_, typename InputValue_, typename InputIndex_>
264std::shared_ptr<Matrix<Value_, Index_> > convert_to_fragmented_sparse(const Matrix<InputValue_, InputIndex_>* matrix, bool row, int threads = 1) {
266 *matrix,
267 row,
268 [&]{
269 ConvertToFragmentedSparseOptions opt;
270 opt.num_threads = threads;
271 return opt;
272 }()
273 );
274}
275
276template<typename StoredValue_, typename StoredIndex_, typename InputValue_, typename InputIndex_>
277FragmentedSparseContents<StoredValue_, StoredIndex_> retrieve_fragmented_sparse_contents(const Matrix<InputValue_, InputIndex_>* matrix, bool row, int threads = 1) {
279 *matrix,
280 row,
281 [&]{
282 RetrieveFragmentedSparseContentsOptions opt;
283 opt.num_threads = threads;
284 return opt;
285 }()
286 );
287}
288
289template <bool row_, typename StoredValue_, typename StoredIndex_, typename InputValue_, typename InputIndex_>
290FragmentedSparseContents<StoredValue_, StoredIndex_> retrieve_fragmented_sparse_contents(const Matrix<InputValue_, InputIndex_>* matrix, int threads = 1) {
292}
293
294template <bool row_, typename Value_, typename Index_, typename StoredValue_ = Value_, typename StoredIndex_ = Index_, typename InputValue_, typename InputIndex_>
295std::shared_ptr<Matrix<Value_, Index_> > convert_to_fragmented_sparse(const Matrix<InputValue_, InputIndex_>* matrix, int threads = 1) {
297}
302}
303
304#endif
Fragmented sparse matrix representation.
Fragmented sparse matrix representation.
Definition FragmentedSparseMatrix.hpp:569
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.
Copy data from one buffer to another.
Flexible representations for matrix data.
Definition Extractor.hpp:15
void parallelize(Function_ fun, const Index_ tasks, const int threads)
Definition parallelize.hpp:42
FragmentedSparseContents< StoredValue_, StoredIndex_ > retrieve_fragmented_sparse_contents(const Matrix< InputValue_, InputIndex_ > &matrix, const bool row, const RetrieveFragmentedSparseContentsOptions &options)
Definition convert_to_fragmented_sparse.hpp:82
I< decltype(std::declval< Container_ >().size())> cast_Index_to_container_size(const Index_ x)
Definition Index_to_container.hpp:56
std::shared_ptr< Matrix< Value_, Index_ > > convert_to_fragmented_sparse(const Matrix< InputValue_, InputIndex_ > &matrix, const bool row, const ConvertToFragmentedSparseOptions &options)
Definition convert_to_fragmented_sparse.hpp:224
Container_ create_container_of_Index_size(const Index_ x, Args_ &&... args)
Definition Index_to_container.hpp:73
auto consecutive_extractor(const Matrix< Value_, Index_ > &matrix, const bool row, const Index_ iter_start, const 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:194
int num_threads
Definition convert_to_fragmented_sparse.hpp:198
Fragmented sparse contents.
Definition convert_to_fragmented_sparse.hpp:33
std::vector< std::vector< Value_ > > value
Definition convert_to_fragmented_sparse.hpp:49
std::vector< std::vector< Index_ > > index
Definition convert_to_fragmented_sparse.hpp:56
Options for retrieve_fragmented_sparse_contents().
Definition convert_to_fragmented_sparse.hpp:62
int num_threads
Definition convert_to_fragmented_sparse.hpp:66