<?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 Offload with persistent MIC buffer: are global pointers required? in Software Archive</title>
    <link>https://community.intel.com/t5/Software-Archive/Offload-with-persistent-MIC-buffer-are-global-pointers-required/m-p/1015881#M36058</link>
    <description>&lt;P&gt;We have been through that once, but here we go again, because latest results confuse me. My question is: in order to re-use a previously allocated memory buffer on the coprocessor, is the programmer required to supply a &lt;EM&gt;global pointer with attribute((target(mic)))&lt;/EM&gt; in pragma offload?&lt;/P&gt;

&lt;P&gt;The reason for this question is that I observe that global variables work in all cases, but local variables work in all cases except one (ouch!). So either it is a bug in the compiler or COI, or it a sign that one programming practice is better than another.&lt;/P&gt;

&lt;P&gt;Below is a code that allocates multiple buffers and keeps them on Xeon Phi using "alloc_if(1) free_if(0)". Then it attempts to re-use these buffers using "alloc_if(0) free_if(0)" and supplying to the offload pragma a pointer to the same memory address that was used during allocation. The result is this:&lt;/P&gt;

&lt;P&gt;1) If the pointer is a global variable with attribute((target(mic))), everything works: host addresses map to the correct coprocessor addresses&lt;/P&gt;

&lt;P&gt;2) If the pointer is a local variable, and the direction of transfer is "out", the application works incorrectly: different host addresses map to the same coprocessor address, which is wrong&lt;/P&gt;

&lt;P&gt;3) If the pointer is a local variable, and the direction of transfer is "in" or "inout" rather than "out", everything works again&lt;/P&gt;

&lt;P&gt;4) Not shown in this code, but tested separately: if the pointer is a local variable, and the direction of transfer is "out", but I use pragma offload_transfer instead of pragma offload, everything works fine, too.&lt;/P&gt;

&lt;P&gt;I would very much appreciate an explanation: is it a bug (i.e., everything should work whether the pointer is local or global), or am I required to use global variables in offload pragma with pre-allocated memory buffer?&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;Here is the code:&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;omp.h&amp;gt;

__attribute__((target(mic)))  float* bufGlobal;

int main() {
  const int N = 1&amp;lt;&amp;lt;10;
  const int m = 4;
  float* data = (float*)_mm_malloc(N*m*sizeof(float), 4096);
  float* buf;
  void* micBuf;

  printf("\nAllocating data on the coprocessor:\n");
  for (int i = 0; i &amp;lt; m; i++) {
    buf = &amp;amp;data[i*N];
#pragma offload target(mic:0) inout(buf : length(N) alloc_if(1) free_if(0))
    {
      micBuf = &amp;amp;buf[0];
    }
    printf("Pointer on CPU=%p -&amp;gt; pointer on MIC=%p\n", buf, micBuf); fflush(0);
  }

  printf("\nRe-using data with the 'out' clause with local pointer (ERROR HERE):\n");
  for (int i = 0; i &amp;lt; m; i++) {
    buf = &amp;amp;data[i*N];
#pragma offload target(mic:0) out(buf : length(N) alloc_if(0) free_if(0)) 
     {
       micBuf = &amp;amp;buf[0];
     }
    printf("Pointer on CPU=%p -&amp;gt; pointer on MIC=%p\n", buf, micBuf); fflush(0);
  }

  printf("\nRe-using data with the 'out' clause with global pointer (works fine):\n");
  for (int i = 0; i &amp;lt; m; i++) {
    bufGlobal = &amp;amp;data[i*N];
#pragma offload target(mic:0) out(bufGlobal : length(N) alloc_if(0) free_if(0)) 
    {
      micBuf = &amp;amp;bufGlobal[0];
    }
    printf("Pointer on CPU=%p -&amp;gt; pointer on MIC=%p\n", bufGlobal, micBuf); fflush(0);
  }
  
  printf("\nRe-using data with the 'in' clause with local pointer (works fine):\n");
  for (int i = 0; i &amp;lt; m; i++) {
    buf = &amp;amp;data[i*N];
#pragma offload target(mic:0) in(buf : length(N) alloc_if(0) free_if(0)) 
    {
      micBuf = &amp;amp;buf[0];
    }
    printf("Pointer on CPU=%p -&amp;gt; pointer on MIC=%p\n", buf, micBuf); fflush(0);
  }

  // Cleanup
  for (int i = 0; i &amp;lt; m; i++) {
    float* buf = &amp;amp;data[i*N];
#pragma offload_transfer target(mic:0) in(buf : length(N) alloc_if(0) free_if(1))
  }

  _mm_free(data);
}&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;And here is the output:&lt;/P&gt;

