.. _program_listing_file_src_sparsebase_format_csc.cc: Program Listing for File csc.cc =============================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/sparsebase/format/csc.cc``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "sparsebase/format/csc.h" #include "sparsebase/utils/logger.h" namespace sparsebase::format { template CSC::CSC(CSC &&rhs) : row_(std::move(rhs.row_)), col_ptr_(std::move(rhs.col_ptr_)), vals_(std::move(rhs.vals_)) { this->nnz_ = rhs.get_num_nnz(); this->order_ = 2; this->dimension_ = rhs.dimension_; rhs.row_ = std::unique_ptr>( nullptr, BlankDeleter()); rhs.col_ptr_ = std::unique_ptr>( nullptr, BlankDeleter()); rhs.vals_ = std::unique_ptr>( nullptr, BlankDeleter()); this->context_ = std::unique_ptr( new sparsebase::context::CPUContext); } template CSC &CSC::operator=( const CSC &rhs) { this->nnz_ = rhs.nnz_; this->order_ = 2; this->dimension_ = rhs.dimension_; auto row = new IDType[rhs.get_num_nnz()]; std::copy(rhs.get_row(), rhs.get_row() + rhs.get_num_nnz(), row); auto col_ptr = new NNZType[(rhs.get_dimensions()[0] + 1)]; std::copy(rhs.get_col_ptr(), rhs.get_col_ptr() + (rhs.get_dimensions()[0] + 1), col_ptr); ValueType *vals = nullptr; if constexpr (!std::is_same_v) { if (rhs.get_vals() != nullptr) { vals = new ValueType[rhs.get_num_nnz()]; std::copy(rhs.get_vals(), rhs.get_vals() + rhs.get_num_nnz(), vals); } } this->row_ = std::unique_ptr>( row, Deleter()); this->col_ptr_ = std::unique_ptr>( col_ptr, Deleter()); this->vals_ = std::unique_ptr>( vals, Deleter()); return *this; } template CSC::CSC(const CSC &rhs) : row_(nullptr, BlankDeleter()), col_ptr_(nullptr, BlankDeleter()), vals_(nullptr, BlankDeleter()) { this->nnz_ = rhs.nnz_; this->order_ = 2; this->dimension_ = rhs.dimension_; auto row = new IDType[rhs.get_num_nnz()]; std::copy(rhs.get_row(), rhs.get_row() + rhs.get_num_nnz(), row); auto col_ptr = new NNZType[(rhs.get_dimensions()[0] + 1)]; std::copy(rhs.get_col_ptr(), rhs.get_col_ptr() + (rhs.get_dimensions()[0] + 1), col_ptr); ValueType *vals = nullptr; if constexpr (!std::is_same_v) { if (rhs.get_vals() != nullptr) { vals = new ValueType[rhs.get_num_nnz()]; std::copy(rhs.get_vals(), rhs.get_vals() + rhs.get_num_nnz(), vals); } } this->row_ = std::unique_ptr>( row, Deleter()); this->col_ptr_ = std::unique_ptr>( col_ptr, Deleter()); this->vals_ = std::unique_ptr>( vals, Deleter()); this->context_ = std::unique_ptr( new sparsebase::context::CPUContext); } template CSC::CSC(IDType n, IDType m, NNZType *col_ptr, IDType *row, ValueType *vals, Ownership own, bool ignore_sort) : col_ptr_(col_ptr, BlankDeleter()), row_(row, BlankDeleter()), vals_(vals, BlankDeleter()) { this->order_ = 2; this->dimension_ = {(DimensionType)n, (DimensionType)m}; this->nnz_ = col_ptr[this->dimension_[0]]; if (own == kOwned) { this->col_ptr_ = std::unique_ptr>( col_ptr, Deleter()); this->row_ = std::unique_ptr>( row, Deleter()); this->vals_ = std::unique_ptr>( vals, Deleter()); } this->context_ = std::unique_ptr( new sparsebase::context::CPUContext); if (!ignore_sort) { bool not_sorted = false; #pragma omp parallel for default(none) reduction(|| \ : not_sorted) \ shared(row, col_ptr, n) for (IDType i = 0; i < n; i++) { NNZType start = col_ptr[i]; NNZType end = col_ptr[i + 1]; IDType prev_value = 0; for (NNZType j = start; j < end; j++) { if (row[j] < prev_value) { not_sorted = true; break; } prev_value = row[j]; } } if (not_sorted) { utils::Logger logger(typeid(this)); logger.Log("CSC column array must be sorted. Sorting...", utils::LOG_LVL_WARNING); #pragma omp parallel for default(none) shared(col_ptr, row, vals, n) for (IDType i = 0; i < n; i++) { NNZType start = col_ptr[i]; NNZType end = col_ptr[i + 1]; if (end - start <= 1) { continue; } if constexpr (std::is_same_v) { std::vector sort_vec; for (NNZType j = start; j < end; j++) { sort_vec.emplace_back(row[j]); } std::sort(sort_vec.begin(), sort_vec.end(), std::less()); for (NNZType j = start; j < end; j++) { row[j] = sort_vec[j - start]; } } else { std::vector> sort_vec; for (NNZType j = start; j < end; j++) { ValueType val = (vals != nullptr) ? vals[j] : 0; sort_vec.emplace_back(row[j], val); } std::sort(sort_vec.begin(), sort_vec.end(), std::less>()); for (NNZType j = start; j < end; j++) { if (vals != nullptr) { vals[j] = sort_vec[j - start].second; } row[j] = sort_vec[j - start].first; } } } } } } template Format *CSC::Clone() const { return new CSC(*this); } template IDType *CSC::get_row() const { return row_.get(); } template NNZType *CSC::get_col_ptr() const { return col_ptr_.get(); } template ValueType *CSC::get_vals() const { return vals_.get(); } template IDType *CSC::release_row() { auto row = row_.release(); this->row_ = std::unique_ptr>( row, BlankDeleter()); return row; } template NNZType *CSC::release_col_ptr() { auto col_ptr = col_ptr_.release(); this->col_ptr_ = std::unique_ptr>( col_ptr, BlankDeleter()); return col_ptr; } template ValueType *CSC::release_vals() { auto vals = vals_.release(); this->vals_ = std::unique_ptr>( vals, BlankDeleter()); return vals; } template void CSC::set_row(IDType *row, Ownership own) { if (own == kOwned) { this->row_ = std::unique_ptr>( row, Deleter()); } else { this->row_ = std::unique_ptr>( row, BlankDeleter()); } } template void CSC::set_col_ptr(NNZType *col_ptr, Ownership own) { if (own == kOwned) { this->col_ptr_ = std::unique_ptr>( col_ptr, Deleter()); } else { this->col_ptr_ = std::unique_ptr>( col_ptr, BlankDeleter()); } } template void CSC::set_vals(ValueType *vals, Ownership own) { if (own == kOwned) { this->vals_ = std::unique_ptr>( vals, Deleter()); } else { this->vals_ = std::unique_ptr>( vals, BlankDeleter()); } } template bool CSC::ColPtrIsOwned() { return (this->col_ptr_.get_deleter().target_type() != typeid(BlankDeleter)); } template bool CSC::RowIsOwned() { return (this->row_.get_deleter().target_type() != typeid(BlankDeleter)); } template bool CSC::ValsIsOwned() { return (this->vals_.get_deleter().target_type() != typeid(BlankDeleter)); } template CSC::~CSC() {} #ifndef _HEADER_ONLY #include "init/csc.inc" #endif } // namespace sparsebase::format