title: Best practices for storing a small constant-valued array in OpenCL kernel?
body: <p>I am writing an OpenCL kernel that convolves an image with a 5x5 Gaussian filter and was wondering what is the best practice for storing the filter constants. In the kernel each thread in a 32x32 workgroup does the following:</p>
  
  <ol>
  <li>loads a pixel into a <code>__local</code> memory buffer, </li>
  <li>sync's via <code>barrier(CLK_LOCAL_MEM_FENCE)</code>, </li>
  <li>and then performs the convolution for it's corresponding pixel.</li>
  </ol>
  
  <p>Here are the buffers for the local image data and the filter:</p>
  
  <pre><code> __local float4 localRegion[32][32]; // image region w 2 pixel apron
   .... 
   static const float filter[5][5] = { // __constant vs __private ??
      {1/256.0,  4/256.0,  6/256.0,  4/256.0, 1/256.0},
      {4/256.0, 16/256.0, 24/256.0, 16/256.0, 4/256.0},
      {6/256.0, 24/256.0, 36/256.0, 24/256.0, 6/256.0},
      {4/256.0, 16/256.0, 24/256.0, 16/256.0, 4/256.0},
      {1/256.0,  4/256.0,  6/256.0,  4/256.0, 1/256.0}
    };
  </code></pre>
  
  <p>What memory regions can hold <code>filter</code>, which is best, and how does initialization occur in each case? Optimally <code>__private</code> would be best, but I am not sure you can statically initialize private array? <code>__local</code> doesn't make sense unless some of the threads are responsible for loading the <code>filter</code> entries (I think)? Also, according the the <a href="https://www.khronos.org/registry/OpenCL/specs/opencl-2.0-openclc.pdf" rel="nofollow noreferrer">khronos docs Sec 6.5</a>, I am not sure <code>static</code> and <code>_private</code> can go together.</p>
  
  <p>According to <a href="https://stackoverflow.com/questions/36827381/small-array-stored-like-variables-in-a-kernel">the answers here</a> and <a href="https://stackoverflow.com/questions/7840720/what-is-the-best-way-to-implement-a-small-lookup-table-in-an-opencl-kernel">here</a>, <code>filter</code> can be stored as <code>__private</code> but its not clear how initialization happens.</p>