<?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 I see the crush even when mkl in Intel® oneAPI Math Kernel Library</title>
    <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031966#M20175</link>
    <description>&lt;P&gt;I see the crush even when mkl_set-num_threads(1). I suspeсе you need to check how to split the input data before mkl routine.&lt;/P&gt;</description>
    <pubDate>Sat, 07 Mar 2015 10:17:21 GMT</pubDate>
    <dc:creator>Gennady_F_Intel</dc:creator>
    <dc:date>2015-03-07T10:17:21Z</dc:date>
    <item>
      <title>Is it save to call ?feast_syev/?feast_heev from multiple threads?</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031963#M20172</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;

&lt;P&gt;I'm developing an application that needs to compute various eigenvalue decompositions. Is it possible to call &lt;STRONG&gt;zfeast_heev&lt;/STRONG&gt; from multiple threads in parallel? Ofcourse, each thread has it's own memory. I could not find this kind of information in the documentation. Currently I'm using &lt;FONT size="2"&gt;&lt;STRONG&gt;zhpevd&lt;/STRONG&gt;, which works fine when called from multiple threads, &lt;/FONT&gt;&lt;STRONG&gt;zfeast_heev&lt;/STRONG&gt; however, do not.&lt;/P&gt;

&lt;P&gt;Looking forward to your answers&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 03 Mar 2015 11:18:40 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031963#M20172</guid>
      <dc:creator>Arne_K_</dc:creator>
      <dc:date>2015-03-03T11:18:40Z</dc:date>
    </item>
    <item>
      <title>yes, it should works in this</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031964#M20173</link>
      <description>&lt;P&gt;yes, it should works in this environment correctly. In the case if there is any concern, please give us the example for investigation.&lt;/P&gt;</description>
      <pubDate>Tue, 03 Mar 2015 14:46:21 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031964#M20173</guid>
      <dc:creator>Gennady_F_Intel</dc:creator>
      <dc:date>2015-03-03T14:46:21Z</dc:date>
    </item>
    <item>
      <title>Hi,</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031965#M20174</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;

&lt;P&gt;I made a small program similar to my usage that shows the error.&lt;/P&gt;

&lt;P&gt;Can you reproduce the error?&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;#include "mkl.h"

#include &amp;lt;boost/thread/thread.hpp&amp;gt;
#include &amp;lt;boost/bind.hpp&amp;gt;
#include &amp;lt;boost/random/normal_distribution.hpp&amp;gt;
#include &amp;lt;boost/random/mersenne_twister.hpp&amp;gt;

#include &amp;lt;vector&amp;gt;
#include &amp;lt;iostream&amp;gt;

#include &amp;lt;cstdio&amp;gt;

//#define USE_THREADS
//#define LOWER_ONLY

struct RunData {
&amp;nbsp;std::vector&amp;lt;MKL_Complex16&amp;gt; C;
&amp;nbsp;std::vector&amp;lt;MKL_Complex16&amp;gt; U;
&amp;nbsp;std::vector&amp;lt;double&amp;gt; D;
&amp;nbsp;MKL_INT info;
&amp;nbsp;MKL_INT dim;
&amp;nbsp;double e_max;
};

struct ThreadCache {
&amp;nbsp;MKL_INT *fpm;
&amp;nbsp;double *epsout;
&amp;nbsp;double *res;
};
&amp;nbsp;
void compute_eigenvalues( RunData&amp;amp; data, ThreadCache&amp;amp; cache ) {

&amp;nbsp;feastinit( cache.fpm );

&amp;nbsp;MKL_INT loop;
&amp;nbsp;double e_min = 0;
&amp;nbsp;double e_max = data.e_max;
&amp;nbsp;MKL_INT n&amp;nbsp;&amp;nbsp; = data.dim;
&amp;nbsp;MKL_INT lda = data.dim;
&amp;nbsp;MKL_INT m0&amp;nbsp; = data.dim;
&amp;nbsp;MKL_INT m&amp;nbsp;&amp;nbsp; = data.dim;
#ifdef LOWER_ONLY
&amp;nbsp;char uplo&amp;nbsp;&amp;nbsp; = 'U';
#else
&amp;nbsp;char uplo&amp;nbsp;&amp;nbsp; = 'F';
#endif

&amp;nbsp;zfeast_heev(&amp;amp;uplo, &amp;amp;n, &amp;amp;data.C[0], &amp;amp;lda, cache.fpm, cache.epsout, &amp;amp;loop, &amp;amp;e_min, &amp;amp;e_max, &amp;amp;m0, &amp;amp;data.D[0], &amp;amp;data.U[0], &amp;amp;m, cache.res, &amp;amp;data.info );

};

void thread_compute_function( std::vector&amp;lt; RunData &amp;gt;* data, unsigned int start, unsigned int end ) {
&amp;nbsp;if( data-&amp;gt;empty() || start &amp;gt;= end || data-&amp;gt;size() &amp;lt; end ) {
&amp;nbsp;&amp;nbsp;return;
&amp;nbsp;}

&amp;nbsp;std::vector&amp;lt;MKL_INT&amp;gt; fpm(128);
&amp;nbsp;std::vector&amp;lt;double&amp;gt;&amp;nbsp; epsout( (*data)[0].dim * (*data)[0].dim );
&amp;nbsp;std::vector&amp;lt;double&amp;gt;&amp;nbsp; res( (*data)[0].dim * (*data)[0].dim );

&amp;nbsp;ThreadCache tc;
&amp;nbsp;tc.fpm&amp;nbsp;&amp;nbsp;&amp;nbsp; = &amp;amp;(fpm[0]);
&amp;nbsp;tc.epsout = &amp;amp;(epsout[0]);
&amp;nbsp;tc.res&amp;nbsp;&amp;nbsp;&amp;nbsp; = &amp;amp;(res[0]);


&amp;nbsp;for( unsigned int i = start; i &amp;lt; end; ++i ) {
&amp;nbsp;&amp;nbsp;std::cerr &amp;lt;&amp;lt; "compute eigenvalues ( " &amp;lt;&amp;lt; (i+1-start) &amp;lt;&amp;lt; " / " &amp;lt;&amp;lt; end-start &amp;lt;&amp;lt; " )\n";
&amp;nbsp;&amp;nbsp;compute_eigenvalues( (*data)&lt;I&gt;, tc );
&amp;nbsp;}
}

// generate random vectors and compute an estimated corrolation matrix
void setup_data( std::vector&amp;lt; RunData &amp;gt; &amp;amp;data, unsigned int n_data, unsigned int n_dims, unsigned int n_loops = 5 ) {

&amp;nbsp;boost::random::mt19937 rng( 0 );
&amp;nbsp;boost::random::normal_distribution&amp;lt;double&amp;gt; normal_dist( 0.15, 3.21 );

&amp;nbsp;data.resize( n_data );
&amp;nbsp;for( unsigned int i_data = 0; i_data &amp;lt; n_data; ++i_data ) {

#ifdef LOWER_ONLY
&amp;nbsp;&amp;nbsp;unsigned int size_C = ((n_dims+1) * n_dims)/2;
#else
&amp;nbsp;&amp;nbsp;unsigned int size_C = n_dims * n_dims;
#endif

&amp;nbsp;&amp;nbsp;RunData &amp;amp;r_data = data[i_data];
&amp;nbsp;&amp;nbsp;r_data.dim = n_dims;
&amp;nbsp;&amp;nbsp;r_data.e_max = 0.0;
&amp;nbsp;&amp;nbsp;r_data.info = 0;
&amp;nbsp;&amp;nbsp;r_data.C.resize( size_C );
&amp;nbsp;&amp;nbsp;r_data.U.resize( n_dims * n_dims );
&amp;nbsp;&amp;nbsp;r_data.D.resize( n_dims );

&amp;nbsp;&amp;nbsp;std::vector&amp;lt; MKL_Complex16 &amp;gt; X( n_dims );

&amp;nbsp;&amp;nbsp;for( unsigned int i_loop = 0; i_loop &amp;lt; n_loops; ++i_loop ) {

&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned int cnt = 0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;// generate random vector
&amp;nbsp;&amp;nbsp;&amp;nbsp;for( unsigned int i_dim = 0; i_dim &amp;lt; n_dims; ++i_dim ) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;X[i_dim].real = normal_dist( rng );
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;X[i_dim].imag = normal_dist( rng );
&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;for( unsigned int i = 0; i &amp;lt; n_dims; ++i ) {
#ifdef LOWER_ONLY
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned int j_start = i;
#else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned int j_start = 0;
#endif
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for( unsigned int j = j_start; j &amp;lt; n_dims; ++j ) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MKL_Complex16 x_ij;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x_ij.real = X&lt;I&gt;.real * X&lt;J&gt;.real + X&lt;I&gt;.imag * X&lt;J&gt;.imag / (n_loops * n_loops);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x_ij.imag = X&lt;I&gt;.imag * X&lt;J&gt;.real - X&lt;I&gt;.real * X&lt;J&gt;.imag / (n_loops * n_loops);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r_data.C[cnt++] = x_ij;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;double sum = 0;
&amp;nbsp;&amp;nbsp;unsigned int cnt = 0;
&amp;nbsp;&amp;nbsp;for( unsigned int i = 0; i &amp;lt; n_dims; ++i ) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;#ifdef LOWER_ONLY
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned int j_start = i;
#else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned int j_start = 0;
#endif
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for( unsigned int j = j_start; j &amp;lt; n_dims; ++j ) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if( i == j )
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sum += r_data.C[cnt].real * r_data.C[cnt].real + r_data.C[cnt].imag * r_data.C[cnt].imag;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;++cnt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;r_data.e_max = sum;
&amp;nbsp;}
}

int main(int argc, char* argv[])
{
&amp;nbsp;unsigned int const n_data&amp;nbsp;&amp;nbsp;= 20;
&amp;nbsp;unsigned int const n_dims&amp;nbsp;&amp;nbsp;= 50;

&amp;nbsp;std::vector&amp;lt; RunData &amp;gt; data;

&amp;nbsp;setup_data( data, n_data, n_dims );

#ifdef USE_THREADS
&amp;nbsp;unsigned int const n_threads&amp;nbsp;= 4;

&amp;nbsp;boost::thread_group thread_pool;

&amp;nbsp;unsigned int data_per_thread = std::max&amp;lt;unsigned int&amp;gt;( 1, data.size() / n_threads );

&amp;nbsp;for( unsigned int i_thread = 0; i_thread &amp;lt; n_threads; ++i_thread ) {
&amp;nbsp;&amp;nbsp;unsigned int start = i_thread * data_per_thread;
&amp;nbsp;&amp;nbsp;unsigned int end = std::min( (i_thread+1) * data_per_thread, data.size() );
&amp;nbsp;&amp;nbsp;thread_pool.create_thread( boost::bind( thread_compute_function, &amp;amp;data, start, end ) );
&amp;nbsp;}

&amp;nbsp;thread_pool.join_all();
#else
&amp;nbsp;thread_compute_function( &amp;amp;data, 0, data.size() );
#endif


&amp;nbsp;for( std::vector&amp;lt; RunData &amp;gt;::const_iterator iter = data.begin(); iter != data.end(); ++iter ) {
&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; "zfeast_heev info value: " &amp;lt;&amp;lt; iter-&amp;gt;info &amp;lt;&amp;lt; std::endl;
&amp;nbsp;}

&amp;nbsp;std::cout &amp;lt;&amp;lt; "Done!\n";

&amp;nbsp;getchar();

&amp;nbsp;std::cout &amp;lt;&amp;lt; "Closing\n";

&amp;nbsp;return 0;
}&lt;/J&gt;&lt;/I&gt;&lt;/J&gt;&lt;/I&gt;&lt;/J&gt;&lt;/I&gt;&lt;/J&gt;&lt;/I&gt;&lt;/I&gt;&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 05 Mar 2015 09:24:55 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031965#M20174</guid>
      <dc:creator>Arne_K_</dc:creator>
      <dc:date>2015-03-05T09:24:55Z</dc:date>
    </item>
    <item>
      <title>I see the crush even when mkl</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031966#M20175</link>
      <description>&lt;P&gt;I see the crush even when mkl_set-num_threads(1). I suspeсе you need to check how to split the input data before mkl routine.&lt;/P&gt;</description>
      <pubDate>Sat, 07 Mar 2015 10:17:21 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031966#M20175</guid>
      <dc:creator>Gennady_F_Intel</dc:creator>
      <dc:date>2015-03-07T10:17:21Z</dc:date>
    </item>
    <item>
      <title>Hi,</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031967#M20176</link>
      <description>&lt;P&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;Hi,&lt;/SPAN&gt;&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;the input data is all independent of each other so I don't know what es to check for. If&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(0, 130, 0); font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; line-height: 14.30880069732666px;"&gt;USE_THREADS&amp;nbsp;&lt;/SPAN&gt;is not defined than everything work but if it is defined it often but not always crashes. As the standard divide and conquer methods works flawlessly when used in parallel I don't understand why this function does not.&lt;/P&gt;

&lt;P&gt;For now I will not use this method in my scenario as I can't get it to work properly.&lt;/P&gt;

&lt;P&gt;Thank you for your time and comments&lt;/P&gt;</description>
      <pubDate>Sat, 07 Mar 2015 10:26:35 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/Is-it-save-to-call-feast-syev-feast-heev-from-multiple-threads/m-p/1031967#M20176</guid>
      <dc:creator>Arne_K_</dc:creator>
      <dc:date>2015-03-07T10:26:35Z</dc:date>
    </item>
  </channel>
</rss>

