14 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
17 if (metadata !=
nullptr) {
delete[] metadata; }
19 if (data !=
nullptr) {
21 for (
size_t i = 0; i < outerDim; i++) {
if (data[i] !=
nullptr) { free(data[i]); } }
25 if (endPointers !=
nullptr) { free(endPointers); }
29 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
33 if constexpr (columnMajor) {
43 index_t =
sizeof(indexT);
48 data = (
void **)malloc(outerDim *
sizeof(
void *));
49 endPointers = (
void **)malloc(outerDim *
sizeof(
void *));
50 }
catch (
const std::exception &e) {
51 std::cerr << e.what() <<
'\n';
55 for (
size_t i = 0; i < outerDim; i++) {
57 endPointers[i] =
nullptr;
61 metadata =
new uint32_t[NUM_META_DATA];
62 metadata[0] = compressionLevel;
63 metadata[1] = innerDim;
64 metadata[2] = outerDim;
67 metadata[5] = index_t;
79 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
82 if (mat.nonZeros() == 0) {
87 endPointers =
nullptr;
99 outerDim = columnMajor ? numCols : numRows;
100 innerDim = columnMajor ? numRows : numCols;
103 nnz = mat.nonZeros();
106 compressCSC(mat.valuePtr(), mat.innerIndexPtr(), mat.outerIndexPtr());
110 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
113 if (mat.nonZeros() == 0) {
118 endPointers =
nullptr;
124 mat.makeCompressed();
127 numRows = mat.rows();
128 numCols = mat.cols();
134 nnz = mat.nonZeros();
137 compressCSC(mat.valuePtr(), mat.innerIndexPtr(), mat.outerIndexPtr());
141 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
145 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
146 template <u
int8_t otherCompressionLevel>
150 if constexpr (otherCompressionLevel == compressionLevel) {
159 if constexpr (otherCompressionLevel == 1) { temp = other.toIVCSC(); }
160 else if constexpr (otherCompressionLevel == 2) { temp = other.toIVCSC(); }
172 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
173 template <
typename T2,
typename indexT2>
176 if (nnz == 0) [[unlikely]] {
180 endPointers =
nullptr;
198 compressCSC(vals, innerIndices, outerPtr);
202 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
203 template <
typename T2,
typename indexT2>
207 if (nnz == 0) [[unlikely]] {
225 index_t =
sizeof(indexT);
227 metadata =
new uint32_t[NUM_META_DATA];
228 metadata[0] = compressionLevel;
229 metadata[1] = innerDim;
230 metadata[2] = outerDim;
233 metadata[5] = index_t;
237 data = (
void **)malloc(outerDim *
sizeof(
void *));
238 endPointers = (
void **)malloc(outerDim *
sizeof(
void *));
239 }
catch (std::bad_alloc &e) {
240 std::cerr <<
"Error: Could not allocate memory for IVSparse matrix" << std::endl;
245 for (
size_t i = 0; i < outerDim; i++) {
247 endPointers[i] =
nullptr;
251 std::sort(entries.begin(), entries.end(), [](
const std::tuple<indexT2, indexT2, T2> &a,
const std::tuple<indexT2, indexT2, T2> &b)
253 if (std::get<1>(a) == std::get<1>(b)) {
254 return std::get<0>(a) < std::get<0>(b);
256 return std::get<1>(a) < std::get<1>(b);
259 std::map<T2, std::vector<indexT2>> maps[outerDim];
262 for (
size_t i = 0; i < nnz; i++) {
264 indexT2 row = std::get<0>(entries[i]);
265 indexT2 col = std::get<1>(entries[i]);
266 T2 val = std::get<2>(entries[i]);
269 if (maps[col].find(val) != maps[col].end()) {
272 maps[col][val].push_back(row - maps[col][val][1]);
275 maps[col][val][1] = row;
278 if (maps[col][val][maps[col][val].size() - 1] > maps[col][val][0])
279 maps[col][val][0] = maps[col][val][maps[col][val].size() - 1];
283 maps[col][val] = std::vector<indexT2>{row};
286 maps[col][val].push_back(row);
287 maps[col][val].push_back(row);
293 #pragma omp parallel for
295 for (uint32_t i = 0; i < outerDim; i++) {
297 size_t outerByteSize = 0;
299 for (
auto &pair : maps[i]) {
301 pair.second[0] = byteWidth(pair.second[0]);
305 outerByteSize +=
sizeof(T) + 1 + (pair.second[0] * (pair.second.size() - 2)) + pair.second[0];
309 if (outerByteSize == 0) {
311 endPointers[i] =
nullptr;
316 try { data[i] = malloc(outerByteSize); }
317 catch (std::bad_alloc &e) {
318 std::cout <<
"Error: " << e.what() << std::endl;
323 void *helpPtr = data[i];
326 for (
auto &pair : maps[i]) {
328 *(T *)helpPtr = (T)pair.first;
329 helpPtr = (T *)helpPtr + 1;
332 *(uint8_t *)helpPtr = (uint8_t)pair.second[0];
333 helpPtr = (uint8_t *)helpPtr + 1;
336 for (
size_t k = 0; k < pair.second.size(); k++) {
339 if (k == 0 || k == 1) {
continue; }
342 switch (pair.second[0]) {
344 *(uint8_t *)helpPtr = (uint8_t)pair.second[k];
345 helpPtr = (uint8_t *)helpPtr + 1;
348 *(uint16_t *)helpPtr = (uint16_t)pair.second[k];
349 helpPtr = (uint16_t *)helpPtr + 1;
352 *(uint32_t *)helpPtr = (uint32_t)pair.second[k];
353 helpPtr = (uint32_t *)helpPtr + 1;
356 *(uint64_t *)helpPtr = (uint64_t)pair.second[k];
357 helpPtr = (uint64_t *)helpPtr + 1;
364 switch (pair.second[0]) {
366 *(uint8_t *)helpPtr = (uint8_t)DELIM;
367 helpPtr = (uint8_t *)helpPtr + 1;
370 *(uint16_t *)helpPtr = (uint16_t)DELIM;
371 helpPtr = (uint16_t *)helpPtr + 1;
374 *(uint32_t *)helpPtr = (uint32_t)DELIM;
375 helpPtr = (uint32_t *)helpPtr + 1;
378 *(uint64_t *)helpPtr = (uint64_t)DELIM;
379 helpPtr = (uint64_t *)helpPtr + 1;
383 endPointers[i] = helpPtr;
393 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
411 index_t =
sizeof(indexT);
415 data = (
void **)malloc(
sizeof(
void *));
416 endPointers = (
void **)malloc(
sizeof(
void *));
417 }
catch (std::bad_alloc &e) {
418 throw std::bad_alloc();
426 endPointers[0] =
nullptr;
429 endPointers[0] = (
char *)data[0] + vec.
byteSize();
431 }
catch (std::bad_alloc &e) {
432 throw std::bad_alloc();
440 metadata =
new uint32_t[NUM_META_DATA];
441 metadata[0] = compressionLevel;
442 metadata[1] = innerDim;
443 metadata[2] = outerDim;
446 metadata[5] = index_t;
456 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
461 for (
size_t i = 1; i < vecs.size(); i++) { temp.
append(vecs[i]); }
474 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
476 FILE *fp = fopen(filename,
"rb");
478 if (fp ==
nullptr) {
throw std::runtime_error(
"Error: Could not open file"); }
481 metadata =
new uint32_t[NUM_META_DATA];
482 fread(metadata,
sizeof(uint32_t), NUM_META_DATA, fp);
485 innerDim = metadata[1];
486 outerDim = metadata[2];
489 index_t = metadata[5];
491 numRows = columnMajor ? innerDim : outerDim;
492 numCols = columnMajor ? outerDim : innerDim;
495 if (metadata[0] != compressionLevel) {
497 throw std::runtime_error(
"Error: Compression level of file does not match compression level of class");
502 data = (
void **)malloc(outerDim *
sizeof(
void *));
503 endPointers = (
void **)malloc(outerDim *
sizeof(
void *));
504 }
catch (std::bad_alloc &e) {
505 std::cerr <<
"Error: Could not allocate memory for IVSparse matrix" << std::endl;
510 for (
size_t i = 0; i < outerDim; i++) {
513 fread(&size,
sizeof(uint64_t), 1, fp);
518 endPointers[i] =
nullptr;
524 data[i] = malloc(size);
525 endPointers[i] = (
char *)data[i] + size;
526 }
catch (std::bad_alloc &e) {
527 throw std::bad_alloc();
532 for (
size_t i = 0; i < outerDim; i++) { fread(data[i], 1, (uint8_t *)endPointers[i] - (uint8_t *)data[i], fp); }
550 template <
typename T,
typename indexT, u
int8_t compressionLevel,
bool columnMajor>
553 if constexpr (columnMajor) {
564 index_t =
sizeof(indexT);
568 data = (
void **)malloc(outerDim *
sizeof(
void *));
569 endPointers = (
void **)malloc(outerDim *
sizeof(
void *));
570 }
catch (
const std::exception &e) {
571 std::cerr << e.what() <<
'\n';
575 for (
size_t i = 0; i < outerDim; i++) {
577 endPointers[i] =
nullptr;
584 #pragma omp parallel for
586 for (
size_t i = 0; i < outerDim; i++) {
589 if (maps[i].empty()) [[unlikely]] {
591 endPointers[i] =
nullptr;
598 for (
auto &val : maps[i]) {
600 byteSize +=
sizeof(T) + 1 + (val.second[val.second.size() - 1] * (val.second.size() - 1) + val.second[val.second.size() - 1]);
604 try { data[i] = malloc(byteSize); }
605 catch (
const std::exception &e) { std::cerr << e.what() <<
'\n'; }
608 endPointers[i] = (
char *)data[i] + byteSize;
611 void *helpPtr = data[i];
613 for (
auto &val : maps[i]) {
615 nnz += val.second.size() - 1;
618 *(T *)helpPtr = val.first;
619 helpPtr = (
char *)helpPtr +
sizeof(T);
620 *(uint8_t *)helpPtr = (uint8_t)val.second[val.second.size() - 1];
621 helpPtr = (uint8_t *)helpPtr + 1;
624 for (
size_t k = 0; k < val.second.size(); k++) {
626 if (k == val.second.size() - 1)
629 switch (val.second[val.second.size() - 1]) {
631 *(uint8_t *)helpPtr = (uint8_t)val.second[k];
632 helpPtr = (uint8_t *)helpPtr + 1;
635 *(uint16_t *)helpPtr = (uint16_t)val.second[k];
636 helpPtr = (uint16_t *)helpPtr + 1;
639 *(uint32_t *)helpPtr = (uint32_t)val.second[k];
640 helpPtr = (uint32_t *)helpPtr + 1;
643 *(uint64_t *)helpPtr = (uint64_t)val.second[k];
644 helpPtr = (uint64_t *)helpPtr + 1;
650 switch (val.second[val.second.size() - 1]) {
652 *(uint8_t *)helpPtr = (uint8_t)DELIM;
653 helpPtr = (uint8_t *)helpPtr + 1;
656 *(uint16_t *)helpPtr = (uint16_t)DELIM;
657 helpPtr = (uint16_t *)helpPtr + 1;
660 *(uint32_t *)helpPtr = (uint32_t)DELIM;
661 helpPtr = (uint32_t *)helpPtr + 1;
664 *(uint64_t *)helpPtr = (uint64_t)DELIM;
665 helpPtr = (uint64_t *)helpPtr + 1;
673 metadata =
new uint32_t[NUM_META_DATA];
676 metadata[0] = compressionLevel;
677 metadata[1] = innerDim;
678 metadata[2] = outerDim;
681 metadata[5] = index_t;
Definition: IVCSC_Vector.hpp:27
uint32_t getLength()
Definition: IVCSC_Vector_Methods.hpp:183
void * end()
Definition: IVCSC_Vector_Methods.hpp:171
size_t byteSize()
Definition: IVCSC_Vector_Methods.hpp:175
uint32_t nonZeros()
Definition: IVCSC_Vector_Methods.hpp:163
void * begin()
Definition: IVCSC_Vector_Methods.hpp:167
Definition: IVCSC_SparseMatrix.hpp:27
void append(typename SparseMatrix< T, indexT, compressionLevel, columnMajor >::Vector &vec)
Definition: IVCSC_Methods.hpp:202
SparseMatrix()
Definition: IVCSC_SparseMatrix.hpp:93
~SparseMatrix()
Destroy the Sparse Matrix object.
Definition: IVCSC_Constructors.hpp:15