1#ifndef TATAMI_CONVERT_TO_DENSE_H
2#define TATAMI_CONVERT_TO_DENSE_H
15#include "sanisizer/sanisizer.hpp"
46template <
typename StoredValue_,
typename InputValue_,
typename InputIndex_>
48 const InputIndex_ NR = matrix.
nrow();
49 const InputIndex_ NC = matrix.
ncol();
51 const auto primary = (pref_rows ? NR : NC);
52 const auto secondary = (pref_rows ? NC : NR);
57 if (row_major == pref_rows) {
58 constexpr bool same_type = std::is_same<InputValue_, StoredValue_>::value;
61 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
64 if constexpr(same_type) {
67 return std::vector<InputValue_>(secondary);
71 for (InputIndex_ x = 0; x < length; ++x) {
72 const auto store_copy = store + sanisizer::product_unsafe<std::size_t>(secondary, start + x);
73 if constexpr(same_type) {
74 auto ptr = wrk->fetch(store_copy);
75 copy_n(ptr, secondary, store_copy);
77 auto ptr = wrk->fetch(temp.data());
78 std::copy_n(ptr, secondary, store_copy);
84 std::fill_n(store, sanisizer::product_unsafe<std::size_t>(primary, secondary), 0);
91 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
99 for (InputIndex_ x = 0; x < primary; ++x) {
100 const auto range = wrk->fetch(vtemp.data(), itemp.data());
101 for (InputIndex_ i = 0; i < range.number; ++i) {
102 store[sanisizer::nd_offset<std::size_t>(x, primary, range.index[i])] = range.value[i];
111 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
118 constexpr InputIndex_ block_size = 16;
119 const InputIndex_ alloc = std::min(primary, block_size);
120 std::vector<InputValue_> bigbuffer(sanisizer::product_unsafe<
typename std::vector<InputValue_>::size_type>(length, alloc));
121 std::vector<const InputValue_*> ptrs(alloc);
122 std::vector<InputValue_*> buf_ptrs(alloc);
123 for (InputIndex_ i = 0; i < alloc; ++i) {
124 buf_ptrs[i] = bigbuffer.data() + sanisizer::product_unsafe<std::size_t>(length, i);
127 InputIndex_ prim_i = 0;
128 while (prim_i < primary) {
129 const InputIndex_ prim_to_process = std::min(
static_cast<InputIndex_
>(primary - prim_i), block_size);
130 for (InputIndex_ c = 0; c < prim_to_process; ++c) {
131 ptrs[c] = wrk->fetch(buf_ptrs[c]);
134 InputIndex_ sec_i = 0;
135 while (sec_i < length) {
136 const InputIndex_ sec_end = sec_i + std::min(
static_cast<InputIndex_
>(length - sec_i), block_size);
137 for (InputIndex_ c = 0; c < prim_to_process; ++c) {
138 const auto input = ptrs[c];
139 for (InputIndex_ r = sec_i; r < sec_end; ++r) {
140 store[sanisizer::nd_offset<std::size_t>(c + prim_i, primary, r + start)] = input[r];
146 prim_i += prim_to_process;
171 typename StoredValue_ = Value_,
172 typename InputValue_,
176 const auto NR = matrix.
nrow();
177 const auto NC = matrix.
ncol();
178 const auto buffer_size = sanisizer::product<typename std::vector<StoredValue_>::size_type>(attest_for_Index(NR), attest_for_Index(NC));
179 std::vector<StoredValue_> buffer(buffer_size);
182 return std::shared_ptr<Matrix<Value_, Index_> >(
183 new DenseMatrix<Value_, Index_, I<
decltype(buffer)> >(
184 sanisizer::cast<Index_>(attest_for_Index(NR)),
185 sanisizer::cast<Index_>(attest_for_Index(NC)),
196template <
typename StoredValue_,
typename InputValue_,
typename InputIndex_>
197void convert_to_dense(
const Matrix<InputValue_, InputIndex_>* matrix,
bool row_major, StoredValue_* store,
int threads = 1) {
203 ConvertToDenseOptions options;
204 options.num_threads = threads;
210template <
typename Value_ =
double,
typename Index_ =
int,
typename StoredValue_ = Value_,
typename InputValue_,
typename InputIndex_>
211inline std::shared_ptr<Matrix<Value_, Index_> >
convert_to_dense(
const Matrix<InputValue_, InputIndex_>* matrix,
bool row_major,
int threads = 1) {
212 ConvertToDenseOptions options;
213 options.num_threads = threads;
218 ConvertToDenseOptions options;
219 options.num_threads = threads;
225template<
bool row_,
typename StoredValue_,
typename InputValue_,
typename InputIndex_>
226void convert_to_dense(
const Matrix<InputValue_, InputIndex_>* matrix, StoredValue_* store,
int threads = 1) {
230template<
bool row_,
typename Value_,
typename Index_,
typename StoredValue_ = Value_,
typename InputValue_,
typename InputIndex_>
231inline std::shared_ptr<Matrix<Value_, Index_> >
convert_to_dense(
const Matrix<InputValue_, InputIndex_>* matrix,
int threads = 1) {
Dense matrix representation.
Convert index type to container size.
Dense matrix representation.
Definition DenseMatrix.hpp:172
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
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
Index_ can_cast_Index_to_container_size(const Index_ x)
Definition Index_to_container.hpp:49
void convert_to_dense(const Matrix< InputValue_, InputIndex_ > &matrix, const bool row_major, StoredValue_ *const store, const ConvertToDenseOptions &options)
Definition convert_to_dense.hpp:47
Value_ * copy_n(const Value_ *const input, const Size_ n, Value_ *const output)
Definition copy.hpp:37
Container_ create_container_of_Index_size(const Index_ x, Args_ &&... args)
Definition Index_to_container.hpp:82
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_dense().
Definition convert_to_dense.hpp:28
int num_threads
Definition convert_to_dense.hpp:32