Advertisement
Guest User

Untitled

a guest
May 4th, 2016
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.88 KB | None | 0 0
  1. // An openCL kernel implementation of a box blur filter.
  2.  
  3. // Takes an intensity image represented by width * height
  4. // integer values. Then, it applies a box blur to the image and writes it
  5. // to the output buffer.
  6.  
  7. // Uses blocking optimization to achieve better performance as opposed to
  8. // a naive implementation where the number of work items is equal to
  9. // the number of pixels in the image.
  10.  
  11. // Uses local GPU memory to compute values more efficiently within work groups.
  12.  
  13. __kernel void boxblur_naive (__read_only __global int* image,
  14.                              __read_only __global int* imageSize,
  15.                              __read_only __global int* k,
  16.                              __read_only __global int* blockSize,
  17.                              __read_write __local int* localmem,
  18.                              __write_only __global int* output)
  19. {
  20.     // extract mask dimensions for easier use
  21.     int left = k[0];
  22.     int up = k[1];
  23.     int right = k[2];
  24.     int down = k[3];
  25.  
  26.     int blockX = get_global_id(0) * blockSize[0]; // x position of first element in block (internal block coordinates (0,0))
  27.     int blockY = get_global_id(1) * blockSize[1]; // y position of first element in block
  28.  
  29.     // get block sizes
  30.     int blockWidth = blockSize[0];
  31.     int blockHeight = blockSize[1];
  32.  
  33.     // check if block violates boundary on y-axis
  34.     //if (blockY + blockSize[1] > imageSize[1])
  35.     //  blockHeight = blockY + (blockSize[1] - 1) - imageSize[1];   // reduce size of block to fit y-boundary
  36.  
  37.     // calculate all positions in block
  38.     for (int i = 0; i < blockHeight; i++)
  39.     {
  40.         // check if block violates boundary on x-axis
  41.         //if (blockX + blockSize[0] > imageSize[0])
  42.         //  blockWidth = blockX + (blockSize[0] - 1) - imageSize[0]; // reduce size of block to fit x-boundary
  43.  
  44.         for (int j = 0; j < blockWidth; j++)
  45.         {
  46.             // find position of matrix entry to calculate
  47.             int col = blockX + j;
  48.             int row = blockY + i;
  49.  
  50.             // copy current value into local memory
  51.             // (notice: "offset" needed because local memory size
  52.             // is equal to work group size extended by mask size)
  53.             localmem[left +
  54.                      get_local_id(0) +
  55.                      (get_local_size(0) * (get_local_id(1) + up))] = image[col + (row * imageSize[0])];
  56.  
  57.             // if current value is on a work group border,
  58.             // load missing neighbor values into local memory (non-overlapping!):
  59.             //
  60.             // top left value in work group
  61.             int val;
  62.             int localXOffset = left + (get_local_id(0) * get_local_size(0));
  63.             int localYOffset = up + (get_local_id(1) * get_local_size(1));
  64.  
  65.             if(get_local_id(0) == 0 &&
  66.                get_local_id(1) == 0)
  67.             {
  68.                 for(int y = get_global_id(1) - up; y < get_global_id(1); y++)
  69.                     for(int x = get_global_id(0) - left; x < get_global_id(0); x++)
  70.                     {
  71.                         // use neutral element if position is OOB in input image
  72.                         val = y < 0 || x < 0 || y >= imageSize[1] || x >= imageSize[0] ? 0 : image[x + (y * imageSize[0])];
  73.  
  74.                         // translate global to local value position and
  75.                         // copy neighbor values from global to local memory
  76.                         localmem[(x + localXOffset) + ((y * imageSize[0]) + localYOffset)] = val;
  77.                     }
  78.             }
  79.  
  80.             // top right
  81.             else if(get_local_id(0) == 0 &&
  82.                     get_local_id(1) == get_local_size(1) - 1)
  83.             {
  84.                 for(int y = get_global_id(1) - up; y < get_global_id(1); y++)
  85.                     for(int x = get_global_id(0) + 1; x <= get_global_id(0) + right; x++)
  86.                     {
  87.                         val = y < 0 || x < 0 || y >= imageSize[1] || x >= imageSize[0] ? 0 : image[x + (y * imageSize[0])];
  88.                         localmem[(x + localXOffset) + ((y * imageSize[0]) + localYOffset)] = val;
  89.                     }
  90.             }
  91.  
  92.             // bottom left
  93.             else if (get_local_id(0) == get_local_size(0) - 1 &&
  94.                      get_local_id(1) == 0)
  95.             {
  96.                 for(int y = get_global_id(1) + 1; y <= get_global_id(1) + down; y++)
  97.                     for(int x = get_global_id(0) - left; x < get_global_id(0); x++)
  98.                     {
  99.                         val = y < 0 || x < 0 || y >= imageSize[1] || x >= imageSize[0] ? 0 : image[x + (y * imageSize[0])];
  100.                         localmem[(x + localXOffset) + ((y * imageSize[0]) + localYOffset)] = val;
  101.                     }
  102.             }
  103.  
  104.             // bottom right
  105.             else if (get_local_id(0) == get_local_size(0) - 1 &&
  106.                      get_local_id(1) == get_local_size(1) - 1)
  107.             {
  108.                 for(int y = get_global_id(1) + 1; y <= get_global_id(1) + down; y++)
  109.                     for(int x = get_global_id(0) + 1; x <= get_global_id(0) + right; x++)
  110.                     {
  111.                         val = y < 0 || x < 0 || y >= imageSize[1] || x >= imageSize[0] ? 0 : image[x + (y * imageSize[0])];
  112.                         localmem[(x + localXOffset) + ((y * imageSize[0]) + localYOffset)] = val;
  113.                     }
  114.             }
  115.  
  116.             // upper border
  117.             else if (get_local_id(0) == 0)
  118.             {
  119.                 for(int y = get_global_id(1) - up; y < get_global_id(1); y++)
  120.                     for(int x = get_global_id(0) - left; x <= get_global_id(0) + right; x++) // ADD EXPLICIT CHECK HERE SO NO OVERLAP OCCURS
  121.                     {
  122.                         val = y < 0 || x < 0 || y >= imageSize[1] || x >= imageSize[0] ? 0 : image[x + (y * imageSize[0])];
  123.                         localmem[(x + localXOffset) + ((y * imageSize[0]) + localYOffset)] = val;
  124.                     }
  125.             }
  126.  
  127.             // left border
  128.             else if (get_local_id(1) == 0)
  129.             {
  130.                 for(int y = get_global_id(1) - up; y <= get_global_id(1) + down; y++)
  131.                     for(int x = get_global_id(0) - left; x < get_global_id(0); x++) // ADD EXPLICIT CHECK HERE SO NO OVERLAP OCCURS
  132.                     {
  133.                         val = y < 0 || x < 0 || y >= imageSize[1] || x >= imageSize[0] ? 0 : image[x + (y * imageSize[0])];
  134.                         localmem[(x + localXOffset) + ((y * imageSize[0]) + localYOffset)] = val;
  135.                     }
  136.             }
  137.  
  138.             // right border
  139.             else if (get_local_id(1) == get_local_size(1) - 1)
  140.             {
  141.                 for(int y = get_global_id(1) - up; y < get_global_id(1); y++)
  142.                     for(int x = get_global_id(0) + 1; x <= get_global_id(0) + right; x++) // ADD EXPLICIT CHECK HERE SO NO OVERLAP OCCURS
  143.                     {
  144.                         val = y < 0 || x < 0 || y >= imageSize[1] || x >= imageSize[0] ? 0 : image[x + (y * imageSize[0])];
  145.                         localmem[(x + localXOffset) + ((y * imageSize[0]) + localYOffset)] = val;
  146.                     }
  147.             }
  148.  
  149.             // lower border
  150.             else if (get_local_id(0) == get_local_size(0) - 1)
  151.             {
  152.                 for(int y = get_global_id(1) + 1; y <= get_global_id(1) + down; y++)
  153.                     for(int x = get_global_id(0) - left; x <= get_global_id(0) + right; x++) // ADD EXPLICIT CHECK HERE SO NO OVERLAP OCCURS
  154.                     {
  155.                         val = y < 0 || x < 0 || y >= imageSize[1] || x >= imageSize[0] ? 0 : image[x + (y * imageSize[0])];
  156.                         localmem[(x + localXOffset) + ((y * imageSize[0]) + localYOffset)] = val;
  157.                     }
  158.             }
  159.  
  160.             // Normal case - value is not a border value.
  161.             else
  162.             {
  163.                 // nothing else to do
  164.             }
  165.  
  166.             // only when all work items have arrived here,
  167.             // computation continues - otherwise, not all needed
  168.             // values might be available in local memory
  169.             barrier (CLK_LOCAL_MEM_FENCE);
  170.  
  171.  
  172.             // check out-of-bounds conditions
  173.             // and resize mask if needed
  174.             /*if (col - left < 0)
  175.                 left = left + (col - left);
  176.  
  177.             if (row - up < 0)
  178.                 up = up + (row - up);
  179.  
  180.             if (col + right >= imageSize[0])
  181.                 right = right - (col + right - imageSize[0]) - 1;
  182.  
  183.             if (row + down >= imageSize[1])
  184.                 down = down - (row + down - imageSize[1]) - 1;*/
  185.  
  186.             // get sum of all elements inside the mask
  187.             // centered at (col, row)
  188.             int sum = 0;
  189.             int val2;
  190.  
  191.             /*for(int c_row = row - up; c_row <= row + down; c_row++)
  192.                 for(int c_col = col - left; c_col <= col + right; c_col++)
  193.                 {
  194.                     // check if value is out of bounds - if yes, use neutral element 0
  195.                     val2 = c_row < 0 ||
  196.                            c_row >= imageSize[1] ||
  197.                            c_col < 0 ||
  198.                            c_col >= imageSize[0] ?
  199.                            0 : localmem[c_col + c_row * (left + get_local_size(0) + right)];
  200.  
  201.                     sum += val2; // sum neighbors using local memory
  202.                 }*/
  203.  
  204.             // divide by size of mask
  205.             int masksize = (left + 1 + right) * (up + 1 + down); // +1 because of "middle" element
  206.             int pixelValue = sum / masksize;
  207.  
  208.             // write new pixel intensity value to output image
  209.             //output[col + (row * imageSize[0])] = pixelValue;
  210.             output[col + (row * imageSize[0])] = localmem[col + row * (left + get_local_size(0) + right)];
  211.         }
  212.     }
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement