(5622,17729,'2014-05-20 15:11:39','2014-05-20 15:11:39','<p>Mobile devices are carving their niche into the world of computing with more processing power day by day. GPUs on mobile devices have been around for a while, but using them for accelerating computation is still quite new. Until recently, the only way to access the GPU was through OpenGL. Around december 2008, Khronos released OpenCL, a generic API for accelerating non-graphics tasks. OpenCL enables us to take advantage of acceleration hardware. Since it is an open standard, many hardware vendors provide support on their devices. With the recent release of Adreno and Mali SDKs, you can now run OpenCL code on mobile GPUs.</p>\r\n<p>Today\'s post is going to be about how to do image processing on camera feed on Android devices using OpenCL. To successfully complete this tutorial, you need to have basic knowledge of how to write OpenCL kernels and native code for Android.</p>\r\n<h3 id=\"opencl\">OpenCL</h3>\r\n<p>To use OpenCL on your mobile device\'s GPU, you must obtain the compatible libOpenCL.so library and the corresponding OpenCL headers.</p>\r\n<p>I initially thought I could just use the C++ OpenCL header available from Khronos website for development, however that didn\'t work. I faced compilation errors because of incompatible OpenGL headers. There are couple of ways to get the compatible headers. You can either use the <a href=\"https://github.com/arrayfire/androidcl/tree/master/jni/include\">headers</a> provided along with the example application or extract them from Adreno/Mali SDK. For Adreno SDK, you can find the headers at <code>&lt;Adreno_SDK&gt;/Development/Inc/CL</code>. For Mali SDK, you can find the headers at <code>&lt;MALI_SDK&gt;/include/CL</code>.</p>\r\n<p>For newer devices such as Samsung Galaxy Note 3 and Samsung Galaxy S5, it is very likely the library is already present on the mobile device. My test device is a Note 3 for which i found the library under <code>/system/vendor/lib</code>. You can do <code>adb pull /system/vendor/lib/libOpenCL.so ./</code> to get the file to your desktop machine. In these kind of cases, you might be able to use the library out of the box without any issues. For any other scenario, please use the directions in following sections to get the library and make it work if available.</p>\r\n<h4 id=\"adreno-gpu\">Adreno GPU</h4>\r\n<p>If you do not find the library on your device, check if your device has OpenCL support on the corresponding vendor\'s website. If your GPU does have OpenCL support, you might have to update your OS in order to get the recent updates. If you don\'t find the library even after OS update, you might want to email the vendor. However, if your GPU does not have OpenCL support, there isn\'t much we can do.</p>\r\n<p>If you do find the library and can\'t use for some reason. Try to update your device drivers using the ones provided by Qualcomm. You can download them from <a href=\"https://developer.qualcomm.com/mobile-development/maximize-hardware/mobile-gaming-graphics-adreno/tools-and-resources\">here</a>. Ensure that you are downloading the Adreno driver but not the Adreno SDK. Follow the instructions in the package and update the drivers on your device. This should resolve any issues you have.</p>\r\n<h4 id=\"mali-gpu\">Mali GPU</h4>\r\n<p>Download the SDK from <a href=\"http://malideveloper.arm.com/develop-for-mali/sdks/mali-opencl-sdk/\">here</a>. Follow the instructions in the package and build the shared library and copy it on to your device.</p>\r\n<h4 id=\"kernels\">Kernels</h4>\r\n<p>I needed to do two things to achieve my target.</p>\r\n<ul>\r\n<li>Convert frame data provided by Android camera from NV21 format to RGBA8888 format.<br /></li>\r\n<li>Run laplacian operator on the RGBA8888 image data.</li>\r\n</ul>\r\n<p>Getting a grayscale image from NV21 format is cake walk, just read the first width*height bytes and you are done. As per the format of <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a>, for each 2x2 sub-matrix of pixels, there will be a pair (v,u). Since 4 pixels are reading same (v,u), i decided to use shared memory to reduce reading latency. The code below is the core of this conversion kernel, that is expected to speed up the conversion if compared to a pure C code.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define BLK_SIZE    16</span>\r\n<span class=\"co\">//prefix D for decoding</span>\r\n<span class=\"ot\">#define DSHRD_LEN   (BLK_SIZE/2)</span>\r\n<span class=\"ot\">#define DSHRD_SIZE  (2*DSHRD_LEN*DSHRD_LEN)</span>\r\n<span class=\"co\">// ...</span>\r\n<span class=\"co\">// ..</span>\r\n<span class=\"co\">// kernel signature</span>\r\n{\r\n    __local uchar uvShrd[DSHRD_SIZE];\r\n    <span class=\"dt\">int</span> gx  = get_global_id(<span class=\"dv\">0</span>);\r\n    <span class=\"dt\">int</span> gy  = get_global_id(<span class=\"dv\">1</span>);\r\n    <span class=\"dt\">int</span> lx  = get_local_id(<span class=\"dv\">0</span>);\r\n    <span class=\"dt\">int</span> ly  = get_local_id(<span class=\"dv\">1</span>);\r\n    <span class=\"dt\">int</span> off = im_width*im_height;\r\n    <span class=\"dt\">int</span> inIdx= gy*im_width+gx;\r\n    <span class=\"dt\">int</span> uvIdx= off + (gy/<span class=\"dv\">2</span>)*im_width + (gx &amp; ~<span class=\"dv\">1</span>);   <span class=\"co\">// took me a while to figure out this formula</span>\r\n    <span class=\"dt\">int</span> shlx = lx/<span class=\"dv\">2</span>;\r\n    <span class=\"dt\">int</span> shly = ly/<span class=\"dv\">2</span>;\r\n    <span class=\"dt\">int</span> shIdx= <span class=\"dv\">2</span>*(shlx+shly*DSHRD_LEN);\r\n    <span class=\"kw\">if</span>( gx%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> &amp;&amp; gy%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> ) {\r\n        uvShrd[shIdx<span class=\"dv\">+0</span>] = in[uvIdx<span class=\"dv\">+0</span>];\r\n        uvShrd[shIdx<span class=\"dv\">+1</span>] = in[uvIdx<span class=\"dv\">+1</span>];\r\n    }\r\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\r\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\r\n    <span class=\"kw\">if</span>( y &lt; <span class=\"dv\">16</span> ) y=<span class=\"dv\">16</span>;\r\n    barrier(CLK_LOCAL_MEM_FENCE);\r\n    <span class=\"co\">//..... rest of code that does color space conversion</span>\r\n}</code></pre>\r\n<p>Laplacian kernel is pretty straightforward, read all eight neighbors pixel values using shared memory and compute the convolution result. You can find kernels source code <a href=\"https://github.com/arrayfire/androidcl/blob/master/assets/kernels.cl\">here</a>.</p>\r\n<h4 id=\"auxilary-code\">Auxilary Code</h4>\r\n<p>The JNI native function declarations can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.h\">processor.h</a>. I have included couple of extra Android related headers which are required to read bitmap files and print debug messages from JNI routines. The C-string pointed by macro <code>app_name</code> can be used to prune the output of the command <code>adb logcat</code> to get only messages that are associated with our JNI routines. To do that, you need to pass the value of <code>app_name</code> to adb command as an option as shown below.</p>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">adb</span> logcat -s <span class=\"st\">&quot;JNIProcessor&quot;</span></code></pre>\r\n<p>This is quite useful when you are debugging problems that are related to accuracy of results.</p>\r\n<p>The full source code for JNI native functions can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.cpp\">processor.cpp</a>. Following are brief descriptions of the Android/JNI functions I have used in this project.</p>\r\n<ul>\r\n<li><code>AndroidBitmap_getInfo</code> - provides details like width, height, stride, format.<br /></li>\r\n<li><code>AndroidBitmap_lockPixels</code> - gives us a pointer to the memory location of image data. Once lockPixels is called, it has to be followed by a unlockPixels at some point later in the code.<br /></li>\r\n<li><code>GetPrimitiveArrayCritical</code> - as the name suggets, this is some kind of performance critical call. Hence, we should take care that the code amid a GetPrimitiveArrayCritical call and the corresponding ReleasePrimitiveArrayCritical call doesn\'t stall execution for extended periods of time. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s Java documentation</a>, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical. So, just be careful when you use this function.<br /></li>\r\n<li><code>ReleasePrimitiveArrayCritical</code> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.<br /></li>\r\n<li><code>AndroidBitmap_unlockPixels</code> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\n<p>Listed below are some of the other auxilary functions that i needed to make the code look clean.</p>\r\n<ul>\r\n<li><code>throwJavaException</code> - convenience function used to throw Java exceptions from JNI routines.<br /></li>\r\n<li><code>cb</code> - callback function provided when OpenCL kernels are built. When you actually look at this, you might wonder why did i do this part alone using C-interface of OpenCL. I just wanted to try it out, hence it happened so.<br /></li>\r\n<li><code>Java_com_example_LiveFeatureActivity_compileKernels</code> - as you might have noticed, this is a JNI routine i used to compile the OpenCL kernels only once during the app start up.</li>\r\n</ul>\r\n<h3 id=\"build-on-linux\">Build (on Linux)</h3>\r\n<p>Android-NDK provides a very useful tool <code>ndk-build</code> to build native code for Android.</p>\r\n<ol>\r\n<li>Clone the git repo <code>git clone https://github.com/arrayfire/androidcl</code><br /></li>\r\n<li><code>cd androidcl</code><br /></li>\r\n<li>Ensure android-ndk installed and environment variable <code>ANDROID_NDK</code> is pointing to ndk installation root.<br /></li>\r\n<li>Ensure environment variable <code>PATH</code> has the path <code>$ANDROID_NDK</code> appended to it.<br /></li>\r\n<li>Run <code>ndk-build</code> from project root.<br /></li>\r\n<li>If you have <code>eclipse</code> installed, then import the project from eclipse and build it as usually.<br /></li>\r\n<li>If you do not have eclipse or don\'t want to use it, then I assume you might already know about apache-ant tool. Run <code>ant debug</code></li>\r\n</ol>\r\n<h4 id=\"android.mk\">Android.mk</h4>\r\n<p>There are couple of things that you need to do to use OpenCL on Android apart from standard JNI makefile instructions.</p>\r\n<ul>\r\n<li>Ensure that you set <code>LOCAL_ARM_MODE</code> to <code>arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.<br /></li>\r\n<li>Ensure that the variable <code>LOCAL_CPPFLAGS</code> has been set to point to OpenCL headers.<br /></li>\r\n<li>Add <code>libOpenCL.so</code> dependency to <code>LOCAL_LDLIBS</code> variable.</li>\r\n</ul>\r\n<p>Click <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk.</p>\r\n<p>Note: In case you want a static library, replace <code>include $(BUILD_SHARED_LIBRARY)</code> with <code>include $(BUILD_STATIC_LIBRARY)</code>.</p>\r\n<h4 id=\"application.mk\">Application.mk</h4>\r\n<p>This file is not mandatory, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. In this project i have set <code>APP_STL</code> to <code>gnustl_static</code> to declare that i want to use the static version of gnustl. I have also set the Android API target version as 14 by setting <code>APP_PLATFORM</code> to <code>android-14</code>.<br />Click <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk.</p>\r\n<h3 id=\"app-installation\">App Installation</h3>\r\n<h4 id=\"ant-users\">ant-users</h4>\r\n<p>For installing the app in your mobile device do <code>ant debug install</code>. Should you choose to remove it after you are done playing with it, just do <code>ant debug uninstall</code>.</p>\r\n<h4 id=\"eclipse-users\">eclipse-users</h4>\r\n<p>Right click the project in workspace and click the menu item &quot;Run As -&gt; Android Application&quot;.</p>\r\nYou can see below the video of the app running live.\r\n[video width=\"1280\" height=\"720\" mp4=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/05/ocl_demo.mp4\"]Screen capture of the live app[/video]\r\n<br/>\r\nStay tuned for more exciting developments as we continue to add more examples of OpenCL on Andriod!','Getting started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-20 15:11:39','2014-05-20 15:11:39','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5624,6,'2014-05-20 15:33:18','2014-05-20 15:33:18','Mobile devices are carving their niche into the world of computing with more processing power day by day. GPUs on mobile devices have been around for a while, but using them for accelerating computation is still quite new. Until recently, the only way to access the GPU was through OpenGL. Around december 2008, Khronos released OpenCL, a generic API for accelerating non-graphics tasks. OpenCL enables us to take advantage of acceleration hardware. Since it is an open standard, many hardware vendors provide support on their devices. With the recent release of Adreno and Mali SDKs, you can now run OpenCL code on mobile GPUs.\n\nToday\'s post is going to be about how to do image processing on camera feed on Android devices using OpenCL. To successfully complete this tutorial, you need to have basic knowledge of how to write OpenCL kernels and native code for Android.\n<h3 id=\"opencl\">OpenCL</h3>\nTo use OpenCL on your mobile device\'s GPU, you must obtain the compatible libOpenCL.so library and the corresponding OpenCL headers.\n\nI initially thought I could just use the C++ OpenCL header available from Khronos website for development, however that didn\'t work. I faced compilation errors because of incompatible OpenGL headers. There are couple of ways to get the compatible headers. You can either use the <a href=\"https://github.com/arrayfire/androidcl/tree/master/jni/include\">headers</a> provided along with the example application or extract them from Adreno/Mali SDK. For Adreno SDK, you can find the headers at <code>&lt;Adreno_SDK&gt;/Development/Inc/CL</code>. For Mali SDK, you can find the headers at <code>&lt;MALI_SDK&gt;/include/CL</code>.\n\nFor newer devices such as Samsung Galaxy Note 3 and Samsung Galaxy S5, it is very likely the library is already present on the mobile device. My test device is a Note 3 for which i found the library under <code>/system/vendor/lib</code>. You can do <code>adb pull /system/vendor/lib/libOpenCL.so ./</code> to get the file to your desktop machine. In these kind of cases, you might be able to use the library out of the box without any issues. For any other scenario, please use the directions in following sections to get the library and make it work if available.\n<h4 id=\"adreno-gpu\">Adreno GPU</h4>\nIf you do not find the library on your device, check if your device has OpenCL support on the corresponding vendor\'s website. If your GPU does have OpenCL support, you might have to update your OS in order to get the recent updates. If you don\'t find the library even after OS update, you might want to email the vendor. However, if your GPU does not have OpenCL support, there isn\'t much we can do.\n\nIf you do find the library and can\'t use for some reason. Try to update your device drivers using the ones provided by Qualcomm. You can download them from <a href=\"https://developer.qualcomm.com/mobile-development/maximize-hardware/mobile-gaming-graphics-adreno/tools-and-resources\">here</a>. Ensure that you are downloading the Adreno driver but not the Adreno SDK. Follow the instructions in the package and update the drivers on your device. This should resolve any issues you have.\n<h4 id=\"mali-gpu\">Mali GPU</h4>\nDownload the SDK from <a href=\"http://malideveloper.arm.com/develop-for-mali/sdks/mali-opencl-sdk/\">here</a>. Follow the instructions in the package and build the shared library and copy it on to your device.\n<h4 id=\"kernels\">Kernels</h4>\nI needed to do two things to achieve my target.\n<ul>\n	<li>Convert frame data provided by Android camera from NV21 format to RGBA8888 format.</li>\n	<li>Run laplacian operator on the RGBA8888 image data.</li>\n</ul>\nGetting a grayscale image from NV21 format is cake walk, just read the first width*height bytes and you are done. As per the format of <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a>, for each 2x2 sub-matrix of pixels, there will be a pair (v,u). Since 4 pixels are reading same (v,u), i decided to use shared memory to reduce reading latency. The code below is the core of this conversion kernel, that is expected to speed up the conversion if compared to a pure C code.\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define BLK_SIZE    16</span>\n<span class=\"co\">//prefix D for decoding</span>\n<span class=\"ot\">#define DSHRD_LEN   (BLK_SIZE/2)</span>\n<span class=\"ot\">#define DSHRD_SIZE  (2*DSHRD_LEN*DSHRD_LEN)</span>\n<span class=\"co\">// ...</span>\n<span class=\"co\">// ..</span>\n<span class=\"co\">// kernel signature</span>\n{\n    __local uchar uvShrd[DSHRD_SIZE];\n    <span class=\"dt\">int</span> gx  = get_global_id(<span class=\"dv\">0</span>);\n    <span class=\"dt\">int</span> gy  = get_global_id(<span class=\"dv\">1</span>);\n    <span class=\"dt\">int</span> lx  = get_local_id(<span class=\"dv\">0</span>);\n    <span class=\"dt\">int</span> ly  = get_local_id(<span class=\"dv\">1</span>);\n    <span class=\"dt\">int</span> off = im_width*im_height;\n    <span class=\"dt\">int</span> inIdx= gy*im_width+gx;\n    <span class=\"dt\">int</span> uvIdx= off + (gy/<span class=\"dv\">2</span>)*im_width + (gx &amp; ~<span class=\"dv\">1</span>);   <span class=\"co\">// took me a while to figure out this formula</span>\n    <span class=\"dt\">int</span> shlx = lx/<span class=\"dv\">2</span>;\n    <span class=\"dt\">int</span> shly = ly/<span class=\"dv\">2</span>;\n    <span class=\"dt\">int</span> shIdx= <span class=\"dv\">2</span>*(shlx+shly*DSHRD_LEN);\n    <span class=\"kw\">if</span>( gx%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> &amp;&amp; gy%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> ) {\n        uvShrd[shIdx<span class=\"dv\">+0</span>] = in[uvIdx<span class=\"dv\">+0</span>];\n        uvShrd[shIdx<span class=\"dv\">+1</span>] = in[uvIdx<span class=\"dv\">+1</span>];\n    }\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\n    <span class=\"kw\">if</span>( y &lt; <span class=\"dv\">16</span> ) y=<span class=\"dv\">16</span>;\n    barrier(CLK_LOCAL_MEM_FENCE);\n    <span class=\"co\">//..... rest of code that does color space conversion</span>\n}</code></pre>\nLaplacian kernel is pretty straightforward, read all eight neighbors pixel values using shared memory and compute the convolution result. You can find kernels source code <a href=\"https://github.com/arrayfire/androidcl/blob/master/assets/kernels.cl\">here</a>.\n<h4 id=\"auxilary-code\">Auxilary Code</h4>\nThe JNI native function declarations can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.h\">processor.h</a>. I have included couple of extra Android related headers which are required to read bitmap files and print debug messages from JNI routines. The C-string pointed by macro <code>app_name</code> can be used to prune the output of the command <code>adb logcat</code> to get only messages that are associated with our JNI routines. To do that, you need to pass the value of <code>app_name</code> to adb command as an option as shown below.\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">adb</span> logcat -s <span class=\"st\">\"JNIProcessor\"</span></code></pre>\nThis is quite useful when you are debugging problems that are related to accuracy of results.\n\nThe full source code for JNI native functions can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.cpp\">processor.cpp</a>. Following are brief descriptions of the Android/JNI functions I have used in this project.\n<ul>\n	<li><code>AndroidBitmap_getInfo</code> - provides details like width, height, stride, format.</li>\n	<li><code>AndroidBitmap_lockPixels</code> - gives us a pointer to the memory location of image data. Once lockPixels is called, it has to be followed by a unlockPixels at some point later in the code.</li>\n	<li><code>GetPrimitiveArrayCritical</code> - as the name suggets, this is some kind of performance critical call. Hence, we should take care that the code amid a GetPrimitiveArrayCritical call and the corresponding ReleasePrimitiveArrayCritical call doesn\'t stall execution for extended periods of time. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s Java documentation</a>, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical. So, just be careful when you use this function.</li>\n	<li><code>ReleasePrimitiveArrayCritical</code> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\n	<li><code>AndroidBitmap_unlockPixels</code> - used to release memory space used by a previous lockPixels call.</li>\n</ul>\nListed below are some of the other auxilary functions that i needed to make the code look clean.\n<ul>\n	<li><code>throwJavaException</code> - convenience function used to throw Java exceptions from JNI routines.</li>\n	<li><code>cb</code> - callback function provided when OpenCL kernels are built. When you actually look at this, you might wonder why did i do this part alone using C-interface of OpenCL. I just wanted to try it out, hence it happened so.</li>\n	<li><code>Java_com_example_LiveFeatureActivity_compileKernels</code> - as you might have noticed, this is a JNI routine i used to compile the OpenCL kernels only once during the app start up.</li>\n</ul>\n<h3 id=\"build-on-linux\">Build (on Linux)</h3>\nAndroid-NDK provides a very useful tool <code>ndk-build</code> to build native code for Android.\n<ol>\n	<li>Clone the git repo <code>git clone https://github.com/arrayfire/androidcl</code></li>\n	<li><code>cd androidcl</code></li>\n	<li>Ensure android-ndk installed and environment variable <code>ANDROID_NDK</code> is pointing to ndk installation root.</li>\n	<li>Ensure environment variable <code>PATH</code> has the path <code>$ANDROID_NDK</code> appended to it.</li>\n	<li>Run <code>ndk-build</code> from project root.</li>\n	<li>If you have <code>eclipse</code> installed, then import the project from eclipse and build it as usually.</li>\n	<li>If you do not have eclipse or don\'t want to use it, then I assume you might already know about apache-ant tool. Run <code>ant debug</code></li>\n</ol>\n<h4 id=\"android.mk\">Android.mk</h4>\nThere are couple of things that you need to do to use OpenCL on Android apart from standard JNI makefile instructions.\n<ul>\n	<li>Ensure that you set <code>LOCAL_ARM_MODE</code> to <code>arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.</li>\n	<li>Ensure that the variable <code>LOCAL_CPPFLAGS</code> has been set to point to OpenCL headers.</li>\n	<li>Add <code>libOpenCL.so</code> dependency to <code>LOCAL_LDLIBS</code> variable.</li>\n</ul>\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk.\n\nNote: In case you want a static library, replace <code>include $(BUILD_SHARED_LIBRARY)</code> with <code>include $(BUILD_STATIC_LIBRARY)</code>.\n<h4 id=\"application.mk\">Application.mk</h4>\nThis file is not mandatory, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. In this project i have set <code>APP_STL</code> to <code>gnustl_static</code> to declare that i want to use the static version of gnustl. I have also set the Android API target version as 14 by setting <code>APP_PLATFORM</code> to <code>android-14</code>.\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk.\n<h3 id=\"app-installation\">App Installation</h3>\n<h4 id=\"ant-users\">ant-users</h4>\nFor installing the app in your mobile device do <code>ant debug install</code>. Should you choose to remove it after you are done playing with it, just do <code>ant debug uninstall</code>.\n<h4 id=\"eclipse-users\">eclipse-users</h4>\nRight click the project in workspace and click the menu item \"Run As -&gt; Android Application\".\n\nYou can see below the video of the app running live.\n\n[video width=\"1280\" height=\"720\" mp4=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/05/ocl_demo.mp4\"]Screen capture of the live app[/video]\n\n&nbsp;\n\nStay tuned for more exciting developments as we continue to add more examples of OpenCL on Andriod!','Getting started with OpenCL on Android','','inherit','open','closed','','5574-autosave-v1','','','2014-05-20 15:33:18','2014-05-20 15:33:18','',5574,'http://sandbox.arrayfire.com/5574-autosave-v1/',0,'revision','',0),(5625,6,'2014-05-20 15:31:57','2014-05-20 15:31:57','Mobile devices are carving their niche into the world of computing with more processing power day by day. GPUs on mobile devices have been around for a while, but using them for accelerating computation is still quite new. Until recently, the only way to access the GPU was through OpenGL. Around december 2008, Khronos released OpenCL, a generic API for accelerating non-graphics tasks. OpenCL enables us to take advantage of acceleration hardware. Since it is an open standard, many hardware vendors provide support on their devices. With the recent release of Adreno and Mali SDKs, you can now run OpenCL code on mobile GPUs.\r\n\r\nToday\'s post is going to be about how to do image processing on camera feed on Android devices using OpenCL. To successfully complete this tutorial, you need to have basic knowledge of how to write OpenCL kernels and native code for Android.\r\n<h3 id=\"opencl\">OpenCL</h3>\r\nTo use OpenCL on your mobile device\'s GPU, you must obtain the compatible libOpenCL.so library and the corresponding OpenCL headers.\r\n\r\nI initially thought I could just use the C++ OpenCL header available from Khronos website for development, however that didn\'t work. I faced compilation errors because of incompatible OpenGL headers. There are couple of ways to get the compatible headers. You can either use the <a href=\"https://github.com/arrayfire/androidcl/tree/master/jni/include\">headers</a> provided along with the example application or extract them from Adreno/Mali SDK. For Adreno SDK, you can find the headers at <code>&lt;Adreno_SDK&gt;/Development/Inc/CL</code>. For Mali SDK, you can find the headers at <code>&lt;MALI_SDK&gt;/include/CL</code>.\r\n\r\nFor newer devices such as Samsung Galaxy Note 3 and Samsung Galaxy S5, it is very likely the library is already present on the mobile device. My test device is a Note 3 for which i found the library under <code>/system/vendor/lib</code>. You can do <code>adb pull /system/vendor/lib/libOpenCL.so ./</code> to get the file to your desktop machine. In these kind of cases, you might be able to use the library out of the box without any issues. For any other scenario, please use the directions in following sections to get the library and make it work if available.\r\n<h4 id=\"adreno-gpu\">Adreno GPU</h4>\r\nIf you do not find the library on your device, check if your device has OpenCL support on the corresponding vendor\'s website. If your GPU does have OpenCL support, you might have to update your OS in order to get the recent updates. If you don\'t find the library even after OS update, you might want to email the vendor. However, if your GPU does not have OpenCL support, there isn\'t much we can do.\r\n\r\nIf you do find the library and can\'t use for some reason. Try to update your device drivers using the ones provided by Qualcomm. You can download them from <a href=\"https://developer.qualcomm.com/mobile-development/maximize-hardware/mobile-gaming-graphics-adreno/tools-and-resources\">here</a>. Ensure that you are downloading the Adreno driver but not the Adreno SDK. Follow the instructions in the package and update the drivers on your device. This should resolve any issues you have.\r\n<h4 id=\"mali-gpu\">Mali GPU</h4>\r\nDownload the SDK from <a href=\"http://malideveloper.arm.com/develop-for-mali/sdks/mali-opencl-sdk/\">here</a>. Follow the instructions in the package and build the shared library and copy it on to your device.\r\n<h4 id=\"kernels\">Kernels</h4>\r\nI needed to do two things to achieve my target.\r\n<ul>\r\n	<li>Convert frame data provided by Android camera from NV21 format to RGBA8888 format.</li>\r\n	<li>Run laplacian operator on the RGBA8888 image data.</li>\r\n</ul>\r\nGetting a grayscale image from NV21 format is cake walk, just read the first width*height bytes and you are done. As per the format of <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a>, for each 2x2 sub-matrix of pixels, there will be a pair (v,u). Since 4 pixels are reading same (v,u), i decided to use shared memory to reduce reading latency. The code below is the core of this conversion kernel, that is expected to speed up the conversion if compared to a pure C code.\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define BLK_SIZE    16</span>\r\n<span class=\"co\">//prefix D for decoding</span>\r\n<span class=\"ot\">#define DSHRD_LEN   (BLK_SIZE/2)</span>\r\n<span class=\"ot\">#define DSHRD_SIZE  (2*DSHRD_LEN*DSHRD_LEN)</span>\r\n<span class=\"co\">// ...</span>\r\n<span class=\"co\">// ..</span>\r\n<span class=\"co\">// kernel signature</span>\r\n{\r\n    __local uchar uvShrd[DSHRD_SIZE];\r\n    <span class=\"dt\">int</span> gx  = get_global_id(<span class=\"dv\">0</span>);\r\n    <span class=\"dt\">int</span> gy  = get_global_id(<span class=\"dv\">1</span>);\r\n    <span class=\"dt\">int</span> lx  = get_local_id(<span class=\"dv\">0</span>);\r\n    <span class=\"dt\">int</span> ly  = get_local_id(<span class=\"dv\">1</span>);\r\n    <span class=\"dt\">int</span> off = im_width*im_height;\r\n    <span class=\"dt\">int</span> inIdx= gy*im_width+gx;\r\n    <span class=\"dt\">int</span> uvIdx= off + (gy/<span class=\"dv\">2</span>)*im_width + (gx &amp; ~<span class=\"dv\">1</span>);   <span class=\"co\">// took me a while to figure out this formula</span>\r\n    <span class=\"dt\">int</span> shlx = lx/<span class=\"dv\">2</span>;\r\n    <span class=\"dt\">int</span> shly = ly/<span class=\"dv\">2</span>;\r\n    <span class=\"dt\">int</span> shIdx= <span class=\"dv\">2</span>*(shlx+shly*DSHRD_LEN);\r\n    <span class=\"kw\">if</span>( gx%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> &amp;&amp; gy%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> ) {\r\n        uvShrd[shIdx<span class=\"dv\">+0</span>] = in[uvIdx<span class=\"dv\">+0</span>];\r\n        uvShrd[shIdx<span class=\"dv\">+1</span>] = in[uvIdx<span class=\"dv\">+1</span>];\r\n    }\r\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\r\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\r\n    <span class=\"kw\">if</span>( y &lt; <span class=\"dv\">16</span> ) y=<span class=\"dv\">16</span>;\r\n    barrier(CLK_LOCAL_MEM_FENCE);\r\n    <span class=\"co\">//..... rest of code that does color space conversion</span>\r\n}</code></pre>\r\nLaplacian kernel is pretty straightforward, read all eight neighbors pixel values using shared memory and compute the convolution result. You can find kernels source code <a href=\"https://github.com/arrayfire/androidcl/blob/master/assets/kernels.cl\">here</a>.\r\n<h4 id=\"auxilary-code\">Auxilary Code</h4>\r\nThe JNI native function declarations can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.h\">processor.h</a>. I have included couple of extra Android related headers which are required to read bitmap files and print debug messages from JNI routines. The C-string pointed by macro <code>app_name</code> can be used to prune the output of the command <code>adb logcat</code> to get only messages that are associated with our JNI routines. To do that, you need to pass the value of <code>app_name</code> to adb command as an option as shown below.\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">adb</span> logcat -s <span class=\"st\">\"JNIProcessor\"</span></code></pre>\r\nThis is quite useful when you are debugging problems that are related to accuracy of results.\r\n\r\nThe full source code for JNI native functions can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.cpp\">processor.cpp</a>. Following are brief descriptions of the Android/JNI functions I have used in this project.\r\n<ul>\r\n	<li><code>AndroidBitmap_getInfo</code> - provides details like width, height, stride, format.</li>\r\n	<li><code>AndroidBitmap_lockPixels</code> - gives us a pointer to the memory location of image data. Once lockPixels is called, it has to be followed by a unlockPixels at some point later in the code.</li>\r\n	<li><code>GetPrimitiveArrayCritical</code> - as the name suggets, this is some kind of performance critical call. Hence, we should take care that the code amid a GetPrimitiveArrayCritical call and the corresponding ReleasePrimitiveArrayCritical call doesn\'t stall execution for extended periods of time. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s Java documentation</a>, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical. So, just be careful when you use this function.</li>\r\n	<li><code>ReleasePrimitiveArrayCritical</code> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><code>AndroidBitmap_unlockPixels</code> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nListed below are some of the other auxilary functions that i needed to make the code look clean.\r\n<ul>\r\n	<li><code>throwJavaException</code> - convenience function used to throw Java exceptions from JNI routines.</li>\r\n	<li><code>cb</code> - callback function provided when OpenCL kernels are built. When you actually look at this, you might wonder why did i do this part alone using C-interface of OpenCL. I just wanted to try it out, hence it happened so.</li>\r\n	<li><code>Java_com_example_LiveFeatureActivity_compileKernels</code> - as you might have noticed, this is a JNI routine i used to compile the OpenCL kernels only once during the app start up.</li>\r\n</ul>\r\n<h3 id=\"build-on-linux\">Build (on Linux)</h3>\r\nAndroid-NDK provides a very useful tool <code>ndk-build</code> to build native code for Android.\r\n<ol>\r\n	<li>Clone the git repo <code>git clone https://github.com/arrayfire/androidcl</code></li>\r\n	<li><code>cd androidcl</code></li>\r\n	<li>Ensure android-ndk installed and environment variable <code>ANDROID_NDK</code> is pointing to ndk installation root.</li>\r\n	<li>Ensure environment variable <code>PATH</code> has the path <code>$ANDROID_NDK</code> appended to it.</li>\r\n	<li>Run <code>ndk-build</code> from project root.</li>\r\n	<li>If you have <code>eclipse</code> installed, then import the project from eclipse and build it as usually.</li>\r\n	<li>If you do not have eclipse or don\'t want to use it, then I assume you might already know about apache-ant tool. Run <code>ant debug</code></li>\r\n</ol>\r\n<h4 id=\"android.mk\">Android.mk</h4>\r\nThere are couple of things that you need to do to use OpenCL on Android apart from standard JNI makefile instructions.\r\n<ul>\r\n	<li>Ensure that you set <code>LOCAL_ARM_MODE</code> to <code>arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.</li>\r\n	<li>Ensure that the variable <code>LOCAL_CPPFLAGS</code> has been set to point to OpenCL headers.</li>\r\n	<li>Add <code>libOpenCL.so</code> dependency to <code>LOCAL_LDLIBS</code> variable.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk.\r\n\r\nNote: In case you want a static library, replace <code>include $(BUILD_SHARED_LIBRARY)</code> with <code>include $(BUILD_STATIC_LIBRARY)</code>.\r\n<h4 id=\"application.mk\">Application.mk</h4>\r\nThis file is not mandatory, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. In this project i have set <code>APP_STL</code> to <code>gnustl_static</code> to declare that i want to use the static version of gnustl. I have also set the Android API target version as 14 by setting <code>APP_PLATFORM</code> to <code>android-14</code>.\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk.\r\n<h3 id=\"app-installation\">App Installation</h3>\r\n<h4 id=\"ant-users\">ant-users</h4>\r\nFor installing the app in your mobile device do <code>ant debug install</code>. Should you choose to remove it after you are done playing with it, just do <code>ant debug uninstall</code>.\r\n<h4 id=\"eclipse-users\">eclipse-users</h4>\r\nRight click the project in workspace and click the menu item \"Run As -&gt; Android Application\".\r\n\r\nYou can see below the video of the app running live.\r\n\r\n[video width=\"1280\" height=\"720\" mp4=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/05/ocl_demo.mp4\"]Screen capture of the live app[/video]\r\n\r\n\r\nStay tuned for more exciting developments as we continue to add more examples of OpenCL on Andriod!','Getting started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-20 15:31:57','2014-05-20 15:31:57','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5626,6,'2014-05-20 15:33:20','2014-05-20 15:33:20','Mobile devices are carving their niche into the world of computing with more processing power day by day. GPUs on mobile devices have been around for a while, but using them for accelerating computation is still quite new. Until recently, the only way to access the GPU was through OpenGL. Around december 2008, Khronos released OpenCL, a generic API for accelerating non-graphics tasks. OpenCL enables us to take advantage of acceleration hardware. Since it is an open standard, many hardware vendors provide support on their devices. With the recent release of Adreno and Mali SDKs, you can now run OpenCL code on mobile GPUs.\r\n\r\nToday\'s post is going to be about how to do image processing on camera feed on Android devices using OpenCL. To successfully complete this tutorial, you need to have basic knowledge of how to write OpenCL kernels and native code for Android.\r\n<h3 id=\"opencl\">OpenCL</h3>\r\nTo use OpenCL on your mobile device\'s GPU, you must obtain the compatible libOpenCL.so library and the corresponding OpenCL headers.\r\n\r\nI initially thought I could just use the C++ OpenCL header available from Khronos website for development, however that didn\'t work. I faced compilation errors because of incompatible OpenGL headers. There are couple of ways to get the compatible headers. You can either use the <a href=\"https://github.com/arrayfire/androidcl/tree/master/jni/include\">headers</a> provided along with the example application or extract them from Adreno/Mali SDK. For Adreno SDK, you can find the headers at <code>&lt;Adreno_SDK&gt;/Development/Inc/CL</code>. For Mali SDK, you can find the headers at <code>&lt;MALI_SDK&gt;/include/CL</code>.\r\n\r\nFor newer devices such as Samsung Galaxy Note 3 and Samsung Galaxy S5, it is very likely the library is already present on the mobile device. My test device is a Note 3 for which i found the library under <code>/system/vendor/lib</code>. You can do <code>adb pull /system/vendor/lib/libOpenCL.so ./</code> to get the file to your desktop machine. In these kind of cases, you might be able to use the library out of the box without any issues. For any other scenario, please use the directions in following sections to get the library and make it work if available.\r\n<h4 id=\"adreno-gpu\">Adreno GPU</h4>\r\nIf you do not find the library on your device, check if your device has OpenCL support on the corresponding vendor\'s website. If your GPU does have OpenCL support, you might have to update your OS in order to get the recent updates. If you don\'t find the library even after OS update, you might want to email the vendor. However, if your GPU does not have OpenCL support, there isn\'t much we can do.\r\n\r\nIf you do find the library and can\'t use for some reason. Try to update your device drivers using the ones provided by Qualcomm. You can download them from <a href=\"https://developer.qualcomm.com/mobile-development/maximize-hardware/mobile-gaming-graphics-adreno/tools-and-resources\">here</a>. Ensure that you are downloading the Adreno driver but not the Adreno SDK. Follow the instructions in the package and update the drivers on your device. This should resolve any issues you have.\r\n<h4 id=\"mali-gpu\">Mali GPU</h4>\r\nDownload the SDK from <a href=\"http://malideveloper.arm.com/develop-for-mali/sdks/mali-opencl-sdk/\">here</a>. Follow the instructions in the package and build the shared library and copy it on to your device.\r\n<h4 id=\"kernels\">Kernels</h4>\r\nI needed to do two things to achieve my target.\r\n<ul>\r\n	<li>Convert frame data provided by Android camera from NV21 format to RGBA8888 format.</li>\r\n	<li>Run laplacian operator on the RGBA8888 image data.</li>\r\n</ul>\r\nGetting a grayscale image from NV21 format is cake walk, just read the first width*height bytes and you are done. As per the format of <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a>, for each 2x2 sub-matrix of pixels, there will be a pair (v,u). Since 4 pixels are reading same (v,u), i decided to use shared memory to reduce reading latency. The code below is the core of this conversion kernel, that is expected to speed up the conversion if compared to a pure C code.\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define BLK_SIZE    16</span>\r\n<span class=\"co\">//prefix D for decoding</span>\r\n<span class=\"ot\">#define DSHRD_LEN   (BLK_SIZE/2)</span>\r\n<span class=\"ot\">#define DSHRD_SIZE  (2*DSHRD_LEN*DSHRD_LEN)</span>\r\n<span class=\"co\">// ...</span>\r\n<span class=\"co\">// ..</span>\r\n<span class=\"co\">// kernel signature</span>\r\n{\r\n    __local uchar uvShrd[DSHRD_SIZE];\r\n    <span class=\"dt\">int</span> gx  = get_global_id(<span class=\"dv\">0</span>);\r\n    <span class=\"dt\">int</span> gy  = get_global_id(<span class=\"dv\">1</span>);\r\n    <span class=\"dt\">int</span> lx  = get_local_id(<span class=\"dv\">0</span>);\r\n    <span class=\"dt\">int</span> ly  = get_local_id(<span class=\"dv\">1</span>);\r\n    <span class=\"dt\">int</span> off = im_width*im_height;\r\n    <span class=\"dt\">int</span> inIdx= gy*im_width+gx;\r\n    <span class=\"dt\">int</span> uvIdx= off + (gy/<span class=\"dv\">2</span>)*im_width + (gx &amp; ~<span class=\"dv\">1</span>);   <span class=\"co\">// took me a while to figure out this formula</span>\r\n    <span class=\"dt\">int</span> shlx = lx/<span class=\"dv\">2</span>;\r\n    <span class=\"dt\">int</span> shly = ly/<span class=\"dv\">2</span>;\r\n    <span class=\"dt\">int</span> shIdx= <span class=\"dv\">2</span>*(shlx+shly*DSHRD_LEN);\r\n    <span class=\"kw\">if</span>( gx%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> &amp;&amp; gy%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> ) {\r\n        uvShrd[shIdx<span class=\"dv\">+0</span>] = in[uvIdx<span class=\"dv\">+0</span>];\r\n        uvShrd[shIdx<span class=\"dv\">+1</span>] = in[uvIdx<span class=\"dv\">+1</span>];\r\n    }\r\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\r\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\r\n    <span class=\"kw\">if</span>( y &lt; <span class=\"dv\">16</span> ) y=<span class=\"dv\">16</span>;\r\n    barrier(CLK_LOCAL_MEM_FENCE);\r\n    <span class=\"co\">//..... rest of code that does color space conversion</span>\r\n}</code></pre>\r\nLaplacian kernel is pretty straightforward, read all eight neighbors pixel values using shared memory and compute the convolution result. You can find kernels source code <a href=\"https://github.com/arrayfire/androidcl/blob/master/assets/kernels.cl\">here</a>.\r\n<h4 id=\"auxilary-code\">Auxilary Code</h4>\r\nThe JNI native function declarations can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.h\">processor.h</a>. I have included couple of extra Android related headers which are required to read bitmap files and print debug messages from JNI routines. The C-string pointed by macro <code>app_name</code> can be used to prune the output of the command <code>adb logcat</code> to get only messages that are associated with our JNI routines. To do that, you need to pass the value of <code>app_name</code> to adb command as an option as shown below.\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">adb</span> logcat -s <span class=\"st\">\"JNIProcessor\"</span></code></pre>\r\nThis is quite useful when you are debugging problems that are related to accuracy of results.\r\n\r\nThe full source code for JNI native functions can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.cpp\">processor.cpp</a>. Following are brief descriptions of the Android/JNI functions I have used in this project.\r\n<ul>\r\n	<li><code>AndroidBitmap_getInfo</code> - provides details like width, height, stride, format.</li>\r\n	<li><code>AndroidBitmap_lockPixels</code> - gives us a pointer to the memory location of image data. Once lockPixels is called, it has to be followed by a unlockPixels at some point later in the code.</li>\r\n	<li><code>GetPrimitiveArrayCritical</code> - as the name suggets, this is some kind of performance critical call. Hence, we should take care that the code amid a GetPrimitiveArrayCritical call and the corresponding ReleasePrimitiveArrayCritical call doesn\'t stall execution for extended periods of time. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s Java documentation</a>, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical. So, just be careful when you use this function.</li>\r\n	<li><code>ReleasePrimitiveArrayCritical</code> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><code>AndroidBitmap_unlockPixels</code> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nListed below are some of the other auxilary functions that i needed to make the code look clean.\r\n<ul>\r\n	<li><code>throwJavaException</code> - convenience function used to throw Java exceptions from JNI routines.</li>\r\n	<li><code>cb</code> - callback function provided when OpenCL kernels are built. When you actually look at this, you might wonder why did i do this part alone using C-interface of OpenCL. I just wanted to try it out, hence it happened so.</li>\r\n	<li><code>Java_com_example_LiveFeatureActivity_compileKernels</code> - as you might have noticed, this is a JNI routine i used to compile the OpenCL kernels only once during the app start up.</li>\r\n</ul>\r\n<h3 id=\"build-on-linux\">Build (on Linux)</h3>\r\nAndroid-NDK provides a very useful tool <code>ndk-build</code> to build native code for Android.\r\n<ol>\r\n	<li>Clone the git repo <code>git clone https://github.com/arrayfire/androidcl</code></li>\r\n	<li><code>cd androidcl</code></li>\r\n	<li>Ensure android-ndk installed and environment variable <code>ANDROID_NDK</code> is pointing to ndk installation root.</li>\r\n	<li>Ensure environment variable <code>PATH</code> has the path <code>$ANDROID_NDK</code> appended to it.</li>\r\n	<li>Run <code>ndk-build</code> from project root.</li>\r\n	<li>If you have <code>eclipse</code> installed, then import the project from eclipse and build it as usually.</li>\r\n	<li>If you do not have eclipse or don\'t want to use it, then I assume you might already know about apache-ant tool. Run <code>ant debug</code></li>\r\n</ol>\r\n<h4 id=\"android.mk\">Android.mk</h4>\r\nThere are couple of things that you need to do to use OpenCL on Android apart from standard JNI makefile instructions.\r\n<ul>\r\n	<li>Ensure that you set <code>LOCAL_ARM_MODE</code> to <code>arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.</li>\r\n	<li>Ensure that the variable <code>LOCAL_CPPFLAGS</code> has been set to point to OpenCL headers.</li>\r\n	<li>Add <code>libOpenCL.so</code> dependency to <code>LOCAL_LDLIBS</code> variable.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk.\r\n\r\nNote: In case you want a static library, replace <code>include $(BUILD_SHARED_LIBRARY)</code> with <code>include $(BUILD_STATIC_LIBRARY)</code>.\r\n<h4 id=\"application.mk\">Application.mk</h4>\r\nThis file is not mandatory, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. In this project i have set <code>APP_STL</code> to <code>gnustl_static</code> to declare that i want to use the static version of gnustl. I have also set the Android API target version as 14 by setting <code>APP_PLATFORM</code> to <code>android-14</code>.\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk.\r\n<h3 id=\"app-installation\">App Installation</h3>\r\n<h4 id=\"ant-users\">ant-users</h4>\r\nFor installing the app in your mobile device do <code>ant debug install</code>. Should you choose to remove it after you are done playing with it, just do <code>ant debug uninstall</code>.\r\n<h4 id=\"eclipse-users\">eclipse-users</h4>\r\nRight click the project in workspace and click the menu item \"Run As -&gt; Android Application\".\r\n\r\nYou can see below the video of the app running live.\r\n\r\n[video width=\"1280\" height=\"720\" mp4=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/05/ocl_demo.mp4\"]Screen capture of the live app[/video]\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\nStay tuned for more exciting developments as we continue to add more examples of OpenCL on Andriod!','Getting started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-20 15:33:20','2014-05-20 15:33:20','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5627,6,'2014-05-20 15:33:58','2014-05-20 15:33:58','Mobile devices are carving their niche into the world of computing with more processing power day by day. GPUs on mobile devices have been around for a while, but using them for accelerating computation is still quite new. Until recently, the only way to access the GPU was through OpenGL. Around december 2008, Khronos released OpenCL, a generic API for accelerating non-graphics tasks. OpenCL enables us to take advantage of acceleration hardware. Since it is an open standard, many hardware vendors provide support on their devices. With the recent release of Adreno and Mali SDKs, you can now run OpenCL code on mobile GPUs.\r\n\r\nToday\'s post is going to be about how to do image processing on camera feed on Android devices using OpenCL. To successfully complete this tutorial, you need to have basic knowledge of how to write OpenCL kernels and native code for Android.\r\n<h3 id=\"opencl\">OpenCL</h3>\r\nTo use OpenCL on your mobile device\'s GPU, you must obtain the compatible libOpenCL.so library and the corresponding OpenCL headers.\r\n\r\nI initially thought I could just use the C++ OpenCL header available from Khronos website for development, however that didn\'t work. I faced compilation errors because of incompatible OpenGL headers. There are couple of ways to get the compatible headers. You can either use the <a href=\"https://github.com/arrayfire/androidcl/tree/master/jni/include\">headers</a> provided along with the example application or extract them from Adreno/Mali SDK. For Adreno SDK, you can find the headers at <code>&lt;Adreno_SDK&gt;/Development/Inc/CL</code>. For Mali SDK, you can find the headers at <code>&lt;MALI_SDK&gt;/include/CL</code>.\r\n\r\nFor newer devices such as Samsung Galaxy Note 3 and Samsung Galaxy S5, it is very likely the library is already present on the mobile device. My test device is a Note 3 for which i found the library under <code>/system/vendor/lib</code>. You can do <code>adb pull /system/vendor/lib/libOpenCL.so ./</code> to get the file to your desktop machine. In these kind of cases, you might be able to use the library out of the box without any issues. For any other scenario, please use the directions in following sections to get the library and make it work if available.\r\n<h4 id=\"adreno-gpu\">Adreno GPU</h4>\r\nIf you do not find the library on your device, check if your device has OpenCL support on the corresponding vendor\'s website. If your GPU does have OpenCL support, you might have to update your OS in order to get the recent updates. If you don\'t find the library even after OS update, you might want to email the vendor. However, if your GPU does not have OpenCL support, there isn\'t much we can do.\r\n\r\nIf you do find the library and can\'t use for some reason. Try to update your device drivers using the ones provided by Qualcomm. You can download them from <a href=\"https://developer.qualcomm.com/mobile-development/maximize-hardware/mobile-gaming-graphics-adreno/tools-and-resources\">here</a>. Ensure that you are downloading the Adreno driver but not the Adreno SDK. Follow the instructions in the package and update the drivers on your device. This should resolve any issues you have.\r\n<h4 id=\"mali-gpu\">Mali GPU</h4>\r\nDownload the SDK from <a href=\"http://malideveloper.arm.com/develop-for-mali/sdks/mali-opencl-sdk/\">here</a>. Follow the instructions in the package and build the shared library and copy it on to your device.\r\n<h4 id=\"kernels\">Kernels</h4>\r\nI needed to do two things to achieve my target.\r\n<ul>\r\n	<li>Convert frame data provided by Android camera from NV21 format to RGBA8888 format.</li>\r\n	<li>Run laplacian operator on the RGBA8888 image data.</li>\r\n</ul>\r\nGetting a grayscale image from NV21 format is cake walk, just read the first width*height bytes and you are done. As per the format of <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a>, for each 2x2 sub-matrix of pixels, there will be a pair (v,u). Since 4 pixels are reading same (v,u), i decided to use shared memory to reduce reading latency. The code below is the core of this conversion kernel, that is expected to speed up the conversion if compared to a pure C code.\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define BLK_SIZE    16</span>\r\n<span class=\"co\">//prefix D for decoding</span>\r\n<span class=\"ot\">#define DSHRD_LEN   (BLK_SIZE/2)</span>\r\n<span class=\"ot\">#define DSHRD_SIZE  (2*DSHRD_LEN*DSHRD_LEN)</span>\r\n<span class=\"co\">// ...</span>\r\n<span class=\"co\">// ..</span>\r\n<span class=\"co\">// kernel signature</span>\r\n{\r\n    __local uchar uvShrd[DSHRD_SIZE];\r\n    <span class=\"dt\">int</span> gx  = get_global_id(<span class=\"dv\">0</span>);\r\n    <span class=\"dt\">int</span> gy  = get_global_id(<span class=\"dv\">1</span>);\r\n    <span class=\"dt\">int</span> lx  = get_local_id(<span class=\"dv\">0</span>);\r\n    <span class=\"dt\">int</span> ly  = get_local_id(<span class=\"dv\">1</span>);\r\n    <span class=\"dt\">int</span> off = im_width*im_height;\r\n    <span class=\"dt\">int</span> inIdx= gy*im_width+gx;\r\n    <span class=\"dt\">int</span> uvIdx= off + (gy/<span class=\"dv\">2</span>)*im_width + (gx &amp; ~<span class=\"dv\">1</span>);   <span class=\"co\">// took me a while to figure out this formula</span>\r\n    <span class=\"dt\">int</span> shlx = lx/<span class=\"dv\">2</span>;\r\n    <span class=\"dt\">int</span> shly = ly/<span class=\"dv\">2</span>;\r\n    <span class=\"dt\">int</span> shIdx= <span class=\"dv\">2</span>*(shlx+shly*DSHRD_LEN);\r\n    <span class=\"kw\">if</span>( gx%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> &amp;&amp; gy%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> ) {\r\n        uvShrd[shIdx<span class=\"dv\">+0</span>] = in[uvIdx<span class=\"dv\">+0</span>];\r\n        uvShrd[shIdx<span class=\"dv\">+1</span>] = in[uvIdx<span class=\"dv\">+1</span>];\r\n    }\r\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\r\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\r\n    <span class=\"kw\">if</span>( y &lt; <span class=\"dv\">16</span> ) y=<span class=\"dv\">16</span>;\r\n    barrier(CLK_LOCAL_MEM_FENCE);\r\n    <span class=\"co\">//..... rest of code that does color space conversion</span>\r\n}</code></pre>\r\nLaplacian kernel is pretty straightforward, read all eight neighbors pixel values using shared memory and compute the convolution result. You can find kernels source code <a href=\"https://github.com/arrayfire/androidcl/blob/master/assets/kernels.cl\">here</a>.\r\n<h4 id=\"auxilary-code\">Auxilary Code</h4>\r\nThe JNI native function declarations can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.h\">processor.h</a>. I have included couple of extra Android related headers which are required to read bitmap files and print debug messages from JNI routines. The C-string pointed by macro <code>app_name</code> can be used to prune the output of the command <code>adb logcat</code> to get only messages that are associated with our JNI routines. To do that, you need to pass the value of <code>app_name</code> to adb command as an option as shown below.\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">adb</span> logcat -s <span class=\"st\">\"JNIProcessor\"</span></code></pre>\r\nThis is quite useful when you are debugging problems that are related to accuracy of results.\r\n\r\nThe full source code for JNI native functions can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.cpp\">processor.cpp</a>. Following are brief descriptions of the Android/JNI functions I have used in this project.\r\n<ul>\r\n	<li><code>AndroidBitmap_getInfo</code> - provides details like width, height, stride, format.</li>\r\n	<li><code>AndroidBitmap_lockPixels</code> - gives us a pointer to the memory location of image data. Once lockPixels is called, it has to be followed by a unlockPixels at some point later in the code.</li>\r\n	<li><code>GetPrimitiveArrayCritical</code> - as the name suggets, this is some kind of performance critical call. Hence, we should take care that the code amid a GetPrimitiveArrayCritical call and the corresponding ReleasePrimitiveArrayCritical call doesn\'t stall execution for extended periods of time. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s Java documentation</a>, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical. So, just be careful when you use this function.</li>\r\n	<li><code>ReleasePrimitiveArrayCritical</code> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><code>AndroidBitmap_unlockPixels</code> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nListed below are some of the other auxilary functions that i needed to make the code look clean.\r\n<ul>\r\n	<li><code>throwJavaException</code> - convenience function used to throw Java exceptions from JNI routines.</li>\r\n	<li><code>cb</code> - callback function provided when OpenCL kernels are built. When you actually look at this, you might wonder why did i do this part alone using C-interface of OpenCL. I just wanted to try it out, hence it happened so.</li>\r\n	<li><code>Java_com_example_LiveFeatureActivity_compileKernels</code> - as you might have noticed, this is a JNI routine i used to compile the OpenCL kernels only once during the app start up.</li>\r\n</ul>\r\n<h3 id=\"build-on-linux\">Build (on Linux)</h3>\r\nAndroid-NDK provides a very useful tool <code>ndk-build</code> to build native code for Android.\r\n<ol>\r\n	<li>Clone the git repo <code>git clone https://github.com/arrayfire/androidcl</code></li>\r\n	<li><code>cd androidcl</code></li>\r\n	<li>Ensure android-ndk installed and environment variable <code>ANDROID_NDK</code> is pointing to ndk installation root.</li>\r\n	<li>Ensure environment variable <code>PATH</code> has the path <code>$ANDROID_NDK</code> appended to it.</li>\r\n	<li>Run <code>ndk-build</code> from project root.</li>\r\n	<li>If you have <code>eclipse</code> installed, then import the project from eclipse and build it as usually.</li>\r\n	<li>If you do not have eclipse or don\'t want to use it, then I assume you might already know about apache-ant tool. Run <code>ant debug</code></li>\r\n</ol>\r\n<h4 id=\"android.mk\">Android.mk</h4>\r\nThere are couple of things that you need to do to use OpenCL on Android apart from standard JNI makefile instructions.\r\n<ul>\r\n	<li>Ensure that you set <code>LOCAL_ARM_MODE</code> to <code>arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.</li>\r\n	<li>Ensure that the variable <code>LOCAL_CPPFLAGS</code> has been set to point to OpenCL headers.</li>\r\n	<li>Add <code>libOpenCL.so</code> dependency to <code>LOCAL_LDLIBS</code> variable.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk.\r\n\r\nNote: In case you want a static library, replace <code>include $(BUILD_SHARED_LIBRARY)</code> with <code>include $(BUILD_STATIC_LIBRARY)</code>.\r\n<h4 id=\"application.mk\">Application.mk</h4>\r\nThis file is not mandatory, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. In this project i have set <code>APP_STL</code> to <code>gnustl_static</code> to declare that i want to use the static version of gnustl. I have also set the Android API target version as 14 by setting <code>APP_PLATFORM</code> to <code>android-14</code>.\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk.\r\n<h3 id=\"app-installation\">App Installation</h3>\r\n<h4 id=\"ant-users\">ant-users</h4>\r\nFor installing the app in your mobile device do <code>ant debug install</code>. Should you choose to remove it after you are done playing with it, just do <code>ant debug uninstall</code>.\r\n<h4 id=\"eclipse-users\">eclipse-users</h4>\r\nRight click the project in workspace and click the menu item \"Run As -&gt; Android Application\".\r\n\r\nYou can see below the video of the app running live.\r\n\r\n[video width=\"1280\" height=\"720\" mp4=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/05/ocl_demo.mp4\"]Screen capture of the live app[/video]\r\n\r\n&nbsp;\r\n\r\nStay tuned for more exciting developments as we continue to add more examples of OpenCL on Andriod!','Getting started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-20 15:33:58','2014-05-20 15:33:58','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5628,6,'2014-05-20 15:35:09','2014-05-20 15:35:09','Mobile devices are carving their niche into the world of computing with more processing power day by day. GPUs on mobile devices have been around for a while, but using them for accelerating computation is still quite new. Until recently, the only way to access the GPU was through OpenGL. Around december 2008, Khronos released OpenCL, a generic API for accelerating non-graphics tasks. OpenCL enables us to take advantage of acceleration hardware. Since it is an open standard, many hardware vendors provide support on their devices. With the recent release of Adreno and Mali SDKs, you can now run OpenCL code on mobile GPUs.\r\n\r\nToday\'s post is going to be about how to do image processing on camera feed on Android devices using OpenCL. To successfully complete this tutorial, you need to have basic knowledge of how to write OpenCL kernels and native code for Android.\r\n<h3 id=\"opencl\">OpenCL</h3>\r\nTo use OpenCL on your mobile device\'s GPU, you must obtain the compatible libOpenCL.so library and the corresponding OpenCL headers.\r\n\r\nI initially thought I could just use the C++ OpenCL header available from Khronos website for development, however that didn\'t work. I faced compilation errors because of incompatible OpenGL headers. There are couple of ways to get the compatible headers. You can either use the <a href=\"https://github.com/arrayfire/androidcl/tree/master/jni/include\">headers</a> provided along with the example application or extract them from Adreno/Mali SDK. For Adreno SDK, you can find the headers at <code>&lt;Adreno_SDK&gt;/Development/Inc/CL</code>. For Mali SDK, you can find the headers at <code>&lt;MALI_SDK&gt;/include/CL</code>.\r\n\r\nFor newer devices such as Samsung Galaxy Note 3 and Samsung Galaxy S5, it is very likely the library is already present on the mobile device. My test device is a Note 3 for which i found the library under <code>/system/vendor/lib</code>. You can do <code>adb pull /system/vendor/lib/libOpenCL.so ./</code> to get the file to your desktop machine. In these kind of cases, you might be able to use the library out of the box without any issues. For any other scenario, please use the directions in following sections to get the library and make it work if available.\r\n<h4 id=\"adreno-gpu\">Adreno GPU</h4>\r\nIf you do not find the library on your device, check if your device has OpenCL support on the corresponding vendor\'s website. If your GPU does have OpenCL support, you might have to update your OS in order to get the recent updates. If you don\'t find the library even after OS update, you might want to email the vendor. However, if your GPU does not have OpenCL support, there isn\'t much we can do.\r\n\r\nIf you do find the library and can\'t use for some reason. Try to update your device drivers using the ones provided by Qualcomm. You can download them from <a href=\"https://developer.qualcomm.com/mobile-development/maximize-hardware/mobile-gaming-graphics-adreno/tools-and-resources\">here</a>. Ensure that you are downloading the Adreno driver but not the Adreno SDK. Follow the instructions in the package and update the drivers on your device. This should resolve any issues you have.\r\n<h4 id=\"mali-gpu\">Mali GPU</h4>\r\nDownload the SDK from <a href=\"http://malideveloper.arm.com/develop-for-mali/sdks/mali-opencl-sdk/\">here</a>. Follow the instructions in the package and build the shared library and copy it on to your device.\r\n<h4 id=\"kernels\">Kernels</h4>\r\nI needed to do two things to achieve my target.\r\n<ul>\r\n	<li>Convert frame data provided by Android camera from NV21 format to RGBA8888 format.</li>\r\n	<li>Run laplacian operator on the RGBA8888 image data.</li>\r\n</ul>\r\nGetting a grayscale image from NV21 format is cake walk, just read the first width*height bytes and you are done. As per the format of <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a>, for each 2x2 sub-matrix of pixels, there will be a pair (v,u). Since 4 pixels are reading same (v,u), i decided to use shared memory to reduce reading latency. The code below is the core of this conversion kernel, that is expected to speed up the conversion if compared to a pure C code.\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define BLK_SIZE    16</span>\r\n<span class=\"co\">//prefix D for decoding</span>\r\n<span class=\"ot\">#define DSHRD_LEN   (BLK_SIZE/2)</span>\r\n<span class=\"ot\">#define DSHRD_SIZE  (2*DSHRD_LEN*DSHRD_LEN)</span>\r\n<span class=\"co\">// ...</span>\r\n<span class=\"co\">// ..</span>\r\n<span class=\"co\">// kernel signature</span>\r\n{\r\n    __local uchar uvShrd[DSHRD_SIZE];\r\n    <span class=\"dt\">int</span> gx  = get_global_id(<span class=\"dv\">0</span>);\r\n    <span class=\"dt\">int</span> gy  = get_global_id(<span class=\"dv\">1</span>);\r\n    <span class=\"dt\">int</span> lx  = get_local_id(<span class=\"dv\">0</span>);\r\n    <span class=\"dt\">int</span> ly  = get_local_id(<span class=\"dv\">1</span>);\r\n    <span class=\"dt\">int</span> off = im_width*im_height;\r\n    <span class=\"dt\">int</span> inIdx= gy*im_width+gx;\r\n    <span class=\"dt\">int</span> uvIdx= off + (gy/<span class=\"dv\">2</span>)*im_width + (gx &amp; ~<span class=\"dv\">1</span>);   <span class=\"co\">// took me a while to figure out this formula</span>\r\n    <span class=\"dt\">int</span> shlx = lx/<span class=\"dv\">2</span>;\r\n    <span class=\"dt\">int</span> shly = ly/<span class=\"dv\">2</span>;\r\n    <span class=\"dt\">int</span> shIdx= <span class=\"dv\">2</span>*(shlx+shly*DSHRD_LEN);\r\n    <span class=\"kw\">if</span>( gx%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> &amp;&amp; gy%<span class=\"dv\">2</span>==<span class=\"dv\">0</span> ) {\r\n        uvShrd[shIdx<span class=\"dv\">+0</span>] = in[uvIdx<span class=\"dv\">+0</span>];\r\n        uvShrd[shIdx<span class=\"dv\">+1</span>] = in[uvIdx<span class=\"dv\">+1</span>];\r\n    }\r\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\r\n    <span class=\"dt\">int</span> y   = (<span class=\"bn\">0xFF</span> &amp; ((<span class=\"dt\">int</span>)in[inIdx]));\r\n    <span class=\"kw\">if</span>( y &lt; <span class=\"dv\">16</span> ) y=<span class=\"dv\">16</span>;\r\n    barrier(CLK_LOCAL_MEM_FENCE);\r\n    <span class=\"co\">//..... rest of code that does color space conversion</span>\r\n}</code></pre>\r\nLaplacian kernel is pretty straightforward, read all eight neighbors pixel values using shared memory and compute the convolution result. You can find kernels source code <a href=\"https://github.com/arrayfire/androidcl/blob/master/assets/kernels.cl\">here</a>.\r\n<h4 id=\"auxilary-code\">Auxilary Code</h4>\r\nThe JNI native function declarations can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.h\">processor.h</a>. I have included couple of extra Android related headers which are required to read bitmap files and print debug messages from JNI routines. The C-string pointed by macro <code>app_name</code> can be used to prune the output of the command <code>adb logcat</code> to get only messages that are associated with our JNI routines. To do that, you need to pass the value of <code>app_name</code> to adb command as an option as shown below.\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">adb</span> logcat -s <span class=\"st\">\"JNIProcessor\"</span></code></pre>\r\nThis is quite useful when you are debugging problems that are related to accuracy of results.\r\n\r\nThe full source code for JNI native functions can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.cpp\">processor.cpp</a>. Following are brief descriptions of the Android/JNI functions I have used in this project.\r\n<ul>\r\n	<li><code>AndroidBitmap_getInfo</code> - provides details like width, height, stride, format.</li>\r\n	<li><code>AndroidBitmap_lockPixels</code> - gives us a pointer to the memory location of image data. Once lockPixels is called, it has to be followed by a unlockPixels at some point later in the code.</li>\r\n	<li><code>GetPrimitiveArrayCritical</code> - as the name suggets, this is some kind of performance critical call. Hence, we should take care that the code amid a GetPrimitiveArrayCritical call and the corresponding ReleasePrimitiveArrayCritical call doesn\'t stall execution for extended periods of time. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s Java documentation</a>, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical. So, just be careful when you use this function.</li>\r\n	<li><code>ReleasePrimitiveArrayCritical</code> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><code>AndroidBitmap_unlockPixels</code> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nListed below are some of the other auxilary functions that i needed to make the code look clean.\r\n<ul>\r\n	<li><code>throwJavaException</code> - convenience function used to throw Java exceptions from JNI routines.</li>\r\n	<li><code>cb</code> - callback function provided when OpenCL kernels are built. When you actually look at this, you might wonder why did i do this part alone using C-interface of OpenCL. I just wanted to try it out, hence it happened so.</li>\r\n	<li><code>Java_com_example_LiveFeatureActivity_compileKernels</code> - as you might have noticed, this is a JNI routine i used to compile the OpenCL kernels only once during the app start up.</li>\r\n</ul>\r\n<h3 id=\"build-on-linux\">Build (on Linux)</h3>\r\nAndroid-NDK provides a very useful tool <code>ndk-build</code> to build native code for Android.\r\n<ol>\r\n	<li>Clone the git repo <code>git clone https://github.com/arrayfire/androidcl</code></li>\r\n	<li><code>cd androidcl</code></li>\r\n	<li>Ensure android-ndk installed and environment variable <code>ANDROID_NDK</code> is pointing to ndk installation root.</li>\r\n	<li>Ensure environment variable <code>PATH</code> has the path <code>$ANDROID_NDK</code> appended to it.</li>\r\n	<li>Run <code>ndk-build</code> from project root.</li>\r\n	<li>If you have <code>eclipse</code> installed, then import the project from eclipse and build it as usually.</li>\r\n	<li>If you do not have eclipse or don\'t want to use it, then I assume you might already know about apache-ant tool. Run <code>ant debug</code></li>\r\n</ol>\r\n<h4 id=\"android.mk\">Android.mk</h4>\r\nThere are couple of things that you need to do to use OpenCL on Android apart from standard JNI makefile instructions.\r\n<ul>\r\n	<li>Ensure that you set <code>LOCAL_ARM_MODE</code> to <code>arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.</li>\r\n	<li>Ensure that the variable <code>LOCAL_CPPFLAGS</code> has been set to point to OpenCL headers.</li>\r\n	<li>Add <code>libOpenCL.so</code> dependency to <code>LOCAL_LDLIBS</code> variable.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk.\r\n\r\nNote: In case you want a static library, replace <code>include $(BUILD_SHARED_LIBRARY)</code> with <code>include $(BUILD_STATIC_LIBRARY)</code>.\r\n<h4 id=\"application.mk\">Application.mk</h4>\r\nThis file is not mandatory, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. In this project i have set <code>APP_STL</code> to <code>gnustl_static</code> to declare that i want to use the static version of gnustl. I have also set the Android API target version as 14 by setting <code>APP_PLATFORM</code> to <code>android-14</code>.\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk.\r\n<h3 id=\"app-installation\">App Installation</h3>\r\n<h4 id=\"ant-users\">ant-users</h4>\r\nFor installing the app in your mobile device do <code>ant debug install</code>. Should you choose to remove it after you are done playing with it, just do <code>ant debug uninstall</code>.\r\n<h4 id=\"eclipse-users\">eclipse-users</h4>\r\nRight click the project in workspace and click the menu item \"Run As -&gt; Android Application\".\r\n\r\nYou can see below the video of the app running live.\r\n\r\n[video width=\"1280\" height=\"720\" mp4=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/05/ocl_demo.mp4\"]Screen capture of the live app[/video]\r\n\r\n&nbsp;\r\n\r\nStay tuned for more exciting developments as we continue to add more examples of OpenCL on Andriod!','Getting Started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-20 15:35:09','2014-05-20 15:35:09','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5629,17796,'2014-05-21 18:14:42','2014-05-21 18:14:42','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we ended up presenting a second! In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session:  <a href=\"http://bit.ly/SkzIJs\">http://bit.ly/SkzIJs</a>\r\n\r\n<iframe src=\"//www.youtube.com/embed/ZQVzXaOWSZ0?list=UUMY2gvcox1rppnikFnjSDDA&amp;start=35\" width=\"640\" height=\"360\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"></iframe>\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the webinar we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\nWe hope you enjoyed the webinar. Contact us at <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!','In Case you Missed it: ArrayFire Joint Webinar with AMD','','publish','open','closed','','arrayfire-amd-webinar','','','2014-05-21 22:18:03','2014-05-21 22:18:03','',0,'http://sandbox.arrayfire.com/?p=5629',0,'post','',0),(5630,17796,'2014-05-21 16:52:22','2014-05-21 16:52:22','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session. (embed video):  <a href=\"http://bit.ly/1obT0M2\">http://bit.ly/1obT0M2</a>\r\n\r\n&nbsp;\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us sales@arrayfire.com with any questions, we’re here to help!\r\n\r\n&nbsp;\r\n\r\n&nbsp;','','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 16:52:22','2014-05-21 16:52:22','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5631,17796,'2014-05-21 16:53:21','2014-05-21 16:53:21','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session. (embed video):  <a href=\"http://bit.ly/1obT0M2\">http://bit.ly/1obT0M2</a>\r\n\r\nhttps://www.youtube.com/watch?v=ZQVzXaOWSZ0&amp;list=UUMY2gvcox1rppnikFnjSDDA\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us sales@arrayfire.com with any questions, we’re here to help!\r\n\r\n&nbsp;\r\n\r\n&nbsp;','','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 16:53:21','2014-05-21 16:53:21','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5632,17796,'2014-05-21 16:55:29','2014-05-21 16:55:29','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session. (embed video):  <a href=\"http://bit.ly/1obT0M2\">http://bit.ly/1obT0M2</a>\r\n\r\nhttps://www.youtube.com/watch?v=ZQVzXaOWSZ0&amp;list=UUMY2gvcox1rppnikFnjSDDA\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us <a href=\"http://sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!\r\n\r\n&nbsp;','','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 16:55:29','2014-05-21 16:55:29','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5633,17796,'2014-05-21 16:58:43','2014-05-21 16:58:43','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session. (embed video):  <a href=\"http://bit.ly/1obT0M2\">http://bit.ly/1obT0M2</a>\r\n\r\nhttps://www.youtube.com/watch?v=ZQVzXaOWSZ0&amp;list=UUMY2gvcox1rppnikFnjSDDA\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us \"sales@arrayfire.com<span style=\"text-decoration: underline;\">\"</span> with any questions, we’re here to help!\r\n\r\n&nbsp;','','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 16:58:43','2014-05-21 16:58:43','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5634,17796,'2014-05-21 16:59:26','2014-05-21 16:59:26','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session. (embed video):  <a href=\"http://bit.ly/1obT0M2\">http://bit.ly/1obT0M2</a>\r\n\r\nhttps://www.youtube.com/watch?v=ZQVzXaOWSZ0&amp;list=UUMY2gvcox1rppnikFnjSDDA\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us &lt;sales@arrayfire.com<span style=\"text-decoration: underline;\">&gt;</span> with any questions, we’re here to help!\r\n\r\n&nbsp;','','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 16:59:26','2014-05-21 16:59:26','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5635,17796,'2014-05-21 17:10:55','2014-05-21 17:10:55','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session. (embed video):  <a href=\"http://bit.ly/1obT0M2\">http://bit.ly/1obT0M2</a>\r\n\r\nhttps://www.youtube.com/watch?v=ZQVzXaOWSZ0&amp;list=UUMY2gvcox1rppnikFnjSDDA\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us sales@arrayfire.com with any questions, we’re here to help!\r\n\r\n&nbsp;\r\n\r\n<address>\r\n<a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a>.<br> \r\n\r\n</address>','','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 17:10:55','2014-05-21 17:10:55','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5636,17796,'2014-05-21 17:12:12','2014-05-21 17:12:12','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session. (embed video):  <a href=\"http://bit.ly/1obT0M2\">http://bit.ly/1obT0M2</a>\r\n\r\nhttps://www.youtube.com/watch?v=ZQVzXaOWSZ0&amp;list=UUMY2gvcox1rppnikFnjSDDA\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us \r\n<address>\r\n<a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a>.<br> \r\n</address>\r\nwith any questions, we’re here to help!\r\n&nbsp;\r\n','','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 17:12:12','2014-05-21 17:12:12','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5637,17796,'2014-05-21 17:12:45','2014-05-21 17:12:45','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session. (embed video):  <a href=\"http://bit.ly/1obT0M2\">http://bit.ly/1obT0M2</a>\r\n\r\nhttps://www.youtube.com/watch?v=ZQVzXaOWSZ0&amp;list=UUMY2gvcox1rppnikFnjSDDA\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!\r\n\r\n&nbsp;','','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 17:12:45','2014-05-21 17:12:45','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5638,17796,'2014-05-21 18:14:37','2014-05-21 18:14:37','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session. (embed video):  <a href=\"http://bit.ly/1obT0M2\">http://bit.ly/1obT0M2</a>\r\n\r\nhttps://www.youtube.com/watch?v=ZQVzXaOWSZ0&amp;list=UUMY2gvcox1rppnikFnjSDDA\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!\r\n\r\n&nbsp;','ArrayFire-AMD Webinar','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 18:14:37','2014-05-21 18:14:37','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5639,17796,'2014-05-21 22:17:43','2014-05-21 22:17:43','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we ended up presenting a second! In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session:  <a href=\"http://bit.ly/SkzIJs\">http://bit.ly/SkzIJs</a>\r\n\r\n<iframe src=\"//www.youtube.com/embed/ZQVzXaOWSZ0?list=UUMY2gvcox1rppnikFnjSDDA&amp;start=35\" width=\"640\" height=\"360\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"></iframe>\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the webinar we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\nWe hope you enjoyed the webinar. Contact us at <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!','In Case you Missed it: ArrayFire Joint Webinar with AMD','','inherit','open','closed','','5629-autosave-v1','','','2014-05-21 22:17:43','2014-05-21 22:17:43','',5629,'http://sandbox.arrayfire.com/5629-autosave-v1/',0,'revision','',0),(5640,17796,'2014-05-21 21:18:10','2014-05-21 21:18:10','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session:  <a href=\"http://bit.ly/1obT0M2\">http://bit.ly/1obT0M2</a>\r\n\r\nhttp://youtu.be/ZQVzXaOWSZ0\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!\r\n\r\n&nbsp;','ArrayFire-AMD Webinar','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 21:18:10','2014-05-21 21:18:10','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5641,7,'2014-05-21 21:29:24','2014-05-21 21:29:24','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session:  <a href=\"http://bit.ly/SkzIJs\">http://bit.ly/SkzIJs</a>\r\n\r\n<iframe width=\"640\" height=\"360\" src=\"//www.youtube.com/embed/ZQVzXaOWSZ0?list=UUMY2gvcox1rppnikFnjSDDA&start=35\" frameborder=\"0\" allowfullscreen></iframe>\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!\r\n\r\n&nbsp;','ArrayFire-AMD Webinar','','inherit','open','closed','','5629-autosave-v1','','','2014-05-21 21:29:24','2014-05-21 21:29:24','',5629,'http://sandbox.arrayfire.com/5629-autosave-v1/',0,'revision','',0),(5642,7,'2014-05-21 21:28:29','2014-05-21 21:28:29','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session:  <a href=\"http://bit.ly/SkzIJs\">http://bit.ly/SkzIJs</a>\r\n\r\n<iframe width=\"640\" height=\"360\" src=\"//www.youtube.com/embed/ZQVzXaOWSZ0?list=UUMY2gvcox1rppnikFnjSDDAstart=35\" frameborder=\"0\" allowfullscreen></iframe>\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!\r\n\r\n&nbsp;','ArrayFire-AMD Webinar','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 21:28:29','2014-05-21 21:28:29','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5643,7,'2014-05-21 21:29:34','2014-05-21 21:29:34','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session:  <a href=\"http://bit.ly/SkzIJs\">http://bit.ly/SkzIJs</a>\r\n\r\n<iframe width=\"640\" height=\"360\" src=\"//www.youtube.com/embed/ZQVzXaOWSZ0?list=UUMY2gvcox1rppnikFnjSDDA&start=35\" frameborder=\"0\" allowfullscreen></iframe>\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\n&nbsp;\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\n&nbsp;\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\n&nbsp;\r\n\r\nWe hope you enjoyed the webinar. Contact us <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!\r\n\r\n&nbsp;','ArrayFire-AMD Webinar','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 21:29:34','2014-05-21 21:29:34','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5644,6,'2014-05-21 21:44:28','2014-05-21 21:44:28','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we ended up presenting a second! In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session:  <a href=\"http://bit.ly/SkzIJs\">http://bit.ly/SkzIJs</a>\n\n<iframe src=\"//www.youtube.com/embed/ZQVzXaOWSZ0?list=UUMY2gvcox1rppnikFnjSDDA&amp;start=35\" width=\"640\" height=\"360\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"></iframe>\n\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\n\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\n\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\n\nWe hope you enjoyed the webinar. Contact us at <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!','In Case you Missed it: ArrayFire Joint Webinar with AMD','','inherit','open','closed','','5629-autosave-v1','','','2014-05-21 21:44:28','2014-05-21 21:44:28','',5629,'http://sandbox.arrayfire.com/5629-autosave-v1/',0,'revision','',0),(5645,6,'2014-05-21 21:34:06','2014-05-21 21:34:06','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we we ended up presenting a second. In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session:  <a href=\"http://bit.ly/SkzIJs\">http://bit.ly/SkzIJs</a>\r\n\r\n<iframe src=\"//www.youtube.com/embed/ZQVzXaOWSZ0?list=UUMY2gvcox1rppnikFnjSDDA&amp;start=35\" width=\"640\" height=\"360\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"></iframe>\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\nWe hope you enjoyed the webinar. Contact us at <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!','In Case you Missed it: ArrayFire Joint Webinar with AMD','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 21:34:06','2014-05-21 21:34:06','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5646,6,'2014-05-21 21:39:09','2014-05-21 21:39:09','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we ended up presenting a second! In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session:  <a href=\"http://bit.ly/SkzIJs\">http://bit.ly/SkzIJs</a>\r\n\r\n<iframe src=\"//www.youtube.com/embed/ZQVzXaOWSZ0?list=UUMY2gvcox1rppnikFnjSDDA&amp;start=35\" width=\"640\" height=\"360\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"></iframe>\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the talk, we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how  difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\nWe hope you enjoyed the webinar. Contact us at <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!','In Case you Missed it: ArrayFire Joint Webinar with AMD','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 21:39:09','2014-05-21 21:39:09','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5647,6,'2014-05-21 21:45:00','2014-05-21 21:45:00','ArrayFire recently gave two webinar presentations to OpenCL developers as part of a joint webinar series with AMD. Due to popular demand for the first webinar, we ended up presenting a second! In case you missed it, here’s a recording of the webinar complete with the presentation and an informative Q&amp;A session:  <a href=\"http://bit.ly/SkzIJs\">http://bit.ly/SkzIJs</a>\r\n\r\n<iframe src=\"//www.youtube.com/embed/ZQVzXaOWSZ0?list=UUMY2gvcox1rppnikFnjSDDA&amp;start=35\" width=\"640\" height=\"360\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"></iframe>\r\n\r\nThis webinar focused on enhancing productivity by using existing OpenCL libraries while achieving a high level of performance and maximizing system utilization. We demonstrated how our ArrayFire software library offers simple GPU programming with the benefit of awesome performance. In the webinar we showed how to use several image processing and computer vision building blocks in less than 3 lines of code.  The immediate takeaway message of these examples is that ArrayFire offers a large number of highly optimized building blocks. And because ArrayFire fully supports OpenCL, that high level of performance is portable to any OpenCL supported device. This means you only have to write the code once and then you can run it everywhere OpenCL is supported.\r\n\r\nThe Q&amp;A session of the webinar had lots of fantastic questions! Many of them focused on performance and capabilities of ArrayFire and OpenCL. The least technical question asked how difficult it would be for a life-science PhD to enter the GPU arena (if it at all feasible). As a person who worked in social network analysis for several years, I responded saying that it is very feasible for a life-science student or any other student to do GPU computing - high level or low level. The high level programming includes the use of existing GPU libraries, including ArrayFire. Typically this requires domain expertise. The low level programming would be the creation of GPU libraries. The latter requires more than just domain expertise, it requires computational expertise. As the number of applications benefiting from the usage of GPUs increases, it is crucial that domain experts and computational experts meet up: 1) Find the right set of building blocks needed by the community, and 2) implement those building blocks as best as possible with an understanding of the real-world requirement of the applications.\r\n\r\nAt ArrayFire, we are constantly on the lookout for people who: 1) know what challenging problems are out there, and 2) have the skills to solve those problems. This allows us to greatly extend the capabilities of our software library.\r\n\r\nWe hope you enjoyed the webinar. Contact us at <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a> with any questions, we’re here to help!','In Case you Missed it: ArrayFire Joint Webinar with AMD','','inherit','open','closed','','5629-revision-v1','','','2014-05-21 21:45:00','2014-05-21 21:45:00','',5629,'http://sandbox.arrayfire.com/5629-revision-v1/',0,'revision','',0),(5651,17728,'2014-05-27 18:05:35','2014-05-27 18:05:35','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong><a href=\"#note1\"><sup>1</sup></a>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + cos(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(af::abs(y - 1));\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated. Since ArrayFire uses its own context internally, you need to get the context from a memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nThe code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>\r\n\r\n<sup><a id=\"note1\">1 </a><strong>af::sync() is not needed if you are not using streams in CUDA. af::sync() ensures you are not unintentionally doing out of order executions. af::sync() is always required when writing OpenCL kernels.</strong></sup>','Custom Kernels with ArrayFire','','publish','open','closed','','custom-kernels-with-arrayfire','','','2014-05-27 19:52:25','2014-05-27 19:52:25','',0,'http://sandbox.arrayfire.com/?p=5651',0,'post','',0),(5652,17728,'2014-05-23 19:59:59','2014-05-23 19:59:59','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep around the old implementation for testing purposes. In this post we are going to talk about how you can integrate your custom kernels into ArrayFire in a seamless fashion.\r\n\r\nFirst let us look at the code and then break it down bit by bit.\r\n\r\n&nbsp;','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-23 19:59:59','2014-05-23 19:59:59','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5653,17728,'2014-05-23 20:05:43','2014-05-23 20:05:43','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep around the old implementation for testing purposes. In this post we are going to talk about how you can integrate your custom kernels into ArrayFire in a seamless fashion.\r\n\r\nFirst let us look at the code and then break it down bit by bit.\r\n\r\n<code>\r\nint main()\r\n{\r\n    // Generate input data\r\n    af::array x = af::randu(num, 1);\r\n\r\n    // Create empty array with required dimensions\r\n    af::array y = af::array(num, 1);\r\n\r\n    // Get device pointers\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    // Finish the tasks arrayfire was doing\r\n    af::sync();\r\n\r\n    // Launch kernel to do the following operations\r\n    // y = sin(x)^2 + con(x)^2\r\n    launch_simple_kernel(d_y, d_x, num);\r\n\r\n    // Tell arrayfire it controls the pointers again\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    // Check for errors\r\n    // sin(x)^ + cos(x)^2 == 1\r\n    // The following should print 0\r\n    float err = af::sum<float>(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n\r\n    return 0;\r\n}\r\n</code>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-23 20:05:43','2014-05-23 20:05:43','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5654,17728,'2014-05-23 20:07:37','2014-05-23 20:07:37','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep around the old implementation for testing purposes. In this post we are going to talk about how you can integrate your custom kernels into ArrayFire in a seamless fashion.\r\n\r\nFirst let us look at the code and then break it down bit by bit.\r\n\r\n<pre>\r\nint main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum<float>(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-23 20:07:37','2014-05-23 20:07:37','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5655,17728,'2014-05-23 20:22:19','2014-05-23 20:22:19','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep around the old implementation for testing purposes. In this post we are going to talk about how you can integrate your custom kernels into ArrayFire in a seamless fashion.\r\n\r\nFirst let us look at the code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device();\r\n    float *d_y = y.device();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nFirstly you need an input to the kernel. \r\n\r\n<pre>\r\n// Generate input data\r\naf::array x = af::randu(num, 1);\r\n</pre>\r\n\r\nIn this case, it is the variable <strong> x </strong> that has been created as a uniformly random array. If you have data coming from other computations, you can use that instead.\r\n\r\nThe necessary memory required for the output needs to be allocated before we launch the kernel. \r\n<pre>\r\n// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this sample, the output <string> y </strong> has the same number of elements as <strong> x </strong>. Note that we are not specifying the output data type. In such cases ArrayFire assumes the data type is single precision floating point (<strong> af::f32 </strong>). You can add the necessary data type at the end of the <strong> array(..)</strong> constructor.\r\n\r\nOnce you have the input and output arrays, you will need to extract the device pointers / objects using the following manner.\r\n<pre>\r\n // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\n\r\nBefore you launch your custom kernel, it would be best to make sure all the computations performed by ArrayFire have finished. This can be called by using <strong> af::sync(); </strong>\r\n<pre>\r\n// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\n\r\nThe function <strong> launch_simple_kernel </strong> will handle the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post.\r\n\r\nOnce you have finished your computations, you have to tell ArrayFire to take control of the memory objects. \r\n<pre>\r\n// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step because if ArrayFire believes the user still controls the pointer, it does not perform garbage collection on those arrays and will potentially lead to memory leaks.\r\n\r\nYou can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>\r\n// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum<float>(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-23 20:22:19','2014-05-23 20:22:19','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5656,17728,'2014-05-23 20:38:01','2014-05-23 20:38:01','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep around the old implementation for testing purposes. In this post we are going to talk about how you can integrate your custom kernels into ArrayFire in a seamless fashion.\r\n\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device();\r\n    float *d_y = y.device();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nFirstly you need an input to the kernel.\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);\r\n</pre>\r\nIn this case, it is the variable <strong> x </strong> that has been created as a uniformly random array. If you have data coming from other computations, you can use that instead.\r\n\r\nThe necessary memory required for the output needs to be allocated before we launch the kernel.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this sample, the output y has the same number of elements as <strong> x </strong>. Note that we are not specifying the output data type. In such cases ArrayFire assumes the data type is single precision floating point (<strong> af::f32 </strong>). You can add the necessary data type at the end of the <strong> array(..)</strong> constructor.\r\n\r\nOnce you have the input and output arrays, you will need to extract the device pointers / objects using the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device();\r\n float *d_y = y.device();\r\n</pre>\r\nBefore you launch your custom kernel, it would be best to make sure all the computations performed by ArrayFire have finished. This can be called by using <strong> af::sync(); </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong> will handle the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post.\r\n\r\nOnce you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step because if ArrayFire believes the user still controls the pointer, it does not perform garbage collection on those arrays and will potentially lead to memory leaks.\r\n\r\nYou can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\n\r\n<h3>Launching a CUDA kernel </h3>\r\n\r\nIf you are integrating a CUDA kernel into your ArrayFire code base, it is  a fairly straight forward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. You can see how to do that using a simple kernel below.\r\n\r\n<pre>\r\n__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n\r\n<h3>Launching an OpenCL kernel </h3>\r\n\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel bit more complicated.\r\n\r\n<pre>\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\n\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" title=\"OpenCL helper functions.\" target=\"_blank\">over here</a>\r\n\r\nThe OpenCL kernel itself is fairly simple as seen below.\r\n\r\n<pre>\r\n__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-23 20:38:01','2014-05-23 20:38:01','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5657,17728,'2014-05-23 20:45:36','2014-05-23 20:45:36','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep around the old implementation for testing purposes. In this post we are going to talk about how you can integrate your custom kernels into ArrayFire in a seamless fashion.\r\n\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device();\r\n    float *d_y = y.device();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nFirstly you need an input to the kernel.\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);\r\n</pre>\r\nIn this case, it is the variable <strong> x </strong> that has been created as a uniformly random array. If you have data coming from other computations, you can use that instead.\r\n\r\nThe necessary memory required for the output needs to be allocated before we launch the kernel.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this sample, the output y has the same number of elements as <strong> x </strong>. Note that we are not specifying the output data type. In such cases ArrayFire assumes the data type is single precision floating point (<strong> af::f32 </strong>). You can add the necessary data type at the end of the <strong> array(..)</strong> constructor.\r\n\r\nOnce you have the input and output arrays, you will need to extract the device pointers / objects using the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device();\r\n float *d_y = y.device();\r\n</pre>\r\nBefore you launch your custom kernel, it would be best to make sure all the computations performed by ArrayFire have finished. This can be called by using <strong> af::sync(); </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong> will handle the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post.\r\n\r\nOnce you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step because if ArrayFire believes the user still controls the pointer, it does not perform garbage collection on those arrays and will potentially lead to memory leaks.\r\n\r\nYou can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\n\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n\r\n<h3>Launching a CUDA kernel </h3>\r\n\r\nIf you are integrating a CUDA kernel into your ArrayFire code base, it is  a fairly straight forward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. You can see how to do that using a simple kernel below.\r\n\r\n<pre>\r\n__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n\r\n<h3>Launching an OpenCL kernel </h3>\r\n\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel bit more complicated.\r\n\r\n<pre>\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\n\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" title=\"OpenCL helper functions.\" target=\"_blank\">over here</a>\r\n\r\nThe OpenCL kernel itself is fairly simple as seen below.\r\n\r\n<pre>\r\n__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\n\r\nYou can find the code samples at the following links:\r\n	<li> <a href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" title=\"ArrayFire CUDA kernel example\" target=\"_blank\">CUDA</a>\r\n        <li> <a href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" title=\"ArrayFire OpenCL kernel example\" target=\"_blank\">OpenCL</a>\r\n ','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-23 20:45:36','2014-05-23 20:45:36','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5659,17795,'2014-05-30 12:00:59','2014-05-30 12:00:59','In the upcoming months we\'ll be adding a lot of new Computer Vision functionality to ArrayFire, specifically targeting the most commonly used applications in this field. New functions include feature tracking, object classification, scene segmentation, optical flow, and stereo-vision.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features; normally they are corners or blobs of an object.</li>\r\n	<li>Extracting a descriptor for each feature—understanding the texture of a small patch around each feature.</li>\r\n	<li>Descriptor matching—finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\n<h3>Harris corner detector</h3>\r\nIn this article we will be using ArrayFire to dive deeper into the first step of feature tracking: detecting good features. Through a step-by-step guide we will develop a simple corner detector, known as the Harris corner detector [1].\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations; all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n<h5>Loading an image</h5>\r\nBefore writing the code for the corner detector, we need to load an image. The image can be either color or grayscale, but it will only work on the grayscale version; if we upload a color image, we have to convert it before proceeding.\r\n<pre>// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg_color /= 255.f;\r\n</pre>\r\n<h5>Compute first-order derivatives</h5>\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the kernel (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative. ArrayFire contains a function called <a href=\"http://www.accelereyes.com/arrayfire/c/group__math__func__cpp__grad.htm\">grad</a>, which calculates gradients in both directions and will perform faster than the two convolutions. The only difference  is that <a href=\"http://www.accelereyes.com/arrayfire/c/group__math__func__cpp__grad.htm\">grad</a> divides the result by 2, thus, the response factor will change. The use of grad will improve the performance, and factor change can be easily compensated by using a smaller response.\r\n<pre>// Calculate image gradients\r\narray ix, iy;\r\ngrad(ix, iy, img_gray);\r\n</pre>\r\n<h5>Compute second-order derivatives</h5>\r\nAt this point we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n<pre>// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\n<h5>Compute an isotropic window</h5>\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself. We must also check a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used. This can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n<pre>// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\n<h5>Compute trace and determinant</h5>\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n<pre>// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\n<h5>Compute Harris response</h5>\r\nNext, we calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, normally ranging from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result is affected.\r\n<pre>// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\n<h5>Selection of good corners</h5>\r\nNow we already have our Harris responses for each pixel in the image. This value is used to determine whether a pixel is a corner or not. The standard way is to perform a non-maximal suppression, meaning that each pixel can only be a corner if it is a maximum compared to its 8 adjacent pixels. At the moment we do not have a direct way to compute a non-maximal suppression with ArrayFire; we have to write our own kernel for that. Non-maximal suppression is  just one of the cool things we will be able to do with our new computer vision toolset for ArrayFire.\r\n\r\nAn alternative is to do the non-maximal suppression in a naive way. To do this, we will use ArrayFire\'s <a href=\"http://www.accelereyes.com/arrayfire/c/group__image__func__cpp__maxfilt.htm\">maxfilt</a> function, which filters the image with a mask of <code>NxM</code> pixel and returns the maximum value of the neighborhood to the pixel centered within the mask. In this case we will use a <code>3x3</code> pixel mask to return the maximum of the 8-neighborhood, including the central pixel itself.\r\n\r\nThe <a href=\"http://www.accelereyes.com/arrayfire/c/group__image__func__cpp__maxfilt.htm\">maxfilt</a> function alone will not perform a non-maximal suppression, but by combining the function with a few other steps we can get the proper responses.\r\n\r\nThe nature of a pixel can be determined by the Harris responses; a negative response means that a pixel corresponds to the segment of an edge. If the response is small but positive, it corresponds to a flat region. Only a large response corresponds to a corner. By thresholding the response array with the minimum desired Harris response, which, for our example, will be 10<sup>5</sup>, we can calculate a binary response array for which only pixels with a value greater than this threshold will be true. We then multiply it to the original response array to get a new array containing only responses greater that 10<sup>5</sup>.\r\n\r\nHere we will use a threshold of 10<sup>5</sup>. For the implementation presented in this article, we found that corners seem to be better for responses larger than 10<sup>4</sup>, but you can and should play with these values to see how it will affect the image you are working on.\r\n\r\nThe last step for this is testing whether each pixel is equal to the maximum Harris response of the neighborhood. If it is equal, then we keep it, else, the response is not a local maximum and we discard it.\r\n<pre>// Gets maximum response for each 3x3 neighborhood\r\narray max_resp = maxfilt(response, 3, 3);\r\n\r\n// Discard responses that are not greater than threshold\r\narray corners = response > 1e5f;\r\ncorners = corners * response;\r\n\r\n// Discard responses that are not equal to maximum neighborhood response,\r\n// scale them to original response value\r\ncorners = (corners == max_resp) * corners;\r\n</pre>\r\nIf you still think you want a non-maximal suppression kernel for yourself, you can write it instead of using the last piece of code above. If you have never written your own kernel to work with an ArrayFire array, check out the <a href=\"http://sandbox.arrayfire.com/custom-kernels-with-arrayfire/\">Custom Kernels with ArrayFire</a> post. Writing the non-maximal suppression kernel itself will not take more than 20 or 30 lines of code.\r\n<h5>Plotting corners</h5>\r\nThis last step is done on the <abbr title=\"Central Processing Unit\">CPU</abbr> side; we only do this to show the corners that are detected. This will most likely be unnecessary unless you want to visualize, but, for the sake of clarity, we will include this part to show the result.\r\n<pre>// Gets host pointer to response data\r\nfloat* h_corners = corners.host();\r\n\r\n// Draw draw_len x draw_len crosshairs where the corners are\r\nconst int draw_len = 3;\r\nfor (int y = draw_len; y < img_color.dims(0) - draw_len; y++) {\r\n    for (int x = draw_len; x < img_color.dims(1) - draw_len; x++) {\r\n        // Only draws crosshair if is a corner\r\n        if (h_corners[x * corners.dims(0) + y] > 1e5f) {\r\n            // Draw horizontal line of (draw_len * 2 + 1) pixels centered on the corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(y, seq(x-draw_len, x+draw_len), 0) = 0.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 1) = 1.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 2) = 0.f;\r\n\r\n            // Draw vertical line of (draw_len * 2 + 1) pixels centered on  the corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(seq(y-draw_len, y+draw_len), x, 0) = 0.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 1) = 1.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 2) = 0.f;\r\n        }\r\n    }\r\n}</pre>\r\n<h5>Visualize results</h5>\r\nFinally, the image can be visualized.\r\n<pre>// Previews color image with green crosshairs\r\nimage(img_color);\r\n</pre>\r\nBelow you can see Lena\'s picture after the Harris corner detection and plotting. The green crosshairs indicate where corners are.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena.png\"><img class=\"alignnone size-full wp-image-5710\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena.png\" alt=\"Harris Corners - Lena\" width=\"1024\" height=\"600\" /></a>\r\n\r\nTo test for correctness of the algorithm, nothing better than a picture with well-defined corners. Below you can see the picture of a white square on a black background and the corners marked by green crosshairs.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_square.png\"><img class=\"alignnone size-full wp-image-5711\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_square.png\" alt=\"Harris Corners - Square\" width=\"1024\" height=\"600\" /></a>\r\n\r\nAll sources to our examples can be found in our <a href=\"https://github.com/arrayfire/arrayfire_examples\">ArrayFire examples project</a> on GitHub, and the complete code for this article can be viewed via this direct <a href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/image_processing/harris_demo.cpp\">link</a>.\r\n\r\nWe would like to hear from you! What you are working on the computer vision field and what features would you like to see in ArrayFire? Please share your thoughts and requests below or contact us at <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a>.\r\n<h5>References</h5>\r\n[1] Harris, Chris, and Mike Stephens. \"A combined corner and edge detector.\" <em>Alvey vision conference</em>. Vol. 15. 1988.','Writing a Simple Corner Detector with ArrayFire','','publish','open','closed','','creating-a-simple-corner-detector-with-arrayfire','','','2014-06-20 02:26:19','2014-06-20 02:26:19','',0,'http://sandbox.arrayfire.com/?p=5659',0,'post','',2),(5660,17795,'2014-05-25 21:22:50','2014-05-25 21:22:50','','Creating a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-25 21:22:50','2014-05-25 21:22:50','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5662,17795,'2014-05-25 21:59:40','2014-05-25 21:59:40','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of most GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector.\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction.\r\n\r\n&nbsp;','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-25 21:59:40','2014-05-25 21:59:40','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5664,17729,'2014-08-12 16:08:50','2014-08-12 16:08:50','Mobile devices are carving their niche into the world of computing with more processing power day by day. GPUs on mobile devices have been around for a while, but using them for accelerating computation is still quite new. Until recently, the only way to access the GPU was through OpenGL. Around december 2008, Khronos released OpenCL, a generic API for accelerating non-graphics tasks. OpenCL enables us to take advantage of acceleration hardware. Since it is an open standard, many hardware vendors provide support on their devices. With the recent release of Adreno and Mali SDKs, you can now run OpenCL code on mobile GPUs.\r\n\r\nToday\'s post is going to be about how to do image processing on camera feed on Android devices using OpenCL. To successfully complete this tutorial, you need to have basic knowledge of how to write OpenCL kernels and native code for Android.\r\n<h3 id=\"opencl\">OpenCL</h3>\r\nTo use OpenCL on your mobile device\'s GPU, you must obtain the compatible libOpenCL.so library and the corresponding OpenCL headers.\r\n\r\nI initially thought I could just use the C++ OpenCL header available from Khronos website for development, however that didn\'t work. I faced compilation errors because of incompatible OpenGL headers. There are couple of ways to get the compatible headers. You can either use the <a href=\"https://github.com/arrayfire/androidcl/tree/master/jni/include\">headers</a> provided along with the example application or extract them from Adreno/Mali SDK. For Adreno SDK, you can find the headers at <code>&lt;Adreno_SDK&gt;/Development/Inc/CL</code>. For Mali SDK, you can find the headers at <code>&lt;MALI_SDK&gt;/include/CL</code>.\r\n\r\nFor newer devices such as Samsung Galaxy Note 3 and Samsung Galaxy S5, it is very likely the library is already present on the mobile device. My test device is a Note 3 for which i found the library under <code>/system/vendor/lib</code>. You can do <code>adb pull /system/vendor/lib/libOpenCL.so ./</code> to get the file to your desktop machine. In these kind of cases, you might be able to use the library out of the box without any issues. For any other scenario, please use the directions in following sections to get the library and make it work if available.\r\n<h4 id=\"adreno-gpu\">Adreno GPU</h4>\r\nIf you do not find the library on your device, check if your device has OpenCL support on the corresponding vendor\'s website. If your GPU does have OpenCL support, you might have to update your OS in order to get the recent updates. If you don\'t find the library even after OS update, you might want to email the vendor. However, if your GPU does not have OpenCL support, there isn\'t much we can do.\r\n\r\nIf you do find the library and can\'t use for some reason. Try to update your device drivers using the ones provided by Qualcomm. You can download them from <a href=\"https://developer.qualcomm.com/mobile-development/maximize-hardware/mobile-gaming-graphics-adreno/tools-and-resources\">here</a>. Ensure that you are downloading the Adreno driver but not the Adreno SDK. Follow the instructions in the package and update the drivers on your device. This should resolve any issues you have.\r\n<h4 id=\"mali-gpu\">Mali GPU</h4>\r\nDownload the SDK from <a href=\"http://malideveloper.arm.com/develop-for-mali/sdks/mali-opencl-sdk/\">here</a>. Follow the instructions in the package and build the shared library and copy it on to your device.\r\n<h4 id=\"kernels\">Kernels</h4>\r\nI needed to do two things to achieve my target.\r\n<ul>\r\n	<li>Convert frame data provided by Android camera from NV21 format to RGBA8888 format.</li>\r\n	<li>Run laplacian operator on the RGBA8888 image data.</li>\r\n</ul>\r\nGetting a grayscale image from NV21 format is cake walk, just read the first width*height bytes and you are done. As per the format of <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a>, for each 2x2 sub-matrix of pixels, there will be a pair (v,u). Since 4 pixels are reading same (v,u), i decided to use shared memory to reduce reading latency. The code below is the core of this conversion kernel, that is expected to speed up the conversion if compared to a pure C code.\r\n<pre>\r\n#define BLK_SIZE 16\r\n//prefix D for decoding\r\n#define DSHRD_LEN (BLK_SIZE/2)\r\n#define DSHRD_SIZE (2*DSHRD_LEN*DSHRD_LEN)\r\n// ...\r\n// ...\r\n// kernel signature\r\n{\r\n    __local uchar uvShrd[DSHRD_SIZE];\r\n    int gx = get_global_id(0);\r\n    int gy = get_global_id(1);\r\n    int lx = get_local_id(0);\r\n    int ly = get_local_id(1);\r\n    int off = im_width*im_height;\r\n    int inIdx= gy*im_width+gx;\r\n    int uvIdx= off + (gy/2)*im_width + (gx & ~1); // took me a while to figure out this formula\r\n    int shlx = lx/2;\r\n    int shly = ly/2;\r\n    int shIdx= 2*(shlx+shly*DSHRD_LEN);\r\n    if( gx%2==0 && gy%2==0 ) {\r\n        uvShrd[shIdx+0] = in[uvIdx+0];\r\n        uvShrd[shIdx+1] = in[uvIdx+1];\r\n    }\r\n    int y = (0xFF & ((int)in[inIdx]));\r\n    int y = (0xFF & ((int)in[inIdx]));\r\n    if( y < 16 ) y=16;\r\n    barrier(CLK_LOCAL_MEM_FENCE);\r\n    //..... rest of code that does color space conversion\r\n}\r\n</pre>\r\nLaplacian kernel is pretty straightforward, read all eight neighbors pixel values using shared memory and compute the convolution result. You can find kernels source code <a href=\"https://github.com/arrayfire/androidcl/blob/master/assets/kernels.cl\">here</a>.\r\n<h4 id=\"auxilary-code\">Auxilary Code</h4>\r\nThe JNI native function declarations can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.h\">processor.h</a>. I have included couple of extra Android related headers which are required to read bitmap files and print debug messages from JNI routines. The C-string pointed by macro <code>app_name</code> can be used to prune the output of the command <code>adb logcat</code> to get only messages that are associated with our JNI routines. To do that, you need to pass the value of <code>app_name</code> to adb command as an option as shown below.\r\n<pre>adb logcat -s \"JNIProcessor\"</pre>\r\nThis is quite useful when you are debugging problems that are related to accuracy of results.\r\n\r\nThe full source code for JNI native functions can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.cpp\">processor.cpp</a>. Following are brief descriptions of the Android/JNI functions I have used in this project.\r\n<ul>\r\n	<li><code>AndroidBitmap_getInfo</code> - provides details like width, height, stride, format.</li>\r\n	<li><code>AndroidBitmap_lockPixels</code> - gives us a pointer to the memory location of image data. Once lockPixels is called, it has to be followed by a unlockPixels at some point later in the code.</li>\r\n	<li><code>GetPrimitiveArrayCritical</code> - as the name suggets, this is some kind of performance critical call. Hence, we should take care that the code amid a GetPrimitiveArrayCritical call and the corresponding ReleasePrimitiveArrayCritical call doesn\'t stall execution for extended periods of time. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s Java documentation</a>, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical. So, just be careful when you use this function.</li>\r\n	<li><code>ReleasePrimitiveArrayCritical</code> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><code>AndroidBitmap_unlockPixels</code> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nListed below are some of the other auxilary functions that i needed to make the code look clean.\r\n<ul>\r\n	<li><code>throwJavaException</code> - convenience function used to throw Java exceptions from JNI routines.</li>\r\n	<li><code>cb</code> - callback function provided when OpenCL kernels are built. When you actually look at this, you might wonder why did i do this part alone using C-interface of OpenCL. I just wanted to try it out, hence it happened so.</li>\r\n	<li><code>Java_com_example_LiveFeatureActivity_compileKernels</code> - as you might have noticed, this is a JNI routine i used to compile the OpenCL kernels only once during the app start up.</li>\r\n</ul>\r\n<h3 id=\"build-on-linux\">Build (on Linux)</h3>\r\nAndroid-NDK provides a very useful tool <code>ndk-build</code> to build native code for Android.\r\n<ol>\r\n	<li>Clone the git repo <code>git clone https://github.com/arrayfire/androidcl</code></li>\r\n	<li><code>cd androidcl</code></li>\r\n	<li>Ensure android-ndk installed and environment variable <code>ANDROID_NDK</code> is pointing to ndk installation root.</li>\r\n	<li>Ensure environment variable <code>PATH</code> has the path <code>$ANDROID_NDK</code> appended to it.</li>\r\n	<li>Run <code>ndk-build</code> from project root.</li>\r\n	<li>If you have <code>eclipse</code> installed, then import the project from eclipse and build it as usually.</li>\r\n	<li>If you do not have eclipse or don\'t want to use it, then I assume you might already know about apache-ant tool. Run <code>ant debug</code></li>\r\n</ol>\r\n<h4 id=\"android.mk\">Android.mk</h4>\r\nThere are couple of things that you need to do to use OpenCL on Android apart from standard JNI makefile instructions.\r\n<ul>\r\n	<li>Ensure that you set <code>LOCAL_ARM_MODE</code> to <code>arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.</li>\r\n	<li>Ensure that the variable <code>LOCAL_CPPFLAGS</code> has been set to point to OpenCL headers.</li>\r\n	<li>Add <code>libOpenCL.so</code> dependency to <code>LOCAL_LDLIBS</code> variable.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk.\r\n\r\nNote: In case you want a static library, replace <code>include $(BUILD_SHARED_LIBRARY)</code> with <code>include $(BUILD_STATIC_LIBRARY)</code>.\r\n<h4 id=\"application.mk\">Application.mk</h4>\r\nThis file is not mandatory, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. In this project i have set <code>APP_STL</code> to <code>gnustl_static</code> to declare that i want to use the static version of gnustl. I have also set the Android API target version as 14 by setting <code>APP_PLATFORM</code> to <code>android-14</code>.\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk.\r\n<h3 id=\"app-installation\">App Installation</h3>\r\n<h4 id=\"ant-users\">ant-users</h4>\r\nFor installing the app in your mobile device do <code>ant debug install</code>. Should you choose to remove it after you are done playing with it, just do <code>ant debug uninstall</code>.\r\n<h4 id=\"eclipse-users\">eclipse-users</h4>\r\nRight click the project in workspace and click the menu item \"Run As -&gt; Android Application\".\r\n\r\nYou can see below the video of the app running live.\r\n\r\n[video width=\"1280\" height=\"720\" mp4=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/05/ocl_demo.mp4\"]Screen capture of the live app[/video]\r\n\r\n&nbsp;\r\n\r\nStay tuned for more exciting developments as we continue to add more examples of OpenCL on Andriod!','Getting Started with OpenCL on Android','','inherit','open','closed','','5574-autosave-v1','','','2014-08-12 16:08:50','2014-08-12 16:08:50','',5574,'http://sandbox.arrayfire.com/5574-autosave-v1/',0,'revision','',0),(5665,17729,'2014-05-25 23:36:42','2014-05-25 23:36:42','Mobile devices are carving their niche into the world of computing with more processing power day by day. GPUs on mobile devices have been around for a while, but using them for accelerating computation is still quite new. Until recently, the only way to access the GPU was through OpenGL. Around december 2008, Khronos released OpenCL, a generic API for accelerating non-graphics tasks. OpenCL enables us to take advantage of acceleration hardware. Since it is an open standard, many hardware vendors provide support on their devices. With the recent release of Adreno and Mali SDKs, you can now run OpenCL code on mobile GPUs.\r\n\r\nToday\'s post is going to be about how to do image processing on camera feed on Android devices using OpenCL. To successfully complete this tutorial, you need to have basic knowledge of how to write OpenCL kernels and native code for Android.\r\n<h3 id=\"opencl\">OpenCL</h3>\r\nTo use OpenCL on your mobile device\'s GPU, you must obtain the compatible libOpenCL.so library and the corresponding OpenCL headers.\r\n\r\nI initially thought I could just use the C++ OpenCL header available from Khronos website for development, however that didn\'t work. I faced compilation errors because of incompatible OpenGL headers. There are couple of ways to get the compatible headers. You can either use the <a href=\"https://github.com/arrayfire/androidcl/tree/master/jni/include\">headers</a> provided along with the example application or extract them from Adreno/Mali SDK. For Adreno SDK, you can find the headers at <code>&lt;Adreno_SDK&gt;/Development/Inc/CL</code>. For Mali SDK, you can find the headers at <code>&lt;MALI_SDK&gt;/include/CL</code>.\r\n\r\nFor newer devices such as Samsung Galaxy Note 3 and Samsung Galaxy S5, it is very likely the library is already present on the mobile device. My test device is a Note 3 for which i found the library under <code>/system/vendor/lib</code>. You can do <code>adb pull /system/vendor/lib/libOpenCL.so ./</code> to get the file to your desktop machine. In these kind of cases, you might be able to use the library out of the box without any issues. For any other scenario, please use the directions in following sections to get the library and make it work if available.\r\n<h4 id=\"adreno-gpu\">Adreno GPU</h4>\r\nIf you do not find the library on your device, check if your device has OpenCL support on the corresponding vendor\'s website. If your GPU does have OpenCL support, you might have to update your OS in order to get the recent updates. If you don\'t find the library even after OS update, you might want to email the vendor. However, if your GPU does not have OpenCL support, there isn\'t much we can do.\r\n\r\nIf you do find the library and can\'t use for some reason. Try to update your device drivers using the ones provided by Qualcomm. You can download them from <a href=\"https://developer.qualcomm.com/mobile-development/maximize-hardware/mobile-gaming-graphics-adreno/tools-and-resources\">here</a>. Ensure that you are downloading the Adreno driver but not the Adreno SDK. Follow the instructions in the package and update the drivers on your device. This should resolve any issues you have.\r\n<h4 id=\"mali-gpu\">Mali GPU</h4>\r\nDownload the SDK from <a href=\"http://malideveloper.arm.com/develop-for-mali/sdks/mali-opencl-sdk/\">here</a>. Follow the instructions in the package and build the shared library and copy it on to your device.\r\n<h4 id=\"kernels\">Kernels</h4>\r\nI needed to do two things to achieve my target.\r\n<ul>\r\n	<li>Convert frame data provided by Android camera from NV21 format to RGBA8888 format.</li>\r\n	<li>Run laplacian operator on the RGBA8888 image data.</li>\r\n</ul>\r\nGetting a grayscale image from NV21 format is cake walk, just read the first width*height bytes and you are done. As per the format of <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a>, for each 2x2 sub-matrix of pixels, there will be a pair (v,u). Since 4 pixels are reading same (v,u), i decided to use shared memory to reduce reading latency. The code below is the core of this conversion kernel, that is expected to speed up the conversion if compared to a pure C code.\r\n<pre>\r\n#define BLK_SIZE 16\r\n//prefix D for decoding\r\n#define DSHRD_LEN (BLK_SIZE/2)\r\n#define DSHRD_SIZE (2*DSHRD_LEN*DSHRD_LEN)\r\n// ...\r\n// ...\r\n// kernel signature\r\n{\r\n    __local uchar uvShrd[DSHRD_SIZE];\r\n    int gx = get_global_id(0);\r\n    int gy = get_global_id(1);\r\n    int lx = get_local_id(0);\r\n    int ly = get_local_id(1);\r\n    int off = im_width*im_height;\r\n    int inIdx= gy*im_width+gx;\r\n    int uvIdx= off + (gy/2)*im_width + (gx & ~1); // took me a while to figure out this formula\r\n    int shlx = lx/2;\r\n    int shly = ly/2;\r\n    int shIdx= 2*(shlx+shly*DSHRD_LEN);\r\n    if( gx%2==0 && gy%2==0 ) {\r\n        uvShrd[shIdx+0] = in[uvIdx+0];\r\n        uvShrd[shIdx+1] = in[uvIdx+1];\r\n    }\r\n    int y = (0xFF & ((int)in[inIdx]));\r\n    int y = (0xFF & ((int)in[inIdx]));\r\n    if( y < 16 ) y=16;\r\n    barrier(CLK_LOCAL_MEM_FENCE);\r\n    //..... rest of code that does color space conversion\r\n}\r\n</pre>\r\nLaplacian kernel is pretty straightforward, read all eight neighbors pixel values using shared memory and compute the convolution result. You can find kernels source code <a href=\"https://github.com/arrayfire/androidcl/blob/master/assets/kernels.cl\">here</a>.\r\n<h4 id=\"auxilary-code\">Auxilary Code</h4>\r\nThe JNI native function declarations can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.h\">processor.h</a>. I have included couple of extra Android related headers which are required to read bitmap files and print debug messages from JNI routines. The C-string pointed by macro <code>app_name</code> can be used to prune the output of the command <code>adb logcat</code> to get only messages that are associated with our JNI routines. To do that, you need to pass the value of <code>app_name</code> to adb command as an option as shown below.\r\n<pre>adb logcat -s \"JNIProcessor\"</pre>\r\nThis is quite useful when you are debugging problems that are related to accuracy of results.\r\n\r\nThe full source code for JNI native functions can be seen in the file <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/processor.cpp\">processor.cpp</a>. Following are brief descriptions of the Android/JNI functions I have used in this project.\r\n<ul>\r\n	<li><code>AndroidBitmap_getInfo</code> - provides details like width, height, stride, format.</li>\r\n	<li><code>AndroidBitmap_lockPixels</code> - gives us a pointer to the memory location of image data. Once lockPixels is called, it has to be followed by a unlockPixels at some point later in the code.</li>\r\n	<li><code>GetPrimitiveArrayCritical</code> - as the name suggets, this is some kind of performance critical call. Hence, we should take care that the code amid a GetPrimitiveArrayCritical call and the corresponding ReleasePrimitiveArrayCritical call doesn\'t stall execution for extended periods of time. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s Java documentation</a>, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical. So, just be careful when you use this function.</li>\r\n	<li><code>ReleasePrimitiveArrayCritical</code> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><code>AndroidBitmap_unlockPixels</code> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nListed below are some of the other auxilary functions that i needed to make the code look clean.\r\n<ul>\r\n	<li><code>throwJavaException</code> - convenience function used to throw Java exceptions from JNI routines.</li>\r\n	<li><code>cb</code> - callback function provided when OpenCL kernels are built. When you actually look at this, you might wonder why did i do this part alone using C-interface of OpenCL. I just wanted to try it out, hence it happened so.</li>\r\n	<li><code>Java_com_example_LiveFeatureActivity_compileKernels</code> - as you might have noticed, this is a JNI routine i used to compile the OpenCL kernels only once during the app start up.</li>\r\n</ul>\r\n<h3 id=\"build-on-linux\">Build (on Linux)</h3>\r\nAndroid-NDK provides a very useful tool <code>ndk-build</code> to build native code for Android.\r\n<ol>\r\n	<li>Clone the git repo <code>git clone https://github.com/arrayfire/androidcl</code></li>\r\n	<li><code>cd androidcl</code></li>\r\n	<li>Ensure android-ndk installed and environment variable <code>ANDROID_NDK</code> is pointing to ndk installation root.</li>\r\n	<li>Ensure environment variable <code>PATH</code> has the path <code>$ANDROID_NDK</code> appended to it.</li>\r\n	<li>Run <code>ndk-build</code> from project root.</li>\r\n	<li>If you have <code>eclipse</code> installed, then import the project from eclipse and build it as usually.</li>\r\n	<li>If you do not have eclipse or don\'t want to use it, then I assume you might already know about apache-ant tool. Run <code>ant debug</code></li>\r\n</ol>\r\n<h4 id=\"android.mk\">Android.mk</h4>\r\nThere are couple of things that you need to do to use OpenCL on Android apart from standard JNI makefile instructions.\r\n<ul>\r\n	<li>Ensure that you set <code>LOCAL_ARM_MODE</code> to <code>arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.</li>\r\n	<li>Ensure that the variable <code>LOCAL_CPPFLAGS</code> has been set to point to OpenCL headers.</li>\r\n	<li>Add <code>libOpenCL.so</code> dependency to <code>LOCAL_LDLIBS</code> variable.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk.\r\n\r\nNote: In case you want a static library, replace <code>include $(BUILD_SHARED_LIBRARY)</code> with <code>include $(BUILD_STATIC_LIBRARY)</code>.\r\n<h4 id=\"application.mk\">Application.mk</h4>\r\nThis file is not mandatory, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. In this project i have set <code>APP_STL</code> to <code>gnustl_static</code> to declare that i want to use the static version of gnustl. I have also set the Android API target version as 14 by setting <code>APP_PLATFORM</code> to <code>android-14</code>.\r\nClick <a href=\"https://github.com/arrayfire/androidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk.\r\n<h3 id=\"app-installation\">App Installation</h3>\r\n<h4 id=\"ant-users\">ant-users</h4>\r\nFor installing the app in your mobile device do <code>ant debug install</code>. Should you choose to remove it after you are done playing with it, just do <code>ant debug uninstall</code>.\r\n<h4 id=\"eclipse-users\">eclipse-users</h4>\r\nRight click the project in workspace and click the menu item \"Run As -&gt; Android Application\".\r\n\r\nYou can see below the video of the app running live.\r\n\r\n[video width=\"1280\" height=\"720\" mp4=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/05/ocl_demo.mp4\"]Screen capture of the live app[/video]\r\n\r\n&nbsp;\r\n\r\nStay tuned for more exciting developments as we continue to add more examples of OpenCL on Andriod!','Getting Started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-25 23:36:42','2014-05-25 23:36:42','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5666,17795,'2014-05-26 00:11:23','2014-05-26 00:11:23','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector.\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n\r\nBefore starting writing the code for the corner detector, we need to load an image. The image can be either color or gray-scale, but it will only work on the gray-scale version, so if it is a color image, we have to convert it before proceeding.\r\n\r\n<pre>\r\n// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg /= 255.f;\r\n</pre>\r\n\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the special filter (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative.\r\n\r\n<pre>\r\n// Load a first-order derivative filter to an array\r\nconst unsigned deriv_len = 3;\r\nconst float h_deriv[deriv_len] = {-1.0f, 0.0f, 1.0f};\r\narray deriv(1, deriv_len, h_deriv);\r\n\r\n// Compute first-order derivatives\r\narray ix = convolve(img_gray, deriv);\r\narray iy = convolve(img_gray, deriv.T());\r\n</pre>\r\n\r\nAt this point, we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n\r\n<pre>\r\n// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\n\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself, but a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used, and it can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n\r\n<pre>\r\n// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\n\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n\r\n<pre>\r\n// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\n\r\nFinally, we then calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, and usually it ranges from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result changes.\r\n\r\n<pre>\r\n// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\n\r\nNow we already have our Harris responses for each pixel in the image. \r\n\r\n&nbsp;','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-26 00:11:23','2014-05-26 00:11:23','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5667,17795,'2014-05-26 00:28:15','2014-05-26 00:28:15','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector.\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n\r\nBefore starting writing the code for the corner detector, we need to load an image. The image can be either color or gray-scale, but it will only work on the gray-scale version, so if it is a color image, we have to convert it before proceeding.\r\n<pre>// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg /= 255.f;\r\n</pre>\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the special filter (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative.\r\n<pre>// Load a first-order derivative filter to an array\r\nconst unsigned deriv_len = 3;\r\nconst float h_deriv[deriv_len] = {-1.0f, 0.0f, 1.0f};\r\narray deriv(1, deriv_len, h_deriv);\r\n\r\n// Compute first-order derivatives\r\narray ix = convolve(img_gray, deriv);\r\narray iy = convolve(img_gray, deriv.T());\r\n</pre>\r\nAt this point, we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n<pre>// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself, but a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used, and it can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n<pre>// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n<pre>// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\nFinally, we then calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, and usually it ranges from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result changes.\r\n<pre>// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\nNow we already have our Harris responses for each pixel in the image. This value is used to determine whether a pixel is a corner or not. The standard way is to perform a non-maximal suppression, meaning that for each pixel it can only be a corner if it\'s a maximum compared to its 8 adjacent pixels. At the moment we don\'t have an easy way to compute a non-maximal suppression with ArrayFire, we have to write our own kernel for that, and that is only one of the cool things we will be able to do with our new computer vision toolset for ArrayFire.\r\n\r\nTo avoid taking it much longer and going into much more detail, we will avoid the non-maximal suppression in this post, but we encourage you to write your own kernel for non-maximal suppression, we promise you it will not take more than 20 or 30 lines of code.\r\n\r\nThe last computation to determine whether a pixel is a corner or not, is establish a threshold. The nature of a pixel can be determined by the Harris responses, a negative response means that a pixel corresponds to the segment of an edge. If the response is small but positive, it corresponds to a flat region. Only a large response corresponds to a corner.\r\n\r\nHere, we will use a threshold of 10<sup>6</sup>. For the implementation presented in this article, we found that corners seem to be better for responses larger than 10<sup>5</sup>, but you can and should play with these values to see how it will affect the image you are working on.\r\n\r\n&nbsp;','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-26 00:28:15','2014-05-26 00:28:15','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5669,17795,'2014-05-26 00:45:20','2014-05-26 00:45:20','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector.\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n\r\nBefore starting writing the code for the corner detector, we need to load an image. The image can be either color or gray-scale, but it will only work on the gray-scale version, so if it is a color image, we have to convert it before proceeding.\r\n<pre>// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg /= 255.f;\r\n</pre>\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the special filter (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative.\r\n<pre>// Load a first-order derivative filter to an array\r\nconst unsigned deriv_len = 3;\r\nconst float h_deriv[deriv_len] = {-1.0f, 0.0f, 1.0f};\r\narray deriv(1, deriv_len, h_deriv);\r\n\r\n// Compute first-order derivatives\r\narray ix = convolve(img_gray, deriv);\r\narray iy = convolve(img_gray, deriv.T());\r\n</pre>\r\nAt this point, we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n<pre>// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself, but a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used, and it can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n<pre>// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n<pre>// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\nFinally, we then calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, and usually it ranges from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result changes.\r\n<pre>// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\nNow we already have our Harris responses for each pixel in the image. This value is used to determine whether a pixel is a corner or not. The standard way is to perform a non-maximal suppression, meaning that for each pixel it can only be a corner if it\'s a maximum compared to its 8 adjacent pixels. At the moment we don\'t have an easy way to compute a non-maximal suppression with ArrayFire, we have to write our own kernel for that, and that is only one of the cool things we will be able to do with our new computer vision toolset for ArrayFire.\r\n\r\nTo avoid taking it much longer and going into much more detail, we will avoid the non-maximal suppression in this post, but we encourage you to write your own kernel for non-maximal suppression, we promise you it will not take more than 20 or 30 lines of code.\r\n\r\nThe last computation to determine whether a pixel is a corner or not, is establish a threshold. The nature of a pixel can be determined by the Harris responses, a negative response means that a pixel corresponds to the segment of an edge. If the response is small but positive, it corresponds to a flat region. Only a large response corresponds to a corner.\r\n\r\nHere, we will use a threshold of 10<sup>6</sup>. For the implementation presented in this article, we found that corners seem to be better for responses larger than 10<sup>5</sup>, but you can and should play with these values to see how it will affect the image you are working on.\r\n\r\nThis last step is done on the CPU side, we only do this to show the corners that are detected. Most likely, you will not need to do this unless you want to visualize, but for the sake of clarity, we include this part to show the result.\r\n\r\n<pre>\r\n// Gets host pointer to response data\r\nfloat* h_response = response.host();\r\n\r\n// Draw draw_len x draw_len crosses where corners are\r\nconst int draw_len = 3;\r\nfor (int y = draw_len; y &lt; response.dims(0) - draw_len; y++) {\r\n    for (int x = draw_len; x  10^6\r\n        if (h_response[x * response.dims(0) + y] &gt; 1e6f) {\r\n            // Draw horizontal line of (draw_len * 2 + 1) pixels over center of corner\r\n            // Set only the first channel to 1 (red lines)\r\n            img_color(y, seq(x-draw_len, x+draw_len), 0) = 1.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 1) = 0.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 2) = 0.f;\r\n\r\n            // Draw vertical line of (draw_len * 2 + 1) pixels over center of corner\r\n            // Set only the first channel to 1 (red lines)\r\n            img_color(seq(y-draw_len, y+draw_len), x, 0) = 1.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 1) = 0.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 2) = 0.f;\r\n        }\r\n    }\r\n}\r\n</pre>\r\n\r\nFinally, the image can be visualized.\r\n\r\n<pre>\r\n// Previews color image with red crosses\r\nimage(img_color);\r\n</pre>\r\n\r\nBelow you can see Lena\'s picture after the Harris corner detection and plotting. Not the red crosses, many of them look like red circles, and this is because we omitted the non-maximal suppression. When we perform the non-maximum suppression, there will never be two adjacent corners.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena-1024x624.png\" alt=\"Lena and Harris Corners\" width=\"742\" height=\"452\" class=\"alignnone size-large wp-image-5668\" /></a>\r\n\r\nWe would like to hear from you what you are working on the computer vision field and which features you would like to see in ArrayFire. Please share your thoughts and requests below.\r\n\r\n&nbsp;','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-26 00:45:20','2014-05-26 00:45:20','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5671,17795,'2014-05-26 00:49:20','2014-05-26 00:49:20','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector.\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n\r\nBefore starting writing the code for the corner detector, we need to load an image. The image can be either color or gray-scale, but it will only work on the gray-scale version, so if it is a color image, we have to convert it before proceeding.\r\n<pre>// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg /= 255.f;\r\n</pre>\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the special filter (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative.\r\n<pre>// Load a first-order derivative filter to an array\r\nconst unsigned deriv_len = 3;\r\nconst float h_deriv[deriv_len] = {-1.0f, 0.0f, 1.0f};\r\narray deriv(1, deriv_len, h_deriv);\r\n\r\n// Compute first-order derivatives\r\narray ix = convolve(img_gray, deriv);\r\narray iy = convolve(img_gray, deriv.T());\r\n</pre>\r\nAt this point, we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n<pre>// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself, but a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used, and it can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n<pre>// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n<pre>// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\nFinally, we then calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, and usually it ranges from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result changes.\r\n<pre>// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\nNow we already have our Harris responses for each pixel in the image. This value is used to determine whether a pixel is a corner or not. The standard way is to perform a non-maximal suppression, meaning that for each pixel it can only be a corner if it\'s a maximum compared to its 8 adjacent pixels. At the moment we don\'t have an easy way to compute a non-maximal suppression with ArrayFire, we have to write our own kernel for that, and that is only one of the cool things we will be able to do with our new computer vision toolset for ArrayFire.\r\n\r\nTo avoid taking it much longer and going into much more detail, we will avoid the non-maximal suppression in this post, but we encourage you to write your own kernel for non-maximal suppression, we promise you it will not take more than 20 or 30 lines of code.\r\n\r\nThe last computation to determine whether a pixel is a corner or not, is establish a threshold. The nature of a pixel can be determined by the Harris responses, a negative response means that a pixel corresponds to the segment of an edge. If the response is small but positive, it corresponds to a flat region. Only a large response corresponds to a corner.\r\n\r\nHere, we will use a threshold of 10<sup>6</sup>. For the implementation presented in this article, we found that corners seem to be better for responses larger than 10<sup>5</sup>, but you can and should play with these values to see how it will affect the image you are working on.\r\n\r\nThis last step is done on the CPU side, we only do this to show the corners that are detected. Most likely, you will not need to do this unless you want to visualize, but for the sake of clarity, we include this part to show the result.\r\n\r\n<pre>\r\n// Gets host pointer to response data\r\nfloat* h_response = response.host();\r\n\r\n// Draw draw_len x draw_len crosses where corners are\r\nconst int draw_len = 3;\r\nfor (int y = draw_len; y &lt; response.dims(0) - draw_len; y++) {\r\n    for (int x = draw_len; x  10^6\r\n        if (h_response[x * response.dims(0) + y] &gt; 1e6f) {\r\n            // Draw horizontal line of (draw_len * 2 + 1) pixels over center of corner\r\n            // Set only the first channel to 1 (red lines)\r\n            img_color(y, seq(x-draw_len, x+draw_len), 0) = 1.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 1) = 0.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 2) = 0.f;\r\n\r\n            // Draw vertical line of (draw_len * 2 + 1) pixels over center of corner\r\n            // Set only the first channel to 1 (red lines)\r\n            img_color(seq(y-draw_len, y+draw_len), x, 0) = 1.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 1) = 0.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 2) = 0.f;\r\n        }\r\n    }\r\n}\r\n</pre>\r\n\r\nFinally, the image can be visualized.\r\n\r\n<pre>\r\n// Previews color image with red crosses\r\nimage(img_color);\r\n</pre>\r\n\r\nBelow you can see Lena\'s picture after the Harris corner detection and plotting. Not the red crosses, many of them look like red circles, and this is because we omitted the non-maximal suppression. When we perform the non-maximum suppression, there will never be two adjacent corners.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\" alt=\"Lena with Harris corners\" width=\"1024\" height=\"600\" class=\"alignnone size-full wp-image-5670\" /></a>\r\n\r\nWe would like to hear from you what you are working on the computer vision field and which features you would like to see in ArrayFire. Please share your thoughts and requests below.\r\n\r\n&nbsp;','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-26 00:49:20','2014-05-26 00:49:20','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5672,17795,'2014-05-26 00:50:17','2014-05-26 00:50:17','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector.\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n\r\nBefore starting writing the code for the corner detector, we need to load an image. The image can be either color or gray-scale, but it will only work on the gray-scale version, so if it is a color image, we have to convert it before proceeding.\r\n<pre>// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg /= 255.f;\r\n</pre>\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the special filter (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative.\r\n<pre>// Load a first-order derivative filter to an array\r\nconst unsigned deriv_len = 3;\r\nconst float h_deriv[deriv_len] = {-1.0f, 0.0f, 1.0f};\r\narray deriv(1, deriv_len, h_deriv);\r\n\r\n// Compute first-order derivatives\r\narray ix = convolve(img_gray, deriv);\r\narray iy = convolve(img_gray, deriv.T());\r\n</pre>\r\nAt this point, we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n<pre>// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself, but a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used, and it can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n<pre>// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n<pre>// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\nFinally, we then calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, and usually it ranges from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result changes.\r\n<pre>// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\nNow we already have our Harris responses for each pixel in the image. This value is used to determine whether a pixel is a corner or not. The standard way is to perform a non-maximal suppression, meaning that for each pixel it can only be a corner if it\'s a maximum compared to its 8 adjacent pixels. At the moment we don\'t have an easy way to compute a non-maximal suppression with ArrayFire, we have to write our own kernel for that, and that is only one of the cool things we will be able to do with our new computer vision toolset for ArrayFire.\r\n\r\nTo avoid taking it much longer and going into much more detail, we will avoid the non-maximal suppression in this post, but we encourage you to write your own kernel for non-maximal suppression, we promise you it will not take more than 20 or 30 lines of code.\r\n\r\nThe last computation to determine whether a pixel is a corner or not, is establish a threshold. The nature of a pixel can be determined by the Harris responses, a negative response means that a pixel corresponds to the segment of an edge. If the response is small but positive, it corresponds to a flat region. Only a large response corresponds to a corner.\r\n\r\nHere, we will use a threshold of 10<sup>6</sup>. For the implementation presented in this article, we found that corners seem to be better for responses larger than 10<sup>5</sup>, but you can and should play with these values to see how it will affect the image you are working on.\r\n\r\nThis last step is done on the CPU side, we only do this to show the corners that are detected. Most likely, you will not need to do this unless you want to visualize, but for the sake of clarity, we include this part to show the result.\r\n\r\n<pre>\r\n// Gets host pointer to response data\r\nfloat* h_response = response.host();\r\n\r\n// Draw draw_len x draw_len crosses where corners are\r\nconst int draw_len = 3;\r\nfor (int y = draw_len; y &lt; response.dims(0) - draw_len; y++) {\r\n    for (int x = draw_len; x  10^6\r\n        if (h_response[x * response.dims(0) + y] &gt; 1e6f) {\r\n            // Draw horizontal line of (draw_len * 2 + 1) pixels over center of corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(y, seq(x-draw_len, x+draw_len), 0) = 0.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 1) = 1.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 2) = 0.f;\r\n\r\n            // Draw vertical line of (draw_len * 2 + 1) pixels over center of corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(seq(y-draw_len, y+draw_len), x, 0) = 0.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 1) = 1.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 2) = 0.f;\r\n        }\r\n    }\r\n}\r\n</pre>\r\n\r\nFinally, the image can be visualized.\r\n\r\n<pre>\r\n// Previews color image with green crosses\r\nimage(img_color);\r\n</pre>\r\n\r\nBelow you can see Lena\'s picture after the Harris corner detection and plotting. Note the green crosses, many of them look like green circles, and this is because we omitted the non-maximal suppression. When we perform the non-maximum suppression, there will never be two adjacent corners.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\" alt=\"Lena with Harris corners\" width=\"1024\" height=\"600\" class=\"alignnone size-full wp-image-5670\" /></a>\r\n\r\nWe would like to hear from you what you are working on the computer vision field and which features you would like to see in ArrayFire. Please share your thoughts and requests below.\r\n\r\n&nbsp;','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-26 00:50:17','2014-05-26 00:50:17','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5673,17795,'2014-05-26 01:02:23','2014-05-26 01:02:23','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector.\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n\r\nBefore starting writing the code for the corner detector, we need to load an image. The image can be either color or gray-scale, but it will only work on the gray-scale version, so if it is a color image, we have to convert it before proceeding.\r\n<pre>// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg /= 255.f;\r\n</pre>\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the special filter (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative.\r\n<pre>// Load a first-order derivative filter to an array\r\nconst unsigned deriv_len = 3;\r\nconst float h_deriv[deriv_len] = {-1.0f, 0.0f, 1.0f};\r\narray deriv(1, deriv_len, h_deriv);\r\n\r\n// Compute first-order derivatives\r\narray ix = convolve(img_gray, deriv);\r\narray iy = convolve(img_gray, deriv.T());\r\n</pre>\r\nAt this point, we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n<pre>// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself, but a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used, and it can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n<pre>// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n<pre>// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\nFinally, we then calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, and usually it ranges from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result changes.\r\n<pre>// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\nNow we already have our Harris responses for each pixel in the image. This value is used to determine whether a pixel is a corner or not. The standard way is to perform a non-maximal suppression, meaning that for each pixel it can only be a corner if it\'s a maximum compared to its 8 adjacent pixels. At the moment we don\'t have an easy way to compute a non-maximal suppression with ArrayFire, we have to write our own kernel for that, and that is only one of the cool things we will be able to do with our new computer vision toolset for ArrayFire.\r\n\r\nTo avoid taking it much longer and going into much more detail, we will avoid the non-maximal suppression in this post, but we encourage you to write your own kernel for non-maximal suppression, we promise you it will not take more than 20 or 30 lines of code.\r\n\r\nThe last computation to determine whether a pixel is a corner or not, is establish a threshold. The nature of a pixel can be determined by the Harris responses, a negative response means that a pixel corresponds to the segment of an edge. If the response is small but positive, it corresponds to a flat region. Only a large response corresponds to a corner.\r\n\r\nHere, we will use a threshold of 10<sup>6</sup>. For the implementation presented in this article, we found that corners seem to be better for responses larger than 10<sup>5</sup>, but you can and should play with these values to see how it will affect the image you are working on.\r\n\r\nThis last step is done on the CPU side, we only do this to show the corners that are detected. Most likely, you will not need to do this unless you want to visualize, but for the sake of clarity, we include this part to show the result.\r\n<pre class=\"wp-code-highlight prettyprint\">// Gets host pointer to response data\r\nfloat* h_response = response.host();\r\n\r\n// Draw draw_len x draw_len crosses where the corners are\r\nconst int draw_len = 3;\r\nfor (int y = draw_len; y &lt; response.dims(0) - draw_len; y++) {\r\n    for (int x = draw_len; x &lt; response.dims(1) - draw_len; x++) {\r\n        // Only draws corner if response is &gt; 10^6\r\n        if (h_response[x * response.dims(0) + y] &gt; 1e6f) {\r\n            // Draw horizontal line of (draw_len * 2 + 1) pixels over center of corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(y, seq(x-draw_len, x+draw_len), 0) = 0.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 1) = 1.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 2) = 0.f;\r\n\r\n            // Draw vertical line of (draw_len * 2 + 1) pixels over center of corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(seq(y-draw_len, y+draw_len), x, 0) = 0.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 1) = 1.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 2) = 0.f;\r\n        }\r\n    }\r\n}\r\n</pre>\r\nFinally, the image can be visualized.\r\n<pre>// Previews color image with green crosses\r\nimage(img_color);\r\n</pre>\r\nBelow you can see Lena\'s picture after the Harris corner detection and plotting. Note the green crosses, many of them look like green circles, and this is because we omitted the non-maximal suppression. When we perform the non-maximum suppression, there will never be two adjacent corners.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\"><img class=\"alignnone size-full wp-image-5670\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\" alt=\"Lena with Harris corners\" width=\"1024\" height=\"600\" /></a>\r\n\r\nWe would like to hear from you what you are working on the computer vision field and which features you would like to see in ArrayFire. Please share your thoughts and requests below.\r\n\r\n&nbsp;','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-26 01:02:23','2014-05-26 01:02:23','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5674,17795,'2014-05-26 13:32:57','2014-05-26 13:32:57','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\n<h4>Harris corner detector</h4>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector [1].\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n<h5>Loading an image</h5>\r\nBefore starting writing the code for the corner detector, we need to load an image. The image can be either color or gray-scale, but it will only work on the gray-scale version, so if it is a color image, we have to convert it before proceeding.\r\n<pre>// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg /= 255.f;\r\n</pre>\r\n<h5>Compute first-order derivatives</h5>\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the special filter (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative.\r\n<pre>// Load a first-order derivative filter to an array\r\nconst unsigned deriv_len = 3;\r\nconst float h_deriv[deriv_len] = {-1.0f, 0.0f, 1.0f};\r\narray deriv(1, deriv_len, h_deriv);\r\n\r\n// Compute first-order derivatives\r\narray ix = convolve(img_gray, deriv);\r\narray iy = convolve(img_gray, deriv.T());\r\n</pre>\r\n<h5>Compute second-order derivatives</h5>\r\nAt this point, we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n<pre>// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\n<h5>Compute an isotropic window</h5>\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself, but a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used, and it can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n<pre>// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\n<h5>Compute trace and determinant</h5>\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n<pre>// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\n<h5>Compute Harris response</h5>\r\nFinally, we then calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, and usually it ranges from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result changes.\r\n<pre>// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\n<h5>Selection of good corners and plotting</h5>\r\nNow we already have our Harris responses for each pixel in the image. This value is used to determine whether a pixel is a corner or not. The standard way is to perform a non-maximal suppression, meaning that for each pixel it can only be a corner if it\'s a maximum compared to its 8 adjacent pixels. At the moment we don\'t have an easy way to compute a non-maximal suppression with ArrayFire, we have to write our own kernel for that, and that is only one of the cool things we will be able to do with our new computer vision toolset for ArrayFire.\r\n\r\nTo avoid taking it much longer and going into much more detail, we will avoid the non-maximal suppression in this post, but we encourage you to write your own kernel for non-maximal suppression, we promise it will not take more than 20 or 30 lines of code.\r\n\r\nThe last computation to determine whether a pixel is a corner or not, is establish a threshold. The nature of a pixel can be determined by the Harris responses, a negative response means that a pixel corresponds to the segment of an edge. If the response is small but positive, it corresponds to a flat region. Only a large response corresponds to a corner.\r\n\r\nHere, we will use a threshold of 10<sup>6</sup>. For the implementation presented in this article, we found that corners seem to be better for responses larger than 10<sup>5</sup>, but you can and should play with these values to see how it will affect the image you are working on.\r\n\r\nThis last step is done on the CPU side, we only do this to show the corners that are detected. Most likely, you will not need to do this unless you want to visualize, but for the sake of clarity, we include this part to show the result.\r\n<pre>// Gets host pointer to response data\r\nfloat* h_response = response.host();\r\n\r\n// Draw draw_len x draw_len crosses where the corners are\r\nconst int draw_len = 3;\r\nfor (int y = draw_len; y ≤ response.dims(0) - draw_len; y++) {\r\n    for (int x = draw_len; x &lt; response.dims(1) - draw_len; x++) {\r\n        // Only draws corner if response is &gt; 10^6\r\n        if (h_response[x * response.dims(0) + y] &gt; 1e6f) {\r\n            // Draw horizontal line of (draw_len * 2 + 1) pixels centered on the corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(y, seq(x-draw_len, x+draw_len), 0) = 0.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 1) = 1.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 2) = 0.f;\r\n\r\n            // Draw vertical line of (draw_len * 2 + 1) pixels centered on  the corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(seq(y-draw_len, y+draw_len), x, 0) = 0.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 1) = 1.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 2) = 0.f;\r\n        }\r\n    }\r\n}</pre>\r\n<h5>Visualize results</h5>\r\nFinally, the image can be visualized.\r\n<pre>// Previews color image with green crosses\r\nimage(img_color);\r\n</pre>\r\nBelow you can see Lena\'s picture after the Harris corner detection and plotting. Note the green crosses, many of them look like green circles, and this is because we omitted the non-maximal suppression. When we perform the non-maximum suppression, there will never be two adjacent corners.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\"><img class=\"alignnone size-full wp-image-5670\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\" alt=\"Lena with Harris corners\" width=\"1024\" height=\"600\" /></a>\r\n\r\nWe would like to hear from you, what you are working on the computer vision field and which features you would like to see in ArrayFire. Please share your thoughts and requests below.\r\n<h5>References</h5>\r\n[1] Harris, Chris, and Mike Stephens. \"A combined corner and edge detector.\" <em>Alvey vision conference</em>. Vol. 15. 1988.\r\n\r\n&nbsp;','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-26 13:32:57','2014-05-26 13:32:57','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0);
INSERT INTO `wp_posts` VALUES (5676,17795,'2014-05-26 13:44:14','2014-05-26 13:44:14','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\n<h4>Harris corner detector</h4>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector [1].\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n<h5>Loading an image</h5>\r\nBefore starting writing the code for the corner detector, we need to load an image. The image can be either color or gray-scale, but it will only work on the gray-scale version, so if it is a color image, we have to convert it before proceeding.\r\n<pre>// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg /= 255.f;\r\n</pre>\r\n<h5>Compute first-order derivatives</h5>\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the special filter (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative.\r\n<pre>// Load a first-order derivative filter to an array\r\nconst unsigned deriv_len = 3;\r\nconst float h_deriv[deriv_len] = {-1.0f, 0.0f, 1.0f};\r\narray deriv(1, deriv_len, h_deriv);\r\n\r\n// Compute first-order derivatives\r\narray ix = convolve(img_gray, deriv);\r\narray iy = convolve(img_gray, deriv.T());\r\n</pre>\r\n<h5>Compute second-order derivatives</h5>\r\nAt this point, we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n<pre>// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\n<h5>Compute an isotropic window</h5>\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself, but a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used, and it can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n<pre>// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\n<h5>Compute trace and determinant</h5>\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n<pre>// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\n<h5>Compute Harris response</h5>\r\nFinally, we then calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, and usually it ranges from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result changes.\r\n<pre>// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\n<h5>Selection of good corners and plotting</h5>\r\nNow we already have our Harris responses for each pixel in the image. This value is used to determine whether a pixel is a corner or not. The standard way is to perform a non-maximal suppression, meaning that for each pixel it can only be a corner if it\'s a maximum compared to its 8 adjacent pixels. At the moment we don\'t have an easy way to compute a non-maximal suppression with ArrayFire, we have to write our own kernel for that, and that is only one of the cool things we will be able to do with our new computer vision toolset for ArrayFire.\r\n\r\nTo avoid taking it much longer and going into much more detail, we will avoid the non-maximal suppression in this post, but we encourage you to write your own kernel for non-maximal suppression, we promise it will not take more than 20 or 30 lines of code.\r\n\r\nThe last computation to determine whether a pixel is a corner or not, is establish a threshold. The nature of a pixel can be determined by the Harris responses, a negative response means that a pixel corresponds to the segment of an edge. If the response is small but positive, it corresponds to a flat region. Only a large response corresponds to a corner.\r\n\r\nHere, we will use a threshold of 10<sup>6</sup>. For the implementation presented in this article, we found that corners seem to be better for responses larger than 10<sup>5</sup>, but you can and should play with these values to see how it will affect the image you are working on.\r\n\r\nThis last step is done on the CPU side, we only do this to show the corners that are detected. Most likely, you will not need to do this unless you want to visualize, but for the sake of clarity, we include this part to show the result.\r\n<pre>// Gets host pointer to response data\r\nfloat* h_response = response.host();\r\n\r\n// Draw draw_len x draw_len crosses where the corners are\r\nconst int draw_len = 3;\r\nfor (int y = draw_len; y &lt; response.dims(0) - draw_len; y++) {\r\n    for (int x = draw_len; x &lt; response.dims(1) - draw_len; x++) {\r\n        // Only draws corner if response is &gt; 10^6\r\n        if (h_response[x * response.dims(0) + y] &gt; 1e6f) {\r\n            // Draw horizontal line of (draw_len * 2 + 1) pixels centered on the corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(y, seq(x-draw_len, x+draw_len), 0) = 0.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 1) = 1.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 2) = 0.f;\r\n\r\n            // Draw vertical line of (draw_len * 2 + 1) pixels centered on  the corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(seq(y-draw_len, y+draw_len), x, 0) = 0.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 1) = 1.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 2) = 0.f;\r\n        }\r\n    }\r\n}</pre>\r\n<h5>Visualize results</h5>\r\nFinally, the image can be visualized.\r\n<pre>// Previews color image with green crosses\r\nimage(img_color);\r\n</pre>\r\nBelow you can see Lena\'s picture after the Harris corner detection and plotting. Note the green crosses, many of them look like green circles, and this is because we omitted the non-maximal suppression. When we perform the non-maximum suppression, there will never be two adjacent corners.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\"><img class=\"alignnone size-full wp-image-5670\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\" alt=\"Lena with Harris corners\" width=\"1024\" height=\"600\" /></a>\r\n\r\nWe would like to hear from you, what you are working on the computer vision field and which features you would like to see in ArrayFire. Please share your thoughts and requests below.\r\n<h5>References</h5>\r\n[1] Harris, Chris, and Mike Stephens. \"A combined corner and edge detector.\" <em>Alvey vision conference</em>. Vol. 15. 1988.\r\n\r\n&nbsp;','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-26 13:44:14','2014-05-26 13:44:14','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5679,17795,'2014-05-26 23:06:35','2014-05-26 23:06:35','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\n<h3>Harris corner detector</h3>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector [1].\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n<h5>Loading an image</h5>\r\nBefore starting writing the code for the corner detector, we need to load an image. The image can be either color or gray-scale, but it will only work on the gray-scale version, so if it is a color image, we have to convert it before proceeding.\r\n<pre>// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg /= 255.f;\r\n</pre>\r\n<h5>Compute first-order derivatives</h5>\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the special filter (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative.\r\n<pre>// Load a first-order derivative filter to an array\r\nconst unsigned deriv_len = 3;\r\nconst float h_deriv[deriv_len] = {-1.0f, 0.0f, 1.0f};\r\narray deriv(1, deriv_len, h_deriv);\r\n\r\n// Compute first-order derivatives\r\narray ix = convolve(img_gray, deriv);\r\narray iy = convolve(img_gray, deriv.T());\r\n</pre>\r\n<h5>Compute second-order derivatives</h5>\r\nAt this point, we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n<pre>// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\n<h5>Compute an isotropic window</h5>\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself, but a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used, and it can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n<pre>// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\n<h5>Compute trace and determinant</h5>\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n<pre>// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\n<h5>Compute Harris response</h5>\r\nFinally, we then calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, and usually it ranges from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result changes.\r\n<pre>// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\n<h5>Selection of good corners and plotting</h5>\r\nNow we already have our Harris responses for each pixel in the image. This value is used to determine whether a pixel is a corner or not. The standard way is to perform a non-maximal suppression, meaning that for each pixel it can only be a corner if it\'s a maximum compared to its 8 adjacent pixels. At the moment we don\'t have an easy way to compute a non-maximal suppression with ArrayFire, we have to write our own kernel for that, and that is only one of the cool things we will be able to do with our new computer vision toolset for ArrayFire.\r\n\r\nTo avoid taking it much longer and going into much more detail, we will avoid the non-maximal suppression in this post, but we encourage you to write your own kernel for non-maximal suppression, we promise it will not take more than 20 or 30 lines of code.\r\n\r\nThe last computation to determine whether a pixel is a corner or not, is establish a threshold. The nature of a pixel can be determined by the Harris responses, a negative response means that a pixel corresponds to the segment of an edge. If the response is small but positive, it corresponds to a flat region. Only a large response corresponds to a corner.\r\n\r\nHere, we will use a threshold of 10<sup>6</sup>. For the implementation presented in this article, we found that corners seem to be better for responses larger than 10<sup>5</sup>, but you can and should play with these values to see how it will affect the image you are working on.\r\n\r\nThis last step is done on the CPU side, we only do this to show the corners that are detected. Most likely, you will not need to do this unless you want to visualize, but for the sake of clarity, we include this part to show the result.\r\n<pre>// Gets host pointer to response data\r\nfloat* h_response = response.host();\r\n\r\n// Draw draw_len x draw_len crosses where the corners are\r\nconst int draw_len = 3;\r\nfor (int y = draw_len; y &lt; response.dims(0) - draw_len; y++) {\r\n    for (int x = draw_len; x &lt; response.dims(1) - draw_len; x++) {\r\n        // Only draws corner if response is &gt; 10^6\r\n        if (h_response[x * response.dims(0) + y] &gt; 1e6f) {\r\n            // Draw horizontal line of (draw_len * 2 + 1) pixels centered on the corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(y, seq(x-draw_len, x+draw_len), 0) = 0.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 1) = 1.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 2) = 0.f;\r\n\r\n            // Draw vertical line of (draw_len * 2 + 1) pixels centered on  the corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(seq(y-draw_len, y+draw_len), x, 0) = 0.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 1) = 1.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 2) = 0.f;\r\n        }\r\n    }\r\n}</pre>\r\n<h5>Visualize results</h5>\r\nFinally, the image can be visualized.\r\n<pre>// Previews color image with green crosses\r\nimage(img_color);\r\n</pre>\r\nBelow you can see Lena\'s picture after the Harris corner detection and plotting. Note the green crosses, many of them look like green circles, and this is because we omitted the non-maximal suppression. When we perform the non-maximum suppression, there will never be two adjacent corners.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\"><img class=\"alignnone size-full wp-image-5670\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\" alt=\"Lena with Harris corners\" width=\"1024\" height=\"600\" /></a>\r\n\r\nTo test for correctness of the algorithm, nothing better than a picture with well-defined corners. Below you can see the picture of a white square on a black background and the corners marked by green crosses.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_square.png\"><img class=\"alignnone size-full wp-image-5678\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_square.png\" alt=\"Square with Harris corners\" width=\"1024\" height=\"600\" /></a>\r\n\r\nWe would like to hear from you, what you are working on the computer vision field and which features you would like to see in ArrayFire. Please share your thoughts and requests below or contact us at <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a>.\r\n<h5>References</h5>\r\n[1] Harris, Chris, and Mike Stephens. \"A combined corner and edge detector.\" <em>Alvey vision conference</em>. Vol. 15. 1988.\r\n\r\n&nbsp;','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-26 23:06:35','2014-05-26 23:06:35','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5681,17728,'2014-05-27 17:01:44','2014-05-27 17:01:44','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep around the old implementation for testing purposes. In this post we are going to talk about how you can integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device&lt;float&gt;();\r\n    float *d_y = y.device&lt;float&gt;();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nFirstly you need an input to the kernel.\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);\r\n</pre>\r\nIn this case, it is the variable <strong> x </strong> that has been created as a uniformly random array. If you have data coming from other computations, you can use that instead.\r\n\r\nThe necessary memory required for the output needs to be allocated before we launch the kernel.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this sample, the output y has the same number of elements as <strong> x </strong>. Note that we are not specifying the output data type. In such cases ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). You can add the necessary data type at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor.\r\n\r\nOnce you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device&lt;float&gt;()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device&lt;float&gt;();\r\n float *d_y = y.device&lt;float&gt;();\r\n</pre>\r\nBefore you launch your custom kernel, it would be best to make sure all the computations performed by ArrayFire have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong> will handle the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post.\r\n\r\nOnce you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step because if ArrayFire believes the user still controls the pointer, it does not perform garbage collection on those arrays and will potentially lead to memory leaks.\r\n\r\nYou can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIf you are integrating a CUDA kernel into your ArrayFire code base, it is a fairly straight forward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. You can see how to do that using a simple kernel below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id &lt; num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel&lt;&lt;&lt;blocks, threads&gt;&gt;&gt;(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &amp;d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &amp;d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &amp;num);\r\n\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &amp;global, &amp;local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a>\r\n\r\nThe OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id &lt; num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:01:44','2014-05-27 17:01:44','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5682,17796,'2014-05-27 17:19:57','2014-05-27 17:19:57','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\n<h3>In and Out of ArrayFire</h3>\nFirst let us look at the following code and then break it down bit by bit.\n<pre>int main()\n{\n    af::array x = af::randu(num, 1);\n\n    af::array y = af::array(num, 1);\n\n    float *d_x = x.device&lt;float&gt;();\n    float *d_y = y.device&lt;float&gt;();\n\n    af::sync();\n\n    launch_simple_kernel(d_y, d_x, num);\n    x.unlock();\n    y.unlock();\n\n    float err = af::sum(y - 1);\n    printf(\"Error: %f\\n\", err);\n    return 0;\n}\n</pre>\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\n<pre>// Generate input data\naf::array x = af::randu(num, 1);</pre>\nThe necessary memory required for the output is allocated before  the kernel launch.\n<pre>// Create empty array with required dimensions\naf::array y = af::array(num, 1);\n</pre>\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor.\n\nOnce you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device&lt;float&gt;()</a> method in the following manner.\n<pre> // Get device pointers\n float *d_x = x.device&lt;float&gt;();\n float *d_y = y.device&lt;float&gt;();\n</pre>\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\n<pre>// Finish the tasks arrayfire was doing\naf::sync();\n\n// Launch kernel to do the following operations\n// y = sin(x)^2 + con(x)^2\nlaunch_simple_kernel(d_y, d_x, num);\n</pre>\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post.\n\nOnce you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\n<pre>// Tell arrayfire it controls the pointers again\nx.unlock();\ny.unlock();\n</pre>\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects will can potentially lead to memory leaks.\n\nYou can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\n<pre>// Check for errors\n// sin(x)^ + cos(x)^2 == 1\n// The following should print 0\nfloat err = af::sum(y - 1);\nprintf(\"Error: %f\\n\", err);\n</pre>\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\n<h3>Launching a CUDA kernel</h3>\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\n<pre>__global__\nstatic void simple_kernel(float *d_y,\n                          const float *d_x,\n                          const int num)\n{\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\n\n    if (id &lt; num) {\n        float x = d_x[id];\n        float sin_x = sin(x);\n        float cos_x = cos(x);\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\n    }\n}\n\nvoid inline launch_simple_kernel(float *d_y,\n                                 const float *d_x,\n                                 const int num)\n{\n    // Set launch configuration\n    const int threads = 256;\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\n    simple_kernel&lt;&lt;&lt;blocks, threads&gt;&gt;&gt;(d_y, d_x, num);\n    // Synchronize and check for error\n    cudaDeviceSynchronize();\n}\n</pre>\n<h3>Launching an OpenCL kernel</h3>\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\n<pre>void inline launch_simple_kernel(float *d_y,\n                                 const float *d_x,\n                                 const int num)\n{\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\n\n    cl_context context = get_context((cl_mem)d_x);\n    cl_program program = build_program(context, simple_kernel);\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\n    cl_command_queue queue = create_queue(context);\n\n    cl_int err = CL_SUCCESS;\n    int arg = 0;\n\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &amp;d_y);\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &amp;d_x);\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &amp;num);\n\n    size_t local  = 256;\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &amp;global, &amp;local, 0, NULL, NULL);\n    clFinish(queue);\n    return;\n}\n</pre>\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a>\n\nThe OpenCL kernel itself is fairly simple as seen below.\n<pre>__kernel\nvoid simple_kernel(__global float *d_y,\n                   __global const float *d_x,\n                   const int num)\n{\n    const int id = get_global_id(0);\n\n    if (id &lt; num) {\n        float x = d_x[id];\n        float sin_x = sin(x);\n        float cos_x = cos(x);\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\n    }\n}\n</pre>\nYou can find the code samples at the following links:\n<ul>\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-autosave-v1','','','2014-05-27 17:19:57','2014-05-27 17:19:57','',5651,'http://sandbox.arrayfire.com/5651-autosave-v1/',0,'revision','',0),(5683,17796,'2014-05-27 17:20:16','2014-05-27 17:20:16','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device&lt;float&gt;();\r\n    float *d_y = y.device&lt;float&gt;();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor.\r\n\r\nOnce you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device&lt;float&gt;()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device&lt;float&gt;();\r\n float *d_y = y.device&lt;float&gt;();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post.\r\n\r\nOnce you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects will can potentially lead to memory leaks.\r\n\r\nYou can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id &lt; num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel&lt;&lt;&lt;blocks, threads&gt;&gt;&gt;(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &amp;d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &amp;d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &amp;num);\r\n\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &amp;global, &amp;local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a>\r\n\r\nThe OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id &lt; num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:20:16','2014-05-27 17:20:16','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5684,17728,'2014-05-27 17:35:18','2014-05-27 17:35:18','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device&lt;float&gt;();\r\n    float *d_y = y.device&lt;float&gt;();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor.\r\n\r\nOnce you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device&lt;float&gt;()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device&lt;float&gt;();\r\n float *d_y = y.device&lt;float&gt;();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post.\r\n\r\nOnce you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects will can potentially lead to memory leaks.\r\n\r\nYou can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id &lt; num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel&lt;&lt;&lt;blocks, threads&gt;&gt;&gt;(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");   // Read the OpenCL kernel as a string\r\n\r\n    cl_context context = get_context((cl_mem)d_x);                // Get OpenCL context from memory buffer\r\n    cl_program program = build_program(context, simple_kernel);   // Build the OpenCL kernels\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\"); // Access the necessary OpenCL kernel\r\n    cl_command_queue queue = create_queue(context);               // Create a command queue\r\n\r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &amp;d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &amp;d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &amp;num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &amp;global, &amp;local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a>\r\n\r\nThe OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id &lt; num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:35:18','2014-05-27 17:35:18','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5685,17728,'2014-05-27 17:37:09','2014-05-27 17:37:09','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device&lt;float&gt;();\r\n    float *d_y = y.device&lt;float&gt;();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device&lt;float&gt;()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device&lt;float&gt;();\r\n float *d_y = y.device&lt;float&gt;();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects will can potentially lead to memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id &lt; num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel&lt;&lt;&lt;blocks, threads&gt;&gt;&gt;(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &amp;d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &amp;d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &amp;num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &amp;global, &amp;local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id &lt; num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:37:09','2014-05-27 17:37:09','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5686,17728,'2014-05-27 17:39:59','2014-05-27 17:39:59','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. You may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device&lt;float&gt;();\r\n    float *d_y = y.device&lt;float&gt;();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device&lt;float&gt;()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device&lt;float&gt;();\r\n float *d_y = y.device&lt;float&gt;();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects will can potentially lead to memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel&lt;&lt;&lt;blocks, threads&gt;&gt;&gt;(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:39:59','2014-05-27 17:39:59','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5687,17728,'2014-05-27 17:41:36','2014-05-27 17:41:36','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device&lt;float&gt;();\r\n    float *d_y = y.device&lt;float&gt;();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(y - 1);\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device&lt;float&gt;()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device&lt;float&gt;();\r\n float *d_y = y.device&lt;float&gt;();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects will can potentially lead to memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel&lt;&lt;&lt;blocks, threads&gt;&gt;&gt;(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:41:36','2014-05-27 17:41:36','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5688,17728,'2014-05-27 17:42:58','2014-05-27 17:42:58','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device<float>;()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects will can potentially lead to memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel&lt;&lt;&lt;blocks, threads&gt;&gt;&gt;(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:42:58','2014-05-27 17:42:58','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5689,17728,'2014-05-27 17:43:33','2014-05-27 17:43:33','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\"><pre>array::device<float>;</pre>()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects will can potentially lead to memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel&lt;&lt;&lt;blocks, threads&gt;&gt;&gt;(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:43:33','2014-05-27 17:43:33','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5690,17728,'2014-05-27 17:44:01','2014-05-27 17:44:01','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects will can potentially lead to memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel&lt;&lt;&lt;blocks, threads&gt;&gt;&gt;(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:44:01','2014-05-27 17:44:01','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5691,17728,'2014-05-27 17:44:33','2014-05-27 17:44:33','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects will can potentially lead to memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:44:33','2014-05-27 17:44:33','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5692,17728,'2014-05-27 17:53:33','2014-05-27 17:53:33','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects and can potentially lead to memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:53:33','2014-05-27 17:53:33','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5693,17728,'2014-05-27 17:55:47','2014-05-27 17:55:47','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects, and lead to memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:55:47','2014-05-27 17:55:47','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5694,17728,'2014-05-27 17:58:15','2014-05-27 17:58:15','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:58:15','2014-05-27 17:58:15','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5695,17728,'2014-05-27 17:59:11','2014-05-27 17:59:11','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straight forward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:59:11','2014-05-27 17:59:11','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5696,17728,'2014-05-27 17:59:53','2014-05-27 17:59:53','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need onto set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 17:59:53','2014-05-27 17:59:53','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5697,17728,'2014-05-27 18:00:28','2014-05-27 18:00:28','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nSince ArrayFire uses its own context internally, you need to get the context from the memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context. The code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 18:00:28','2014-05-27 18:00:28','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5698,17728,'2014-05-27 18:01:42','2014-05-27 18:01:42','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated. Since ArrayFire uses its own context internally, you need to get the context from a memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nThe code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 18:01:42','2014-05-27 18:01:42','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5699,17728,'2014-05-27 18:17:44','2014-05-27 18:17:44','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + con(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(y - 1);\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated. Since ArrayFire uses its own context internally, you need to get the context from a memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nThe code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom Kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 18:17:44','2014-05-27 18:17:44','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5702,17728,'2014-05-27 19:14:38','2014-05-27 19:14:38','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + cos(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(af::abs(y - 1));\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated. Since ArrayFire uses its own context internally, you need to get the context from a memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nThe code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom Kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 19:14:38','2014-05-27 19:14:38','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5703,17728,'2014-05-27 19:43:39','2014-05-27 19:43:39','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong><sup>^</sup>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + cos(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(af::abs(y - 1));\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated. Since ArrayFire uses its own context internally, you need to get the context from a memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nThe code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>','Custom Kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 19:43:39','2014-05-27 19:43:39','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5704,17728,'2014-05-27 19:49:43','2014-05-27 19:49:43','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\n<h3>In and Out of ArrayFire</h3>\nFirst let us look at the following code and then break it down bit by bit.\n<pre>int main()\n{\n    af::array x = af::randu(num, 1);\n\n    af::array y = af::array(num, 1);\n\n    float *d_x = x.device<float>();\n    float *d_y = y.device<float>();\n\n    af::sync();\n\n    launch_simple_kernel(d_y, d_x, num);\n    x.unlock();\n    y.unlock();\n\n    float err = af::sum(af::abs(y - 1));\n    printf(\"Error: %f\\n\", err);\n    return 0;\n}\n</pre>\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\n<pre>// Generate input data\naf::array x = af::randu(num, 1);</pre>\nThe necessary memory required for the output is allocated before  the kernel launch.\n<pre>// Create empty array with required dimensions\naf::array y = af::array(num, 1);\n</pre>\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\n<pre> // Get device pointers\n float *d_x = x.device<float>();\n float *d_y = y.device<float>();\n</pre>\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong><a href=\"#note1\"><sup>1/sup></a>\n<pre>// Finish the tasks arrayfire was doing\naf::sync();\n\n// Launch kernel to do the following operations\n// y = sin(x)^2 + cos(x)^2\nlaunch_simple_kernel(d_y, d_x, num);\n</pre>\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\n<pre>// Tell arrayfire it controls the pointers again\nx.unlock();\ny.unlock();\n</pre>\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\n<pre>// Check for errors\n// sin(x)^ + cos(x)^2 == 1\n// The following should print 0\nfloat err = af::sum(af::abs(y - 1));\nprintf(\"Error: %f\\n\", err);\n</pre>\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\n<h3>Launching a CUDA kernel</h3>\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\n<pre>__global__\nstatic void simple_kernel(float *d_y,\n                          const float *d_x,\n                          const int num)\n{\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\n\n    if (id < num) {\n        float x = d_x[id];\n        float sin_x = sin(x);\n        float cos_x = cos(x);\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\n    }\n}\n\nvoid inline launch_simple_kernel(float *d_y,\n                                 const float *d_x,\n                                 const int num)\n{\n    // Set launch configuration\n    const int threads = 256;\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\n    // Synchronize and check for error\n    cudaDeviceSynchronize();\n}\n</pre>\n<h3>Launching an OpenCL kernel</h3>\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated. Since ArrayFire uses its own context internally, you need to get the context from a memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context.\n<pre>void inline launch_simple_kernel(float *d_y,\n                                 const float *d_x,\n                                 const int num)\n{\n    // Read the OpenCL kernel as a string\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\n\n    // Get OpenCL context from memory buffer and create a Queue\n    cl_context context = get_context((cl_mem)d_x);\n    cl_command_queue queue = create_queue(context);\n\n    // Build the OpenCL program and get the kernel\n    cl_program program = build_program(context, simple_kernel_str);\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\n    \n    cl_int err = CL_SUCCESS;\n    int arg = 0;\n\n    // Set input parameters for the kernel\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\n\n    // Set launch configuration\n    size_t local  = 256;\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\n    // Launch OpenCL kernel\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\n    clFinish(queue);\n    return;\n}\n</pre>\nThe code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\n<pre>__kernel\nvoid simple_kernel(__global float *d_y,\n                   __global const float *d_x,\n                   const int num)\n{\n    const int id = get_global_id(0);\n\n    if (id < num) {\n        float x = d_x[id];\n        float sin_x = sin(x);\n        float cos_x = cos(x);\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\n    }\n}\n</pre>\nYou can find the code samples at the following links:\n<ul>\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\n</ul>\n\n<a id=\"note1\"><sup>1</sup></a>: af::sync() is not needed if you are not using streams in CUDA. af::sync() ensures you are not unintenti out of order executions. ','Custom Kernels with ArrayFire','','inherit','open','closed','','5651-autosave-v1','','','2014-05-27 19:49:43','2014-05-27 19:49:43','',5651,'http://sandbox.arrayfire.com/5651-autosave-v1/',0,'revision','',0),(5705,17728,'2014-05-27 19:50:38','2014-05-27 19:50:38','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong><a href=\"#note1\"><sup>1/sup></a>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + cos(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(af::abs(y - 1));\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated. Since ArrayFire uses its own context internally, you need to get the context from a memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nThe code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>\r\n\r\n<a id=\"note1\"><sup>1</sup></a>: af::sync() is not needed if you are not using streams in CUDA. af::sync() ensures you are not unintentionally doing out of order executions. af::sync() is always required when writing OpenCL kernels.','Custom Kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 19:50:38','2014-05-27 19:50:38','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5706,17728,'2014-05-27 19:51:17','2014-05-27 19:51:17','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong><a href=\"#note1\"><sup>1</sup></a>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + cos(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(af::abs(y - 1));\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated. Since ArrayFire uses its own context internally, you need to get the context from a memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nThe code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>\r\n\r\n<a id=\"note1\"><sup>1</sup></a>: af::sync() is not needed if you are not using streams in CUDA. af::sync() ensures you are not unintentionally doing out of order executions. af::sync() is always required when writing OpenCL kernels.','Custom Kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 19:51:17','2014-05-27 19:51:17','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5707,17728,'2014-05-27 19:51:58','2014-05-27 19:51:58','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong><a href=\"#note1\"><sup>1</sup></a>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + cos(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(af::abs(y - 1));\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated. Since ArrayFire uses its own context internally, you need to get the context from a memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nThe code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>\r\n\r\n<sup><a id=\"note1\">1</a>af::sync() is not needed if you are not using streams in CUDA. af::sync() ensures you are not unintentionally doing out of order executions. af::sync() is always required when writing OpenCL kernels.</sup>','Custom Kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 19:51:58','2014-05-27 19:51:58','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5708,17728,'2014-05-27 19:52:25','2014-05-27 19:52:25','As <a title=\"ArrayFire function list\" href=\"http://www.sandbox.arrayfire.com/docs/group__arrayfire__func.htm\" target=\"_blank\">extensive</a> as ArrayFire is, there are a few cases where you are still working with custom CUDA or OpenCL kernels. For example, you may want to integrate ArrayFire into an existing code base for productivity or you may want to keep it around the old implementation for testing purposes. In this post we are going to talk about how to integrate your custom kernels into ArrayFire in a seamless fashion.\r\n<h3>In and Out of ArrayFire</h3>\r\nFirst let us look at the following code and then break it down bit by bit.\r\n<pre>int main()\r\n{\r\n    af::array x = af::randu(num, 1);\r\n\r\n    af::array y = af::array(num, 1);\r\n\r\n    float *d_x = x.device<float>();\r\n    float *d_y = y.device<float>();\r\n\r\n    af::sync();\r\n\r\n    launch_simple_kernel(d_y, d_x, num);\r\n    x.unlock();\r\n    y.unlock();\r\n\r\n    float err = af::sum(af::abs(y - 1));\r\n    printf(\"Error: %f\\n\", err);\r\n    return 0;\r\n}\r\n</pre>\r\nMost kernels require an input. In this case we created a uniform random array, <strong>x.</strong>  If you have an input you can use it instead of <strong>x.</strong>\r\n<pre>// Generate input data\r\naf::array x = af::randu(num, 1);</pre>\r\nThe necessary memory required for the output is allocated before  the kernel launch.\r\n<pre>// Create empty array with required dimensions\r\naf::array y = af::array(num, 1);\r\n</pre>\r\nIn this example, the output is the same size as in the input. Note that the actual output data type is not specified. For such cases, ArrayFire assumes the data type is single precision floating point (<a title=\"ArrayFire data types\" href=\"http://www.sandbox.arrayfire.com/docs/namespaceaf.htm#acfe99d230e216901bd782cc580e4e815\"><strong> af::f32 </strong></a>). If necessary, the data type can be specified at the end of the <a title=\"array constructors\" href=\"http://www.sandbox.arrayfire.com/docs/classaf_1_1array.htm\"><strong> array(..)</strong></a> constructor. Once you have the input and output arrays, you will need to extract the device pointers / objects using <a title=\"Getting device pointers from ArrayFire\" href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__device.htm\">array::device()</a> method in the following manner.\r\n<pre> // Get device pointers\r\n float *d_x = x.device<float>();\r\n float *d_y = y.device<float>();\r\n</pre>\r\nBefore  launching your custom kernel, it is best to make sure that all ArrayFire computations have finished. This can be called by using <strong><a href=\"http://www.sandbox.arrayfire.com/docs/group__array__func__cpp__sync.htm\"> af::sync()</a>; </strong><a href=\"#note1\"><sup>1</sup></a>\r\n<pre>// Finish the tasks arrayfire was doing\r\naf::sync();\r\n\r\n// Launch kernel to do the following operations\r\n// y = sin(x)^2 + cos(x)^2\r\nlaunch_simple_kernel(d_y, d_x, num);\r\n</pre>\r\nThe function <strong> launch_simple_kernel </strong>handles the launching of your custom kernel. We will have a look at how to do this in CUDA and OpenCL later in the post. Once you have finished your computations, you have to tell ArrayFire to take control of the memory objects.\r\n<pre>// Tell arrayfire it controls the pointers again\r\nx.unlock();\r\ny.unlock();\r\n</pre>\r\nThis is a very crucial step as ArrayFire believes the user is still in control of the pointer. This means that ArrayFire will not perform garbage collection on these objects resulting in memory leaks. You can now proceed with the rest of the program. In our particular example, we are just performing an error check and exiting.\r\n<pre>// Check for errors\r\n// sin(x)^ + cos(x)^2 == 1\r\n// The following should print 0\r\nfloat err = af::sum(af::abs(y - 1));\r\nprintf(\"Error: %f\\n\", err);\r\n</pre>\r\nOne of the benefits of ArrayFire is that it enables you to use the same code base for both CUDA and OpenCL devices. In the same vein, this particular example can be used to extend using a CUDA kernel or an OpenCL kernel. The externally defined <strong>launch_simple_kernel</strong> will be the only part of your code base that will change when moving from CUDA to OpenCL (or vice versa!).\r\n<h3>Launching a CUDA kernel</h3>\r\nIntegrating a CUDA kernel into your ArrayFire code base is a fairly straightforward process. You need to set the launch configuration parameters, launch the kernel and wait for the computations to finish. This is shown below.\r\n<pre>__global__\r\nstatic void simple_kernel(float *d_y,\r\n                          const float *d_x,\r\n                          const int num)\r\n{\r\n    const int id = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n\r\nvoid inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Set launch configuration\r\n    const int threads = 256;\r\n    const int blocks = (num / threads) + ((num % threads) ? 1 : 0);\r\n    simple_kernel<<<blocks, threads>>>(d_y, d_x, num);\r\n    // Synchronize and check for error\r\n    cudaDeviceSynchronize();\r\n}\r\n</pre>\r\n<h3>Launching an OpenCL kernel</h3>\r\nIf you are integrating an OpenCL kernel into your ArrayFire code base, launching a kernel is a bit more complicated. Since ArrayFire uses its own context internally, you need to get the context from a memory object. Once you have access to the same context ArrayFire is using, the rest of the process is exactly the same as launching a stand alone OpenCL context.\r\n<pre>void inline launch_simple_kernel(float *d_y,\r\n                                 const float *d_x,\r\n                                 const int num)\r\n{\r\n    // Read the OpenCL kernel as a string\r\n    std::string simple_kernel_str = get_kernel_string(\"simple.cl\");\r\n\r\n    // Get OpenCL context from memory buffer and create a Queue\r\n    cl_context context = get_context((cl_mem)d_x);\r\n    cl_command_queue queue = create_queue(context);\r\n\r\n    // Build the OpenCL program and get the kernel\r\n    cl_program program = build_program(context, simple_kernel_str);\r\n    cl_kernel   kernel = create_kernel(program, \"simple_kernel\");\r\n    \r\n    cl_int err = CL_SUCCESS;\r\n    int arg = 0;\r\n\r\n    // Set input parameters for the kernel\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_y);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(cl_mem), &d_x);\r\n    err |= clSetKernelArg(kernel, arg++, sizeof(int   ), &num);\r\n\r\n    // Set launch configuration\r\n    size_t local  = 256;\r\n    size_t global = local * (num / local + ((num % local) ? 1 : 0));\r\n    // Launch OpenCL kernel\r\n    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL);\r\n    clFinish(queue);\r\n    return;\r\n}\r\n</pre>\r\nThe code snippet above uses helper functions. You can find the helper functions <a title=\"OpenCL helper functions.\" href=\"https://github.com/arrayfire/arrayfire_examples/blob/master/opencl/helper.h\" target=\"_blank\">over here</a> The OpenCL kernel itself is fairly simple as seen below.\r\n<pre>__kernel\r\nvoid simple_kernel(__global float *d_y,\r\n                   __global const float *d_x,\r\n                   const int num)\r\n{\r\n    const int id = get_global_id(0);\r\n\r\n    if (id < num) {\r\n        float x = d_x[id];\r\n        float sin_x = sin(x);\r\n        float cos_x = cos(x);\r\n        d_y[id] = (sin_x * sin_x) + (cos_x * cos_x);\r\n    }\r\n}\r\n</pre>\r\nYou can find the code samples at the following links:\r\n<ul>\r\n	<li><a title=\"ArrayFire CUDA kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/cuda\" target=\"_blank\">CUDA</a></li>\r\n	<li><a title=\"ArrayFire OpenCL kernel example\" href=\"https://github.com/arrayfire/arrayfire_examples/tree/master/opencl\" target=\"_blank\">OpenCL</a></li>\r\n</ul>\r\n\r\n<sup><a id=\"note1\">1 </a><strong>af::sync() is not needed if you are not using streams in CUDA. af::sync() ensures you are not unintentionally doing out of order executions. af::sync() is always required when writing OpenCL kernels.</strong></sup>','Custom Kernels with ArrayFire','','inherit','open','closed','','5651-revision-v1','','','2014-05-27 19:52:25','2014-05-27 19:52:25','',5651,'http://sandbox.arrayfire.com/5651-revision-v1/',0,'revision','',0),(5709,17795,'2014-05-27 23:32:13','2014-05-27 23:32:13','During the next months, we will be working on a lot of new Computer Vision functionality for ArrayFire. This means dozens of new functions specifically targeted for the most common and used applications in this field, like feature tracking, object classification, scene segmentation, optical flow, stereo-vision, among others, will be added to take full advantage of GPU devices.\r\n\r\nFeature tracking consists of three basic steps:\r\n<ol>\r\n	<li>Detecting good or unique features, normally they are corners or blobs of an image;</li>\r\n	<li>Extracting a descriptor for each feature, that consists of understanding the texture of a small patch around each feature;</li>\r\n	<li>Descriptor matching, finding out the best match for each pair of descriptors (one from the object being tracked, another from a scene that potentially contains that object), if any.</li>\r\n</ol>\r\n<h3>Harris corner detector</h3>\r\nTo get started on what is coming to ArrayFire, in this article we dive deeper in the first step of feature tracking, detecting good features. Through a step-by-step guide, we will develop a simple corner detector, known as the Harris corner detector [1].\r\n\r\nThe Harris corner detector is very simple to implement, especially when you have so many good tools and libraries out there to do the core matrix manipulation. What we specifically need for Harris are some convolutions, together with a few element-wise matrix addition and multiplication operations, all of these operations are present in most scientific tools and libraries that work with matrix manipulation. I will try to avoid going into the mathematical details in this post and go directly to the implementation.\r\n<h5>Loading an image</h5>\r\nBefore starting writing the code for the corner detector, we need to load an image. The image can be either color or gray-scale, but it will only work on the gray-scale version, so if it is a color image, we have to convert it before proceeding.\r\n<pre>// Load a color image\r\narray img_color = loadimage(\"lena.jpg\", true);\r\n// Convert the image from RGB to gray-scale\r\narray img_gray = colorspace(img_color, af_gray, af_rgb);\r\n// For visualization in ArrayFire, color images must be in the [0.0f-1.0f] interval\r\nimg /= 255.f;\r\n</pre>\r\n<h5>Compute first-order derivatives</h5>\r\nThe first step in the Harris corner detector is to determine first order derivatives of an image, in both horizontal and vertical directions. This can be achieved by one convolution for each direction, with the special filter (-1, 0, 1)  for horizontal derivative and its transpose for vertical derivative. ArrayFire contains a function called<code>grad</code>, it calculates gradients in both directions and will perform faster than the two convolutions. The only difference is <conv>grad</code> divides the result by 2, thus the response factor will change, but this can be compensated by using a smaller response while improving computation performance, so it will be used instead.\r\n<pre>\r\n// Calculate image gradients\r\narray ix, iy;\r\ngrad(ix, iy, img_gray);\r\n</pre>\r\n<h5>Compute second-order derivatives</h5>\r\nAt this point, we have both horizontal and vertical first order derivatives of our image, but Harris corner detector is processed with second-order derivatives, which can be easily computed in ArrayFire with simple element-wise multiplications of the first-order derivatives.\r\n<pre>// Compute second-order derivatives\r\narray ixx = ix * ix;\r\narray ixy = ix * iy;\r\narray iyy = iy * iy;\r\n</pre>\r\n<h5>Compute an isotropic window</h5>\r\nTo check the cornerness of each pixel of an image, it\'s not enough to check the pixel value itself, but a small window around that pixel. To reduce noise sensitivity and have an isotropic response, Harris claims that a smooth circular window should be used, and it can be achieved by filtering of all three second-order derivatives with a Gaussian kernel.\r\n<pre>// Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels\r\n// These values can be changed to use a smaller or larger window\r\narray gauss_filt = gaussiankernel(5, 5, 1.0, 1.0);\r\n\r\n// Filter second-order derivatives with Gaussian kernel computed previously\r\nixx = convolve(ixx, gauss_filt);\r\nixy = convolve(ixy, gauss_filt);\r\niyy = convolve(iyy, gauss_filt);\r\n</pre>\r\n<h5>Compute trace and determinant</h5>\r\nFrom a second-order Hessian matrix, we then compute the values of its trace and determinant. These are the values we will need later to calculate the Harris response for each pixel in the image.\r\n<pre>// Calculate trace\r\narray tr = ixx + iyy;\r\n// Calculate determinant\r\narray det = ixx * iyy - ixy * ixy;\r\n</pre>\r\n<h5>Compute Harris response</h5>\r\nFinally, we then calculate the Harris response for each pixel. For this calculation, Harris uses an empirically defined constant <code>k</code>. This constant is usually very small, and usually it ranges from <code>0.04</code> to <code>0.06</code>. In our case, we will use <code>k = 0.04</code>, but we encourage you to play with this value and see how the result changes.\r\n<pre>// Calculate Harris response\r\narray response = det - 0.04f * (tr * tr);\r\n</pre>\r\n<h5>Selection of good corners</h5>\r\nNow we already have our Harris responses for each pixel in the image. This value is used to determine whether a pixel is a corner or not. The standard way is to perform a non-maximal suppression, meaning that for each pixel it can only be a corner if it is a maximum compared to its 8 adjacent pixels. At the moment we do not have an easy way to compute a non-maximal suppression with ArrayFire, we have to write our own kernel for that, and that is only one of the cool things we will be able to do with our new computer vision toolset for ArrayFire.\r\n\r\nAn alternative is to do the non-maximal suppression in a naive way. To do this, we will use ArrayFire\'s <code>maxfilt</code> function, that filters the image with a mask of <code>NxM</code> pixel and returns the maximum value of the neighborhood to the pixel centered within the mask. In this case we will use a <code>3x3</code> pixel mask to return the maximum of the 8-neighborhood, including the central pixel itself.\r\n\r\nThe <code>maxfilt</code> function alone will not perform a non-maximal suppression, but with a few more lines of code we can get the proper responses.\r\n\r\nThe nature of a pixel can be determined by the Harris responses, a negative response means that a pixel corresponds to the segment of an edge. If the response is small but positive, it corresponds to a flat region. Only a large response corresponds to a corner. By thresholding the response array with the minimum desired Harris response, that for our example will be 10<sup>5</sup>, we can calculate a binary response array for which only pixels with a value greater than this threshold will be true. We then multiply it to the original response array to get a new array containing only responses greater that 10<sup>6</sup>.\r\n\r\nHere, we will use a threshold of 10<sup>5</sup>. For the implementation presented in this article, we found that corners seem to be better for responses larger than 10<sup>4</sup>, but you can and should play with these values to see how it will affect the image you are working on.\r\n\r\nThe last step for this is testing whether each pixel is equal to the maximum Harris response of the neighborhood. If it is equal, then we keep it, else, the response is not a local maximum and we discard it.\r\n\r\n<pre>\r\n// Gets maximum response for each 3x3 neighborhood\r\narray max_resp = maxfilt(response, 3, 3);\r\n\r\n// Discard responses that are not greater than threshold\r\narray corners = response > 1e6f;\r\ncorners = corners * response;\r\n\r\n// Discard responses that are not equal to maximum neighborhood response\r\ncorners = (corners == max_resp);\r\n</pre>\r\n\r\nIf you still think you want a non-maximal suppression kernel for yourself, you can still write it instead of using the last piece of code above. If you have never written your own kernel to work with an ArrayFire array, check out the <a href=\"http://sandbox.arrayfire.com/custom-kernels-with-arrayfire/\">Custom Kernels with ArrayFire</a> post. Writing the non-maximal suppression kernel itself will not take more than 20 or 30 lines of code.\r\n\r\n<h5>Plotting corners</h5>\r\n\r\nThis last step is done on the CPU side, we only do this to show the corners that are detected. Most likely, you will not need to do this unless you want to visualize, but for the sake of clarity, we include this part to show the result.\r\n<pre>// Gets host pointer to response data\r\nfloat* h_corners = corners.host();\r\n\r\n// Draw draw_len x draw_len crosshairs where the corners are\r\nconst int draw_len = 3;\r\nfor (int y = draw_len; y < img.dims(0) - draw_len; y++) {\r\n    for (int x = draw_len; x < img.dims(1) - draw_len; x++) {\r\n        // Only draws crosshair if is a corner\r\n        if (h_corners[x * corners.dims(0) + y] == true) {\r\n            // Draw horizontal line of (draw_len * 2 + 1) pixels centered on the corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(y, seq(x-draw_len, x+draw_len), 0) = 0.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 1) = 1.f;\r\n            img_color(y, seq(x-draw_len, x+draw_len), 2) = 0.f;\r\n\r\n            // Draw vertical line of (draw_len * 2 + 1) pixels centered on  the corner\r\n            // Set only the first channel to 1 (green lines)\r\n            img_color(seq(y-draw_len, y+draw_len), x, 0) = 0.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 1) = 1.f;\r\n            img_color(seq(y-draw_len, y+draw_len), x, 2) = 0.f;\r\n        }\r\n    }\r\n}</pre>\r\n<h5>Visualize results</h5>\r\nFinally, the image can be visualized.\r\n<pre>// Previews color image with green crosshairs\r\nimage(img_color);\r\n</pre>\r\nBelow you can see Lena\'s picture after the Harris corner detection and plotting. The green crosshairs indicate where corners are.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\"><img class=\"alignnone size-full wp-image-5670\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena1.png\" alt=\"Lena with Harris corners\" width=\"1024\" height=\"600\" /></a>\r\n\r\nTo test for correctness of the algorithm, nothing better than a picture with well-defined corners. Below you can see the picture of a white square on a black background and the corners marked by green crosshairs.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_square.png\"><img class=\"alignnone size-full wp-image-5678\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_square.png\" alt=\"Square with Harris corners\" width=\"1024\" height=\"600\" /></a>\r\n\r\nWe would like to hear from you, what you are working on the computer vision field and which features you would like to see in ArrayFire. Please share your thoughts and requests below or contact us at <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a>.\r\n<h5>References</h5>\r\n[1] Harris, Chris, and Mike Stephens. \"A combined corner and edge detector.\" <em>Alvey vision conference</em>. Vol. 15. 1988.\r\n','Writing a Simple Corner Detector with ArrayFire','','inherit','open','closed','','5659-revision-v1','','','2014-05-27 23:32:13','2014-05-27 23:32:13','',5659,'http://sandbox.arrayfire.com/5659-revision-v1/',0,'revision','',0),(5710,17795,'2014-05-27 23:50:15','2014-05-27 23:50:15','','Harris Corners - Lena','','inherit','open','closed','','harris_lena','','','2014-05-27 23:50:15','2014-05-27 23:50:15','',5659,'http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_lena.png',0,'attachment','image/png',0),(5711,17795,'2014-05-27 23:50:18','2014-05-27 23:50:18','','Harris Corners - Square','','inherit','open','closed','','harris_square','','','2014-05-27 23:50:18','2014-05-27 23:50:18','',5659,'http://sandbox.arrayfire.com/wp-content/uploads/2014/12/harris_square.png',0,'attachment','image/png',0),