Skip to content

Commit

Permalink
change reserve instance method of sparse matrix classes to free funct…
Browse files Browse the repository at this point in the history
…ions.
  • Loading branch information
rileyjmurray committed Sep 3, 2024
1 parent 380513a commit 17fa752
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 165 deletions.
6 changes: 3 additions & 3 deletions RandBLAS/sparse_data/base.hh
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@

namespace RandBLAS::sparse_data {

enum class IndexBase : char {
enum class IndexBase : int {
// ---------------------------------------------------------------
// zero-based indexing
Zero = 'Z',
Zero = 0,
// ---------------------------------------------------------------
// one-based indexing
One = 'O'
One = 1
};

template <typename T>
Expand Down
12 changes: 6 additions & 6 deletions RandBLAS/sparse_data/conversions.hh
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void coo_to_csc(COOMatrix<T, sint_t1> &coo, CSCMatrix<T, sint_t2> &csc) {
randblas_require(csc.index_base == IndexBase::Zero);
randblas_require(coo.index_base == IndexBase::Zero);
sort_coo_data(NonzeroSort::CSC, coo);
csc.reserve(coo.nnz);
reserve(coo.nnz, csc);
csc.colptr[0] = 0;
int64_t ell = 0;
for (int64_t j = 0; j < coo.n_cols; ++j) {
Expand All @@ -67,7 +67,7 @@ void csc_to_coo(CSCMatrix<T, sint_t1> &csc, COOMatrix<T, sint_t2> &coo) {
randblas_require(csc.n_cols == coo.n_cols);
randblas_require(csc.index_base == IndexBase::Zero);
randblas_require(coo.index_base == IndexBase::Zero);
coo.reserve(csc.nnz);
reserve(csc.nnz, coo);
int64_t ell = 0;
for (int64_t j = 0; j < csc.n_cols; ++j) {
for (int64_t i = csc.colptr[j]; i < csc.colptr[j+1]; ++i) {
Expand All @@ -88,7 +88,7 @@ void coo_to_csr(COOMatrix<T, sint_t1> &coo, CSRMatrix<T, sint_t2> &csr) {
randblas_require(csr.index_base == IndexBase::Zero);
randblas_require(coo.index_base == IndexBase::Zero);
sort_coo_data(NonzeroSort::CSR, coo);
csr.reserve(coo.nnz);
reserve(coo.nnz, csr);
csr.rowptr[0] = (sint_t2) 0;
int64_t ell = 0;
for (int64_t i = 0; i < coo.n_rows; ++i) {
Expand All @@ -108,7 +108,7 @@ void csr_to_coo(CSRMatrix<T, sint_t1> &csr, COOMatrix<T, sint_t2> &coo) {
randblas_require(csr.n_cols == coo.n_cols);
randblas_require(csr.index_base == IndexBase::Zero);
randblas_require(coo.index_base == IndexBase::Zero);
coo.reserve(csr.nnz);
reserve(csr.nnz, coo);
int64_t ell = 0;
for (int64_t i = 0; i < csr.n_rows; ++i) {
for (int64_t j = csr.rowptr[i]; j < csr.rowptr[i+1]; ++j) {
Expand All @@ -129,7 +129,7 @@ CSRMatrix<T, sint_t> transpose_as_csr(CSCMatrix<T, sint_t> &A, bool share_memory
return At;
} else {
CSRMatrix<T, sint_t> At(A.n_cols, A.n_rows, A.index_base);
At.reserve(A.nnz);
reserve(A.nnz, At);
for (int64_t i = 0; i < A.nnz; ++i) {
At.colidxs[i] = A.rowidxs[i];
At.vals[i] = A.vals[i];
Expand All @@ -147,7 +147,7 @@ CSCMatrix<T, sint_t> transpose_as_csc(CSRMatrix<T, sint_t> &A, bool share_memory
return At;
} else {
CSCMatrix<T, sint_t> At(A.n_cols, A.n_rows, A.index_base);
At.reserve(A.nnz);
reserve(A.nnz, At);
for (int64_t i = 0; i < A.nnz; ++i) {
At.rowidxs[i] = A.colidxs[i];
At.vals[i] = A.vals[i];
Expand Down
86 changes: 38 additions & 48 deletions RandBLAS/sparse_data/coo_matrix.hh
Original file line number Diff line number Diff line change
Expand Up @@ -112,22 +112,20 @@ struct COOMatrix {
bool own_memory;
int64_t nnz = 0;
IndexBase index_base;
T *vals = nullptr;
T *vals;
// ---------------------------------------------------------------------------
/// Row indicies for nonzeros.
sint_t *rows = nullptr;
/// Row indicies for nonzeros. If non-null, this is presumed to have length
/// at least \math{\ttt{nnz}.}
sint_t *rows;
// ---------------------------------------------------------------------------
/// Column indicies for nonzeros
sint_t *cols = nullptr;
/// Column indicies for nonzeros. If non-null, this is presumed to have length
/// at least \math{\ttt{nnz}.}
sint_t *cols;
// ---------------------------------------------------------------------------
/// A flag to indicate if the data in (rows, cols, vals) is sorted in a
/// A flag to indicate if the data in (vals, rows, cols) is sorted in a
/// CSC-like order, a CSR-like order, or neither order.
NonzeroSort sort = NonzeroSort::None;

bool _can_reserve = true;
// ^ A flag to indicate if we're allowed to allocate new memory for
// (rows, cols, vals). Set to false after COOMatrix.reserve(...) is called.

COOMatrix(
int64_t n_rows,
int64_t n_cols,
Expand All @@ -137,23 +135,21 @@ struct COOMatrix {
sint_t *cols,
bool compute_sort_type,
IndexBase index_base
) : n_rows(n_rows), n_cols(n_cols), own_memory(false), index_base(index_base) {
this->nnz = nnz;
this->vals = vals;
this->rows = rows;
this->cols = cols;
) : n_rows(n_rows), n_cols(n_cols), own_memory(false), nnz(nnz), index_base(index_base),
vals(vals), rows(rows), cols(cols) {
if (compute_sort_type) {
this->sort = coo_sort_type(nnz, rows, cols);
sort = coo_sort_type(nnz, rows, cols);
} else {
this->sort = NonzeroSort::None;
sort = NonzeroSort::None;
}
};

COOMatrix(
int64_t n_rows,
int64_t n_cols,
IndexBase index_base
) : n_rows(n_rows), n_cols(n_cols), own_memory(true), index_base(index_base) {};
) : n_rows(n_rows), n_cols(n_cols), own_memory(true), nnz(0), index_base(index_base),
vals(nullptr), rows(nullptr), cols(nullptr) {};

// Constructs an empty sparse matrix of given dimensions.
// Data can't stored in this object until a subsequent call to reserve(int64_t nnz).
Expand Down Expand Up @@ -219,34 +215,13 @@ struct COOMatrix {
) : COOMatrix(n_rows, n_cols, nnz, vals, rows, cols, compute_sort_type, IndexBase::Zero) {};

~COOMatrix() {
if (this->own_memory) {
if (own_memory) {
if (vals != nullptr) delete [] vals;
if (rows != nullptr) delete [] rows;
if (cols != nullptr) delete [] cols;
}
};

// @verbatim embed:rst:leading-slashes
// Attach three buffers of length nnz for (vals, rows, cols).
// This function can only be called if :math:`\ttt{own_memory == true},`` and
// it can only be called once.
//
// @endverbatim
void reserve(int64_t nnz) {
randblas_require(this->_can_reserve);
randblas_require(this->own_memory);
randblas_require(vals == nullptr);
randblas_require(rows == nullptr);
randblas_require(cols == nullptr);
this->nnz = nnz;
if (this->nnz > 0) {
vals = new T[nnz];
rows = new sint_t[nnz];
cols = new sint_t[nnz];
}
_can_reserve = false;
}

/////////////////////////////////////////////////////////////////////
//
// Undocumented functions (don't appear in doxygen)
Expand All @@ -255,12 +230,12 @@ struct COOMatrix {

// move constructor
COOMatrix(COOMatrix<T, sint_t> &&other)
: n_rows(other.n_rows), n_cols(other.n_cols), own_memory(other.own_memory), index_base(other.index_base) {
this->nnz = other.nnz;
std::swap(this->rows, other.rows);
std::swap(this->cols, other.cols);
std::swap(this->vals, other.vals);
this->_can_reserve = other._can_reserve;
: n_rows(other.n_rows), n_cols(other.n_cols), own_memory(other.own_memory), nnz(0), index_base(other.index_base),
vals(nullptr), rows(nullptr), cols(nullptr) {
nnz = other.nnz;
std::swap(rows, other.rows);
std::swap(cols, other.cols);
std::swap(vals, other.vals);
other.nnz = 0;
}

Expand All @@ -271,6 +246,22 @@ static_assert(SparseMatrix<COOMatrix<float>>);
static_assert(SparseMatrix<COOMatrix<double>>);
#endif


template <typename T, SignedInteger sint_t>
void reserve(int64_t nnz, COOMatrix<T,sint_t> &M) {
randblas_require(M.own_memory);
randblas_require(M.vals == nullptr);
randblas_require(M.rows == nullptr);
randblas_require(M.cols == nullptr);
M.nnz = nnz;
if (M.nnz > 0) {
M.vals = new T[nnz];
M.rows = new sint_t[nnz];
M.cols = new sint_t[nnz];
}
return;
}

template <typename T, SignedInteger sint_t>
void sort_coo_data(NonzeroSort s, int64_t nnz, T *vals, sint_t *rows, sint_t *cols) {
if (s == NonzeroSort::None)
Expand Down Expand Up @@ -358,7 +349,7 @@ void dense_to_coo(int64_t stride_row, int64_t stride_col, T *mat, T abs_tol, COO
int64_t n_rows = spmat.n_rows;
int64_t n_cols = spmat.n_cols;
int64_t nnz = nnz_in_dense(n_rows, n_cols, stride_row, stride_col, mat, abs_tol);
spmat.reserve(nnz);
reserve(nnz, spmat);
nnz = 0;
#define MAT(_i, _j) mat[(_i) * stride_row + (_j) * stride_col]
for (int64_t i = 0; i < n_rows; ++i) {
Expand Down Expand Up @@ -386,7 +377,6 @@ void dense_to_coo(Layout layout, T* mat, T abs_tol, COOMatrix<T> &spmat) {

template <typename T>
void coo_to_dense(const COOMatrix<T> &spmat, int64_t stride_row, int64_t stride_col, T *mat) {
randblas_require(spmat.index_base == IndexBase::Zero);
#define MAT(_i, _j) mat[(_i) * stride_row + (_j) * stride_col]
for (int64_t i = 0; i < spmat.n_rows; ++i) {
for (int64_t j = 0; j < spmat.n_cols; ++j) {
Expand Down
7 changes: 4 additions & 3 deletions RandBLAS/sparse_data/coo_spmm_impl.hh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@

namespace RandBLAS::sparse_data::coo {

template <typename T, RandBLAS::SignedInteger sint_t = int64_t>
using RandBLAS::SignedInteger;

template <typename T, SignedInteger sint_t = int64_t>
static int64_t set_filtered_coo(
// COO-format matrix data
const T *vals,
Expand Down Expand Up @@ -75,8 +77,7 @@ static int64_t set_filtered_coo(
}



template <typename T, RandBLAS::SignedInteger sint_t>
template <typename T, SignedInteger sint_t>
static void apply_coo_left_jki_p11(
T alpha,
blas::Layout layout_B,
Expand Down
77 changes: 34 additions & 43 deletions RandBLAS/sparse_data/csc_matrix.hh
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@

namespace RandBLAS::sparse_data {

using RandBLAS::SignedInteger;

// =============================================================================
/// A CSC-format sparse matrix that complies with the SparseMatrix concept.
///
template <typename T, RandBLAS::SignedInteger sint_t = int64_t>
template <typename T, SignedInteger sint_t = int64_t>
struct CSCMatrix {
using scalar_t = T;
using index_t = sint_t;
Expand All @@ -48,26 +50,26 @@ struct CSCMatrix {
bool own_memory;
int64_t nnz = 0;
IndexBase index_base;
T *vals = nullptr;
T *vals;

// ---------------------------------------------------------------------------
/// Row index array in the CSC format.
///
sint_t *rowidxs = nullptr;
sint_t *rowidxs;

// ---------------------------------------------------------------------------
/// Pointer offset array for the CSC format. The number of nonzeros in column j
/// is given by colptr[j+1] - colptr[j]. The row index of the k-th nonzero
/// in column j is rowidxs[colptr[j] + k].
///
sint_t *colptr = nullptr;
bool _can_reserve = true;
sint_t *colptr;

CSCMatrix(
int64_t n_rows,
int64_t n_cols,
IndexBase index_base
) : n_rows(n_rows), n_cols(n_cols), own_memory(true), index_base(index_base) { };
) : n_rows(n_rows), n_cols(n_cols), own_memory(true), nnz(0), index_base(index_base),
vals(nullptr), rowidxs(nullptr), colptr(nullptr) { };

CSCMatrix(
int64_t n_rows,
Expand All @@ -77,12 +79,8 @@ struct CSCMatrix {
sint_t *rowidxs,
sint_t *colptr,
IndexBase index_base
) : n_rows(n_rows), n_cols(n_cols), own_memory(false), index_base(index_base) {
this->nnz = nnz;
this->vals = vals;
this->rowidxs = rowidxs;
this->colptr = colptr;
};
) : n_rows(n_rows), n_cols(n_cols), own_memory(false), nnz(nnz), index_base(index_base),
vals(vals), rowidxs(rowidxs), colptr(colptr) { };

// Constructs an empty sparse matrix of given dimensions.
// Data can't stored in this object until a subsequent call to reserve(int64_t nnz).
Expand Down Expand Up @@ -135,43 +133,20 @@ struct CSCMatrix {
) : CSCMatrix(n_rows, n_cols, nnz, vals, rowidxs, colptr, IndexBase::Zero) {};

~CSCMatrix() {
if (this->own_memory) {
if (own_memory) {
if (rowidxs != nullptr) delete [] rowidxs;
if (colptr != nullptr) delete [] colptr;
if (vals != nullptr) delete [] vals;
}
};


// @verbatim embed:rst:leading-slashes
// Attach three buffers to this CSCMatrix, (vals, rowidxs, colptr), of sufficient
// size for this matrix to hold nnz structural nonzeros.
// This function can only be called if :math:`\ttt{own_memory == true},`` and
// it can only be called once.
//
// @endverbatim
void reserve(int64_t nnz) {
randblas_require(_can_reserve);
randblas_require(own_memory);
if (colptr == nullptr)
colptr = new sint_t[n_cols + 1]{0};
this->nnz = nnz;
if (nnz > 0) {
randblas_require( rowidxs == nullptr );
randblas_require( vals == nullptr );
rowidxs = new sint_t[nnz]{0};
vals = new T[nnz]{0.0};
}
_can_reserve = false;
};

CSCMatrix(CSCMatrix<T, sint_t> &&other)
: n_rows(other.n_rows), n_cols(other.n_cols), own_memory(other.own_memory), index_base(other.index_base) {
this->nnz = other.nnz;
std::swap(this->rowidxs, other.rowidxs);
std::swap(this->colptr , other.colptr );
std::swap(this->vals , other.vals );
this->_can_reserve = other._can_reserve;
: n_rows(other.n_rows), n_cols(other.n_cols), own_memory(other.own_memory), nnz(0), index_base(other.index_base),
vals(nullptr), rowidxs(nullptr), colptr(nullptr) {
nnz = other.nnz;
std::swap(rowidxs, other.rowidxs);
std::swap(colptr , other.colptr );
std::swap(vals , other.vals );
other.nnz = 0;
};
};
Expand All @@ -181,6 +156,22 @@ static_assert(SparseMatrix<CSCMatrix<float>>);
static_assert(SparseMatrix<CSCMatrix<double>>);
#endif


template <typename T, SignedInteger sint_t>
void reserve(int64_t nnz, CSCMatrix<T,sint_t> &M) {
randblas_require(M.own_memory);
if (M.colptr == nullptr)
M.colptr = new sint_t[M.n_cols + 1]{0};
M.nnz = nnz;
if (nnz > 0) {
randblas_require( M.rowidxs == nullptr );
randblas_require( M.vals == nullptr );
M.rowidxs = new sint_t[nnz]{0};
M.vals = new T[nnz]{0.0};
}
return;
}

} // end namespace RandBLAS::sparse_data

namespace RandBLAS::sparse_data::csc {
Expand Down Expand Up @@ -226,7 +217,7 @@ void dense_to_csc(int64_t stride_row, int64_t stride_col, T *mat, T abs_tol, CSC
// Step 1: count the number of entries with absolute value at least abstol
int64_t nnz = nnz_in_dense(n_rows, n_cols, stride_row, stride_col, mat, abs_tol);
// Step 2: allocate memory needed by the sparse matrix
spmat.reserve(nnz);
reserve(nnz, spmat);
// Step 3: traverse the dense matrix again, populating the sparse matrix as we go
nnz = 0;
spmat.colptr[0] = 0;
Expand Down
Loading

0 comments on commit 17fa752

Please sign in to comment.