25template<
typename ColIndex_,
typename ValueOut_ =
double,
typename IndexOut_ =
int,
typename ValueIn_,
typename IndexIn_>
27 const auto NR = mat.
nrow(), NC = mat.
ncol();
28 const IndexIn_ leftovers = NC % chunk_size;
29 const IndexIn_ nchunks = sanisizer::max(1, NC / chunk_size + (leftovers != 0));
45 for (
auto& x : max_per_chunk) {
50 for (
auto& x : num_per_chunk) {
64 for (IndexIn_ r = start, end = start + length; r < end; ++r) {
65 const auto range = ext->fetch(r, dbuffer.data(), ibuffer.data());
66 for (IndexIn_ i = 0; i < range.number; ++i) {
68 const auto chunk = range.index[i] / chunk_size;
69 const auto cat = categorize(range.value[i]);
70 max_per_chunk[chunk][r] = std::max(max_per_chunk[chunk][r], cat);
71 ++num_per_chunk[chunk][r];
82 for (IndexIn_ r = start, end = start + length; r < end; ++r) {
83 auto ptr = ext->fetch(r, dbuffer.data());
84 for (IndexIn_ c = 0; c < NC; ++c) {
86 const auto chunk = c / chunk_size;
87 const auto cat = categorize(ptr[c]);
88 max_per_chunk[chunk][r] = std::max(max_per_chunk[chunk][r], cat);
89 ++num_per_chunk[chunk][r];
120 for (IndexIn_ r = start, end = start + length; r < end; ++r) {
121 for (I<
decltype(nchunks)> chunk = 0; chunk < nchunks; ++chunk) {
122 output_positions[chunk] = get_sparse_ptr(store8, store16, store32, assigned_category, assigned_position, chunk, r);
125 auto range = ext->fetch(r, dbuffer.data(), ibuffer.data());
126 for (IndexIn_ i = 0; i < range.number; ++i) {
127 if (range.value[i]) {
128 const IndexIn_ chunk = range.index[i] / chunk_size;
129 const IndexIn_ col = range.index[i] % chunk_size;
130 fill_sparse_value(store8, store16, store32, assigned_category[chunk][r], chunk, col, range.value[i], output_positions[chunk]++);
138 for (IndexIn_ r = start, end = start + length; r < end; ++r) {
139 for (I<
decltype(nchunks)> chunk = 0; chunk < nchunks; ++chunk) {
140 output_positions[chunk] = get_sparse_ptr(store8, store16, store32, assigned_category, assigned_position, chunk, r);
143 auto ptr = ext->fetch(r, dbuffer.data());
144 for (IndexIn_ c = 0; c < NC; ++c) {
146 const IndexIn_ chunk = c / chunk_size;
147 const IndexIn_ col = c % chunk_size;
148 fill_sparse_value(store8, store16, store32, assigned_category[chunk][r], chunk, col, ptr[c], output_positions[chunk]++);
157 return consolidate_matrices<ValueOut_, IndexOut_>(
170template<
typename ColIndex_,
typename ValueOut_ =
double,
typename IndexOut_ =
int,
typename ValueIn_,
typename IndexIn_>
171std::shared_ptr<tatami::Matrix<ValueOut_, IndexOut_> > convert_by_column(
const tatami::Matrix<ValueIn_, IndexIn_>& mat,
const IndexIn_ chunk_size,
const int nthreads) {
172 const auto NR = mat.
nrow(), NC = mat.
ncol();
173 const IndexIn_ leftovers = NC % chunk_size;
174 const IndexIn_ nchunks = sanisizer::max(1, NC / chunk_size + (leftovers != 0));
189 auto max_per_chunk_threaded = sanisizer::create<std::vector<std::vector<std::vector<Category> > > >(nthreads);
190 for (
auto& max_per_chunk : max_per_chunk_threaded) {
192 for (
auto& x : max_per_chunk) {
197 auto num_per_chunk_threaded = sanisizer::create<std::vector<std::vector<std::vector<IndexIn_> > > >(nthreads);
198 for (
auto& num_per_chunk : num_per_chunk_threaded) {
200 for (
auto& x : num_per_chunk) {
206 tatami::parallelize([&](
const int t,
const IndexIn_ start,
const IndexIn_ length) ->
void {
215 auto& max_per_chunk = max_per_chunk_threaded[t];
216 auto& num_per_chunk = num_per_chunk_threaded[t];
218 for (IndexIn_ c = start, end = start + length; c < end; ++c) {
219 const auto range = ext->fetch(c, dbuffer.data(), ibuffer.data());
220 const auto chunk = c / chunk_size;
221 auto& max_vec = max_per_chunk[chunk];
222 auto& num_vec = num_per_chunk[chunk];
224 for (IndexIn_ i = 0; i < range.number; ++i) {
225 if (range.value[i]) {
226 const auto cat = categorize(range.value[i]);
227 const auto r = range.index[i];
228 max_vec[r] = std::max(max_vec[r], cat);
236 tatami::parallelize([&](
const int t,
const IndexIn_ start,
const IndexIn_ length) ->
void {
240 auto& max_per_chunk = max_per_chunk_threaded[t];
241 auto& num_per_chunk = num_per_chunk_threaded[t];
243 for (IndexIn_ c = start, end = start + length; c < end; ++c) {
244 const auto ptr = ext->fetch(c, dbuffer.data());
245 const auto chunk = c / chunk_size;
246 auto& max_vec = max_per_chunk[chunk];
247 auto& num_vec = num_per_chunk[chunk];
249 for (IndexIn_ r = 0; r < NR; ++r) {
251 auto cat = categorize(ptr[r]);
252 max_vec[r] = std::max(max_vec[r], cat);
263 for (I<
decltype(nchunks)> chunk = 0; chunk < nchunks; ++chunk) {
265 max_per_chunk[chunk].swap(max_per_chunk_threaded[0][chunk]);
266 num_per_chunk[chunk].swap(num_per_chunk_threaded[0][chunk]);
268 for (
int t = 1; t < nthreads; ++t) {
269 for (IndexIn_ r = 0; r < NR; ++r) {
270 max_per_chunk[chunk][r] = std::max(max_per_chunk[chunk][r], max_per_chunk_threaded[t][chunk][r]);
271 num_per_chunk[chunk][r] += num_per_chunk_threaded[t][chunk][r];
294 for (I<
decltype(nchunks)> chunk = 0; chunk < nchunks; ++chunk) {
296 for (IndexIn_ r = 0; r < length; ++r) {
297 output_positions[chunk][r] = get_sparse_ptr(store8, store16, store32, assigned_category, assigned_position, chunk, r + start);
307 for (IndexIn_ c = 0; c < NC; ++c) {
308 const auto range = ext->fetch(c, dbuffer.data(), ibuffer.data());
309 const auto chunk = c / chunk_size;
310 const IndexIn_ col = c % chunk_size;
311 auto& outpos = output_positions[chunk];
313 for (IndexIn_ i = 0; i < range.number; ++i) {
314 if (range.value[i]) {
315 const auto r = range.index[i];
316 fill_sparse_value(store8, store16, store32, assigned_category[chunk][r], chunk, col, range.value[i], outpos[r - start]++);
324 for (IndexIn_ c = 0; c < NC; ++c) {
325 const auto ptr = ext->fetch(c, dbuffer.data());
326 const auto chunk = c / chunk_size;
327 const IndexIn_ col = c % chunk_size;
328 auto& outpos = output_positions[chunk];
330 for (IndexIn_ r = 0; r < NR; ++r) {
332 fill_sparse_value(store8, store16, store32, assigned_category[chunk][r], chunk, col, ptr[r], outpos[r - start]++);
341 return consolidate_matrices<ValueOut_, IndexOut_>(
403template<
typename ValueOut_ =
double,
typename IndexOut_ =
int,
typename ColumnIndex_ = std::u
int16_t,
typename ValueIn_,
typename IndexIn_>
405 const IndexIn_ chunk_size = check_chunk_size<IndexIn_, ColumnIndex_>(options.
chunk_size);
407 return convert_by_row<ColumnIndex_, ValueOut_, IndexOut_>(mat, chunk_size, options.
num_threads);
409 return convert_by_column<ColumnIndex_, ValueOut_, IndexOut_>(mat, chunk_size, options.
num_threads);
417template<
typename ValueOut_ =
double,
typename IndexOut_ =
int,
typename ColumnIndex_ = std::u
int16_t,
typename ValueIn_,
typename IndexIn_>
420 ConvertToLayeredSparseOptions opt;
421 opt.chunk_size = chunk_size;
422 opt.num_threads = num_threads;
427template<
typename ValueOut_ =
double,
typename IndexOut_ =
int,
typename ColumnIndex_ = std::u
int16_t,
typename ValueIn_,
typename IndexIn_>