1#ifndef TATAMI_CONVERT_TO_COMPRESSED_SPARSE_H
2#define TATAMI_CONVERT_TO_COMPRESSED_SPARSE_H
27namespace convert_to_compressed_sparse_internal {
29template<
typename Value_,
typename Index_,
typename Count_>
30void count_compressed_sparse_non_zeros_consistent(
33 const Index_ secondary,
40 opt.sparse_extract_value =
false;
41 opt.sparse_extract_index =
false;
42 opt.sparse_ordered_index =
false;
44 parallelize([&](
const int,
const Index_ start,
const Index_ length) ->
void {
45 auto wrk = consecutive_extractor<true>(matrix, row, start, length, opt);
46 for (Index_ x = 0; x < length; ++x) {
47 const auto range = wrk->fetch(NULL, NULL);
48 output[start + x] = range.number;
53 parallelize([&](
const int,
const Index_ start,
const Index_ length) ->
void {
54 auto buffer_v = create_container_of_Index_size<std::vector<Value_> >(secondary);
55 auto wrk = consecutive_extractor<false>(matrix, row, start, length);
56 for (Index_ p = start, pe = start + length; p < pe; ++p) {
57 const auto ptr = wrk->fetch(buffer_v.data());
59 for (Index_ s = 0; s < secondary; ++s) {
60 count += (ptr[s] != 0);
68template<
typename Value_,
typename Index_,
typename Count_>
69void count_compressed_sparse_non_zeros_inconsistent(
72 const Index_ secondary,
80 auto nz_counts = sanisizer::create<std::vector<std::optional<std::vector<Count_> > > >(threads - 1);
81 const auto get_ptr = [&](
const int t, std::optional<std::vector<Count_> >& nz_tmp) -> Count_* {
83 nz_tmp.emplace(cast_Index_to_container_size<std::vector<Count_> >(primary));
84 return nz_tmp->data();
89 const auto save_output = [&](
const int t, std::optional<std::vector<Count_> >& nz_tmp) {
91 nz_counts[t - 1] = std::move(nz_tmp);
98 opt.sparse_extract_value =
false;
99 opt.sparse_ordered_index =
false;
101 num_used =
parallelize([&](
const int t,
const Index_ start,
const Index_ length) ->
void {
102 std::optional<std::vector<Count_> > nz_tmp;
103 Count_* cur_counts = get_ptr(t, nz_tmp);
105 auto wrk = consecutive_extractor<true>(matrix, !row, start, length, opt);
106 auto buffer_i = create_container_of_Index_size<std::vector<Index_> >(primary);
107 for (Index_ x = 0; x < length; ++x) {
108 const auto range = wrk->fetch(NULL, buffer_i.data());
109 for (Index_ i = 0; i < range.number; ++i) {
110 ++cur_counts[range.index[i]];
114 save_output(t, nz_tmp);
115 }, secondary, threads);
118 num_used =
parallelize([&](
const int t,
const Index_ start,
const Index_ length) ->
void {
119 std::optional<std::vector<Count_> > nz_tmp;
120 Count_* cur_counts = get_ptr(t, nz_tmp);
122 auto wrk = consecutive_extractor<false>(matrix, !row, start, length);
123 auto buffer_v = create_container_of_Index_size<std::vector<Value_> >(primary);
124 for (Index_ x = 0; x < length; ++x) {
125 const auto ptr = wrk->fetch(buffer_v.data());
126 for (Index_ p = 0; p < primary; ++p) {
127 cur_counts[p] += (ptr[p] != 0);
131 save_output(t, nz_tmp);
132 }, secondary, threads);
135 for (
int t = 1; t < num_used; ++t) {
136 const auto& y = *(nz_counts[t - 1]);
137 for (Index_ p = 0; p < primary; ++p) {
143template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
144void fill_compressed_sparse_matrix_consistent(
146 const InputIndex_ primary,
147 const InputIndex_ secondary,
149 const Pointer_*
const pointers,
150 StoredValue_*
const output_value,
151 StoredIndex_*
const output_index,
156 opt.sparse_ordered_index =
false;
158 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
159 auto wrk = consecutive_extractor<true>(matrix, row, start, length, opt);
160 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(secondary);
161 auto buffer_i = create_container_of_Index_size<std::vector<InputIndex_> >(secondary);
163 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
169 const auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
170 const auto offset = pointers[p];
171 std::copy_n(range.value, range.number, output_value + offset);
172 std::copy_n(range.index, range.number, output_index + offset);
174 }, primary, threads);
177 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
178 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(secondary);
179 auto wrk = consecutive_extractor<false>(matrix, row, start, length);
181 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
182 const auto ptr = wrk->fetch(buffer_v.data());
183 auto offset = pointers[p];
184 for (InputIndex_ s = 0; s < secondary; ++s) {
185 const auto val = ptr[s];
187 output_value[offset] = val;
188 output_index[offset] = s;
193 }, primary, threads);
197template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
198void fill_compressed_sparse_matrix_inconsistent(
200 const InputIndex_ primary,
201 const InputIndex_ secondary,
203 const Pointer_*
const pointers,
204 StoredValue_*
const output_value,
205 StoredIndex_*
const output_index,
210 opt.sparse_ordered_index =
false;
212 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
213 auto wrk = consecutive_extractor<true>(matrix, !row,
static_cast<InputIndex_
>(0), secondary, start, length, opt);
214 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(length);
215 auto buffer_i = create_container_of_Index_size<std::vector<InputIndex_> >(length);
216 std::vector<Pointer_> offset_copy(pointers + start, pointers + start + length);
218 for (InputIndex_ x = 0; x < secondary; ++x) {
219 const auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
220 for (InputIndex_ i = 0; i < range.number; ++i) {
221 auto& pos = offset_copy[range.index[i] - start];
222 output_value[pos] = range.value[i];
223 output_index[pos] = x;
227 }, primary, threads);
230 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
231 auto wrk = consecutive_extractor<false>(matrix, !row,
static_cast<InputIndex_
>(0), secondary, start, length);
232 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(length);
233 std::vector<Pointer_> offset_copy(pointers + start, pointers + start + length);
235 for (InputIndex_ x = 0; x < secondary; ++x) {
236 const auto ptr = wrk->fetch(buffer_v.data());
237 for (InputIndex_ p = 0; p < length; ++p) {
238 const auto val = ptr[p];
240 auto& pos = offset_copy[p];
241 output_value[pos] = val;
242 output_index[pos] = x;
247 }, primary, threads);
281template<
typename Value_,
typename Index_,
typename Count_>
285 Count_*
const output,
288 const Index_ NR = matrix.
nrow();
289 const Index_ NC = matrix.
ncol();
290 const Index_ primary = (row ? NR : NC);
291 const Index_ secondary = (row ? NC : NR);
292 std::fill_n(output, primary, 0);
295 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_consistent(matrix, primary, secondary, row, output, options.
num_threads);
297 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_inconsistent(matrix, primary, secondary, row, output, options.
num_threads);
330template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
334 const Pointer_*
const pointers,
335 StoredValue_*
const output_value,
336 StoredIndex_*
const output_index,
339 const InputIndex_ NR = matrix.
nrow();
340 const InputIndex_ NC = matrix.
ncol();
341 const InputIndex_ primary = (row ? NR : NC);
342 const InputIndex_ secondary = (row ? NC : NR);
345 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_consistent(matrix, primary, secondary, row, pointers, output_value, output_index, options.
num_threads);
347 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_inconsistent(matrix, primary, secondary, row, pointers, output_value, output_index, options.
num_threads);
361template<
typename Value_,
typename Index_,
typename Po
inter_>
412template<
typename StoredValue_,
typename StoredIndex_,
typename StoredPo
inter_ = std::
size_t,
typename InputValue_,
typename InputIndex_>
421 auto& output_v = output.
value;
422 auto& output_i = output.
index;
425 const InputIndex_ NR = matrix.
nrow();
426 const InputIndex_ NC = matrix.
ncol();
427 const InputIndex_ primary = (row ? NR : NC);
428 const InputIndex_ secondary = (row ? NC : NR);
430 output_p.resize(sanisizer::sum<I<
decltype(output_p.size())> >(attest_for_Index(primary), 1));
443 const auto& store_v = frag.value;
444 const auto& store_i = frag.index;
446 for (InputIndex_ p = 0; p < primary; ++p) {
447 output_p[p + 1] = output_p[p] + store_v[p].size();
450 output_v.reserve(output_p.back());
451 output_i.reserve(output_p.back());
452 for (InputIndex_ p = 0; p < primary; ++p) {
453 output_v.insert(output_v.end(), store_v[p].begin(), store_v[p].end());
454 output_i.insert(output_i.end(), store_i[p].begin(), store_i[p].end());
459 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_consistent(matrix, primary, secondary, row, output_p.data() + 1, options.
num_threads);
460 for (InputIndex_ i = 1; i <= primary; ++i) {
461 output_p[i] += output_p[i - 1];
465 output_v.resize(output_p.back());
466 output_i.resize(output_p.back());
467 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_consistent(
480 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_inconsistent(matrix, primary, secondary, row, output_p.data() + 1, options.
num_threads);
481 for (InputIndex_ i = 1; i <= primary; ++i) {
482 output_p[i] += output_p[i - 1];
486 output_v.resize(output_p.back());
487 output_i.resize(output_p.back());
488 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_inconsistent(
539 typename StoredValue_ = Value_,
540 typename StoredIndex_ = Index_,
541 typename StoredPointer_ = std::size_t,
542 typename InputValue_,
560 return std::shared_ptr<Matrix<Value_, Index_> >(
564 std::vector<StoredValue_>,
565 std::vector<StoredIndex_>,
566 std::vector<StoredPointer_>
570 std::move(comp.value),
571 std::move(comp.index),
572 std::move(comp.pointers),
575 CompressedSparseMatrixOptions copt;
587template<
typename Value_,
typename Index_,
typename Count_>
594 CountCompressedSparseNonZerosOptions copt;
595 copt.num_threads = threads;
601template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
604 const Pointer_* pointers,
605 StoredValue_* output_value,
606 StoredIndex_* output_index,
616 FillCompressedSparseContentsOptions fopt;
617 fopt.num_threads = threads;
623template<
typename StoredValue_,
typename StoredIndex_,
typename StoredPo
inter_ = std::
size_t,
typename InputValue_,
typename InputIndex_>
624CompressedSparseContents<StoredValue_, StoredIndex_, StoredPointer_>
retrieve_compressed_sparse_contents(
const Matrix<InputValue_, InputIndex_>* matrix,
bool row,
bool two_pass,
int threads = 1) {
629 RetrieveCompressedSparseContentsOptions opt;
630 opt.two_pass = two_pass;
631 opt.num_threads = threads;
637template<
typename Value_ =
double,
typename Index_ =
int,
typename StoredValue_ = Value_,
typename StoredIndex_ = Index_,
typename InputValue_,
typename InputIndex_>
638std::shared_ptr<Matrix<Value_, Index_> >
convert_to_compressed_sparse(
const Matrix<InputValue_, InputIndex_>* matrix,
bool row,
bool two_pass =
false,
int threads = 1) {
643 ConvertToCompressedSparseOptions opt;
644 opt.two_pass = two_pass;
645 opt.num_threads = threads;
651template <
bool row_,
typename Value_,
typename Index_,
typename InputValue_,
typename InputIndex_>
656template <
bool row_,
typename Value_,
typename Index_,
typename StoredValue_ = Value_,
typename StoredIndex_ = Index_,
typename InputValue_,
typename InputIndex_>
657std::shared_ptr<Matrix<Value_, Index_> >
convert_to_compressed_sparse(
const Matrix<InputValue_, InputIndex_>* matrix,
bool two_pass =
false,
int threads = 1) {
Compressed sparse matrix representation.
Convert index type to container size.
Compressed sparse matrix representation.
Definition CompressedSparseMatrix.hpp:580
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
Convert a matrix into a fragmented sparse format.
Copy data from one buffer to another.
Flexible representations for matrix data.
Definition Extractor.hpp:15
void count_compressed_sparse_non_zeros(const tatami::Matrix< Value_, Index_ > &matrix, const bool row, Count_ *const output, const CountCompressedSparseNonZerosOptions &options)
Definition convert_to_compressed_sparse.hpp:282
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
CompressedSparseContents< StoredValue_, StoredIndex_, StoredPointer_ > retrieve_compressed_sparse_contents(const Matrix< InputValue_, InputIndex_ > &matrix, const bool row, const RetrieveCompressedSparseContentsOptions &options)
Definition convert_to_compressed_sparse.hpp:413
int parallelize(Function_ fun, const Index_ tasks, const int workers)
Definition parallelize.hpp:58
void fill_compressed_sparse_contents(const tatami::Matrix< InputValue_, InputIndex_ > &matrix, const bool row, const Pointer_ *const pointers, StoredValue_ *const output_value, StoredIndex_ *const output_index, const FillCompressedSparseContentsOptions &options)
Definition convert_to_compressed_sparse.hpp:331
std::shared_ptr< Matrix< Value_, Index_ > > convert_to_compressed_sparse(const Matrix< InputValue_, InputIndex_ > &matrix, const bool row, const ConvertToCompressedSparseOptions &options)
Definition convert_to_compressed_sparse.hpp:545
Parallelized iteration over a tatami::Matrix.
Compressed sparse contents.
Definition convert_to_compressed_sparse.hpp:362
std::vector< Index_ > index
Definition convert_to_compressed_sparse.hpp:371
std::vector< Value_ > value
Definition convert_to_compressed_sparse.hpp:366
std::vector< Pointer_ > pointers
Definition convert_to_compressed_sparse.hpp:376
Options for convert_to_compressed_sparse().
Definition convert_to_compressed_sparse.hpp:506
bool two_pass
Definition convert_to_compressed_sparse.hpp:511
int num_threads
Definition convert_to_compressed_sparse.hpp:516
Options for count_compressed_sparse_non_zeros().
Definition convert_to_compressed_sparse.hpp:259
int num_threads
Definition convert_to_compressed_sparse.hpp:263
Options for fill_compressed_sparse_contents().
Definition convert_to_compressed_sparse.hpp:304
int num_threads
Definition convert_to_compressed_sparse.hpp:308
Options for retrieve_compressed_sparse_contents().
Definition convert_to_compressed_sparse.hpp:382
int num_threads
Definition convert_to_compressed_sparse.hpp:392
bool two_pass
Definition convert_to_compressed_sparse.hpp:387
Options for retrieve_fragmented_sparse_contents().
Definition convert_to_fragmented_sparse.hpp:62
int num_threads
Definition convert_to_fragmented_sparse.hpp:66