&lt;PRE class="brush:plain;"&gt;Allocating data on the coprocessor:
Pointer on CPU=0xcf7000 -&amp;gt; pointer on MIC=0x7f200610e000
Pointer on CPU=0xcf8000 -&amp;gt; pointer on MIC=0x7f200610b000
Pointer on CPU=0xcf9000 -&amp;gt; pointer on MIC=0x7f2006108000
Pointer on CPU=0xcfa000 -&amp;gt; pointer on MIC=0x7f2006105000

Re-using data with the 'out' clause with local pointer (ERROR HERE):
Pointer on CPU=0xcf7000 -&amp;gt; pointer on MIC=0x7f2006105000
Pointer on CPU=0xcf8000 -&amp;gt; pointer on MIC=0x7f2006105000
Pointer on CPU=0xcf9000 -&amp;gt; pointer on MIC=0x7f2006105000
Pointer on CPU=0xcfa000 -&amp;gt; pointer on MIC=0x7f2006105000

Re-using data with the 'out' clause with global pointer (works fine):
Pointer on CPU=0xcf7000 -&amp;gt; pointer on MIC=0x7f200610e000
Pointer on CPU=0xcf8000 -&amp;gt; pointer on MIC=0x7f200610b000
Pointer on CPU=0xcf9000 -&amp;gt; pointer on MIC=0x7f2006108000
Pointer on CPU=0xcfa000 -&amp;gt; pointer on MIC=0x7f2006105000

Re-using data with the 'in' clause with local pointer (works fine):
Pointer on CPU=0xcf7000 -&amp;gt; pointer on MIC=0x7f200610e000
Pointer on CPU=0xcf8000 -&amp;gt; pointer on MIC=0x7f200610b000
Pointer on CPU=0xcf9000 -&amp;gt; pointer on MIC=0x7f2006108000
Pointer on CPU=0xcfa000 -&amp;gt; pointer on MIC=0x7f2006105000&lt;/PRE&gt;</description>
    <pubDate>Thu, 19 Feb 2015 23:11:58 GMT</pubDate>
    <dc:creator>Andrey_Vladimirov</dc:creator>
    <dc:date>2015-02-19T23:11:58Z</dc:date>
    <item>
      <title>Offload with persistent MIC buffer: are global pointers required?</title>
      <link>https://community.intel.com/t5/Software-Archive/Offload-with-persistent-MIC-buffer-are-global-pointers-required/m-p/1015881#M36058</link>
      <description>&lt;P&gt;We have been through that once, but here we go again, because latest results confuse me. My question is: in order to re-use a previously allocated memory buffer on the coprocessor, is the programmer required to supply a &lt;EM&gt;global pointer with attribute((target(mic)))&lt;/EM&gt; in pragma offload?&lt;/P&gt;

&lt;P&gt;The reason for this question is that I observe that global variables work in all cases, but local variables work in all cases except one (ouch!). So either it is a bug in the compiler or COI, or it a sign that one programming practice is better than another.&lt;/P&gt;

