Program Listing for File csc.cc
↰ Return to documentation for file (src/sparsebase/format/csc.cc
)
#include "sparsebase/format/csc.h"
#include "sparsebase/utils/logger.h"
namespace sparsebase::format {
template <typename IDType, typename NNZType, typename ValueType>
CSC<IDType, NNZType, ValueType>::CSC(CSC<IDType, NNZType, ValueType> &&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<IDType, std::function<void(IDType *)>>(
nullptr, BlankDeleter<IDType>());
rhs.col_ptr_ = std::unique_ptr<NNZType, std::function<void(NNZType *)>>(
nullptr, BlankDeleter<NNZType>());
rhs.vals_ = std::unique_ptr<ValueType, std::function<void(ValueType *)>>(
nullptr, BlankDeleter<ValueType>());
this->context_ = std::unique_ptr<sparsebase::context::Context>(
new sparsebase::context::CPUContext);
}
template <typename IDType, typename NNZType, typename ValueType>
CSC<IDType, NNZType, ValueType> &CSC<IDType, NNZType, ValueType>::operator=(
const CSC<IDType, NNZType, ValueType> &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<ValueType, void>) {
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<IDType, std::function<void(IDType *)>>(
row, Deleter<IDType>());
this->col_ptr_ = std::unique_ptr<NNZType, std::function<void(NNZType *)>>(
col_ptr, Deleter<NNZType>());
this->vals_ = std::unique_ptr<ValueType, std::function<void(ValueType *)>>(
vals, Deleter<ValueType>());
return *this;
}
template <typename IDType, typename NNZType, typename ValueType>
CSC<IDType, NNZType, ValueType>::CSC(const CSC<IDType, NNZType, ValueType> &rhs)
: row_(nullptr, BlankDeleter<IDType>()),
col_ptr_(nullptr, BlankDeleter<NNZType>()),
vals_(nullptr, BlankDeleter<ValueType>()) {
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<ValueType, void>) {
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<IDType, std::function<void(IDType *)>>(
row, Deleter<IDType>());
this->col_ptr_ = std::unique_ptr<NNZType, std::function<void(NNZType *)>>(
col_ptr, Deleter<NNZType>());
this->vals_ = std::unique_ptr<ValueType, std::function<void(ValueType *)>>(
vals, Deleter<ValueType>());
this->context_ = std::unique_ptr<sparsebase::context::Context>(
new sparsebase::context::CPUContext);
}
template <typename IDType, typename NNZType, typename ValueType>
CSC<IDType, NNZType, ValueType>::CSC(IDType n, IDType m, NNZType *col_ptr,
IDType *row, ValueType *vals,
Ownership own, bool ignore_sort)
: col_ptr_(col_ptr, BlankDeleter<NNZType>()),
row_(row, BlankDeleter<IDType>()),
vals_(vals, BlankDeleter<ValueType>()) {
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<NNZType, std::function<void(NNZType *)>>(
col_ptr, Deleter<NNZType>());
this->row_ = std::unique_ptr<IDType, std::function<void(IDType *)>>(
row, Deleter<IDType>());
this->vals_ = std::unique_ptr<ValueType, std::function<void(ValueType *)>>(
vals, Deleter<ValueType>());
}
this->context_ = std::unique_ptr<sparsebase::context::Context>(
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<ValueType, void>) {
std::vector<IDType> 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<ValueType>());
for (NNZType j = start; j < end; j++) {
row[j] = sort_vec[j - start];
}
} else {
std::vector<std::pair<IDType, ValueType>> 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<std::pair<IDType, ValueType>>());
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 <typename IDType, typename NNZType, typename ValueType>
Format *CSC<IDType, NNZType, ValueType>::Clone() const {
return new CSC(*this);
}
template <typename IDType, typename NNZType, typename ValueType>
IDType *CSC<IDType, NNZType, ValueType>::get_row() const {
return row_.get();
}
template <typename IDType, typename NNZType, typename ValueType>
NNZType *CSC<IDType, NNZType, ValueType>::get_col_ptr() const {
return col_ptr_.get();
}
template <typename IDType, typename NNZType, typename ValueType>
ValueType *CSC<IDType, NNZType, ValueType>::get_vals() const {
return vals_.get();
}
template <typename IDType, typename NNZType, typename ValueType>
IDType *CSC<IDType, NNZType, ValueType>::release_row() {
auto row = row_.release();
this->row_ = std::unique_ptr<IDType, std::function<void(IDType *)>>(
row, BlankDeleter<IDType>());
return row;
}
template <typename IDType, typename NNZType, typename ValueType>
NNZType *CSC<IDType, NNZType, ValueType>::release_col_ptr() {
auto col_ptr = col_ptr_.release();
this->col_ptr_ = std::unique_ptr<NNZType, std::function<void(NNZType *)>>(
col_ptr, BlankDeleter<NNZType>());
return col_ptr;
}
template <typename IDType, typename NNZType, typename ValueType>
ValueType *CSC<IDType, NNZType, ValueType>::release_vals() {
auto vals = vals_.release();
this->vals_ = std::unique_ptr<ValueType, std::function<void(ValueType *)>>(
vals, BlankDeleter<ValueType>());
return vals;
}
template <typename IDType, typename NNZType, typename ValueType>
void CSC<IDType, NNZType, ValueType>::set_row(IDType *row, Ownership own) {
if (own == kOwned) {
this->row_ = std::unique_ptr<IDType, std::function<void(IDType *)>>(
row, Deleter<IDType>());
} else {
this->row_ = std::unique_ptr<IDType, std::function<void(IDType *)>>(
row, BlankDeleter<IDType>());
}
}
template <typename IDType, typename NNZType, typename ValueType>
void CSC<IDType, NNZType, ValueType>::set_col_ptr(NNZType *col_ptr,
Ownership own) {
if (own == kOwned) {
this->col_ptr_ = std::unique_ptr<NNZType, std::function<void(NNZType *)>>(
col_ptr, Deleter<NNZType>());
} else {
this->col_ptr_ = std::unique_ptr<NNZType, std::function<void(NNZType *)>>(
col_ptr, BlankDeleter<NNZType>());
}
}
template <typename IDType, typename NNZType, typename ValueType>
void CSC<IDType, NNZType, ValueType>::set_vals(ValueType *vals, Ownership own) {
if (own == kOwned) {
this->vals_ = std::unique_ptr<ValueType, std::function<void(ValueType *)>>(
vals, Deleter<ValueType>());
} else {
this->vals_ = std::unique_ptr<ValueType, std::function<void(ValueType *)>>(
vals, BlankDeleter<ValueType>());
}
}
template <typename IDType, typename NNZType, typename ValueType>
bool CSC<IDType, NNZType, ValueType>::ColPtrIsOwned() {
return (this->col_ptr_.get_deleter().target_type() !=
typeid(BlankDeleter<NNZType>));
}
template <typename IDType, typename NNZType, typename ValueType>
bool CSC<IDType, NNZType, ValueType>::RowIsOwned() {
return (this->row_.get_deleter().target_type() !=
typeid(BlankDeleter<IDType>));
}
template <typename IDType, typename NNZType, typename ValueType>
bool CSC<IDType, NNZType, ValueType>::ValsIsOwned() {
return (this->vals_.get_deleter().target_type() !=
typeid(BlankDeleter<ValueType>));
}
template <typename IDType, typename NNZType, typename ValueType>
CSC<IDType, NNZType, ValueType>::~CSC() {}
#ifndef _HEADER_ONLY
#include "init/csc.inc"
#endif
} // namespace sparsebase::format