I'm trying to transpose matrix (GF(2) field, so no need to store elements) that is written in modifed CSR format:
class GF2_CSR_Matrix
{
protected:
uint64_t rows;
uint64_t columns;
uint64_t non_zero;
std::vector<uint64_t> nonzeros_per_row; (Here each element is only number of NZ in row, unlike classical CSR which stores total NZ in rows before)
std::vector<uint64_t> column_indexes; (idx of columns containing NZ)
}
Also I have parallelized function to count partial sum.
void calculate_prefix_sum(std::vector<std::pair<uint64_t, uint64_t>> &j_ends,
const std::vector<uint64_t> &nonzeros_per_row) // .first is start of indexing, .second is end. In fact [i].second equals [i+1].first
Can somebody help me?
Something along these lines (not tested):
// Eventually, will have a count of non-zero elements
// in all columns to the left of `col`.
// But first, just count non-zeros per column.
std::vector<uint64_t> cumulative_nonzeros_per_column(columns, 0);
for (uint64_t col : column_indexes) {
++cumulative_nonzeros_per_column[col];
}
// Now convert to cumulative counts.
uint64_t cumulative_count = 0;
for (uint64_t& col_count : cumulative_nonzeros_per_column) {
uint64_t prev_count = cumulative_count;
cumulative_count += col_count;
col_count = prev_count;
}
std::vector<uint64_t> row_indexes(non_zero);
std::vector<uint64_t> nonzeros_per_column(columns, 0);
uint64_t row = 0;
uint64_t nz_in_row = 0;
for (uint64_t col : column_indexes) {
for (;;) {
if (++nz_in_row <= nonzeros_per_row[row]) break;
++row;
nz_in_row = 0;
}
// How many non-zero elements would precede this element in column-wise
// traversal? The cumulative count in all columns to the left, plus the
// count encountered so far in the current column.
row_indexes[cumulative_nonzeros_per_column[col] +
nonzeros_per_column[col]++] = row;
}
// row_indexes becomes column_indexes of the transposed matrix
// nonzeros_per_row becomes nonzeros_per_column of the transposed matrix