<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: migrating cursparseDense2Sparse() in Intel® oneAPI Math Kernel Library</title>
    <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1522011#M35083</link>
    <description>&lt;P&gt;There is currently (as of oneMKL 2023.2) no function that converts dense to sparse or sparse to dense in oneMKL.&amp;nbsp; 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.&amp;nbsp; Sparse to dense is very straight forward, but dense to sparse is not as simple.&amp;nbsp; As such, I will provide a rough outline here (dense -&amp;gt; CSR) for those who might want to implement such a function themselves&lt;BR /&gt;&lt;BR /&gt;A basic breakdown with a pseudo code algorithm (for dense -&amp;gt; CSR with 0 base indexing) is as follows:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="cpp"&gt;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) &amp;lt; 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 &amp;lt; nrows; ++row) {
  int_type row_count = 0;
  for (int_type col = 0; col &amp;lt; 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 &amp;lt; 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 &amp;lt; nrows; ++row) {
  int_type row_offset = rowptr[row];
  for (int_type col = 0; col &amp;lt; ncols; ++col) {
    if (isNonzero(denseMat[row][col]) ) {
        colind[row_offset] = col;
        values[row_offset] = denseMat[row][col];
        row_offset++;
    }
  }
}&lt;/LI-CODE&gt;&lt;P&gt;That should give you the CSR format with { nrows, ncols, nnz, rowptr, colind, values }&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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 &amp;gt; 0, but I think you get the point etc.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Spencer&lt;/P&gt;</description>
    <pubDate>Fri, 08 Sep 2023 18:36:04 GMT</pubDate>
    <dc:creator>Spencer_P_Intel</dc:creator>
    <dc:date>2023-09-08T18:36:04Z</dc:date>
    <item>
      <title>migrating cursparseDense2Sparse()</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1521223#M35058</link>
      <description>&lt;P&gt;What are the oneMKL functions for migrating the&amp;nbsp;&lt;SPAN&gt;cusparseDense2Sparse() functions ?&amp;nbsp; Thanks.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;A href="https://docs.nvidia.com/cuda/cusparse/index.html#cusparsedensetosparse" target="_blank"&gt;&lt;SPAN&gt;https://docs.nvidia.com/cuda/cusparse/index.html&lt;/SPAN&gt;&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 06 Sep 2023 18:21:33 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1521223#M35058</guid>
      <dc:creator>sycl-developer</dc:creator>
      <dc:date>2023-09-06T18:21:33Z</dc:date>
    </item>
    <item>
      <title>Re:migrating cursparseDense2Sparse()</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1521965#M35079</link>
      <description>&lt;P&gt;Hi Zheming Jin,&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;Thanks for posting in Intel Communities.&lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt;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?&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;Best Regards,&lt;/P&gt;&lt;P&gt;Shanmukh.SS&lt;/P&gt;&lt;BR /&gt;</description>
      <pubDate>Fri, 08 Sep 2023 17:18:20 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1521965#M35079</guid>
      <dc:creator>ShanmukhS_Intel</dc:creator>
      <dc:date>2023-09-08T17:18:20Z</dc:date>
    </item>
    <item>
      <title>Re: Re:migrating cursparseDense2Sparse()</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1521969#M35080</link>
      <description>&lt;P&gt;Yes.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 08 Sep 2023 17:23:44 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1521969#M35080</guid>
      <dc:creator>sycl-developer</dc:creator>
      <dc:date>2023-09-08T17:23:44Z</dc:date>
    </item>
    <item>
      <title>Re: migrating cursparseDense2Sparse()</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1522011#M35083</link>
      <description>&lt;P&gt;There is currently (as of oneMKL 2023.2) no function that converts dense to sparse or sparse to dense in oneMKL.&amp;nbsp; 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.&amp;nbsp; Sparse to dense is very straight forward, but dense to sparse is not as simple.&amp;nbsp; As such, I will provide a rough outline here (dense -&amp;gt; CSR) for those who might want to implement such a function themselves&lt;BR /&gt;&lt;BR /&gt;A basic breakdown with a pseudo code algorithm (for dense -&amp;gt; CSR with 0 base indexing) is as follows:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="cpp"&gt;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) &amp;lt; 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 &amp;lt; nrows; ++row) {
  int_type row_count = 0;
  for (int_type col = 0; col &amp;lt; 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 &amp;lt; 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 &amp;lt; nrows; ++row) {
  int_type row_offset = rowptr[row];
  for (int_type col = 0; col &amp;lt; ncols; ++col) {
    if (isNonzero(denseMat[row][col]) ) {
        colind[row_offset] = col;
        values[row_offset] = denseMat[row][col];
        row_offset++;
    }
  }
}&lt;/LI-CODE&gt;&lt;P&gt;That should give you the CSR format with { nrows, ncols, nnz, rowptr, colind, values }&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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 &amp;gt; 0, but I think you get the point etc.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Spencer&lt;/P&gt;</description>
      <pubDate>Fri, 08 Sep 2023 18:36:04 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1522011#M35083</guid>
      <dc:creator>Spencer_P_Intel</dc:creator>
      <dc:date>2023-09-08T18:36:04Z</dc:date>
    </item>
    <item>
      <title>Re: migrating cursparseDense2Sparse()</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1522567#M35092</link>
      <description>&lt;P&gt;&lt;SPAN&gt;Thank you for considering adding it in the future release.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 11 Sep 2023 15:54:24 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1522567#M35092</guid>
      <dc:creator>sycl-developer</dc:creator>
      <dc:date>2023-09-11T15:54:24Z</dc:date>
    </item>
    <item>
      <title>Re: migrating cursparseDense2Sparse()</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1524087#M35128</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;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 &lt;A href="https://www.intel.com/content/www/us/en/developer/articles/release-notes/onemkl-release-notes.html" target="_self"&gt;release notes&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Best Regards,&lt;/P&gt;
&lt;P&gt;Shanmukh.SS&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 15 Sep 2023 08:05:22 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/migrating-cursparseDense2Sparse/m-p/1524087#M35128</guid>
      <dc:creator>ShanmukhS_Intel</dc:creator>
      <dc:date>2023-09-15T08:05:22Z</dc:date>
    </item>
  </channel>
</rss>