&lt;P&gt;Below is a code that allocates multiple buffers and keeps them on Xeon Phi using "alloc_if(1) free_if(0)". Then it attempts to re-use these buffers using "alloc_if(0) free_if(0)" and supplying to the offload pragma a pointer to the same memory address that was used during allocation. The result is this:&lt;/P&gt;

&lt;P&gt;1) If the pointer is a global variable with attribute((target(mic))), everything works: host addresses map to the correct coprocessor addresses&lt;/P&gt;

&lt;P&gt;2) If the pointer is a local variable, and the direction of transfer is "out", the application works incorrectly: different host addresses map to the same coprocessor address, which is wrong&lt;/P&gt;

&lt;P&gt;3) If the pointer is a local variable, and the direction of transfer is "in" or "inout" rather than "out", everything works again&lt;/P&gt;

&lt;P&gt;4) Not shown in this code, but tested separately: if the pointer is a local variable, and the direction of transfer is "out", but I use pragma offload_transfer instead of pragma offload, everything works fine, too.&lt;/P&gt;

&lt;P&gt;I would very much appreciate an explanation: is it a bug (i.e., everything should work whether the pointer is local or global), or am I required to use global variables in offload pragma with pre-allocated memory buffer?&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;Here is the code:&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;omp.h&amp;gt;

__attribute__((target(mic)))  float* bufGlobal;

int main() {
  const int N = 1&amp;lt;&amp;lt;10;
  const int m = 4;
  float* data = (float*)_mm_malloc(N*m*sizeof(float), 4096);
  float* buf;
  void* micBuf;

  printf("\nAllocating data on the coprocessor:\n");
  for (int i = 0; i &amp;lt; m; i++) {
    buf = &amp;amp;data[i*N];
#pragma offload target(mic:0) inout(buf : length(N) alloc_if(1) free_if(0))
    {
      micBuf = &amp;amp;buf[0];
    }
    printf("Pointer on CPU=%p -&amp;gt; pointer on MIC=%p\n", buf, micBuf); fflush(0);
  }

  printf("\nRe-using data with the 'out' clause with local pointer (ERROR HERE):\n");
  for (int i = 0; i &amp;lt; m; i++) {
    buf = &amp;amp;data[i*N];
#pragma offload target(mic:0) out(buf : length(N) alloc_if(0) free_if(0)) 
     {
       micBuf = &amp;amp;buf[0];
     }
    printf("Pointer on CPU=%p -&amp;gt; pointer on MIC=%p\n", buf, micBuf); fflush(0);
  }

  printf("\nRe-using data with the 'out' clause with global pointer (works fine):\n");
  for (int i = 0; i &amp;lt; m; i++) {
    bufGlobal = &amp;amp;data[i*N];
#pragma offload target(mic:0) out(bufGlobal : length(N) alloc_if(0) free_if(0)) 
    {
      micBuf = &amp;amp;bufGlobal[0];
    }
    printf("Pointer on CPU=%p -&amp;gt; pointer on MIC=%p\n", bufGlobal, micBuf); fflush(0);
  }
  
  printf("\nRe-using data with the 'in' clause with local pointer (works fine):\n");
  for (int i = 0; i &amp;lt; m; i++) {
    buf = &amp;amp;data[i*N];
#pragma offload target(mic:0) in(buf : length(N) alloc_if(0) free_if(0)) 
    {
      micBuf = &amp;amp;buf[0];
    }
    printf("Pointer on CPU=%p -&amp;gt; pointer on MIC=%p\n", buf, micBuf); fflush(0);
  }

  // Cleanup
  for (int i = 0; i &amp;lt; m; i++) {
    float* buf = &amp;amp;data[i*N];
#pragma offload_transfer target(mic:0) in(buf : length(N) alloc_if(0) free_if(1))
  }

  _mm_free(data);
}&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;And here is the output:&lt;/P&gt;

&lt;PRE class="brush:plain;"&gt;Allocating data on the coprocessor:
Pointer on CPU=0xcf7000 -&amp;gt; pointer on MIC=0x7f200610e000
Pointer on CPU=0xcf8000 -&amp;gt; pointer on MIC=0x7f200610b000
Pointer on CPU=0xcf9000 -&amp;gt; pointer on MIC=0x7f2006108000
Pointer on CPU=0xcfa000 -&amp;gt; pointer on MIC=0x7f2006105000

Re-using data with the 'out' clause with local pointer (ERROR HERE):
Pointer on CPU=0xcf7000 -&amp;gt; pointer on MIC=0x7f2006105000
Pointer on CPU=0xcf8000 -&amp;gt; pointer on MIC=0x7f2006105000
Pointer on CPU=0xcf9000 -&amp;gt; pointer on MIC=0x7f2006105000
Pointer on CPU=0xcfa000 -&amp;gt; pointer on MIC=0x7f2006105000

Re-using data with the 'out' clause with global pointer (works fine):
Pointer on CPU=0xcf7000 -&amp;gt; pointer on MIC=0x7f200610e000
Pointer on CPU=0xcf8000 -&amp;gt; pointer on MIC=0x7f200610b000
Pointer on CPU=0xcf9000 -&amp;gt; pointer on MIC=0x7f2006108000
Pointer on CPU=0xcfa000 -&amp;gt; pointer on MIC=0x7f2006105000

Re-using data with the 'in' clause with local pointer (works fine):
Pointer on CPU=0xcf7000 -&amp;gt; pointer on MIC=0x7f200610e000
Pointer on CPU=0xcf8000 -&amp;gt; pointer on MIC=0x7f200610b000
Pointer on CPU=0xcf9000 -&amp;gt; pointer on MIC=0x7f2006108000
Pointer on CPU=0xcfa000 -&amp;gt; pointer on MIC=0x7f2006105000&lt;/PRE&gt;</description>
      <pubDate>Thu, 19 Feb 2015 23:11:58 GMT</pubDate>
      <guid>https://community.intel.com/t5/Software-Archive/Offload-with-persistent-MIC-buffer-are-global-pointers-required/m-p/1015881#M36058</guid>
      <dc:creator>Andrey_Vladimirov</dc:creator>
      <dc:date>2015-02-19T23:11:58Z</dc:date>
    </item>
    <item>
      <title>This is a bug in the 15.0</title>
      <link>https://community.intel.com/t5/Software-Archive/Offload-with-persistent-MIC-buffer-are-global-pointers-required/m-p/1015882#M36059</link>
      <description>&lt;P&gt;This is a bug in the 15.0 compiler. The code works as is with the previous 14.0 compiler. There is some underlying difference with the handling of the local pointer that affects the &lt;STRONG&gt;OUT &lt;/STRONG&gt;case.&lt;/P&gt;

&lt;P&gt;With 15.0, you can obtain correct results with a work around of adding an additional &lt;STRONG&gt;IN &lt;/STRONG&gt;with &lt;STRONG&gt;length(0)&lt;/STRONG&gt; for the failing case, as follows:&lt;/P&gt;

&lt;P&gt;#pragma offload target(mic:0) &lt;STRONG&gt;in(buf : length(0)&amp;nbsp; alloc_if(0) free_if(0))&lt;/STRONG&gt; \&lt;BR /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out(buf : length(N) alloc_if(0) free_if(0))&lt;/P&gt;

&lt;P&gt;I submitted this to Development (see internal tracking id below) and will post as I learn more.&lt;/P&gt;

&lt;P&gt;(Internal tracking id: DPD200366742)&lt;/P&gt;</description>
      <pubDate>Fri, 20 Feb 2015 10:57:02 GMT</pubDate>
      <guid>https://community.intel.com/t5/Software-Archive/Offload-with-persistent-MIC-buffer-are-global-pointers-required/m-p/1015882#M36059</guid>
      <dc:creator>Kevin_D_Intel</dc:creator>
      <dc:date>2015-02-20T10:57:02Z</dc:date>
    </item>
  </channel>
</rss>

