title: Offloading to intel MIC using aligned data
body: <p>When I compile the code below, i get the warning:</p>
  
  <pre><code>src/parallel_hashing.cpp(50): warning #3218: *MIC* class/struct may fail when offloaded because this field is misaligned or contains data that is misaligned    __declspec(align(64)) list&lt;HashEntry&gt; mChains[TABLE_SIZE];
                                                                                                                                                                                                  ^ 
  </code></pre>
  
  <p>although I think I have taken care to all of the alignments needed.
  when I execute it, I get a segmentation fault.</p>
  
  <p>Does anybody know how can I make it work? </p>
  
  <p>The code:</p>
  
  <pre><code>#pragma offload_attribute(push, target(mic))
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;omp.h&gt;
  #include &lt;list&gt;
  #include &lt;queue&gt;
  #define TABLE_SIZE 3019
  #define NUM_OF_THREADS 60
  #define HASHINH_PRIME 2654435761
  
  using namespace std;
  
  int Hash(int key)
  {
      return (HASHINH_PRIME * key) % TABLE_SIZE;
  }
  
  class __declspec(align(64)) HashEntry
  {
  private:
  
      unsigned int mKey;
      int mDummy[5];
  
  public:
  
      //Ctor
      HashEntry(unsigned int key)
      {
          mKey = key;
          for (int i = 0; i &lt; 5; i++)
          {
              mDummy[i] = key + i;
          }
      }
  
      unsigned int GetKey()
      {
          return mKey; 
      }
  };
  
  class HashTable
  {
  private:
      unsigned int mMaxChainLength;
      __declspec(align(64)) list&lt;HashEntry&gt; mChains[TABLE_SIZE];
  
      void UpdateMaxChainLength()
      {
          int newMaxChainLength = 0;
          for (int i = 0; i &lt; TABLE_SIZE; i++)
          {
              int currentLength = mChains[i].size();
  
              if (currentLength &gt; newMaxChainLength)
              {
                  newMaxChainLength = currentLength;
              }
          }
  
          mMaxChainLength = newMaxChainLength;
      }
  
      list&lt;HashEntry&gt;* GetChain(unsigned int key)
      {
          return &amp;mChains[Hash(key)];
      }
  
  public:
  
      HashTable()
      {
          mMaxChainLength = 0;
      }
  
      unsigned int GetMaxChainLength()
      {
          return mMaxChainLength;
      }
  
      void InsertKey(unsigned int key)
      {
          //create a new entry with the key
          HashEntry newEntry = HashEntry(key);
  
          //get the specific chain
          list&lt;HashEntry&gt;* chain = GetChain(key);
  
          //insert the new entry to the chain
          chain-&gt;insert(chain-&gt;end(), newEntry);
  
          //update mMaxChainLength if needed
          if (chain-&gt;size() &gt; mMaxChainLength)
              mMaxChainLength = chain-&gt;size();
      }
  
      void DeleteKey(unsigned int key)
      {
          //get the specific chain
          list&lt;HashEntry&gt;* chain = GetChain(key);
  
          list&lt;HashEntry&gt;::iterator it = chain-&gt;begin();
          while (it != chain-&gt;end() &amp;&amp; it-&gt;GetKey() != key)
          {
              it++;
          }
  
          if (it != chain-&gt;end())
          {
              chain-&gt;erase(it);
  
              //update mMaxChainLength if the chain (before delete of key) was in the size of mMaxChainLength
              if (chain-&gt;size() == mMaxChainLength - 1)
                  UpdateMaxChainLength();
          }
      }
  
      bool SearchKey(unsigned int key)
      {
          //get the specific chain
          list&lt;HashEntry&gt;* chain = GetChain(key);
  
          list&lt;HashEntry&gt;::iterator it = chain-&gt;begin();
          while (it != chain-&gt;end() &amp;&amp; it-&gt;GetKey() != key)
          {
              it++;
          }
  
          return (it != chain-&gt;end());
      }
  };
  
  HashTable mCoreTables[NUM_OF_THREADS]; 
  
  #pragma offload_attribute(pop)
  
  void CreateTables()
  {
      //parallelize via OpenMP on MIC
      #pragma offload target(mic)
      #pragma omp parallel num_threads(NUM_OF_THREADS)
      {
          int core = omp_get_thread_num();
          for (int i=0; i&lt;100; i++)
          {
              mCoreTables[core].InsertKey(i); //for example
          }
      }   
  }
  
  int main()
  {
      omp_set_nested(1);
      omp_set_max_active_levels(2);
      omp_set_num_threads(NUM_OF_THREADS);
  
      CreateTables(); 
  }
  </code></pre>