14 template <
typename T,
typename indexT,
bool columnMajor>
17 if (metadata !=
nullptr) {
22 if (values !=
nullptr) {
23 for (
size_t i = 0; i < outerDim; i++) {
24 if (values[i] !=
nullptr) {
30 if (counts !=
nullptr) {
31 for (
size_t i = 0; i < outerDim; i++) {
32 if (counts[i] !=
nullptr) {
38 if (indices !=
nullptr) {
39 for (
size_t i = 0; i < outerDim; i++) {
40 if (indices[i] !=
nullptr) {
47 if (valueSizes !=
nullptr) {
50 if (indexSizes !=
nullptr) {
56 template <
typename T,
typename indexT,
bool columnMajor>
65 outerDim = columnMajor ? numCols : numRows;
66 innerDim = columnMajor ? numRows : numCols;
72 compressCSC(mat.valuePtr(), mat.innerIndexPtr(), mat.outerIndexPtr());
76 template <
typename T,
typename indexT,
bool columnMajor>
92 compressCSC(mat.valuePtr(), mat.innerIndexPtr(), mat.outerIndexPtr());
96 template <
typename T,
typename indexT,
bool columnMajor>
102 template <
typename T,
typename indexT,
bool columnMajor>
103 template <u
int8_t otherCompressionLevel>
106 if constexpr (otherCompressionLevel == 2) {
115 if constexpr (otherCompressionLevel == 1) {
117 }
else if constexpr (otherCompressionLevel == 3) {
127 #ifdef IVSPARSE_DEBUG
133 template <
typename T,
typename indexT,
bool columnMajor>
134 template <
typename T2,
typename indexT2>
136 T2 *vals, indexT2 *innerIndices, indexT2 *outerPtr, uint32_t num_rows, uint32_t num_cols, uint32_t nnz) {
138 #ifdef IVSPARSE_DEBUG
139 assert(num_rows > 0 && num_cols > 0 && nnz > 0 &&
140 "Error: Matrix dimensions must be greater than 0");
141 assert(innerIndices !=
nullptr && outerPtr !=
nullptr && vals !=
nullptr &&
142 "Error: Pointers cannot be null");
159 compressCSC(vals, innerIndices, outerPtr);
163 template <
typename T,
typename indexT,
bool columnMajor>
164 template <
typename T2,
typename indexT2>
166 std::vector<std::tuple<indexT2, indexT2, T2>> &entries, uint32_t num_rows, uint32_t num_cols, uint32_t nnz) {
168 #ifdef IVSPARSE_DEBUG
169 assert(num_rows > 0 && num_cols > 0 && nnz > 0 &&
170 "Error: Matrix dimensions must be greater than 0");
191 index_t =
sizeof(indexT);
193 metadata =
new uint32_t[NUM_META_DATA];
195 metadata[1] = innerDim;
196 metadata[2] = outerDim;
199 metadata[5] = index_t;
203 values = (T **)malloc(
sizeof(T *) * outerDim);
204 counts = (indexT **)malloc(
sizeof(indexT *) * outerDim);
205 indices = (indexT **)malloc(
sizeof(indexT *) * outerDim);
206 valueSizes = (indexT *)malloc(
sizeof(indexT) * outerDim);
207 indexSizes = (indexT *)malloc(
sizeof(indexT) * outerDim);
208 }
catch (std::bad_alloc &ba) {
209 std::cerr <<
"bad_alloc caught: " << ba.what() <<
'\n';
210 throw std::runtime_error(
"Error: Could not allocate memory");
214 std::sort(entries.begin(), entries.end(),
215 [](
const std::tuple<indexT2, indexT2, T2> &a,
216 const std::tuple<indexT2, indexT2, T2> &b) {
217 if (std::get<1>(a) == std::get<1>(b)) {
218 return std::get<0>(a) < std::get<0>(b);
220 return std::get<1>(a) < std::get<1>(b);
224 std::map<T2, std::vector<indexT2>> maps[outerDim];
227 for (
size_t i = 0; i < nnz; i++) {
229 indexT2 row = std::get<0>(entries[i]);
230 indexT2 col = std::get<1>(entries[i]);
231 T2 val = std::get<2>(entries[i]);
234 if (maps[col].find(val) != maps[col].end()) {
236 maps[col][val].push_back(row);
239 maps[col][val] = std::vector<indexT2>{row};
245 #ifdef IVSPARSE_HAS_OPENMP
246 #pragma omp parallel for
248 for (
size_t i = 0; i < outerDim; i++) {
250 if (maps[i].empty()) {
253 indices[i] =
nullptr;
259 size_t performanceVecSize = 0;
260 size_t numInidces = 0;
263 for (
auto &val : maps[i]) {
264 performanceVecSize++;
265 numInidces += val.second.size();
269 values[i] = (T *)malloc(
sizeof(T) * maps[i].size());
270 counts[i] = (indexT *)malloc(
sizeof(indexT) * maps[i].size());
271 indices[i] = (indexT *)malloc(
sizeof(indexT) * numInidces);
272 }
catch (std::bad_alloc &ba) {
273 std::cerr <<
"bad_alloc caught: " << ba.what() <<
'\n';
274 throw std::runtime_error(
"Error: Could not allocate memory");
277 valueSizes[i] = maps[i].size();
278 indexSizes[i] = numInidces;
284 for (
auto &val : maps[i]) {
285 values[i][valIndex] = val.first;
286 counts[i][valIndex] = val.second.size();
288 for (
auto &indexVal : val.second) {
289 indices[i][index] = indexVal;
301 #ifdef IVSPARSE_DEBUG
307 template <
typename T,
typename indexT,
bool columnMajor>
313 numRows = vec.getLength();
319 numCols = vec.getLength();
325 index_t =
sizeof(indexT);
327 metadata =
new uint32_t[NUM_META_DATA];
329 metadata[1] = innerDim;
330 metadata[2] = outerDim;
333 metadata[5] = index_t;
337 values = (T **)malloc(
sizeof(T *));
338 counts = (indexT **)malloc(
sizeof(indexT *));
339 indices = (indexT **)malloc(
sizeof(indexT *));
340 valueSizes = (indexT *)malloc(
sizeof(indexT));
341 indexSizes = (indexT *)malloc(
sizeof(indexT));
342 }
catch (std::bad_alloc &ba) {
343 std::cerr <<
"bad_alloc caught: " << ba.what() <<
'\n';
344 throw std::runtime_error(
"Error: Could not allocate memory");
348 if (vec.
byteSize() == 0) [[unlikely]] {
351 indices[0] =
nullptr;
358 valueSizes[0] = vec.uniqueVals();
363 values[0] = (T *)malloc(
sizeof(T) * valueSizes[0]);
364 counts[0] = (indexT *)malloc(
sizeof(indexT) * valueSizes[0]);
365 indices[0] = (indexT *)malloc(
sizeof(indexT) * indexSizes[0]);
366 }
catch (std::bad_alloc &ba) {
367 std::cerr <<
"bad_alloc caught: " << ba.what() <<
'\n';
368 throw std::runtime_error(
"Error: Could not allocate memory");
372 memcpy(values[0], vec.getValues(),
sizeof(T) * valueSizes[0]);
373 memcpy(counts[0], vec.getCounts(),
sizeof(indexT) * valueSizes[0]);
374 memcpy(indices[0], vec.getIndices(),
sizeof(indexT) * indexSizes[0]);
378 #ifdef IVSPARSE_DEBUG
384 template <
typename T,
typename indexT,
bool columnMajor>
392 for (
size_t i = 1; i < vecs.size(); i++) {
402 #ifdef IVSPARSE_DEBUG
408 template <
typename T,
typename indexT,
bool columnMajor>
411 FILE *fp = fopen(filename,
"rb");
413 #ifdef IVSPARSE_DEBUG
416 throw std::runtime_error(
"Error: Could not open file");
421 metadata =
new uint32_t[NUM_META_DATA];
422 fread(metadata,
sizeof(uint32_t), NUM_META_DATA, fp);
425 innerDim = metadata[1];
426 outerDim = metadata[2];
429 index_t = metadata[5];
430 numRows = columnMajor ? innerDim : outerDim;
431 numCols = columnMajor ? outerDim : innerDim;
433 #ifdef IVSPARSE_DEBUG
436 if (metadata[0] != 2) {
438 throw std::runtime_error(
439 "Error: Compression level of file does not match compression level of "
446 values = (T **)malloc(
sizeof(T *) * outerDim);
447 counts = (indexT **)malloc(
sizeof(indexT *) * outerDim);
448 indices = (indexT **)malloc(
sizeof(indexT *) * outerDim);
449 valueSizes = (indexT *)malloc(
sizeof(indexT) * outerDim);
450 indexSizes = (indexT *)malloc(
sizeof(indexT) * outerDim);
451 }
catch (std::bad_alloc &ba) {
452 std::cerr <<
"bad_alloc caught: " << ba.what() <<
'\n';
453 throw std::runtime_error(
"Error: Could not allocate memory");
457 for (
size_t i = 0; i < outerDim; i++) {
458 fread(&valueSizes[i],
sizeof(indexT), 1, fp);
462 for (
size_t i = 0; i < outerDim; i++) {
463 fread(&indexSizes[i],
sizeof(indexT), 1, fp);
467 for (
size_t i = 0; i < outerDim; i++) {
469 values[i] = (T *)malloc(
sizeof(T) * valueSizes[i]);
470 }
catch (std::bad_alloc &ba) {
471 std::cerr <<
"bad_alloc caught: " << ba.what() <<
'\n';
472 throw std::runtime_error(
"Error: Could not allocate memory");
474 fread(values[i],
sizeof(T), valueSizes[i], fp);
478 for (
size_t i = 0; i < outerDim; i++) {
480 counts[i] = (indexT *)malloc(
sizeof(indexT) * valueSizes[i]);
481 }
catch (std::bad_alloc &ba) {
482 std::cerr <<
"bad_alloc caught: " << ba.what() <<
'\n';
483 throw std::runtime_error(
"Error: Could not allocate memory");
485 fread(counts[i],
sizeof(indexT), valueSizes[i], fp);
489 for (
size_t i = 0; i < outerDim; i++) {
491 indices[i] = (indexT *)malloc(
sizeof(indexT) * indexSizes[i]);
492 }
catch (std::bad_alloc &ba) {
493 std::cerr <<
"bad_alloc caught: " << ba.what() <<
'\n';
494 throw std::runtime_error(
"Error: Could not allocate memory");
496 fread(indices[i],
sizeof(indexT), indexSizes[i], fp);
506 #ifdef IVSPARSE_DEBUG
514 template <
typename T,
typename indexT,
bool columnMajor>
516 std::unordered_map<T, std::vector<indexT>> maps[], uint32_t num_rows, uint32_t num_cols) {
519 if constexpr (columnMajor) {
530 index_t =
sizeof(indexT);
534 values = (T **)malloc(
sizeof(T *) * outerDim);
535 counts = (indexT **)malloc(
sizeof(indexT *) * outerDim);
536 indices = (indexT **)malloc(
sizeof(indexT *) * outerDim);
537 valueSizes = (indexT *)malloc(
sizeof(indexT) * outerDim);
538 indexSizes = (indexT *)malloc(
sizeof(indexT) * outerDim);
539 }
catch (std::bad_alloc &ba) {
540 std::cerr <<
"bad_alloc caught: " << ba.what() <<
'\n';
541 throw std::runtime_error(
"Error: Could not allocate memory");
545 #ifdef IVSPARSE_HAS_OPENMP
546 #pragma omp parallel for
548 for (
size_t i = 0; i < outerDim; i++) {
550 if (maps[i].empty()) [[unlikely]] {
553 indices[i] =
nullptr;
560 size_t numInidces = 0;
563 for (
auto &val : maps[i]) {
565 byteSize += (
sizeof(indexT) * val.second.size());
568 numInidces += val.second.size();
572 values[i] = (T *)malloc(
sizeof(T) * maps[i].size());
573 counts[i] = (indexT *)malloc(
sizeof(indexT) * maps[i].size());
574 indices[i] = (indexT *)malloc(
sizeof(indexT) * numInidces);
575 }
catch (std::bad_alloc &ba) {
576 std::cerr <<
"bad_alloc caught: " << ba.what() <<
'\n';
577 throw std::runtime_error(
"Error: Could not allocate memory");
580 valueSizes[i] = maps[i].size();
581 indexSizes[i] = numInidces;
587 for (
auto &val : maps[i]) {
588 values[i][valIndex] = val.first;
589 counts[i][valIndex] = val.second.size();
591 for (
auto &indexVal : val.second) {
592 indices[i][index] = indexVal;
602 metadata =
new uint32_t[NUM_META_DATA];
604 metadata[1] = innerDim;
605 metadata[2] = outerDim;
608 metadata[5] = index_t;
613 #ifdef IVSPARSE_DEBUG
Definition: VCSC_SparseMatrix.hpp:21
void append(typename SparseMatrix< T, indexT, 2, columnMajor >::Vector &vec)
Definition: VCSC_Methods.hpp:241
uint32_t nonZeros() const
Definition: IVSparse_Base_Methods.hpp:39
size_t byteSize() const
Definition: IVSparse_Base_Methods.hpp:42
Definition: IVCSC_SparseMatrix.hpp:29
IVSparse::SparseMatrix< T, indexT, 2, columnMajor > toVCSC()
Definition: IVCSC_Methods.hpp:153
SparseMatrix()
Definition: IVCSC_SparseMatrix.hpp:99
~SparseMatrix()
Destroy the Sparse Matrix object.
Definition: IVCSC_Constructors.hpp:15