diff --git a/samples/convolution/.classpath b/samples/convolution/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..2b3d42947b0a9f028e1acf3ee7d6963e71b1003c
--- /dev/null
+++ b/samples/convolution/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/com.amd.aparapi"/>
+	<classpathentry kind="output" path="classes"/>
+</classpath>
diff --git a/samples/convolution/.project b/samples/convolution/.project
new file mode 100644
index 0000000000000000000000000000000000000000..a304e12fe2c740acb75674e6ccb285155ddf2c2a
--- /dev/null
+++ b/samples/convolution/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>convolution</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/samples/convolution/build.xml b/samples/convolution/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..90979e334ff82caa213a1027e54266a24bb65aca
--- /dev/null
+++ b/samples/convolution/build.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<project name="convolution" default="build" basedir=".">
+   <target name="build" depends="clean">
+      <mkdir dir="classes"/>
+      <javac srcdir="src" destdir="classes" debug="on" includeantruntime="false" >
+         <classpath>
+            <pathelement path="../../com.amd.aparapi/aparapi.jar"/>
+         </classpath>
+      </javac>
+      <jar jarfile="${ant.project.name}.jar" basedir="classes"/>
+   </target>
+
+   <target name="clean">
+      <delete dir="classes"/>
+      <delete file="${ant.project.name}.jar"/>
+   </target>
+
+
+</project>
diff --git a/samples/convolution/convolution.bat b/samples/convolution/convolution.bat
new file mode 100644
index 0000000000000000000000000000000000000000..8db113974911942f23b44384166965422b6f0f90
--- /dev/null
+++ b/samples/convolution/convolution.bat
@@ -0,0 +1,7 @@
+java ^
+ -Djava.library.path=../../com.amd.aparapi.jni ^
+ -Dcom.amd.aparapi.executionMode=%1 ^
+ -classpath ../../com.amd.aparapi/aparapi.jar;convolution.jar ^
+ com.amd.aparapi.sample.convolution.Main
+
+
diff --git a/samples/convolution/convolution.sh b/samples/convolution/convolution.sh
new file mode 100644
index 0000000000000000000000000000000000000000..19f97cc1ab43c1ff9dfb5a670ee37a381187a446
--- /dev/null
+++ b/samples/convolution/convolution.sh
@@ -0,0 +1,5 @@
+java\
+ -Djava.library.path=../../com.amd.aparapi.jni\
+ -Dcom.amd.aparapi.executionMode=$1\
+ -classpath ../../com.amd.aparapi/aparapi.jar:convolution.jar\
+ com.amd.aparapi.sample.convolution.Main
diff --git a/samples/convolution/hang.jpg b/samples/convolution/hang.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d45c811e3a901805a677acd7a076d513ee3b7648
Binary files /dev/null and b/samples/convolution/hang.jpg differ
diff --git a/samples/convolution/src/com/amd/aparapi/sample/convolution/Main.java b/samples/convolution/src/com/amd/aparapi/sample/convolution/Main.java
new file mode 100644
index 0000000000000000000000000000000000000000..46d2d8e7abca2dfee138184855f8e16293a8e70b
--- /dev/null
+++ b/samples/convolution/src/com/amd/aparapi/sample/convolution/Main.java
@@ -0,0 +1,214 @@
+/*
+Copyright (c) 2010-2011, Advanced Micro Devices, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
+following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following
+disclaimer. 
+
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
+disclaimer in the documentation and/or other materials provided with the distribution. 
+
+Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
+derived from this software without specific prior written permission. 
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+If you use the software (in whole or in part), you shall adhere to all applicable U.S., European, and other export
+laws, including but not limited to the U.S. Export Administration Regulations ("EAR"), (15 C.F.R. Sections 730 through
+774), and E.U. Council Regulation (EC) No 1334/2000 of 22 June 2000.  Further, pursuant to Section 740.6 of the EAR,
+you hereby certify that, except pursuant to a license granted by the United States Department of Commerce Bureau of 
+Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export Administration 
+Regulations ("EAR"), you will not (1) export, re-export or release to a national of a country in Country Groups D:1,
+E:1 or E:2 any restricted technology, software, or source code you receive hereunder, or (2) export to Country Groups
+D:1, E:1 or E:2 the direct product of such technology or software, if such foreign produced direct product is subject
+to national security controls as identified on the Commerce Control List (currently found in Supplement 1 to Part 774
+of EAR).  For the most current Country Group listings, or for additional information about the EAR or your obligations
+under those regulations, please refer to the U.S. Bureau of Industry and Security's website at http://www.bis.doc.gov/. 
+
+*/
+
+package com.amd.aparapi.sample.convolution;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.WindowConstants;
+
+import com.amd.aparapi.Kernel;
+
+/**
+ * An example Aparapi application which demonstrates image manipulation via convolution filter
+ *    http://processing.org/learning/pixels/
+ *    http://docs.gimp.org/en/plug-in-convmatrix.html
+ * 
+ * @author Gary Frost
+ */
+public class Main{
+
+
+   final static class ConvolutionFilter{
+      private float[] weights;
+
+      private int offset;
+
+      ConvolutionFilter(float _nw, float _n, float ne, float _w, float _o, float _e, float _sw, float _s, float _se, int _offset) {
+         weights = new float[] {
+               _nw,
+               _w,
+               ne,
+               _w,
+               _o,
+               _e,
+               _sw,
+               _s,
+               _se
+         };
+         offset = _offset;
+      }
+
+   }
+
+   private static final ConvolutionFilter NONE = new ConvolutionFilter(0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 0);
+
+   private static final ConvolutionFilter BLUR = new ConvolutionFilter(1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 0);
+
+   private static final ConvolutionFilter EMBOSS = new ConvolutionFilter(-2f, -1f, 0f, -1f, 1f, 1f, 0f, 1f, 2f, 0);
+
+   public static class ConvolutionKernel extends Kernel{
+
+      private final float[] filter = new float[10];
+
+      private final int[] inputData;
+
+      private final int[] outputData;
+
+      private final int width;
+
+      private final int height;
+
+      private int offset;
+
+      public ConvolutionKernel(int _width, int _height, BufferedImage _inputImage, BufferedImage _outputImage) {
+         inputData = ((DataBufferInt) _inputImage.getRaster().getDataBuffer()).getData();
+         outputData = ((DataBufferInt) _outputImage.getRaster().getDataBuffer()).getData();
+         width = _width;
+         height = _height;
+         setExplicit(true);
+      }
+
+      public void run() {
+
+         int x = getGlobalId() % width;
+         int y = getGlobalId() / width;
+
+         if (x > 1 && x < (width - 1) && y > 1 && y < (height - 1)) {
+
+            int result = 0;
+            // We handle each color separately using rgbshift as an 8 bit mask for red, green, blue
+            for (int rgbShift = 0; rgbShift < 24; rgbShift += 8) { // 0,8,16
+               int channelAccum = 0;
+               float accum = 0;
+               int count = 0;
+               for (int dx = -1; dx < 2; dx++) { // west to east
+                  for (int dy = -1; dy < 2; dy++) { // north to south
+                     int rgb = (inputData[((y + dy) * width) + (x + dx)]);
+                     int channelValue = ((rgb >> rgbShift) & 0xff);
+                     accum += filter[count];
+                     channelAccum += channelValue * filter[count++];
+
+                  }
+               }
+               channelAccum /= accum;
+               channelAccum += offset;
+               channelAccum = max(0, min(channelAccum, 0xff));
+               result |= (channelAccum << rgbShift);
+            }
+            outputData[y * width + x] = result;
+         }
+      }
+
+      public void apply(ConvolutionFilter _filter) {
+         System.arraycopy(_filter.weights, 0, filter, 0, _filter.weights.length);
+         offset = _filter.offset;
+         put(filter);
+         execute(width * height);
+         get(outputData);
+      }
+   }
+
+   public static void main(String[] _args) throws IOException, InterruptedException {
+
+      JFrame frame = new JFrame("Convolution");
+
+      BufferedImage testCard = ImageIO.read(new File("hang.jpg"));
+
+      int imageHeight = testCard.getHeight();
+
+      int imageWidth = testCard.getWidth();
+
+      int padWidth = 64 - (imageWidth % 64);
+
+      int padHeight = 64 - (imageHeight % 64);
+
+      final int width = imageWidth + padWidth; // now multiple of 64
+
+      final int height = imageHeight + padHeight; // now multiple of 64
+
+      final BufferedImage inputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+
+      inputImage.getGraphics().drawImage(testCard, padWidth / 2, padHeight / 2, null);
+      final BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+      outputImage.getGraphics().drawImage(testCard, padWidth / 2, padHeight / 2, null);
+      final ConvolutionKernel lifeKernel = new ConvolutionKernel(width, height, inputImage, outputImage);
+
+      // Create a component for viewing the offscreen image
+      @SuppressWarnings("serial") JComponent viewer = new JComponent(){
+         @Override public void paintComponent(Graphics g) {
+            g.drawImage(outputImage, 0, 0, width, height, 0, 0, width, height, this);
+         }
+      };
+
+      // Set the default size and add to the frames content pane
+      viewer.setPreferredSize(new Dimension(width, height));
+      frame.getContentPane().add(viewer);
+
+      // Swing housekeeping
+      frame.pack();
+      frame.setVisible(true);
+      frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+
+      ConvolutionFilter[] filters = new ConvolutionFilter[] {
+            NONE,
+            BLUR,
+            EMBOSS
+      };
+      long start = System.nanoTime();
+      for (int i = 0; i < 10; i++) {
+      
+         for (ConvolutionFilter filter : filters) {
+
+            lifeKernel.apply(filter); // Work is performed here
+
+            viewer.repaint(); 
+         }
+      }
+      System.out.println((System.nanoTime() - start) / 1000000);
+
+   }
+}