- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What are the oneMKL functions for migrating the cusparseDense2Sparse() functions ? Thanks.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Zheming Jin,
Thanks for posting in Intel Communities.
Based on your query, you would like to get information on MKL routine which converts a dense matrix into a sparse matrix in CSR, CSC, etc. formats. Could you please correct us if there is any difference in our understanding?
Best Regards,
Shanmukh.SS
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is currently (as of oneMKL 2023.2) no function that converts dense to sparse or sparse to dense in oneMKL. It is however something we will consider adding in some future release as conversion routines are convenient for many, including those who are not as familiar with sparse data structures. Sparse to dense is very straight forward, but dense to sparse is not as simple. As such, I will provide a rough outline here (dense -> CSR) for those who might want to implement such a function themselves
A basic breakdown with a pseudo code algorithm (for dense -> CSR with 0 base indexing) is as follows:
typedef int int_type;
typedef double data_type;
// Step 1.
// setup a rule to govern whether you consider a value 0 or not, for
// instance this lambda function to return true/false for isNonzero
const data_type TOL = 1e-14;
auto isNonzero = [=](data_type value){ return std::abs(value) < TOL ? false : true; };
// Step 2.
// allocate rowptr as int_type of nrows+1 and fill it with
// count of nonzeros on each row (offset by one for prefix sum
// in next step)
int_type *rowptr = malloc( (nrows+1) * sizeof(int_type) );
for (int_type row = 0; row < nrows; ++row) {
int_type row_count = 0;
for (int_type col = 0; col < ncols; ++col) {
if (isNonzero(denseMat[row][col]) ) {
row_count++;
}
}
rowptr[row+1] = row_count;
}
// Step 3
// perform a prefix_sum on rowptr values to get total count of nnz
// and offsets ptr for each row, allocate colind and values arrays
rowptr[0] = 0;
for (int_type row = 0; row < nrows; ++row) {
rowptr[row+1] += rowptr[row];
}
const int_type nnz = rowptr[nrows];
int_type *colind = malloc(nnz * sizeof(int_type));
data_type *values = malloc(nnz * sizeof(data_type));
// Step 4:
// fill the colind/values arrays
for (int_type row = 0; row < nrows; ++row) {
int_type row_offset = rowptr[row];
for (int_type col = 0; col < ncols; ++col) {
if (isNonzero(denseMat[row][col]) ) {
colind[row_offset] = col;
values[row_offset] = denseMat[row][col];
row_offset++;
}
}
}
That should give you the CSR format with { nrows, ncols, nnz, rowptr, colind, values }
Of course much of this can be done in parallel with OpenMP or with SYCL language... and you should probably add some safety checks that mallocs succeed or nnz > 0, but I think you get the point etc.
Spencer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for considering adding it in the future release.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for helping us improve our products! We’ve submitted the feature request to the dev team Once it is included in an upcoming release, it would be documented in the release notes.
Best Regards,
Shanmukh.SS
![](/skins/images/D2683F18326913BBA0436CB7114DD569/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page