(5577,17729,'2014-05-15 23:02:29','2014-05-15 23:02:29','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n<code>\r\nJNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\nJNIEnv *env,\r\njclass clazz,\r\njobject outBmp,\r\njByteArray inData,\r\njint width,\r\njint height)\r\n{\r\n// TODO: process the input and write the output\r\n}\r\n</code>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick processor.h to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per [Oracle\'s java documenatation](http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html), 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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick processor.cpp to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the gaussianBlur function as member of the corresponding class. For example, say we have a java class shown as below\r\n\r\n<code>\r\npackage com.example;\r\npublic class CameraPreview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {\r\nstatic {\r\nSystem.loadLibrary(\"JNIProcessor\");\r\n}\r\nprivate void gaussianBlur(Bitmap out, byte[] in, int width, int height);\r\n\r\nprivate Bitmap mTexture;\r\nprivate int width, height;\r\n\r\n////TODO: constructors (setup configuration of mTexture like width and height)\r\n////TODO: Code for surfaceCreated(), surfaceChanged(), surfaceDestroyed()\r\n\r\npublic void onPreviewFrame(byte[] data, Camera camera) {\r\ngaussianBlur(mTexture,data,width,height);\r\ninvalidate();\r\n}\r\n\r\n////TODO: Code onDraw() method that can draw the processed bitmap on to canvas\r\n}\r\n</code>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:02:29','2014-05-15 23:02:29','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5578,17729,'2014-05-15 23:03:41','2014-05-15 23:03:41','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n<code>\r\nJNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\nJNIEnv *env,\r\njclass clazz,\r\njobject outBmp,\r\njByteArray inData,\r\njint width,\r\njint height)\r\n{\r\n// TODO: process the input and write the output\r\n}\r\n</code>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick processor.h to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per [Oracle\'s java documenatation](http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html), 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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick processor.cpp to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the gaussianBlur function as member of the corresponding class. For example, say we have a java class shown as below\r\n\r\n<code>\r\npackage com.example;\r\npublic class CameraPreview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {\r\n    static {\r\n        System.loadLibrary(\"JNIProcessor\");\r\n    }\r\n    private void gaussianBlur(Bitmap out, byte[] in, int width, int height);\r\n    private Bitmap mTexture;\r\n    private int width, height;\r\n    ////TODO: constructors (setup configuration of mTexture like width and height)\r\n    ////TODO: Code for surfaceCreated(), surfaceChanged(), surfaceDestroyed()\r\n    public void onPreviewFrame(byte[] data, Camera camera) {\r\n    gaussianBlur(mTexture,data,width,height);\r\n    invalidate();\r\n    }\r\n    ////TODO: Code onDraw() method that can draw the processed bitmap on to canvas\r\n}\r\n</code>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:03:41','2014-05-15 23:03:41','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5579,17729,'2014-05-15 23:04:38','2014-05-15 23:04:38','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n<code>\r\nJNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\nJNIEnv *env,\r\njclass clazz,\r\njobject outBmp,\r\njByteArray inData,\r\njint width,\r\njint height)\r\n{\r\n// TODO: process the input and write the output\r\n}\r\n</code>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick processor.h to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per [Oracle\'s java documenatation](http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html), 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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick processor.cpp to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the gaussianBlur function as member of the corresponding class. For example, say we have a java class shown as below\r\n<code>\r\npackage com.example;\r\npublic class CameraPreview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {\r\nstatic {\r\nSystem.loadLibrary(\"JNIProcessor\");\r\n}\r\nprivate void gaussianBlur(Bitmap out, byte[] in, int width, int height);\r\nprivate Bitmap mTexture;\r\nprivate int width, height;\r\n////TODO: constructors (setup configuration of mTexture like width and height)\r\n////TODO: Code for surfaceCreated(), surfaceChanged(), surfaceDestroyed()\r\npublic void onPreviewFrame(byte[] data, Camera camera) {\r\ngaussianBlur(mTexture,data,width,height);\r\ninvalidate();\r\n}\r\n////TODO: Code onDraw() method that can draw the processed bitmap on to canvas\r\n}\r\n</code>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:04:38','2014-05-15 23:04:38','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5580,17729,'2014-05-15 23:07:03','2014-05-15 23:07:03','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n<code>\r\nJNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\nJNIEnv *env,\r\njclass clazz,\r\njobject outBmp,\r\njByteArray inData,\r\njint width,\r\njint height)\r\n{\r\n// TODO: process the input and write the output\r\n}\r\n</code>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick processor.h to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick processor.cpp to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the gaussianBlur function as member of the corresponding class. For example, say we have a java class shown as below\r\n<code>\r\npackage com.example;\r\npublic class CameraPreview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {\r\nstatic {\r\nSystem.loadLibrary(\"JNIProcessor\");\r\n}\r\nprivate void gaussianBlur(Bitmap out, byte[] in, int width, int height);\r\nprivate Bitmap mTexture;\r\nprivate int width, height;\r\n////TODO: constructors (setup configuration of mTexture like width and height)\r\n////TODO: Code for surfaceCreated(), surfaceChanged(), surfaceDestroyed()\r\npublic void onPreviewFrame(byte[] data, Camera camera) {\r\ngaussianBlur(mTexture,data,width,height);\r\ninvalidate();\r\n}\r\n////TODO: Code onDraw() method that can draw the processed bitmap on to canvas\r\n}\r\n</code>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:07:03','2014-05-15 23:07:03','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5582,17729,'2014-05-15 23:23:42','2014-05-15 23:23:42','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n<code>\r\nJNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\nJNIEnv *env,\r\njclass clazz,\r\njobject outBmp,\r\njByteArray inData,\r\njint width,\r\njint height)\r\n{\r\n// TODO: process the input and write the output\r\n}\r\n</code>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the <em>gaussianBlur</em> function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>\r\n\r\nThe entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:23:42','2014-05-15 23:23:42','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5583,17729,'2014-05-15 23:35:53','2014-05-15 23:35:53','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n<code>\r\n[code]</code>\r\n\r\n<span style=\"font-family: monospace; line-height: 1.5em;\">JNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(</span>\r\n\r\n<span style=\"font-family: monospace;\">JNIEnv *env,</span><br style=\"font-family: monospace;\" /><span style=\"font-family: monospace;\">jclass clazz,</span><br style=\"font-family: monospace;\" /><span style=\"font-family: monospace;\">jobject outBmp,</span><br style=\"font-family: monospace;\" /><span style=\"font-family: monospace;\">jByteArray inData,</span><br style=\"font-family: monospace;\" /><span style=\"font-family: monospace;\">jint width,</span><br style=\"font-family: monospace;\" /><span style=\"font-family: monospace;\">jint height)</span><br style=\"font-family: monospace;\" /><span style=\"font-family: monospace;\">{</span><br style=\"font-family: monospace;\" /><span style=\"font-family: monospace;\">// TODO: process the input and write the output</span>\r\n\r\n<code><span style=\"line-height: 1.5em;\">}</span></code>\r\n\r\n<code>[/code]\r\n</code>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the <em>gaussianBlur</em> function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>\r\n\r\nThe entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:35:53','2014-05-15 23:35:53','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5584,17729,'2014-05-15 23:37:28','2014-05-15 23:37:28','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n\r\n[code]\r\nJNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\n				JNIEnv      *env,\r\n				jclass      clazz,\r\n				jobject     outBmp,\r\n				jByteArray  inData,\r\n				jint        width,\r\n				jint        height)\r\n{\r\n	// TODO: process the input and write the output\r\n}\r\n[/code]\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the <em>gaussianBlur</em> function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>\r\n\r\nThe entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:37:28','2014-05-15 23:37:28','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5585,17729,'2014-05-15 23:56:41','2014-05-15 23:56:41','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n\r\n<pre class=\"brush:c\">\r\nJNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\nJNIEnv *env,\r\njclass clazz,\r\njobject outBmp,\r\njByteArray inData,\r\njint width,\r\njint height)\r\n{\r\n// TODO: process the input and write the output\r\n}\r\n</pre>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the <em>gaussianBlur</em> function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>\r\n\r\nThe entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:56:41','2014-05-15 23:56:41','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5586,17729,'2014-05-15 23:57:08','2014-05-15 23:57:08','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n\r\n<code class=\"brush:c\">\r\nJNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\nJNIEnv *env,\r\njclass clazz,\r\njobject outBmp,\r\njByteArray inData,\r\njint width,\r\njint height)\r\n{\r\n// TODO: process the input and write the output\r\n}\r\n</code>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the <em>gaussianBlur</em> function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>\r\n\r\nThe entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:57:08','2014-05-15 23:57:08','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5587,17729,'2014-05-15 23:57:22','2014-05-15 23:57:22','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n\r\n<pre class=\"brush:c\">\r\nJNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\nJNIEnv *env,\r\njclass clazz,\r\njobject outBmp,\r\njByteArray inData,\r\njint width,\r\njint height)\r\n{\r\n// TODO: process the input and write the output\r\n}\r\n</pre>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the <em>gaussianBlur</em> function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>\r\n\r\nThe entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:57:22','2014-05-15 23:57:22','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5588,17729,'2014-05-15 23:57:41','2014-05-15 23:57:41','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<code>\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</code>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<code>\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</code>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n\r\n<pre class=\"brush:c\">\r\nJNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height)\r\n{\r\n    // TODO: process the input and write the output\r\n}\r\n</pre>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the <em>gaussianBlur</em> function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>\r\n\r\nThe entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:57:41','2014-05-15 23:57:41','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5589,17729,'2014-05-15 23:59:05','2014-05-15 23:59:05','<h2>Code</h2>\r\nI used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.\r\n\r\nMy final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate</li>\r\n	<li>Write them yourself</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.\r\n<pre class=\"brush:c\">\r\n#define DECLARE(returnType,fullClassName,func,...) \\\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);\r\n</pre>\r\n\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<pre class=\"brush:c\">\r\nDECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)\r\n</pre>\r\n\r\nI like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n\r\n<pre class=\"brush:c\">\r\nJNIEXPORT\r\nvoid JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height)\r\n{\r\n    // TODO: process the input and write the output\r\n}\r\n</pre>\r\n\r\nWith appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.\r\n\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.\r\n<code>\r\nadb logcat -s \"JNIProcessor\"\r\n</code>\r\n\r\nNext comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:\r\n<ul>\r\n	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>\r\n	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>\r\n</ul>\r\nThere are couple of other functions that are not related to JNI.\r\n<ul>\r\n	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>\r\n	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\nClick <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.\r\n\r\nI will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions\r\n<ul>\r\n	<li>pure c method</li>\r\n	<li>opencl kernel for Snapdragon mobile device</li>\r\n</ul>\r\n<h2>Build (for Linux)</h2>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.\r\n<ol>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>\r\n	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>\r\n	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>\r\n	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>\r\n	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>\r\n	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>\r\n</ol>\r\n<h3>Android.mk</h3>\r\n<code>\r\nLOCAL_PATH := $(call my-dir)\r\ninclude $(CLEAR_VARS)\r\nLOCAL_MODULE := JNIProcessor\r\nLOCAL_ARM_MODE := arm\r\nLOCAL_SRC_FILES := processor.cpp\r\nLOCAL_CPPFLAGS := -fexceptions\r\nLOCAL_LDLIBS := -ljnigraphics -llog\r\ninclude $(BUILD_SHARED_LIBRARY)\r\n</code>\r\n<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>\r\n<h3>Application.mk</h3>\r\n<code>\r\nAPP_OPTIM := release\r\nAPP_STL := gnustl_static\r\nAPP_PLATFORM:= android-14\r\n</code>\r\n<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.\r\n<h2>Use the shared library</h2>\r\nNow, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the <em>gaussianBlur</em> function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>\r\n\r\nThe entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-15 23:59:05','2014-05-15 23:59:05','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5590,17729,'2014-05-16 00:11:18','2014-05-16 00:11:18','<h1 id=\"code\">Code</h1>\r\n<p>I used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.</p>\r\n<p>My final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.</p>\r\n<ul>\r\n<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate<br /></li>\r\n<li>Write them yourself</li>\r\n</ul>\r\n<p>I took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define DECLARE(returnType,fullClassName,func,...) \\</span>\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);</code></pre>\r\n<p>An example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">DECLARE(<span class=\"dt\">void</span>,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)</code></pre>\r\n<p>I like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.</p>\r\n<p>Unless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">JNIEXPORT <span class=\"dt\">void</span> JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height)\r\n{\r\n    <span class=\"co\">// TODO: process the input and write the output</span>\r\n}</code></pre>\r\n<p>Click <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 command <code>adb logcat</code> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <code>app_name</code> to adb 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>Next comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:</p>\r\n<ul>\r\n<li><code>AndroidBitmap_getInfo</code> - used to get bitmap details like width, height, stride, format.<br /></li>\r\n<li><code>AndroidBitmap_lockPixels</code> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.<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 of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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>There are couple of other functions that are not related to JNI.</p>\r\n<ul>\r\n<li><code>throwJavaException</code> - convenience function used to throw java exceptions from within jni routines.<br /></li>\r\n<li><code>blur_helper</code> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\n<p>Click <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <code>gblur</code> can be done very easily using a for loop.</p>\r\n<p>I will cover the function <code>convertNV21toRGBA8888</code> in a future post. Will try to do two versions</p>\r\n<ul>\r\n<li>pure c method<br /></li>\r\n<li><code>OpenCL</code> kernel for Snapdragon mobile device with Adreno 320 GPU</li>\r\n</ul>\r\n<h1 id=\"build-for-linux\">Build (for Linux)</h1>\r\n<p>blah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool <code>ndk-build</code>. We need to setup some stuff to run the build command <code>ndk-build</code>.</p>\r\n<ol>\r\n<li>Do <code>mkdir -p ~/jni_droid_test</code> OR Go to root folder of your android application.<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> appened to it.<br /></li>\r\n<li>Do <code>mkdir -p ~/jni_droid_test/jni</code><br /></li>\r\n<li>Do <code>touch Android.mk and Application.mk</code> and prepare the content of the files as directed below.<br /></li>\r\n<li>Do <code>ndk-build</code> from <code>~/jni_droid_test</code></li>\r\n</ol>\r\n<h2 id=\"android.mk\">Android.mk</h2>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">LOCAL_PATH</span>  := <span class=\"ot\">$(</span><span class=\"kw\">call</span> my-dir<span class=\"ot\">)</span>\r\n<span class=\"kw\">include</span> <span class=\"ot\">$(</span><span class=\"kw\">CLEAR_VARS</span><span class=\"ot\">)</span>\r\n<span class=\"kw\">LOCAL_MODULE</span>    := JNIProcessor\r\n<span class=\"kw\">LOCAL_ARM_MODE</span>  := arm\r\n<span class=\"kw\">LOCAL_SRC_FILES</span> := processor.cpp\r\n<span class=\"kw\">LOCAL_CPPFLAGS</span>  := -fexceptions\r\n<span class=\"kw\">LOCAL_LDLIBS</span>    := -ljnigraphics -llog\r\n<span class=\"kw\">include</span> <span class=\"ot\">$(</span><span class=\"kw\">BUILD_SHARED_LIBRARY</span><span class=\"ot\">)</span></code></pre>\r\n<p><code>LOCAL_MODULE := JNIProcessor</code> sets the name of the shared library we are going to build. <code>LOCAL_ARM_MODE := arm</code> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <code>LOCAL_SRC_FILES</code> variables should point to all the source files we want to compile, in our case processor.cpp. <code>LOCAL_CPPFLAGS</code> declares that we would be using c++ exceptions in our code. The flags <code>-ljnigraphics</code>, <code>--llog</code> are used for accessing bitmap, print functions respectively. Finally, the line <code>include $(BUILD_SHARED_LIBRARY)</code> that says we want a shared library. In case you want a static version, do the following <code>include $(BUILD_STATIC_LIBRARY)</code></p>\r\n<h2 id=\"application.mk\">Application.mk</h2>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">APP_OPTIM</span>   := release\r\n<span class=\"kw\">APP_STL</span>     := gnustl_static\r\n<span class=\"kw\">APP_PLATFORM</span>:= android-14</code></pre>\r\n<p><code>APP_STL</code> is used to state that the library we are going to build will require static version of GNU STL. <code>APP_PLATFORM</code> should be your target-platorm. <code>APP_OPTIM</code> declares that this is a release version of the library. Should you need a debug version, just do <code>APP_OPTIM := debug</code>.</p>\r\n<h1 id=\"use-the-shared-library\">Use the shared library</h1>\r\n<p>Now, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the gaussianBlur function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>.</p>\r\n<p>The entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>.</p>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-16 00:11:18','2014-05-16 00:11:18','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5591,17729,'2014-05-16 00:13:18','2014-05-16 00:13:18','<h1 id=\"code\">Code</h1>\r\n<p>I used to use java (jython to be precise) when i used to work as sourceCodeWebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.</p>\r\n<p>My final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.</p>\r\n<ul>\r\n<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate<br /></li>\r\n<li>Write them yourself</li>\r\n</ul>\r\n<p>I took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define DECLARE(returnType,fullClassName,func,...) \\</span>\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);</code></pre>\r\n<p>An example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">DECLARE(<span class=\"dt\">void</span>,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)</code></pre>\r\n<p>I like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.</p>\r\n<p>Unless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">JNIEXPORT <span class=\"dt\">void</span> JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height)\r\n{\r\n    <span class=\"co\">// TODO: process the input and write the output</span>\r\n}</code></pre>\r\n<p>Click <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 command <code>adb logcat</code> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <code>app_name</code> to adb 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>Next comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:</p>\r\n<ul>\r\n<li><code>AndroidBitmap_getInfo</code> - used to get bitmap details like width, height, stride, format.<br /></li>\r\n<li><code>AndroidBitmap_lockPixels</code> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.<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 of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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>There are couple of other functions that are not related to JNI.</p>\r\n<ul>\r\n<li><code>throwJavaException</code> - convenience function used to throw java exceptions from within jni routines.<br /></li>\r\n<li><code>blur_helper</code> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\n<p>Click <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <code>gblur</code> can be done very easily using a for loop.</p>\r\n<p>I will cover the function <code>convertNV21toRGBA8888</code> in a future post. Will try to do two versions</p>\r\n<ul>\r\n<li>pure c method<br /></li>\r\n<li><code>OpenCL</code> kernel for Snapdragon mobile device with Adreno 320 GPU</li>\r\n</ul>\r\n<h1 id=\"build-for-linux\">Build (for Linux)</h1>\r\n<p>blah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool <code>ndk-build</code>. We need to setup some stuff to run the build command <code>ndk-build</code>.</p>\r\n<ol>\r\n<li>Do <code>mkdir -p ~/jni_droid_test</code> OR Go to root folder of your android application.<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> appened to it.<br /></li>\r\n<li>Do <code>mkdir -p ~/jni_droid_test/jni</code><br /></li>\r\n<li>Do <code>touch Android.mk and Application.mk</code> and prepare the content of the files as directed below.<br /></li>\r\n<li>Do <code>ndk-build</code> from <code>~/jni_droid_test</code></li>\r\n</ol>\r\n<h2 id=\"android.mk\">Android.mk</h2>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">LOCAL_PATH</span>  := <span class=\"ot\">$(</span><span class=\"kw\">call</span> my-dir<span class=\"ot\">)</span>\r\n<span class=\"kw\">include</span> <span class=\"ot\">$(</span><span class=\"kw\">CLEAR_VARS</span><span class=\"ot\">)</span>\r\n<span class=\"kw\">LOCAL_MODULE</span>    := JNIProcessor\r\n<span class=\"kw\">LOCAL_ARM_MODE</span>  := arm\r\n<span class=\"kw\">LOCAL_SRC_FILES</span> := processor.cpp\r\n<span class=\"kw\">LOCAL_CPPFLAGS</span>  := -fexceptions\r\n<span class=\"kw\">LOCAL_LDLIBS</span>    := -ljnigraphics -llog\r\n<span class=\"kw\">include</span> <span class=\"ot\">$(</span><span class=\"kw\">BUILD_SHARED_LIBRARY</span><span class=\"ot\">)</span></code></pre>\r\n<p><code>LOCAL_MODULE := JNIProcessor</code> sets the name of the shared library we are going to build. <code>LOCAL_ARM_MODE := arm</code> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <code>LOCAL_SRC_FILES</code> variables should point to all the source files we want to compile, in our case processor.cpp. <code>LOCAL_CPPFLAGS</code> declares that we would be using c++ exceptions in our code. The flags <code>-ljnigraphics</code>, <code>--llog</code> are used for accessing bitmap, print functions respectively. Finally, the line <code>include $(BUILD_SHARED_LIBRARY)</code> that says we want a shared library. In case you want a static version, do the following <code>include $(BUILD_STATIC_LIBRARY)</code></p>\r\n<h2 id=\"application.mk\">Application.mk</h2>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">APP_OPTIM</span>   := release\r\n<span class=\"kw\">APP_STL</span>     := gnustl_static\r\n<span class=\"kw\">APP_PLATFORM</span>:= android-14</code></pre>\r\n<p><code>APP_STL</code> is used to state that the library we are going to build will require static version of GNU STL. <code>APP_PLATFORM</code> should be your target-platorm. <code>APP_OPTIM</code> declares that this is a release version of the library. Should you need a debug version, just do <code>APP_OPTIM := debug</code>.</p>\r\n<h1 id=\"use-the-shared-library\">Use the shared library</h1>\r\n<p>Now, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the gaussianBlur function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>.</p>\r\n<p>The entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>.</p>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-16 00:13:18','2014-05-16 00:13:18','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5592,17729,'2014-05-16 00:18:38','2014-05-16 00:18:38','<h1 id=\"code\">Code</h1>\r\n<p>I used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.</p>\r\n<p>My final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.</p>\r\n<ul>\r\n<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate<br /></li>\r\n<li>Write them yourself</li>\r\n</ul>\r\n<p>I took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define DECLARE(returnType,fullClassName,func,...) \\</span>\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);</code></pre>\r\n<p>An example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">DECLARE(<span class=\"dt\">void</span>,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)</code></pre>\r\n<p>I like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.</p>\r\n<p>Unless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">JNIEXPORT <span class=\"dt\">void</span> JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height)\r\n{\r\n    <span class=\"co\">// TODO: process the input and write the output</span>\r\n}</code></pre>\r\n<p>Click <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 command <code>adb logcat</code> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <code>app_name</code> to adb 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>Next comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:</p>\r\n<ul>\r\n<li><code>AndroidBitmap_getInfo</code> - used to get bitmap details like width, height, stride, format.<br /></li>\r\n<li><code>AndroidBitmap_lockPixels</code> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.<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 of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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>There are couple of other functions that are not related to JNI.</p>\r\n<ul>\r\n<li><code>throwJavaException</code> - convenience function used to throw java exceptions from within jni routines.<br /></li>\r\n<li><code>blur_helper</code> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\n<p>Click <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <code>gblur</code> can be done very easily using a for loop.</p>\r\n<p>I will cover the function <code>convertNV21toRGBA8888</code> in a future post. Will try to do two versions</p>\r\n<ul>\r\n<li>pure c method<br /></li>\r\n<li><code>OpenCL</code> kernel for Snapdragon mobile device with Adreno 320 GPU</li>\r\n</ul>\r\n<h1 id=\"build-for-linux\">Build (for Linux)</h1>\r\n<p>blah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool <code>ndk-build</code>. We need to setup some stuff to run the build command <code>ndk-build</code>.</p>\r\n<ol>\r\n<li>Do <code>mkdir -p ~/jni_droid_test</code> OR Go to root folder of your android application.<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> appened to it.<br /></li>\r\n<li>Do <code>mkdir -p ~/jni_droid_test/jni</code><br /></li>\r\n<li>Do <code>touch Android.mk and Application.mk</code> and prepare the content of the files as directed below.<br /></li>\r\n<li>Do <code>ndk-build</code> from <code>~/jni_droid_test</code></li>\r\n</ol>\r\n<h2 id=\"android.mk\">Android.mk</h2>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">LOCAL_PATH</span>  := <span class=\"ot\">$(</span><span class=\"kw\">call</span> my-dir<span class=\"ot\">)</span>\r\n<span class=\"kw\">include</span> <span class=\"ot\">$(</span><span class=\"kw\">CLEAR_VARS</span><span class=\"ot\">)</span>\r\n<span class=\"kw\">LOCAL_MODULE</span>    := JNIProcessor\r\n<span class=\"kw\">LOCAL_ARM_MODE</span>  := arm\r\n<span class=\"kw\">LOCAL_SRC_FILES</span> := processor.cpp\r\n<span class=\"kw\">LOCAL_CPPFLAGS</span>  := -fexceptions\r\n<span class=\"kw\">LOCAL_LDLIBS</span>    := -ljnigraphics -llog\r\n<span class=\"kw\">include</span> <span class=\"ot\">$(</span><span class=\"kw\">BUILD_SHARED_LIBRARY</span><span class=\"ot\">)</span></code></pre>\r\n<p><code>LOCAL_MODULE := JNIProcessor</code> sets the name of the shared library we are going to build. <code>LOCAL_ARM_MODE := arm</code> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <code>LOCAL_SRC_FILES</code> variables should point to all the source files we want to compile, in our case processor.cpp. <code>LOCAL_CPPFLAGS</code> declares that we would be using c++ exceptions in our code. The flags <code>-ljnigraphics</code>, <code>--llog</code> are used for accessing bitmap, print functions respectively. Finally, the line <code>include $(BUILD_SHARED_LIBRARY)</code> that says we want a shared library. In case you want a static version, do the following <code>include $(BUILD_STATIC_LIBRARY)</code></p>\r\n<h2 id=\"application.mk\">Application.mk</h2>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">APP_OPTIM</span>   := release\r\n<span class=\"kw\">APP_STL</span>     := gnustl_static\r\n<span class=\"kw\">APP_PLATFORM</span>:= android-14</code></pre>\r\n<p><code>APP_STL</code> is used to state that the library we are going to build will require static version of GNU STL. <code>APP_PLATFORM</code> should be your target-platorm. <code>APP_OPTIM</code> declares that this is a release version of the library. Should you need a debug version, just do <code>APP_OPTIM := debug</code>.</p>\r\n<h1 id=\"use-the-shared-library\">Use the shared library</h1>\r\n<p>Now, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the gaussianBlur function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>.</p>\r\n<p>The entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>.</p>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-16 00:18:38','2014-05-16 00:18:38','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5593,17729,'2014-05-16 00:19:31','2014-05-16 00:19:31','<h1 id=\"code\">Code</h1>\r\n<p>I used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.</p>\r\n<p>My final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.</p>\r\n<ul>\r\n<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate<br /></li>\r\n<li>Write them yourself</li>\r\n</ul>\r\n<p>I took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.</p>\r\n<pre class=\"sourceCode c\" style=\"color:blue\"><code class=\"sourceCode c\"><span class=\"ot\">#define DECLARE(returnType,fullClassName,func,...) \\</span>\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);</code></pre>\r\n<p>An example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">DECLARE(<span class=\"dt\">void</span>,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)</code></pre>\r\n<p>I like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.</p>\r\n<p>Unless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">JNIEXPORT <span class=\"dt\">void</span> JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height)\r\n{\r\n    <span class=\"co\">// TODO: process the input and write the output</span>\r\n}</code></pre>\r\n<p>Click <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 command <code>adb logcat</code> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <code>app_name</code> to adb 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>Next comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:</p>\r\n<ul>\r\n<li><code>AndroidBitmap_getInfo</code> - used to get bitmap details like width, height, stride, format.<br /></li>\r\n<li><code>AndroidBitmap_lockPixels</code> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.<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 of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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>There are couple of other functions that are not related to JNI.</p>\r\n<ul>\r\n<li><code>throwJavaException</code> - convenience function used to throw java exceptions from within jni routines.<br /></li>\r\n<li><code>blur_helper</code> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\n<p>Click <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <code>gblur</code> can be done very easily using a for loop.</p>\r\n<p>I will cover the function <code>convertNV21toRGBA8888</code> in a future post. Will try to do two versions</p>\r\n<ul>\r\n<li>pure c method<br /></li>\r\n<li><code>OpenCL</code> kernel for Snapdragon mobile device with Adreno 320 GPU</li>\r\n</ul>\r\n<h1 id=\"build-for-linux\">Build (for Linux)</h1>\r\n<p>blah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool <code>ndk-build</code>. We need to setup some stuff to run the build command <code>ndk-build</code>.</p>\r\n<ol>\r\n<li>Do <code>mkdir -p ~/jni_droid_test</code> OR Go to root folder of your android application.<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> appened to it.<br /></li>\r\n<li>Do <code>mkdir -p ~/jni_droid_test/jni</code><br /></li>\r\n<li>Do <code>touch Android.mk and Application.mk</code> and prepare the content of the files as directed below.<br /></li>\r\n<li>Do <code>ndk-build</code> from <code>~/jni_droid_test</code></li>\r\n</ol>\r\n<h2 id=\"android.mk\">Android.mk</h2>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">LOCAL_PATH</span>  := <span class=\"ot\">$(</span><span class=\"kw\">call</span> my-dir<span class=\"ot\">)</span>\r\n<span class=\"kw\">include</span> <span class=\"ot\">$(</span><span class=\"kw\">CLEAR_VARS</span><span class=\"ot\">)</span>\r\n<span class=\"kw\">LOCAL_MODULE</span>    := JNIProcessor\r\n<span class=\"kw\">LOCAL_ARM_MODE</span>  := arm\r\n<span class=\"kw\">LOCAL_SRC_FILES</span> := processor.cpp\r\n<span class=\"kw\">LOCAL_CPPFLAGS</span>  := -fexceptions\r\n<span class=\"kw\">LOCAL_LDLIBS</span>    := -ljnigraphics -llog\r\n<span class=\"kw\">include</span> <span class=\"ot\">$(</span><span class=\"kw\">BUILD_SHARED_LIBRARY</span><span class=\"ot\">)</span></code></pre>\r\n<p><code>LOCAL_MODULE := JNIProcessor</code> sets the name of the shared library we are going to build. <code>LOCAL_ARM_MODE := arm</code> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <code>LOCAL_SRC_FILES</code> variables should point to all the source files we want to compile, in our case processor.cpp. <code>LOCAL_CPPFLAGS</code> declares that we would be using c++ exceptions in our code. The flags <code>-ljnigraphics</code>, <code>--llog</code> are used for accessing bitmap, print functions respectively. Finally, the line <code>include $(BUILD_SHARED_LIBRARY)</code> that says we want a shared library. In case you want a static version, do the following <code>include $(BUILD_STATIC_LIBRARY)</code></p>\r\n<h2 id=\"application.mk\">Application.mk</h2>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">APP_OPTIM</span>   := release\r\n<span class=\"kw\">APP_STL</span>     := gnustl_static\r\n<span class=\"kw\">APP_PLATFORM</span>:= android-14</code></pre>\r\n<p><code>APP_STL</code> is used to state that the library we are going to build will require static version of GNU STL. <code>APP_PLATFORM</code> should be your target-platorm. <code>APP_OPTIM</code> declares that this is a release version of the library. Should you need a debug version, just do <code>APP_OPTIM := debug</code>.</p>\r\n<h1 id=\"use-the-shared-library\">Use the shared library</h1>\r\n<p>Now, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the gaussianBlur function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>.</p>\r\n<p>The entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>.</p>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-16 00:19:31','2014-05-16 00:19:31','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5594,17729,'2014-05-16 00:19:55','2014-05-16 00:19:55','<h1 id=\"code\">Code</h1>\r\n<p>I used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.</p>\r\n<p>My final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.</p>\r\n<ul>\r\n<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate<br /></li>\r\n<li>Write them yourself</li>\r\n</ul>\r\n<p>I took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define DECLARE(returnType,fullClassName,func,...) \\</span>\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);</code></pre>\r\n<p>An example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">DECLARE(<span class=\"dt\">void</span>,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)</code></pre>\r\n<p>I like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.</p>\r\n<p>Unless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">JNIEXPORT <span class=\"dt\">void</span> JNICALL Java_com_example_CameraPreview_gaussianBlur(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height)\r\n{\r\n    <span class=\"co\">// TODO: process the input and write the output</span>\r\n}</code></pre>\r\n<p>Click <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 command <code>adb logcat</code> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <code>app_name</code> to adb 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>Next comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:</p>\r\n<ul>\r\n<li><code>AndroidBitmap_getInfo</code> - used to get bitmap details like width, height, stride, format.<br /></li>\r\n<li><code>AndroidBitmap_lockPixels</code> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.<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 of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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>There are couple of other functions that are not related to JNI.</p>\r\n<ul>\r\n<li><code>throwJavaException</code> - convenience function used to throw java exceptions from within jni routines.<br /></li>\r\n<li><code>blur_helper</code> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>\r\n</ul>\r\n<p>Click <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. A navie implementation of gaussian blur for function <code>gblur</code> can be done very easily using a for loop.</p>\r\n<p>I will cover the function <code>convertNV21toRGBA8888</code> in a future post. Will try to do two versions</p>\r\n<ul>\r\n<li>pure c method<br /></li>\r\n<li><code>OpenCL</code> kernel for Snapdragon mobile device with Adreno 320 GPU</li>\r\n</ul>\r\n<h1 id=\"build-for-linux\">Build (for Linux)</h1>\r\n<p>blah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool <code>ndk-build</code>. We need to setup some stuff to run the build command <code>ndk-build</code>.</p>\r\n<ol>\r\n<li>Do <code>mkdir -p ~/jni_droid_test</code> OR Go to root folder of your android application.<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> appened to it.<br /></li>\r\n<li>Do <code>mkdir -p ~/jni_droid_test/jni</code><br /></li>\r\n<li>Do <code>touch Android.mk and Application.mk</code> and prepare the content of the files as directed below.<br /></li>\r\n<li>Do <code>ndk-build</code> from <code>~/jni_droid_test</code></li>\r\n</ol>\r\n<h2 id=\"android.mk\">Android.mk</h2>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">LOCAL_PATH</span>  := <span class=\"ot\">$(</span><span class=\"kw\">call</span> my-dir<span class=\"ot\">)</span>\r\n<span class=\"kw\">include</span> <span class=\"ot\">$(</span><span class=\"kw\">CLEAR_VARS</span><span class=\"ot\">)</span>\r\n<span class=\"kw\">LOCAL_MODULE</span>    := JNIProcessor\r\n<span class=\"kw\">LOCAL_ARM_MODE</span>  := arm\r\n<span class=\"kw\">LOCAL_SRC_FILES</span> := processor.cpp\r\n<span class=\"kw\">LOCAL_CPPFLAGS</span>  := -fexceptions\r\n<span class=\"kw\">LOCAL_LDLIBS</span>    := -ljnigraphics -llog\r\n<span class=\"kw\">include</span> <span class=\"ot\">$(</span><span class=\"kw\">BUILD_SHARED_LIBRARY</span><span class=\"ot\">)</span></code></pre>\r\n<p><code>LOCAL_MODULE := JNIProcessor</code> sets the name of the shared library we are going to build. <code>LOCAL_ARM_MODE := arm</code> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <code>LOCAL_SRC_FILES</code> variables should point to all the source files we want to compile, in our case processor.cpp. <code>LOCAL_CPPFLAGS</code> declares that we would be using c++ exceptions in our code. The flags <code>-ljnigraphics</code>, <code>--llog</code> are used for accessing bitmap, print functions respectively. Finally, the line <code>include $(BUILD_SHARED_LIBRARY)</code> that says we want a shared library. In case you want a static version, do the following <code>include $(BUILD_STATIC_LIBRARY)</code></p>\r\n<h2 id=\"application.mk\">Application.mk</h2>\r\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">APP_OPTIM</span>   := release\r\n<span class=\"kw\">APP_STL</span>     := gnustl_static\r\n<span class=\"kw\">APP_PLATFORM</span>:= android-14</code></pre>\r\n<p><code>APP_STL</code> is used to state that the library we are going to build will require static version of GNU STL. <code>APP_PLATFORM</code> should be your target-platorm. <code>APP_OPTIM</code> declares that this is a release version of the library. Should you need a debug version, just do <code>APP_OPTIM := debug</code>.</p>\r\n<h1 id=\"use-the-shared-library\">Use the shared library</h1>\r\n<p>Now, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the gaussianBlur function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href=\"https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java\">here</a>.</p>\r\n<p>The entire skeleton code is avaiable on github at <a href=\"https://github.com/9prady9/skeletons/tree/master/jni_droid_test\">template</a>.</p>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-16 00:19:55','2014-05-16 00:19:55','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5596,1,'2014-05-16 14:21:42','2014-05-16 14:21:42','ArrayFire Enterprise Edition. ArrayFire Enterprise includes one (1) ArrayFire Pro dedicated license with support for 2 GPUs or devices. ArrayFire Enterprise also includes (1) free GPU consulting starter package, technical phone support with priority support response times, and prioritized feature requests. ArrayFire 2 GPU Designated computer licenses are sold as 1-year subscriptions that include updates. At the end of the year, customers may either renew the subscription or continue using ArrayFire Pro without future updates. License includes: Image Processing, Signal Processing, Statistics, Graphics Library, Linear Algebra, Sparse Matrices, and many other functions, as well as support in the ArrayFire forums.  All licenses are subject to the EULA found at <a title=\"http://sandbox.arrayfire.com/legal/#eula\" href=\"http://sandbox.arrayfire.com/legal/#eula\" target=\"_blank\">http://sandbox.arrayfire.com/legal/#eula</a>.','ArrayFire Enterprise (Includes Consulting Starter Package)','Support for 2 GPUs in a single designated computer.  Includes additional premium linear algebra and sparse functions.  Provides a perpetual dedicated license with a 1-year subscription to updates.  Enterprise support included.','inherit','open','closed','','42-autosave-v1','','','2014-05-16 14:21:42','2014-05-16 14:21:42','',42,'http://sandbox.arrayfire.com/42-autosave-v1/',0,'revision','',0),(5597,6,'2014-05-16 19:14:56','2014-05-16 19:14:56','Back by popular demand! You\'re invited to join us for a second <a href=\"https://attendee.gotowebinar.com/register/192783229705722369\">webinar held jointly with AMD</a> to discuss productive OpenCL Programming – An Introduction to OpenCL Libraries. We had so many people attend the first one, we decided to hold a second webinar! The webinar will be held on Monday, May 19 at 9 am PT / 11 am CT / 12 pm ET.\r\n\r\nJoin <a href=\"http://sandbox.arrayfire.com/\">ArrayFire</a> COO Oded Green as he demonstrates best practices to help you quickly get started with OpenCL programming.  Learn how to get the best performance from AMD hardware in various programming languages using the <a href=\"http://www.sandbox.arrayfire.com/docs/\">ArrayFire library</a>. Oded will discuss the latest advancements in the OpenCL ecosystem, including cutting edge OpenCL libraries such as clBLAS, clFFT, clMAGMA and ArrayFire. Examples will be shown in real code for common application domains.\r\n\r\n<a href=\"https://attendee.gotowebinar.com/register/192783229705722369\">Register here</a>. We hope to see you there--don\'t miss out!\r\n\r\n&nbsp;','Joint Webinar with AMD: An Introduction to OpenCL Libraries','','publish','open','closed','','joint-webinar-with-amd-an-introduction-to-opencl-libraries','','','2014-05-16 19:14:56','2014-05-16 19:14:56','',0,'http://sandbox.arrayfire.com/?p=5597',0,'post','',0),(5598,6,'2014-05-16 19:13:16','2014-05-16 19:13:16','Back by popular demand! You\'re invited to join us for a second <a href=\"https://attendee.gotowebinar.com/register/192783229705722369\">webinar held jointly with AMD</a> to discuss productive OpenCL Programming – An Introduction to OpenCL Libraries. We had so many people attend the first one, we decided to hold a second webinar! The webinar will be held on Monday, May 19 at 9 am PT / 11 am CT / 12 pm ET.\r\n\r\nJoin <a href=\"http://sandbox.arrayfire.com/\">ArrayFire</a> COO Oded Green as he demonstrates best practices to help you quickly get started with OpenCL programming.  Learn how to get the best performance from AMD hardware in various programming languages using the <a href=\"http://www.sandbox.arrayfire.com/docs/\">ArrayFire library</a>. Oded will discuss the latest advancements in the OpenCL ecosystem, including cutting edge OpenCL libraries such as clBLAS, clFFT, clMAGMA and ArrayFire. Examples will be shown in real code for common application domains.\r\n\r\n<a href=\"https://attendee.gotowebinar.com/register/192783229705722369\">Register here</a>. We hope to see you there--don\'t miss out!\r\n\r\n&nbsp;','Joint Webinar with AMD: An Introduction to OpenCL Libraries','','inherit','open','closed','','5597-revision-v1','','','2014-05-16 19:13:16','2014-05-16 19:13:16','',5597,'http://sandbox.arrayfire.com/5597-revision-v1/',0,'revision','',0),(5600,17729,'2014-05-17 21:31:36','2014-05-17 21:31:36','<p>I will start with an assumption that whoever is reading this has knowledge of writing basic OpenCL code on desktop and knows how to use JNI for android.</p>\r\n<p>My goal is to do some image processing on camera feed. There are couple of ways to generate c headers for jni.</p>\r\n<ul>\r\n<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate the headers automatically based on the java code.<br /></li>\r\n<li>Write it yourself and avoid typos!</li>\r\n</ul>\r\n<p>I took the second route. After a bit of playing with the tedious naming convention for jni functions, now i use the following macro to create my function declarations.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define DECLARE(returnType,fullClassName,func,...) \\</span>\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);</code></pre>\r\n<p>An example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">DECLARE(<span class=\"dt\">void</span>,com_example_CameraPreview,runfilter,jobject outBmp, jbyteArray inData, jint width, jint height)</code></pre>\r\n<p>I like it this way because it makes my header more readable than it will be if generated using javah.</p>\r\n<p>Unless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">JNIEXPORT <span class=\"dt\">void</span> JNICALL Java_com_example_CameraPreview_runfilter(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height,\r\n                jint        choice)\r\n{\r\n    <span class=\"co\">// TODO: process the input and write the output</span>\r\n}</code></pre>\r\n<p>Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 command <code>adb logcat</code> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <code>app_name</code> to adb 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>Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. Following is some brief descriptions of the android/jni functions i used in the code. I have also added couple of functions of my own to make it look better and i hope it does :)</p>\r\n<ul>\r\n<li><code>AndroidBitmap_getInfo</code> - used to get bitmap details like width, height, stride, format.<br /></li>\r\n<li><code>AndroidBitmap_lockPixels</code> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.<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 of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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 few other auxilary functions that i needed to make the code look a little cleaner.</p>\r\n<ul>\r\n<li><code>file_contents</code> - for reading opencl kernel file from disk<br /></li>\r\n<li><code>throwJavaException</code> - convenience function used to throw java exceptions from within 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 phase.<br /></li>\r\n<li><code>helper</code> - used to abstract out opencl code from other android/jni code.</li>\r\n</ul>\r\n<h1 id=\"opencl\">OpenCL</h1>\r\n<p>My target was to run the application on Adreno GPU\'s for which Qualcomm provides OpenCL library, so the one problem was solved. But, where do i get the headers!! ? I initially thought i could use the OpenCL headers available on khronos website, however that turned out to be disaster. I faced OpenGL header inclusion compilation errors. Sony\'s opencl <a href=\"http://developer.sonymobile.com/knowledge-base/tutorials/android_tutorial/boost-the-performance-of-your-android-app-with-opencl/\">example</a> helped me a bit here. Their example has modified verion of opencl headers that commented out all OpenGL related API of OpenCL, which is what we need exactly. Thanks to them, now i have both headers and lib file. What do i need to do now?</p>\r\n<p>Two steps:</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 edge detection operator on the RGBA8888 image data.</li>\r\n</ul>\r\n<h2 id=\"nv21-to-rgba888\">NV21 to RGBA888</h2>\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 of v, u in that order. Since 4 pixels are reading same u,v, i decided to use shared memory to reduce reading latency. Below code stub is core of this conversion kernel that i hope sped up the conversion in comparison to a pure c verion.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><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 this stupid 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=\"co\">//..... rest of code that does color space conversion</span></code></pre>\r\n<p>Laplacian kernel is pretty straight forward. I brought the decoded frame into shared memory, calculated the result of laplacian operator using pixel values of all 8 neighbors from shared memory and finally write the result to output buffer. You can find the entire kernel source code <a href=\"https://github.com/arrayfire/droidcl/blob/master/assets/kernels.cl\">here</a>.</p>\r\n<h1 id=\"build-for-linux\">Build (for Linux)</h1>\r\n<p>blah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool <code>ndk-build</code>. We need to setup some stuff to run the build command <code>ndk-build</code>.</p>\r\n<p>The entire example app is avaiable on github at <a href=\"https://github.com/arrayfire/droidcl\">template</a>.</p>\r\n<ol>\r\n<li>Do <code>git clone https://github.com/arrayfire/droidcl</code><br /></li>\r\n<li>Do <code>cd droidcl</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> appened to it.<br /></li>\r\n<li>Do <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 run 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. Just do <code>ant debug install</code></li>\r\n</ol>\r\n<h2 id=\"android.mk\">Android.mk</h2>\r\n<p>Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk. There are couple of things that you need to do to use opencl on android apart from standard jni mk instructions.</p>\r\n<ul>\r\n<li>Ensure that you do <code>LOCAL_ARM_MODE := arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.<br /></li>\r\n<li>Set 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.<br />Note: In case you want a static library, do the following <code>include $(BUILD_STATIC_LIBRARY)</code> instead of <code>include $(BUILD_SHARED_LIBRARY)</code>.</li>\r\n</ul>\r\n<h2 id=\"application.mk\">Application.mk</h2>\r\n<p>This file is not mandatory i belive, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk. Declare that you want to use the static version of gnustl by doing <code>APP_STL := gnustl_static</code>. Also, set you target android api version using the variable <code>APP_PLATFORM</code>.</p>','Working with JNI for Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-17 21:31:36','2014-05-17 21:31:36','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5601,17729,'2014-05-17 21:31:56','2014-05-17 21:31:56','<p>I will start with an assumption that whoever is reading this has knowledge of writing basic OpenCL code on desktop and knows how to use JNI for android.</p>\r\n<p>My goal is to do some image processing on camera feed. There are couple of ways to generate c headers for jni.</p>\r\n<ul>\r\n<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate the headers automatically based on the java code.<br /></li>\r\n<li>Write it yourself and avoid typos!</li>\r\n</ul>\r\n<p>I took the second route. After a bit of playing with the tedious naming convention for jni functions, now i use the following macro to create my function declarations.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define DECLARE(returnType,fullClassName,func,...) \\</span>\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);</code></pre>\r\n<p>An example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">DECLARE(<span class=\"dt\">void</span>,com_example_CameraPreview,runfilter,jobject outBmp, jbyteArray inData, jint width, jint height)</code></pre>\r\n<p>I like it this way because it makes my header more readable than it will be if generated using javah.</p>\r\n<p>Unless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">JNIEXPORT <span class=\"dt\">void</span> JNICALL Java_com_example_CameraPreview_runfilter(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height,\r\n                jint        choice)\r\n{\r\n    <span class=\"co\">// TODO: process the input and write the output</span>\r\n}</code></pre>\r\n<p>Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 command <code>adb logcat</code> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <code>app_name</code> to adb 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>Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. Following is some brief descriptions of the android/jni functions i used in the code. I have also added couple of functions of my own to make it look better and i hope it does :)</p>\r\n<ul>\r\n<li><code>AndroidBitmap_getInfo</code> - used to get bitmap details like width, height, stride, format.<br /></li>\r\n<li><code>AndroidBitmap_lockPixels</code> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.<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 of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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 few other auxilary functions that i needed to make the code look a little cleaner.</p>\r\n<ul>\r\n<li><code>file_contents</code> - for reading opencl kernel file from disk<br /></li>\r\n<li><code>throwJavaException</code> - convenience function used to throw java exceptions from within 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 phase.<br /></li>\r\n<li><code>helper</code> - used to abstract out opencl code from other android/jni code.</li>\r\n</ul>\r\n<h1 id=\"opencl\">OpenCL</h1>\r\n<p>My target was to run the application on Adreno GPU\'s for which Qualcomm provides OpenCL library, so the one problem was solved. But, where do i get the headers!! ? I initially thought i could use the OpenCL headers available on khronos website, however that turned out to be disaster. I faced OpenGL header inclusion compilation errors. Sony\'s opencl <a href=\"http://developer.sonymobile.com/knowledge-base/tutorials/android_tutorial/boost-the-performance-of-your-android-app-with-opencl/\">example</a> helped me a bit here. Their example has modified verion of opencl headers that commented out all OpenGL related API of OpenCL, which is what we need exactly. Thanks to them, now i have both headers and lib file. What do i need to do now?</p>\r\n<p>Two steps:</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 edge detection operator on the RGBA8888 image data.</li>\r\n</ul>\r\n<h2 id=\"nv21-to-rgba888\">NV21 to RGBA888</h2>\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 of v, u in that order. Since 4 pixels are reading same u,v, i decided to use shared memory to reduce reading latency. Below code stub is core of this conversion kernel that i hope sped up the conversion in comparison to a pure c verion.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><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 this stupid 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=\"co\">//..... rest of code that does color space conversion</span></code></pre>\r\n<p>Laplacian kernel is pretty straight forward. I brought the decoded frame into shared memory, calculated the result of laplacian operator using pixel values of all 8 neighbors from shared memory and finally write the result to output buffer. You can find the entire kernel source code <a href=\"https://github.com/arrayfire/droidcl/blob/master/assets/kernels.cl\">here</a>.</p>\r\n<h1 id=\"build-for-linux\">Build (for Linux)</h1>\r\n<p>blah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool <code>ndk-build</code>. We need to setup some stuff to run the build command <code>ndk-build</code>.</p>\r\n<p>The entire example app is avaiable on github at <a href=\"https://github.com/arrayfire/droidcl\">template</a>.</p>\r\n<ol>\r\n<li>Do <code>git clone https://github.com/arrayfire/droidcl</code><br /></li>\r\n<li>Do <code>cd droidcl</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> appened to it.<br /></li>\r\n<li>Do <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 run 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. Just do <code>ant debug install</code></li>\r\n</ol>\r\n<h2 id=\"android.mk\">Android.mk</h2>\r\n<p>Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk. There are couple of things that you need to do to use opencl on android apart from standard jni mk instructions.</p>\r\n<ul>\r\n<li>Ensure that you do <code>LOCAL_ARM_MODE := arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.<br /></li>\r\n<li>Set 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.<br />Note: In case you want a static library, do the following <code>include $(BUILD_STATIC_LIBRARY)</code> instead of <code>include $(BUILD_SHARED_LIBRARY)</code>.</li>\r\n</ul>\r\n<h2 id=\"application.mk\">Application.mk</h2>\r\n<p>This file is not mandatory i belive, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk. Declare that you want to use the static version of gnustl by doing <code>APP_STL := gnustl_static</code>. Also, set you target android api version using the variable <code>APP_PLATFORM</code>.</p>','OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-17 21:31:56','2014-05-17 21:31:56','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5603,17729,'2014-05-17 22:08:40','2014-05-17 22:08:40','<p>I will start with an assumption that whoever is reading this has knowledge of writing basic OpenCL code on desktop and knows how to use JNI for android.</p>\r\n<p>My goal is to do some image processing on camera feed. There are couple of ways to generate c headers for jni.</p>\r\n<ul>\r\n<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate the headers automatically based on the java code.<br /></li>\r\n<li>Write it yourself and avoid typos!</li>\r\n</ul>\r\n<p>I took the second route. After a bit of playing with the tedious naming convention for jni functions, now i use the following macro to create my function declarations.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define DECLARE(returnType,fullClassName,func,...) \\</span>\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);</code></pre>\r\n<p>An example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">DECLARE(<span class=\"dt\">void</span>,com_example_CameraPreview,runfilter,jobject outBmp, jbyteArray inData, jint width, jint height)</code></pre>\r\n<p>I like it this way because it makes my header more readable than it will be if generated using javah.</p>\r\n<p>Unless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">JNIEXPORT <span class=\"dt\">void</span> JNICALL Java_com_example_CameraPreview_runfilter(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height,\r\n                jint        choice)\r\n{\r\n    <span class=\"co\">// TODO: process the input and write the output</span>\r\n}</code></pre>\r\n<p>Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 command <code>adb logcat</code> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <code>app_name</code> to adb 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>Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. Following is some brief descriptions of the android/jni functions i used in the code. I have also added couple of functions of my own to make it look better and i hope it does :)</p>\r\n<ul>\r\n<li><code>AndroidBitmap_getInfo</code> - used to get bitmap details like width, height, stride, format.<br /></li>\r\n<li><code>AndroidBitmap_lockPixels</code> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.<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 of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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 few other auxilary functions that i needed to make the code look a little cleaner.</p>\r\n<ul>\r\n<li><code>file_contents</code> - for reading opencl kernel file from disk<br /></li>\r\n<li><code>throwJavaException</code> - convenience function used to throw java exceptions from within 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 phase.<br /></li>\r\n<li><code>helper</code> - used to abstract out opencl code from other android/jni code.</li>\r\n</ul>\r\n<h1 id=\"opencl\">OpenCL</h1>\r\n<p>My target was to run the application on Adreno GPU\'s for which Qualcomm provides OpenCL library, so the one problem was solved. But, where do i get the headers!! ? I initially thought i could use the OpenCL headers available on khronos website, however that turned out to be disaster. I faced OpenGL header inclusion compilation errors. Sony\'s opencl <a href=\"http://developer.sonymobile.com/knowledge-base/tutorials/android_tutorial/boost-the-performance-of-your-android-app-with-opencl/\">example</a> helped me a bit here. Their example has modified verion of opencl headers that commented out all OpenGL related API of OpenCL, which is what we need exactly. Thanks to them, now i have both headers and lib file. What do i need to do now?</p>\r\n<p>Two steps:</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 edge detection operator on the RGBA8888 image data.</li>\r\n</ul>\r\n<h2 id=\"nv21-to-rgba888\">NV21 to RGBA888</h2>\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 of v, u in that order. Since 4 pixels are reading same u,v, i decided to use shared memory to reduce reading latency. Below code stub is core of this conversion kernel that i hope sped up the conversion in comparison to a pure c verion.</p>\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><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 this stupid 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=\"co\">//..... rest of code that does color space conversion</span></code></pre>\r\n<p>Laplacian kernel is pretty straight forward. I brought the decoded frame into shared memory, calculated the result of laplacian operator using pixel values of all 8 neighbors from shared memory and finally write the result to output buffer. You can find the entire kernel source code <a href=\"https://github.com/arrayfire/droidcl/blob/master/assets/kernels.cl\">here</a>.</p>\r\n<h1 id=\"build-for-linux\">Build (for Linux)</h1>\r\n<p>blah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool <code>ndk-build</code>. We need to setup some stuff to run the build command <code>ndk-build</code>.</p>\r\n<p>The entire example app is avaiable on github at <a href=\"https://github.com/arrayfire/droidcl\">template</a>.</p>\r\n<ol>\r\n<li>Do <code>git clone https://github.com/arrayfire/droidcl</code><br /></li>\r\n<li>Do <code>cd droidcl</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> appened to it.<br /></li>\r\n<li>Do <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 run 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. Just do <code>ant debug install</code></li>\r\n</ol>\r\n<h2 id=\"android.mk\">Android.mk</h2>\r\n<p>Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk. There are couple of things that you need to do to use opencl on android apart from standard jni mk instructions.</p>\r\n<ul>\r\n<li>Ensure that you do <code>LOCAL_ARM_MODE := arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.<br /></li>\r\n<li>Set 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.<br />Note: In case you want a static library, do the following <code>include $(BUILD_STATIC_LIBRARY)</code> instead of <code>include $(BUILD_SHARED_LIBRARY)</code>.</li>\r\n</ul>\r\n<h2 id=\"application.mk\">Application.mk</h2>\r\n<p>This file is not mandatory i belive, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk. Declare that you want to use the static version of gnustl by doing <code>APP_STL := gnustl_static</code>. Also, set you target android api version using the variable <code>APP_PLATFORM</code>.</p>\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]','OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-17 22:08:40','2014-05-17 22:08:40','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5605,17794,'2014-05-18 02:39:24','2014-05-18 02:39:24','I will start with an assumption that whoever is reading this has knowledge of writing basic OpenCL code on desktop and knows how to use JNI for android.\r\n\r\nMy goal is to do some image processing on camera feed. There are couple of ways to generate c headers for jni.\r\n<ul>\r\n	<li>Use <a href=\"http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html\">javah</a> and generate the headers automatically based on the java code.</li>\r\n	<li>Write it yourself and avoid typos!</li>\r\n</ul>\r\nI took the second route. After a bit of playing with the tedious naming convention for jni functions, now i use the following macro to create my function declarations.\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><span class=\"ot\">#define DECLARE(returnType,fullClassName,func,...) \\</span>\r\nJNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);</code></pre>\r\nAn example declaration of function that takes <a href=\"http://www.fourcc.org/yuv.php#NV21\">NV21</a> format data as input and writes output to bitmap will be as follows:\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">DECLARE(<span class=\"dt\">void</span>,com_example_CameraPreview,runfilter,jobject outBmp, jbyteArray inData, jint width, jint height)</code></pre>\r\nI like it this way because it makes my header more readable than it will be if generated using javah.\r\n\r\nUnless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don\'t like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\">JNIEXPORT <span class=\"dt\">void</span> JNICALL Java_com_example_CameraPreview_runfilter(\r\n                JNIEnv      *env,\r\n                jclass      clazz,\r\n                jobject     outBmp,\r\n                jByteArray  inData,\r\n                jint        width,\r\n                jint        height,\r\n                jint        choice)\r\n{\r\n    <span class=\"co\">// TODO: process the input and write the output</span>\r\n}</code></pre>\r\nClick <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/processor.h\">processor.h</a> to see the full source code for function declarations. 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 command <code>adb logcat</code> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <code>app_name</code> to adb 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\nClick <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/processor.cpp\">processor.cpp</a> to see the full source code for function implementations. Following is some brief descriptions of the android/jni functions i used in the code. I have also added couple of functions of my own to make it look better and i hope it does :)\r\n<ul>\r\n	<li><code>AndroidBitmap_getInfo</code> - used to get bitmap details like width, height, stride, format.</li>\r\n	<li><code>AndroidBitmap_lockPixels</code> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>\r\n	<li><code>GetPrimitiveArrayCritical</code> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn\'t stall execution. As per <a href=\"http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html\">Oracle\'s java documenatation</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 few other auxilary functions that i needed to make the code look a little cleaner.\r\n<ul>\r\n	<li><code>file_contents</code> - for reading opencl kernel file from disk</li>\r\n	<li><code>throwJavaException</code> - convenience function used to throw java exceptions from within 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 phase.</li>\r\n	<li><code>helper</code> - used to abstract out opencl code from other android/jni code.</li>\r\n</ul>\r\n<h1 id=\"opencl\">OpenCL</h1>\r\nMy target was to run the application on Adreno GPU\'s for which Qualcomm provides OpenCL library, so the one problem was solved. But, where do i get the headers!! ? I initially thought i could use the OpenCL headers available on khronos website, however that turned out to be disaster. I faced OpenGL header inclusion compilation errors. Sony\'s opencl <a href=\"http://developer.sonymobile.com/knowledge-base/tutorials/android_tutorial/boost-the-performance-of-your-android-app-with-opencl/\">example</a> helped me a bit here. Their example has modified verion of opencl headers that commented out all OpenGL related API of OpenCL, which is what we need exactly. Thanks to them, now i have both headers and lib file. What do i need to do now?\r\n\r\nTwo steps:\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 edge detection operator on the RGBA8888 image data.</li>\r\n</ul>\r\n<h2 id=\"nv21-to-rgba888\">NV21 to RGBA888</h2>\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 of v, u in that order. Since 4 pixels are reading same u,v, i decided to use shared memory to reduce reading latency. Below code stub is core of this conversion kernel that i hope sped up the conversion in comparison to a pure c verion.\r\n<pre class=\"sourceCode c\"><code class=\"sourceCode c\"><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 this stupid 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=\"co\">//..... rest of code that does color space conversion</span></code></pre>\r\nLaplacian kernel is pretty straight forward. I brought the decoded frame into shared memory, calculated the result of laplacian operator using pixel values of all 8 neighbors from shared memory and finally write the result to output buffer. You can find the entire kernel source code <a href=\"https://github.com/arrayfire/droidcl/blob/master/assets/kernels.cl\">here</a>.\r\n<h1 id=\"build-for-linux\">Build (for Linux)</h1>\r\nblah blah blah, i can\'t use raw code!. Lets build it. Android-ndk provides a very useful tool <code>ndk-build</code>. We need to setup some stuff to run the build command <code>ndk-build</code>.\r\n\r\nThe entire example app is avaiable on github at <a href=\"https://github.com/arrayfire/droidcl\">template</a>.\r\n<ol>\r\n	<li>Do <code>git clone https://github.com/arrayfire/droidcl</code></li>\r\n	<li>Do <code>cd droidcl</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> appened to it.</li>\r\n	<li>Do <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 run 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. Just do <code>ant debug install</code></li>\r\n</ol>\r\n<h2 id=\"android.mk\">Android.mk</h2>\r\nClick <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/Android.mk\">here</a> to see full content of Android.mk. There are couple of things that you need to do to use opencl on android apart from standard jni mk instructions.\r\n<ul>\r\n	<li>Ensure that you do <code>LOCAL_ARM_MODE := arm</code>, which enables you to build for 32-bit ARM architecture instead of the default 16-bit.</li>\r\n	<li>Set 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.\r\nNote: In case you want a static library, do the following <code>include $(BUILD_STATIC_LIBRARY)</code> instead of <code>include $(BUILD_SHARED_LIBRARY)</code>.</li>\r\n</ul>\r\n<h2 id=\"application.mk\">Application.mk</h2>\r\nThis file is not mandatory i belive, but you may need it in cases where you want specify your requirements about the system libraries you want to use in your application. Click <a href=\"https://github.com/arrayfire/droidcl/blob/master/jni/Application.mk\">here</a> to see full content of Application.mk. Declare that you want to use the static version of gnustl by doing <code>APP_STL := gnustl_static</code>. Also, set you target android api version using the variable <code>APP_PLATFORM</code>.\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]','OpenCL on Android','','inherit','open','closed','','5574-autosave-v1','','','2014-05-18 02:39:24','2014-05-18 02:39:24','',5574,'http://sandbox.arrayfire.com/5574-autosave-v1/',0,'revision','',0),(5608,17729,'2014-05-19 17:05:42','2014-05-19 17:05:42','','ocl_demo','','inherit','open','closed','','ocl_demo','','','2014-05-19 17:05:42','2014-05-19 17:05:42','',5574,'http://sandbox.arrayfire.com/wp-content/uploads/2014/05/ocl_demo.mp4',0,'attachment','video/mp4',0),(5610,7,'2014-05-19 20:10:45','2014-05-19 20:10:45','[content_band inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"two-fifths\"]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]If you want faster code, you\'ve come to the right place.[/custom_headline][gap size=\"15%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.sandbox.arrayfire.com/docs/installation.htm\" size=\"x-large\" block=\"true\"]Download ArrayFire[/button]\r\n\r\n[gap size=\"10%\"]\r\n\r\n[button  type=\"flat\" block=\"true\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"x-large\" ]Schedule a consultation[/button]\r\n\r\n[/column][column type=\"three-fifths\" last=\"true\"][gap size=\"7%\"]\r\n<div id=\"wistia_rj2bar3xxp\"></div>\r\n<script charset=\"ISO-8859-1\" type=\"text/javascript\" src=\"//fast.wistia.com/assets/external/E-v1.js\"></script><script type=\"text/javascript\">// <![CDATA[\r\nwistiaEmbed = Wistia.embed(\"rj2bar3xxp\");\r\n// ]]></script>[/column]\r\n<div id=\"arrayfire\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"]Faster code[/custom_headline]\r\n\r\nArrayFire is a fast, hardware-neutral software library for GPU computing with an easy-to-use API. Its array-based function set makes GPU programming simple. A few lines of code in ArrayFire can replace dozens of lines of raw GPU code, saving you valuable time and lowering development costs.\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.sandbox.arrayfire.com/docs/installation.htm\" size=\"x-large\" ]Download ArrayFire[/button][/column][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/Triumvirate_Exported.png\"][/column] [gap size=\"5%\"]\r\n\r\n[column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/Googlelogo-e1396387097279.png\"][line]Video content analysis is the basis for categorizing videos and enabling search by content. Google used ArrayFire to extract motion features in video, improving performance by substantially accelerating the solution of the L1-regularized least-squares optimization problem.[/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/Koch-Industries-e1396387359637.jpg\"][line]Andrew Shin, Market Risk Manager of Koch Supply &amp; Trading, achieves significant performance increases on option pricing algorithms using ArrayFire software, \"My buddy and I are, at best, novice programmers and we couldn\'t imagine having to figure out how to code all this in CUDA.\"[/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/nasa-e1396387230473.png\"][line]The main thrust of this research was improving Mars rover image compression via GPUs and genetic algorithms. With ArrayFire software and GPUs, the researchers were able to achieve 5X speedups on the larger data sizes.[/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n\r\n[column type=\"one-half\"][gap size=\"15%\"]\r\n\r\n<img alt=\"CUDA logo\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/CUDA-logo.jpg\" width=\"231\" height=\"140\" />\r\n\r\n<img alt=\"OpenCL\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/OpenCLLogo_678x452.png\" width=\"326\" height=\"217\" />\r\n\r\n[/column][column type=\"one-half\" last=\"true\"][gap size=\"10%\"]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"] ArrayFire for CUDA and OpenCL[/custom_headline]\r\n\r\nArrayFire supports CUDA-capable NVIDIA GPUs and most OpenCL devices, including AMD GPUs/APUs and Intel Xeon Phi co-processors. It also supports mobile OpenCL devices from ARM, Qualcomm, and others.\r\n\r\nArrayFire is a high-performance software library designed for maximum productivity and speed without the hassle of writing difficult low-level device code. Each of ArrayFire\'s functions has been hand-tuned by our CUDA and OpenCL experts.\r\n\r\n[/column]\r\n<div id=\"mobile\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"  ]Mobile GPU Computing[/custom_headline]\r\n\r\nMobile GPUs offer accelerated performance. If you would like to use ArrayFire in a mobile application or if you would like to hire our mobile acceleration services, email us at <a href=\"mailto:sales@arrayfire.com\" target=\"_blank\">sales@arrayfire.com</a> and include a description of your application.\r\n\r\nOur clients have achieved between 5X to 30X speed boosts for convolutions and other compute functions on mobile devices. It enables:[icon_list][icon_list_item type=\"angle-double-right\"]Real-time video processing[/icon_list_item][icon_list_item type=\"angle-double-right\"]Better augmented reality [/icon_list_item][icon_list_item type=\"angle-double-right\"]Better computational photograph[/icon_list_item][icon_list_item type=\"angle-double-right\"]Faster data processing[/icon_list_item][/icon_list]\r\n\r\nAll mobile devices have a GPU which can deliver greater compute throughput than the CPU. Why not use the GPU to make your app faster?[/column][column type=\"one-half\" fade=\"true\" last=\"true\" fade_animation=\"in-from-right\" class=\"center-text\"][gap size=\"10%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/mobile_Exported1-e1395437261846.png\"][/column]\r\n<div id=\"documentation\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"]Documentation[/custom_headline]\r\n\r\nArrayFire for C, C++, and Fortran\r\nOpen the hood—take a look at the beautiful nitty-gritty.\r\n\r\n[icon type=\"angle-double-right\"] <a href=\"http://www.sandbox.arrayfire.com/docs/\" target=\"_blank\">CUDA &amp; OpenCL C/C++</a>\r\n\r\nFunctions\r\nHundreds of functions, hand-tuned and optimized by our engineers.\r\n\r\n[icon type=\"angle-double-right\"] <a title=\"ArrayFire Functions\" href=\"http://www.sandbox.arrayfire.com/docs/modules.htm\">ArrayFire Functions</a>\r\n\r\nUser Forums\r\nEvery post gets a response from ArrayFire engineers.\r\n\r\n[icon type=\"angle-double-right\"] <a href=\"http://forums.accelereyes.com/\" target=\"_blank\">User Forums</a>\r\n\r\n[/column][column class=\"center-text\" type=\"one-half\" last=\"true\" fade=\"true\" fade_animation=\"in-from-right\" ][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/gears1.png\"][/column]\r\n<div id=\"benchmarks\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n[column type=\"one-half\" fade=\"true\" fade_animation=\"in-from-left\" ][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Benchmark-guy-torso-opposite-e1392155948298.png\"][/column]\r\n\r\n[column type=\"one-half\" last=\"true\"][custom_headline type=\"left\" level=\"h3\" ]Benchmarks[/custom_headline]\r\n\r\nAll benchmarks were performed on a NVIDIA Tesla C2050 with an Intel i7-950 processor. The benchmarks compare ArrayFire with several popular CPU-based acceleration libraries, including <a href=\"http://software.intel.com/en-us/articles/intel-mkl/\" target=\"_new\">Intel Math Kernel Library</a>, <a href=\"http://software.intel.com/en-us/articles/intel-ipp/\" target=\"_new\">Intel Integrated Performance Primitives</a>, <a href=\"http://eigen.tuxfamily.org/index.php?title=Main_Page\" target=\"_new\">Eigen</a>, and <a href=\"http://arma.sourceforge.net/\" target=\"_new\">Armadillo</a>.[/column]\r\n\r\n[column type=\"one-fifth\"].[/column][column type=\"three-fifths\"][tab_nav type=\"four-up\"][tab_nav_item title=\"Base\" active=\"true\"][tab_nav_item title=\"Linear Algebra\" active=\"\"][tab_nav_item title=\"Convolution\" active=\"\"][tab_nav_item title=\"Utility\" active=\"\"][/tab_nav][tabs][tab active=\"true\"]<img alt=\"Matrix Multiply\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/matrix_multiply-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"Matrix Transpose\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/matrix_transpose-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"FFT\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/fft-1024x730.png\" width=\"491\" height=\"350\" />[/tab][tab]<img alt=\"LU\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/lu-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"SVD\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/svd-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"Solve\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/solve-1024x730.png\" width=\"491\" height=\"350\" />[/tab][tab]<img alt=\"Convs\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/convs-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"Conv\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/conv-1024x730.png\" width=\"491\" height=\"350\" />[/tab][tab]<img alt=\"sum\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/sum-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"sort\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/sort-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"scan\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/scan-1024x730.png\" width=\"491\" height=\"350\" />[/tab][/tabs][/column][column type=\"one-fifth\" last=\"true\"].[/column]\r\n<div id=\"free\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"].[/column][column type=\"one-fourth\"].[custom_headline type=\"center\"  level=\"h3\" class=\"mtn\"]ArrayFire Free[/custom_headline][/column][column type=\"one-fourth\" last=\"true\"].[/column][column type=\"one-fourth\"  fade=\"true\" fade_animation=\"in-from-left\" ][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/right-leaning-e1391788779101.png\"][/column][column type=\"one-fourth\"]\r\n<table>\r\n<tbody>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Functions[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Basic Operations</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Arithmetic</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Signal Processing</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Image Processing</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Statistics</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Visualization</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n[gap size=\"17%\"][button type=\"flat\" block=\"true\" shape=\"rounded\" size=\"large\"  href=\"http://www.sandbox.arrayfire.com/docs/installation.htm\"]Download ArrayFire[/button] [/column][column type=\"one-fourth\"]\r\n<table>\r\n<tbody>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Hardware[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] CUDA</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] OpenCL</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Languages[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] C/C++</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Fortran</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Advanced[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td> [icon type=\"check-circle\" style=\"color: #8cc540;\"] GFOR Loop</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n[/column][column type=\"one-fourth\" last=\"true\"]\r\n<table>\r\n<tbody>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Platforms[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Windows</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Linux</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Mac</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Data Types[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] All types</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Support[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td> [icon type=\"check-circle\" style=\"color: #8cc540;\"] Forums</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n<div id=\"licensing\"></div>\r\n[/column][gap size=\"8%\"]\r\n\r\n[pricing_table id=\"pricing\" columns=\"3\"][pricing_table_column  featured=\"false\" title=\"ArrayFire Developer\" currency=\"$\" price=\"499 / year\" interval=\"$149 / year (Academic)\"] [icon_list] [icon_list_item type=\"star\" ]Dedicated license [/icon_list_item] [icon_list_item  type=\"times-circle\"] Starts at 2 GPUs or devices [/icon_list_item] [icon_list_item type=\"times-circle\"] Linear algebra [/icon_list_item] [icon_list_item type=\"times-circle\"] Sparse matrices [/icon_list_item][icon_list_item type=\"times-circle\"] Phone support [/icon_list_item][icon_list_item type=\"times-circle\"] Premium support &amp; consulting [/icon_list_item][/icon_list] [button href=\"http://sandbox.arrayfire.com/shop\"] Purchase [/button] [/pricing_table_column] [pricing_table_column featured=\"true\" featured_sub=\"Most Popular\" title=\"ArrayFire Pro\" currency=\"$\" price=\"1,499 / year\" interval=\"$525 / year (Academic)\"] [icon_list] [icon_list_item type=\"star\"] Dedicated license [/icon_list_item] [icon_list_item type=\"star\"] Starts at 2 GPUs or devices [/icon_list_item] [icon_list_item type=\"star\"] Linear algebra [/icon_list_item][icon_list_item type=\"star\"] Sparse matrices [/icon_list_item][icon_list_item type=\"times-circle\"] Phone support [/icon_list_item][icon_list_item type=\"times-circle\"] Premium support &amp; consulting [/icon_list_item] [/icon_list] [button href=\"http://sandbox.arrayfire.com/shop\"]Purchase [/button] [/pricing_table_column] [pricing_table_column featured=\"false\" title=\"ArrayFire Enterprise\" currency=\"$\" price=\"2,999 / year\" interval=\"$1,049 / year (Academic)\"] [icon_list] [icon_list_item type=\"star\"] Dedicated license [/icon_list_item] [icon_list_item type=\"star\"] Starts at 2 GPUs or devices [/icon_list_item] [icon_list_item type=\"star\"] Linear algebra [/icon_list_item][icon_list_item type=\"star\"]Sparse matrices [/icon_list_item][icon_list_item type=\"star\"] Phone support[/icon_list_item][icon_list_item type=\"star\"]Premium support &amp; consulting [/icon_list_item][/icon_list] [button href=\"http://sandbox.arrayfire.com/shop\"] Purchase [/button] [/pricing_table_column] [/pricing_table]\r\n<div id=\"whitepapers\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][gap size=\"20%\"][image type=\"thumbnail\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/wp2.jpg\"][button href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/03/arrayfire_matrix_computations_chrzeszczyk.pdf\" shape=\"rounded\" size=\"regular\" block=\"true\"]Download Matrix Computations on the GPU with ArrayFire for C/C++[/button][/column][column type=\"one-half\" last=\"true\"]\r\n\r\n[custom_headline type=\"left\" level=\"h3\" ]Whitepapers[/custom_headline]\r\n\r\n<img alt=\"Whitepaper 1\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Whitepaper-1.png\" width=\"466\" height=\"374\" />\r\n\r\n&nbsp;\r\n\r\n[/column][gap size=\"10%\"]\r\n\r\n[column type=\"one-half\"]<img alt=\"Whitepaper 2\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Whitepaper-2.png\" width=\"442\" height=\"304\" />[/column][column type=\"one-half\" last=\"true\"][image type=\"thumbnail\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/wp1.jpg\"][button href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/03/arrayfire_whitepaper.pdf\" shape=\"rounded\" size=\"regular\"  block=\"true\" float=\"right\"]Download High-level GPU Computing in C, C++, and Fortran[/button][/column]\r\n<div id=\"casestudies\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][gap size=\"12%\"][custom_headline type=\"left\" level=\"h3\" ]Case Studies[/custom_headline]\r\n\r\nLearn how ArrayFire has worked in real code, including applications in academia, finance, government, life sciences, manufacturing, media, and oil &amp; gas.[/column][column type=\"one-half\" last=\"true\" fade=\"true\" fade_animation=\"in-from right\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/model-A.png\"][/column][custom_headline type=\"left\" level=\"h5\"]Academia [/custom_headline][accordion][accordion_item title=\"Accelerating LTE Simulation | Tsinghua University\"]\r\n\r\nAuthors: Yuan Gao, Yin Sun, Chun Hui Zhou, Xin Su, Xi Bin Xu, Shi Dong Zhou, Tsinghua University\r\nSpeedup: 3X\r\n\r\nFast simulations are a driving force in several research projects. However, the accompanying long simulation times can tend to be a drag in many of these projects. In this article, we shall bring up the example of the work on 3GPP LTE System Simulation by Yuan Gao et al (from Tsinghua University, Beijing) and demonstrate how the use of ArrayFire software can significantly improve the simulator performance and lead to faster validation times in simulation projects.[/accordion_item]\r\n\r\n[accordion_item title=\"High Performance Compressive Sensing | Rice University\"]\r\n\r\nAuthors: Nabor Reyna and Wotao Yin from Rice University\r\nSpeedup: 5X\r\n\r\nThis work deals with reconstruction of signals using partial Fourier matrices (RecPF). The major computational components of the algorithm involve shrinkage and FFTs. ArrayFire software is employed to accelerate this compute-heavy code.[/accordion_item]\r\n\r\n[accordion_item title=\"Power System Simulations | Indian Institute of Technology, Roorkee, India\"]\r\nAuthors: Indian Institute of Technology, Roorkee\r\nSpeedup: 35X\r\n\r\nPower flow studies are one of the most important aspects of power system planning and operation. The power flow reveals the sinusoidal steady state characteristics of the entire system - voltages, real and reactive power generated, and absorbed and line losses- elucidating the voltage magnitudes and angles at each bus, the generation of each generating unit, and real and reactive power losses in the system. All this is necessary to ensure the security, economy, and control of electrical energy distribution. Learn how ArrayFire software can deliver magnitudes of performance improvement over CPU-based solutions.[/accordion_item]\r\n\r\n[accordion_item title=\"Antenna Array Simulations | University of Naples Federico II\"]\r\n\r\nAuthors: A. Capozzoli, C. Cucio, A. Liseno at University of Naples Federico II\r\nSpeedup: 24X\r\n\r\nAntenna array design involves repeated simulation to tune the many parameters involved, and waiting around for simulations to finish is no fun. Offloading the optimization problem onto the GPU cuts that time down significantly. In their recent paper, Capozzoli, Curcio, and Liseno of University of Naples Federico II demonstrated how a simple modification to their echo generator array simulation took advantage of the GPU to bring immediate speedups.[/accordion_item]\r\n\r\n[accordion_item title=\"Laplace Transform Inversion | Acunum Algorithms and Simulations\"]\r\n\r\nAuthors: Patrick Kano and Moysey Brio at Acunum Algorithms and Simulations\r\nSpeedup: 3.8X\r\n\r\nThe numerical inversion of the Laplace transform is a long standing problem due its implicit ill-posedness. Patrick Kano and Moysey Brio of Acunum Algorithms and Simulations, with their experience in computational methods and algorithm development, found a solution that not only works, but is very fast.[/accordion_item]\r\n\r\n[accordion_item title=\"Compressed Sensing for Image Reconstruction | College of Engineering, Roorkee, India\"]\r\n\r\nAuthors: Kuldeep Yadav, Ankush Mittal, M. A. Ansar, and Avi Srivastava, College of Engineering, Roorkee, India\r\nSpeedup: 8X\r\n\r\nCompressed sensing is very critical in the areas of medical image reconstruction, image acquisition or sensor networks. An algorithm for compressed sensing developed using a Basis Pursuit Algorithm shows over 8X speedup when run on an NVIDIA GPU.[/accordion_item]\r\n\r\n[accordion_item title=\"Fat/Water Reconstruction for Medical Images | Case Western Reserve University\"]\r\n\r\nAuthors: D. H. Johnson, S. Narayan, C. A. Flask, and D. L. Wilson, Case Western Reserve University\r\nSpeedup: 11.6X\r\n\r\nCase Western Reserve University researchers turned to GPUs running ArrayFire software to develop a fast and robust version of the \"Iterative Decomposition of water and fat with an Echo Asymmetry and Least-squares\" (IDEAL) reconstruction algorithm. This algorithm uses a lot of Image Processing algorithms for reconstruction, and was shown to achieve very high speedups.\r\n[/accordion_item]\r\n\r\n[/accordion]\r\n<h5>Finance</h5>\r\n[accordion][accordion_item title=\"Option Pricing | Koch Supply and Trading\"]\r\n\r\nAuthors: Koch Supply &amp; Trading\r\nSpeedup: 51.8X\r\n\r\nAndrew Shin, Market Risk Manager of Koch Supply &amp; Trading, achieves significant performance increases on option pricing algorithms using ArrayFire software to accelerate his code with GPUs. Andrew says, \"My buddy and I are, at best, novice programmers and we couldn\'t imagine having to figure out how to code all this in CUDA.\" But he found ArrayFire software to be straight-forward. With these results, he says he can see ArrayFire software and GPUs populating Koch\'s mark-to-futures cube, which contains its assets, simulations, and simulated asset prices.[/accordion_item]\r\n\r\n[accordion_item title=\"GPU Computing in Automated Trader | Automated Trader\"]\r\n\r\nAuthors: Automated Trader\r\nSpeedup: 37.5X\r\n\r\nThe Q1 2012 issue of Automated Trader contains an excellent Mashup piece reviewing software for algorithmic trading. The article provides a wonderful glimpse into the 1-2 month adventure of Andy Webb, Automated Trader.s Founder, and Wrecking Crew building a fast trading platform from several technologies. The full trading platform they built was quite extensive. The part that caught our eye was the core computational component of the pipeline. That component involved permuting 1,000 potential pairs with cointegration tests for 350 time windows on each potential pair.\r\n[/accordion_item]\r\n[accordion_item title=\"GPUs in Quantitative Analytics and Finance | Private Bank\"]\r\n\r\nThe world of Quantitative finance is all about getting accurate results really, really fast. ArrayFire is working with one of the largest banks in Spain to maximize their output using GPUs. Click the link below for an overview of the uses of GPU computing in finance.[/accordion_item][/accordion]\r\n<h5>Government</h5>\r\n[accordion][accordion_item title=\"Powering Mars Research | NASA and UAA in Anchorage\" ]\r\n\r\nAuthors: NASA and UAA in Anchorage\r\nSpeedup: 5X\r\n\r\nThe main thrust of this research is improving mars rover image compression via GPUs and genetic algorithms. With ArrayFire software and GPUs, the researchers were able to achieve 5X speedups on the larger data sizes. The algorithm works by pairing neighboring pixels with a random one and then adjusting the random pixel based on whether it incrementally improves the original image. Babb described the algorithm as an embarrassingly parallel process, ideally suited to GPU acceleration. He estimates he has been able to achieve a 20 to 30 percent error reduction in subjects like fingerprints and satellite imagery.[/accordion_item]\r\n\r\n[accordion_item title=\"Radar Image Formation | System Planning Corporation\"]\r\n\r\nAuthors: Gary Rubin and Earl Sager - System Planning Corporation\r\nSpeedup: ~45X\r\n\r\nRadar imaging is computationally intensive. As a result, many imaging algorithms apply FFT-based approximations. While efficient, these algorithms sacrifice data fidelity for speed. Other algorithms better preserve information, but are often too slow for many applications. At System Planning Corporation (SPC) , we have implemented a SAR/ISAR imaging routine based on the Backprojection algorithm. Using ArrayFire software, we have demonstrated speedups of roughly 45x for large datasets.[/accordion_item]\r\n\r\n[accordion_item title=\"Radar Clutter Reduction | System Planning Corporation\"]\r\n\r\nAuthors: David Berger and Gary Rubin - System Planning Corporation\r\nSpeedup: 5-10X\r\n\r\nSystem Planning Corporation (SPC) uses ArrayFire software to accelerate radar processing algorithms. The system processes raw data from marine navigation radars using a variety of thresholding techniques to extract real targets from clutter. This involves highly data-parallel processing in which each radar pulse is subjected to the same computations; very few operations occur across multiple pulses. Using ArrayFire software, SPC has achieved 10x speed improvements relative to a Core i7-920 CPU and 5x improvements relative to a realtime DSP implementation.[/accordion_item]\r\n\r\n[accordion_item title=\"Novel Algorithms for Linear Algebra | SAIC\" ]\r\n\r\nAuthors: Nolan Davis and Daniel Redig, SAIC\r\nSpeedup: 3.5X\r\n\r\nNolan Davis and Daniel Redig at SAIC recently presented work on Hybrid GPU/Multicore Solutions for Large Linear Algebra Problems where they developed a novel algorithm for LU decomposition, one of the most important routines in linear algebra. They presented a Hybrid CPU/GPU computing approach, where problems too large to fit in GPU memory can also be solved faster than using only the CPU.\r\n[/accordion_item]\r\n[accordion_item title=\"Geolocation | BAE Systems\"]\r\n\r\nAuthors: BAE Systems\r\nSpeedup: 17X\r\n\r\nGeolocation is the identification of the real-world geographic location of a target of interest. In this application, the system receives the signal with an array of several antennas and computes the direction of arrival of the radio energy by measuring the time difference of arrival (or the phase difference) at the different antennas.\r\n[/accordion_item]\r\n[accordion_item title=\"Tsunami Modeling | University of Minnesota, Boise State, Saint Scholastica, and NCAR\"]\r\n\r\nAuthors: University of Minnesota, Boise State, Saint Scholastica, and NCAR\r\nSpeedup: 3-5X\r\n\r\nNatural catastrophic disasters like tsunamis commonly strike with little warning. For most people, tsunamis are underrated as major hazards. People sometimes wrongly believe that they occur infrequently and only along distant coasts. Tsunamis are usually caused by earthquakes. Seismic signals can give some margin of warning since the speed of tsunami waves travels at 1/30 the speed of seismic waves. Still there is little time between the creation of the tsunami and its impact making fast processing critical to producing effective warning systems. ArrayFire software was used to run an RBF simulation on the GPU with a time to solution not available by other alternatives.\r\n[/accordion_item][/accordion]\r\n<h5>Life Sciences</h5>\r\n[accordion][accordion_item title=\"Parallelized Gene Predictors | University of Quebec\" ]\r\n\r\nAuthors: University of Quebec\r\nSpeedup: 43X\r\n\r\nComputerized approaches to studying the human genome are challenged by the exploding amount of data, which doubles roughly every 6 months. In order to deal with this burgeoning datasets, demands for faster processing power continue to arise. This work focuses on predicting genes using frequency analysis with FFTs and with an equivalent technique known as Goertzel\'s algorithm. In these applications, the emphasis of this paper is to propose tools to geneticists and molecular biologists for the prediction or identification of new genes using existing complementary strategies. The criteria for these tools are speed, reliability, accuracy and ease of use, thus requiring little training.\r\n[/accordion_item]\r\n[accordion_item title=\"Pathology Advances with GPUs | Northeastern University\" ]\r\n\r\nAuthors: Laboratory for Spectral Diagnosis at Northeastern University\r\nSpeedup: 100X+\r\n\r\nOne element of the hyperspectral image analysis workflow that requires more than a traditional desktop workstation or personal computer is Hierarchical Cluster analysis (HCA). HCA requires a large amount of data space and substantial computation time (~11 hours) for typical datasets using a single processor personal computer. Rather than following the traditional approach of moving to a lower level programming language like C or C++ and complex parallel programming paradigms such as OpenMP or the Massage Passing Interface (MPI), the lab utilized graphics processing units, or GPUs, and the ArrayFire software platform. The solution allowed the lab to dramatically increase the performance of the analysis while substantially decreasing the amount of calendar time to reach the desired results.\r\n[/accordion_item]\r\n[accordion_item title=\"Hepatitis C Virus - Mutation Modeling | Centers for Disease Control and Prevention\" ]\r\n\r\nAuthors: CDC Research and Development Team\r\nSpeedup: ~20X\r\n\r\nThis case study provides a look at biological research regarding coordinated mutations of the Hepatitis C Virus (HCV). ArrayFire provided collaborative R&amp;D resources and greatly improved the speed of this HCV research with the use of parallelization, reducing the computing time from 40 days to less than 1 day. Most importantly, the conclusion of the case study illustrates the the relative price-performance of personal supercomputers that leverage GPUs and ArrayFire software provides a compelling solution versus other architectures and approaches.\r\n[/accordion_item]\r\n[accordion_item title=\"Accelerating the SPM Package for Neuroimaging | Georgia Institute of Technology\" ]\r\n\r\nAuthors: Georgia Institute of Technology\r\nSpeedup: 3.5X\r\n\r\nThe Georgia Tech team explores the value of ArrayFire software and GPUs for fMRI workflows within the popular SPM - Statistical Parametric Mapping software widely used in neuroscience research.\r\n[/accordion_item]\r\n[accordion_item title=\"Medical Image Compression | Indian Institute of Technology, Roorkee, India\" ]\r\n\r\nAuthors: Jaideep Singh, Ipseeta Aruni, R. Balasubramanian - IIT - Roorkee, India\r\nSpeedup: 38X\r\n\r\nThis study presents the acceleration of Haar wavelet-based image compression algorithm for medical imaging on the Graphics Processing Unit (GPU) using ArrayFire software. Due to bandwidth and image size constraints of medical imaging systems, image compression plays a vital role in reducing the bit rate of transmission or storage. Wavelet-based image compression provides the most promising approach for high quality image compression.\r\n[/accordion_item]\r\n[accordion_item title=\"Brain Displacement | Spencer Technologies\"]\r\n\r\nAuthors: Spencer Technologies\r\nSpeedup: 12X\r\n\r\nSpencer describes how ArrayFire software facilitates the development of fast algorithms enabling observation of brain displacement across depth with sampling density that far surpasses previous benchmarks.\r\n[/accordion_item]\r\n[accordion_item title=\"Multidimensional Scaling for Genomics | Leibniz Institute of Plant Genetics and Crop Plant Research\" ]\r\n\r\nAuthors: Leibniz Institute of Plant Genetics and Crop Plant Research\r\nSpeedup: 20-35X\r\n\r\nMultidimensional scaling (MDS) is a general computing technique to turn a distance matrix into a set of reconstructed points with pair-wise relationships approximating the original distances by points located in a usually low-dimensional space. ArrayFire software is used to enhance execution of the HiT-MDS procedure and delivers considerable performance improvement.\r\n[/accordion_item]\r\n[accordion_item title=\"Drug Delivery Model | Georgia Institute of Technology\"]\r\n\r\nAuthors: Georgia Institute of Technology\r\nSpeedup: 70X\r\n\r\nIn this work, the researchers simulate the delivery of a novel nanoparticle chemotherapy drug to cancerous tissue. Simulation allows scientists to predict experimental outcomes and thus reduce the cost of development and time to clinical relevance. The simulation model includes blood vessels, tumor cells, and healthy cells and an engine to calculate the spatial distributions of both drug and oxygen. ArrayFire software is used to speed up the diffusion calculations for the drug and oxygen within the tissue.\r\n[/accordion_item]\r\n[accordion_item title=\"Biomedical Infrared Spectroscopy | University of Manchester and Nofima Mat, Norway\" ]\r\n\r\nAuthors: University of Manchester and Nofima Mat, Norway\r\nSpeedup: Hours of runtime reduction\r\n\r\nThe authors present an iterative algorithm that applies full Mie scattering theory and avoids noise accumulation in their iterative algorithm by integrating a curve-fitting step. ArrayFire software along with NVIDIA GPUs are leveraged to reduce the time added by the curve-fitting step.\r\n[/accordion_item][/accordion]\r\n<h5>Manufacturing</h5>\r\n[accordion][accordion_item title=\"Feature Learning on Images | Stanford\" ]\r\n\r\nAuthors: Andrew Ng, Stanford University\r\nSpeedup: Ability to process many images in parallel\r\n\r\nStanford researchers in Andrew Ng\'s group used GPUs and ArrayFire software to speed up their work on Feature Learning Architectures. They decided to use ArrayFire software for this study because of the need to quickly evaluate many architectures on thousands of images. ArrayFire software taps into the immense computing power of GPUs and speeds up research utilizing many images.\r\n[/accordion_item]\r\n[accordion_item title=\"Tomography of Vegetation - Filtered Back-Projection and Non-Uniform FFTs | Universita di Napoli Federico II\" ]\r\n\r\nAuthors: Drs. Capozzoli, Curcio, di Vico, and Liseno, Universita di Napoli Federico II\r\nSpeedup: 10X\r\n\r\nIn order to investigate changes of forest biomass, scientists use microwave tomography to image the vegetation. At the smallest scale, individual plants can be imaged to investigate branching and growth, but even synthetic aperture radar can reveal large-scale changes in regional ecology. To the right, you can see the experimental setup to image an individual plant.\r\n[/accordion_item]\r\n[accordion_item title=\"Action Recognition with Independent Subspace Analysis | Stanford University\" ]\r\n\r\nAuthors: Quoc Le, Will Zou, Serena Yeung, Andrew Ng, Stanford University\r\nSpeedup: 4.4X\r\n\r\nIn a paper at this year\'s CVPR 2011, entitled \"Learning hierarchical invariant spatio-temporal features for action recognition with independent subspace analysis\", the authors explain how their unsupervised feature learning algorithm competes with other algorithms that are hand crafted or use learned features. For their training purposes, they used a multi-layered stacked convolutional ISA (Independent subspace analysis) network. An ISA is used for learning features from image patches without supervision.\r\n[/accordion_item][/accordion]\r\n<h5>Media and Computer Vision</h5>\r\n[accordion][accordion_item title=\"Fast Computer Vision with OpenCV and ArrayFire | OpenCV Blogger\" ]\r\n\r\nAuthors: OpenCV Blogger\r\nSpeedup: ~10X\r\n\r\nThe OpenCV library is the defacto standard for doing computer vision and image processing research projects. OpenCV includes several hundreds of computer vision algorithms, aimed for use in realtime vision applications. This case study shows how to use both libraries together. There is a simple example application that demonstrates using OpenCV for webcam access and ArrayFire for some basic processing routines and displaying results.\r\n[/accordion_item]\r\n[accordion_item title=\"Video Processing | Google\" ]\r\n\r\nAuthors: Google and Stanford\r\nSpeedup: 10-20X\r\n\r\nVideo content analysis is the basis for categorizing videos and enabling search by content. Growing interest in using sparse-coding methods to extract motion features in video in support of video content analysis led to the application of ArrayFire software to improve performance by substantially accelerating the solution of the L1-regularized least-squares optimization problem.\r\n[/accordion_item]\r\n[accordion_item title=\"Action Recognition with Independent Subspace Analysis | Stanford University\"]\r\n\r\nAuthors: Quoc Le, Will Zou, Serena Yeung, Andrew Ng, Stanford University\r\nSpeedup: 4.4X\r\n\r\nIn a paper at this year\'s CVPR 2011, entitled \"Learning hierarchical invariant spatio-temporal features for action recognition with independent subspace analysis\", the authors explain how their unsupervised feature learning algorithm competes with other algorithms that are hand crafted or use learned features. For their training purposes, they used a multi-layered stacked convolutional ISA (Independent subspace analysis) network. An ISA is used for learning features from image patches without supervision.\r\n[/accordion_item]\r\n[accordion_item title=\"Music Beat Analysis | Georgia Tech\"]\r\n\r\nAuthors: Vidhur Vohra - Georgia Tech\r\nSpeedup: 15X\r\n\r\nDid you ever wonder how the music visualizer in your media player works? Watching it pulsate in synchrony with the beats of the song is almost as entertaining as listening to the song itself! Researchers have been attempting to detect beats in audio signals for many years, and there are many techniques available, from the simplest (and least accurate) to more complicated algorithms that are highly accurate. All algorithms, though, perform some form of signal processing and frequency analysis, applications highly suited to GPU Computing.\r\n[/accordion_item]\r\n[accordion_item title=\"Optimization Methods for Deep Learning | Stanford Artificial Intelligence Laboratory\" ]\r\n\r\nAuthors: Stanford Artificial Intelligence Laboratory\r\nSpeedup: Improved accuracy\r\n\r\nResearchers at SAIL (Stanford Artificial Intelligence Laboratory), have done it again. They have successfully used ArrayFire software to speed up the training part of Deep Learning algorithms. In their paper titled .On Optimization Methods for Deep Learning., they experiment with some of the well known training algorithms and demostrate their scalability across parallel architectures (GPUs as well as multi-machine networks). The algorithms include SGDs (Stochastic Gradient Descent) L-BFGS (Limited BFGS used for solving non-linear problems), CG (Conjugate Gradient).\r\n[/accordion_item]\r\n[accordion_item title=\"Feature Learning on Images | Stanford University\" ]\r\n\r\nAuthors: Andrew Ng, Stanford University\r\nSpeedup: Ability to process many images in parallel\r\n\r\nStanford researchers in Andrew Ng’s group used ArrayFire software to speed up their work on Feature Learning Architectures. They decided to use ArrayFire software for this study because of the need to quickly evaluate many architectures on thousands of images. ArrayFire software taps into the immense computing power of GPUs and speeds up research utilizing many images.\r\n[/accordion_item]\r\n[accordion_item title=\"Digital Holography for Imaging | National University of Ireland, Maynooth\" ]\r\n\r\nAuthors: Nitesh Pandey, Damien Kelly, Bryan Hennelly and Thomas Naughton from the National University of Ireland, Maynooth\r\nSpeedup: 17X\r\n\r\nDigital holography is a powerful imaging technique with many new applications like true 3D display. It allows the capture of both amplitude and phase information of the light reflected off the surface of 3D objects. Researchers at the National University of Ireland, Maynooth are developing techniques based on digital holography for 3D display applications.\r\nReconstruction of large digital holograms can be computationally intensive to generate on CPUs, but GPUs running ArrayFire software offer amazing possibilities.\r\n[/accordion_item][/accordion]\r\n<h5>Oil and Gas</h5>\r\n[accordion][accordion_item title=\"3D Mantle Convection - Geodynamics | Boise State, University of Colorado, University of Minnesota\" ]\r\n\r\nAuthors: Boise State, University of Colorado, University of Minnesota\r\nSpeedup: 2.5-4.5X\r\n\r\nThe authors introduce a GPU implementation of a three-dimensional mantle convection modeling at a high Rayleigh number to the solid earth geophysics community. They outline code development time, compare performance of CPUs versus GPUs, and deliver powerful visualizations.\r\n[/accordion_item]\r\n[accordion_item title=\"Ground Water Simulations | Louisiana State University\" ]\r\n\r\nAuthors: Kevin R. Tubbs and Frank T-C. Tsai at Louisiana State University\r\nSpeedup: &gt;20X\r\n\r\nA lattice Boltzmann method for solving the shallow water equations and the advection-dispersion equation is developed and implemented on graphics processing unit (GPU)-based architectures. The proposed LBM is implemented to an NVIDIA Computing Processor in a single GPU workstation. GPU computing is performed using ArrayFire software. Mass transport with velocity-dependent dispersion in shallow water flow is simulated by combining the MRT-LBM model and the TRT-LBM model. The GPU parallel performance increases as the grid size increases. The results indicate the promise of the GPU-accelerated LBM for modeling mass transport phenomena in shallow water flows.\r\n[/accordion_item]\r\n[accordion_item title=\"Shallow Water Fluid Flow | Louisiana State University\" ]\r\n\r\nAuthors: Louisiana State University\r\nSpeedup: &gt;10X\r\n\r\nA lattice Boltzmann method (LBM) on high performance computing (HPC) environments for three-dimensional shallow water flow fields coupled to mass transport is developed. LBM is an attractive method for solving the multilayered shallow water equations because the extension to multilayer is straight forward with all of the simplicities and advantages of the LBM in mass transport in shallow water flows and the LBM performance on central processing unit (CPU)-based and graphics processing unit (GPU)-based HPC environments.\r\n[/accordion_item][/accordion]\r\n<div id=\"consulting\"></div>\r\n[/content_band]\r\n<div id=\"services\"></div>\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"]Hire our acceleration gang[/custom_headline]\r\n\r\nHire us to accelerate your code. Or to train your pros. Or even to write new code for your organization!\r\n\r\nWe’ve already helped thousands of organizations speedup their code. We’ve accelerated algorithms, data sets, and challenging problems of all types in the past, and we’re confident that we can accelerate your code too.\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://meetme.so/arrayfire\" size=\"x-large\" ]Schedule a consultation[/button][/column][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/Bat-signal-e1391790016951.png\"][/column] [gap size=\"7%\"]\r\n\r\n[column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/LFG-B-HORZ_202_K-e1396448935778.jpg\"][line]Lincoln Financial Group ported their CPU code (C/C++) to CUDA, and this enabled them to speed up the necessary financial calculations. Their primary objective was to reduce the time taken to run this code. Before porting to CUDA, they required 10-12 hours to run the entire code. After porting to CUDA, they were able to do the same work in about 30 minutes.[/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][line]Reveal Imaging, an SAIC company, uses ArrayFire in developing threat-detection products for transportation systems—such as cargo and baggage screening in airports—and in securing facilities and public events.[/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][line]The Glasses.com app relies on computer vision to recognize the features of a user’s face. The application then generates an accurate, high-fidelity, three-dimensional model of that face, and virtually places selected frames on the image.[/column]\r\n<div id=\"starterpackage\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n\r\n[column type=\"one-half\" last=\"false\" fade=\"true\" fade_animation=\"in-from-left\" ][gap size=\"10%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/comingatyou.png\"][/column][column type=\"one-half\" last=\"true\"] [custom_headline type=\"left\" level=\"h3\"]Starter Package ($500)* [/custom_headline] Hire us for 1-day. We set you up with one engineer dedicated for a full day, as well as support from senior and test engineers throughout the day. Here\'s how it works:\r\n\r\n[icon_list] [icon_list_item type=\"angle-double-right\"]Initial phone call[/icon_list_item] [icon_list_item type=\"angle-double-right\"]You send us your code or algorithm [/icon_list_item] [icon_list_item type=\"angle-double-right\"]We analyze your code for potential GPU benefit[/icon_list_item][icon_list_item type=\"angle-double-right\"]We accelerate as much of the code as is possible within the 1-day effort, applying our extensive GPU software libraries[/icon_list_item][icon_list_item type=\"angle-double-right\"]We produce a final report, along with code[/icon_list_item] [/icon_list] The final report outlines the best approach to follow for full GPU-acceleration of your code.\r\n\r\n&nbsp;\r\n\r\n[button type=\"flat\" shape=\"rounded\" size=\"regular\" href=\"http://sandbox.arrayfire.com/product/consulting-starter-package/\" title=\"Starter Package\"]Buy the Starter Package[/button]\r\n\r\n&nbsp;\r\n\r\n*Limit one (1) per customer.\r\n\r\n[/column]\r\n<div id=\"customcode\"></div>\r\n[/content_band] [content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\" ]Coding Work (Custom)[/custom_headline]\r\n\r\n[custom_headline type=\"left\" level=\"h6\" ]Why Choose Us?[/custom_headline] [icon_list] [icon_list_item type=\"angle-double-right\"]Deep experience, already servicing thousands of customers[/icon_list_item] [icon_list_item type=\"angle-double-right\"]Quality work, with leading GPU software [/icon_list_item] [icon_list_item type=\"angle-double-right\"]Efficient delivery, with ArrayFire\'s code base we can deliver results fast[/icon_list_item][icon_list_item type=\"angle-double-right\"]Proven, we make customers happy through faster code[/icon_list_item][/icon_list] [custom_headline type=\"left\" level=\"h6\" ]Our Strengths[/custom_headline] [icon_list] [icon_list_item type=\"angle-double-right\"]Excellence in GPU code[/icon_list_item] [icon_list_item type=\"angle-double-right\"]Well-written, efficient C, C++, Fortran, Java, or .NET [/icon_list_item] [icon_list_item type=\"angle-double-right\"]Application porting and integration[/icon_list_item][icon_list_item type=\"angle-double-right\"]Tuning software to peak hardware performance[/icon_list_item][icon_list_item type=\"angle-double-right\"]Scalability of algorithms to handle enterprise-level programs[/icon_list_item] [/icon_list][button type=\"flat\" shape=\"rounded\" size=\"regular\" href=\"http://meetme.so/arrayfire\" title=\"Tech Consultation\"]Schedule a consultation[/button] [/column][column type=\"one-half\"  fade=\"true\" fade_animation=\"in-from-right\" last=\"true\" ][gap size=\"25%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Holoham.png\"][/column]\r\n<div id=\"training\"></div>\r\n[/content_band] [content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\" ]Training[/custom_headline] Attendees will receive the latest industry knowledge and techniques for GPU computing in CUDA and OpenCL.\r\n\r\nArrayFire offers up to four days of specialized GPU training in CUDA and OpenCL programming. We provide customized on-site training courses for customers that have 3 or more attendees from their organization. We can travel to your location and provide a CUDA or OpenCL training course tailored to meet your application-specific needs. We also offer individual trainings at our Atlanta office. Please contact us to learn more about our training offerings.\r\n\r\nWe recommend that attendees have a working knowledge of C/C++ in order to gain the most from the training courses. For more information about the content of our training lectures and hands-on practicums, please see the following training course syllabus.\r\n\r\n[/column]\r\n\r\n[column type=\"one-half\" last=\"true\" fade=\"true\" fade_animation=\"in-from-right\" class=\"center-text\"][gap size=\"15%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Professor-AF_Exported-e1395436350363.png\" ][/column]\r\n\r\n[column type=\"one-half\" class=\"center-text\"] [gap size=\"17%\"]\r\n<div>[button type=\"flat\" shape=\"rounded\" size=\"jumbo\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]</div>\r\n[/column][column type=\"one-half\" last=\"true\"][custom_headline type=\"left\" level=\"h3\"]Included in Course[/custom_headline]\r\n\r\n[icon_list] [icon_list_item type=\"angle-double-right\"]Instruction by an excellent and interesting expert, with hands-on exercises[/icon_list_item] [icon_list_item type=\"angle-double-right\"]Use of a laptop with CUDA and OpenCL capable GPUs and CPUs [/icon_list_item] [icon_list_item type=\"angle-double-right\"]Choice of Linux or Windows operating system[/icon_list_item][icon_list_item type=\"angle-double-right\"]Printed manual of lecture material[/icon_list_item][icon_list_item type=\"angle-double-right\"]Electronic copy of programming exercises[/icon_list_item][/icon_list]\r\n\r\n[/column]\r\n\r\n<span style=\"line-height: 1.5em;\">[gap size=\"5%\"]</span>\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]Training Course Syllabus[/custom_headline] [column type=\"one-half\"] [custom_headline type=\"left\" level=\"h5\"  accent=\"false\"]Day 1, Introduction[/custom_headline] Lectures:\r\nGPU Computing Overview\r\nThe Programming Model\r\nBasic Dataset Mapping Techniques\r\nLibraries, ArrayFire\r\nProfiling Tools\r\n\r\nPractice:\r\nA Simple Kernel\r\nEquivalent ArrayFire Example\r\nUsing Libraries\r\nMonte Carlo Pi Estimation\r\nTiming and ArrayFire\r\nDebugging Code\r\n\r\n[custom_headline type=\"left\" level=\"h5\" accent=\"false\"]Day 3, Multi-GPU[/custom_headline] Lectures:\r\nMulti-GPU Use Cases\r\nMulti-GPUs: Contexts\r\nExisting Libraries\r\nScaling Across Multiple GPUs\r\n\r\nPractice:\r\nOut of Core Problems: Matrix Multiply\r\nTask Level Parallelism: Optimization\r\nArrayFire Multi-GPU[/column]\r\n\r\n[column type=\"one-half\" last=\"true\"] [custom_headline type=\"left\" level=\"h5\" accent=\"false\"]Day 2, Optimization[/custom_headline] Lectures:\r\nArchitecture: Grids, Blocks, and Threads\r\nMemory Model: Global, Shared, and Constant Memory\r\nAdvanced Mapping Techniques\r\nStreams: Asynchronos Launches and Concurrent Execution\r\nArrayFire: Lazy Evaluation and Code Vectorization\r\n\r\nPractice:\r\nMatrix Transpose\r\nOptimization Using Shared Memory\r\nMedian Filter\r\nOptimization Using Constant Memory\r\nStream Example\r\nArrayFire Example: Nearest Neighbor Algorithm\r\n\r\n[custom_headline type=\"left\" level=\"h5\" accent=\"false\"]Day 4, Algorithm Problems[/custom_headline]\r\n\r\nLectures and Practice:\r\nReductions\r\nScan Algorithms\r\nSort\r\nConvolution\r\nCustomer-Specific Problem [/column][/content_band]','Home','','inherit','open','closed','','245-revision-v1','','','2014-05-19 20:10:45','2014-05-19 20:10:45','',245,'http://sandbox.arrayfire.com/245-revision-v1/',0,'revision','',0),(5611,7,'2014-05-19 20:44:31','2014-05-19 20:44:31','[content_band inner_container=\"true\" no_margin=\"true\" border=\"bottom\" padding_top=\"40px\" padding_bottom=\"40px\" bg_color=\"#FFF\" ]\r\n\r\nWe do business as ArrayFire. Our official company name is AccelerEyes.\r\n<h3>Terms of Use</h3>\r\n<strong>Acceptance of Terms</strong>\r\n\r\nArrayFire makes available for your use on this Web site (the \"Site\") information, documents, software and products (collectively, the \"Materials\") and various services operated by ArrayFire (collectively, the \"Services\"), subject to the terms and conditions set forth in this document (the \"Terms of Use\"). By accessing or using this Site, which includes your access to or use of any of the Services, you agree to the Terms of Use. ArrayFire reserves the right to change the Terms of Use from time to time at its sole discretion. Your use of the Site will be subject to the most current version of the Terms of Use posted on the Site at the time of such use. In addition, when using particular Services or Materials on this Site, you shall be subject to any posted guidelines or rules applicable to such Services or Materials that may contain terms and conditions in addition to those in the Terms of Use. All such guidelines or rules are hereby incorporated by reference into the Terms of Use. If you breach any of the Terms of Use, your authorization to use this Site automatically terminates and you must immediately destroy any Materials Downloaded or printed from the Site.\r\n\r\n<strong>Copyright / Limited License</strong>\r\n\r\nThe Materials and Services on this Site are protected by copyright and/or other intellectual property laws and any unauthorized use of the Materials or Services at this Site may violate such laws. Except as expressly provided herein, ArrayFire and its suppliers do not grant any express or implied right to you under any patents, copyrights, trademarks, or trade secret information with respect to the Materials and Services.\r\n\r\nExcept as specifically permitted herein, no portion of the information or documents on this Site may be reproduced in any form or by any means without the prior written permission of ArrayFire.\r\n\r\n<strong>Use of Software</strong>. The software and accompanying documentation that are made available to Download from this Site are the copyrighted work of ArrayFire and/or its suppliers. Use of the software is governed by the terms of the end user license agreement that accompanies or is included with such software. You will not be able to Download or install any software that is accompanied by or includes an end user license agreement unless you agree to the terms of such end user license agreement. If you do not agree to such terms, you will not be able to use the software. You may not decompile, reverse engineer or otherwise attempt to discover the source code of the software available on the Site.\r\n\r\n<strong>Use of Site Information</strong>. Except as otherwise indicated elsewhere on this Site, you may view, Download and print the documents and information available on this Site subject to the following conditions:\r\n\r\nThe documents and information may be used solely for personal, informational, internal, non-commercial purposes. The documents and information may not be modified or altered in any way. The documents and information on the Site may not be distributed. You may not remove any copyright or other proprietary notices contained in the documents and information.\r\n\r\nArrayFire reserves the right to revoke the authorization to view, Download and print the documents and information available on this Site at any time, and any such use shall be discontinued immediately upon written notice from ArrayFire. The rights granted to you constitute a license and not a transfer of title. The rights specified above to view, Download and print the documents and information available on this Site are not applicable to the design or layout of this Site. Elements of this Site are protected by trade dress and other laws and may not be copied or imitated in whole or in part.\r\n\r\n<strong>Use and Protection of Account Numbers and Password</strong>\r\n\r\nYou are responsible for maintaining the confidentiality of your account number and/or password, if applicable. You are responsible for all uses of your account, whether or not actually or expressly authorized by you.\r\n\r\n<strong>Warranty and Disclaimers</strong>\r\n\r\nEXCEPT AS EXPRESSLY PROVIDED OTHERWISE IN A WRITTEN AGREEMENT BETWEEN YOU AND ArrayFire, ALL MATERIALS AND SERVICES ON THIS SITE ARE PROVIDED \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THE WARRANTY OF NON-INFRINGEMENT. WITHOUT LIMITING THE FOREGOING, ArrayFire MAKES NO WARRANTY THAT (i) THE SERVICES AND MATERIALS WILL MEET YOUR REQUIREMENTS, (ii) THE SERVICES AND MATERIALS WILL BE UNINTERRUPTED, TIMELY, SECURE, OR ERROR-FREE, (iii) THE RESULTS THAT MAY BE OBTAINED FROM THE USE OF THE SERVICES OR MATERIALS WILL BE EFFECTIVE, ACCURATE OR RELIABLE, (iv) THE QUALITY OF ANY PRODUCTS, SERVICES, OR INFORMATION PURCHASED OR OBTAINED BY YOU FROM THE SITE WILL MEET YOUR EXPECTATIONS, AND (v) ANY ERRORS IN THE SOFTWARE OBTAINED FROM THE SITE WILL BE CORRECTED. SOME STATES OR JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES OR LIMITATIONS ON HOW LONG AN IMPLIED WARRANTY MAY LAST, SO THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU. TO THE EXTENT PERMISSIBLE, ANY IMPLIED WARRANTIES ARE LIMITED TO NINETY (90) DAYS.\r\n\r\nTHIS SITE COULD INCLUDE TECHNICAL OR OTHER MISTAKES, INACCURACIES OR TYPOGRAPHICAL ERRORS. ArrayFire MAY MAKE CHANGES TO THE MATERIALS AND SERVICES AT THIS SITE, INCLUDING THE PRICES AND DESCRIPTIONS OF ANY PRODUCTS LISTED HEREIN, AT ANY TIME WITHOUT NOTICE. THE MATERIALS OR SERVICES AT THIS SITE MAY BE OUT OF DATE, AND ArrayFire MAKES NO COMMITMENT TO UPDATE SUCH MATERIALS OR SERVICES.\r\n\r\nArrayFire ASSUMES NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THE INFORMATION, DOCUMENTS, SOFTWARE, MATERIALS AND/OR SERVICES WHICH ARE REFERENCED BY OR LINKED TO THIS SITE. REFERENCES TO OTHER CORPORATIONS, THEIR SERVICES AND PRODUCTS, ARE PROVIDED \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r\n\r\nIN NO EVENT SHALL ArrayFire OR ITS SUPPLIERS BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY SPECIAL, PUNITIVE, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ArrayFire HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OF THIS SITE OR OF ANY WEB SITE REFERENCED OR LINKED TO FROM THIS SITE. SOME JURISDICTIONS PROHIBIT THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, SO THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.\r\n\r\nTHE USE OF THE SERVICES OR THE DOWNLOAD OR OTHER ACQUISITION OF ANY MATERIALS THROUGH THE SITE IS DONE AT YOUR OWN DISCRETION AND RISK AND WITH YOUR AGREEMENT THAT YOU WILL BE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR LOSS OF DATA THAT RESULTS FROM SUCH ACTIVITIES. NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED BY YOU FROM ArrayFire OR THROUGH OR FROM THE SITE SHALL CREATE ANY WARRANTY NOT EXPRESSLY STATED IN THE TERMS OF USE.\r\n\r\nThis Site contains links to third-party Web sites that are not under the control of ArrayFire. ArrayFire makes no representations whatsoever about any other Web site to which you may have access through this Site. When you access a non-ArrayFire Web site, you do so at your own risk and ArrayFire is not responsible for the accuracy or reliability of any information, data, opinions, advice, or statements made on these sites or for the quality of any products or services available on such sites. ArrayFire provides these links merely as a convenience and the inclusion of such links does not imply that ArrayFire endorses or accepts any responsibility for the content or uses of such Web sites.\r\n\r\nThis Site can be accessed from other countries around the world and may contain references to ArrayFire products, services, and programs that have not been announced in your country. These references do not imply that ArrayFire intends to announce such products, services or programs in your country.\r\n\r\n<strong>Personal Information and Privacy</strong>\r\n\r\nTo learn about how ArrayFire protects your personal information, such as your name and address, refer to the ArrayFire Online Privacy Policy. Please note that any non-personal information or material sent to ArrayFire will be generally be deemed to NOT be confidential.\r\n\r\n<strong>License for User Content</strong>\r\n\r\nCertain Services offered on this Site accommodate or require user-supplied information, materials or communications (collectively, \'User Content\'). Depending upon the nature of the Service, by submitting User Content to this Site you grant ArrayFire one of the following two types of licenses:\r\n\r\nFor User Content that is the result of your creative efforts, such as examples of work you have done using ArrayFire products, you hereby grant ArrayFire a worldwide, royalty-free, non-exclusive license to reproduce and modify (for purposes of formatting, maintenance or Site administration only) such User Content. You also grant ArrayFire the right to distribute and publicly display and perform such User Content for the purpose for which such User Content was submitted to the Service. This license will be in effect until such User Content is removed from the Site.\r\n\r\nFor User Content such as comments to the ArrayFire User to User Forums, bug reports, piracy reports or product suggestions, you grant ArrayFire an unrestricted, worldwide, irrevocable license to use, reproduce, display, perform, modify, transmit and distribute such User Content, and you also agree that ArrayFire is free to use any ideas, concepts, know-how or techniques that you send us for any purpose. However, we will not release your name or otherwise publicize the fact that you submitted such User Content to us unless: (a) you grant us permission to do so; (b) we first notify you that the User Content you submit to a particular part of the Site will be published or otherwise used with your name on it; or (c) we are required to do so by law.\r\n\r\n<strong>Prohibited Communications</strong>\r\n\r\nYou may only submit to the Site, User Content that is (a) owned by you, (b) submitted with the express permission of the owner, or (c) in the public domain. You are prohibited from posting or transmitting to or from this Site any unlawful, threatening, libelous, defamatory, obscene, pornographic, or other materials that would violate any law or the rights of others, including without limitation, laws against copyright infringement. Violation of these restrictions may result in limitations on access by you to this Site.\r\n\r\n<strong>Managing User Content and Communications</strong>\r\n\r\nArrayFire reserves the right, in its sole discretion, to delete or remove your User Content from the Site and to restrict, suspend or terminate your access to all or part of this Site, at any time for any reason without prior notice or liability.\r\n\r\nArrayFire may establish general practices and limits on the use of any Service, including, but not limited to, limits on retention time, file size, and storage space for User Content. ArrayFire shall have no liability or responsibility for the deletion or failure to store any information or materials in connection with any Service.\r\n\r\nArrayFire may, but is not obligated to, monitor or review (i) any areas on the Site where users transmit or post User Content, including but not limited to areas where Services are available, or chat rooms, bulletin boards or other user forums, and (ii) the substance of any User Content.\r\n\r\nTo the maximum extent permitted by law, ArrayFire will have no liability related to User Content arising under the laws of copyright, libel, privacy, obscenity, or otherwise. ArrayFire also disclaims all liability with respect to the misuse, loss, modification, or unavailability of any User Content.\r\n\r\n<strong>User Forums</strong>\r\n\r\nIn addition to these Terms of Use, users of the ArrayFire User To User Forums must agree to a separate legal agreement located within the Forums Registration area of the Site. Your access to the User to User Forums will be denied for violation of the prohibitions set forth in this Terms of Use under the Section entitled PROHIBITED COMMUNICATIONS.\r\n\r\n<strong>Notification of Copyright Infringement</strong>\r\n\r\nArrayFire will, in appropriate circumstances, terminate the accounts of users who infringe the intellectual property rights of others. If you believe that your work has been used or copied in a way that constitutes copyright infringement and such infringement is occurring on this Site or on sites linked to from this Site, please provide ArrayFire\' Copyright Agent a Notice containing the following elements:\r\n\r\na physical or electronic signature of the person authorized to act on behalf of the owner of the copyright interest that is alleged to have been infringed; a description of the copyrighted work or works that you claim have been infringed and identification of what material in such work(s) is claimed to be infringing and which you request to be removed or access to which is to be disabled; a description of where the material that you claim is infringing is located on the ArrayFire site; information sufficient to permit ArrayFire to contact you, such as your physical address, telephone number, and email address; a statement by you that you have a good faith belief that the use of the material identified in your Notice in the manner complained of is not authorized by the copyright owner, its agent, or the law; a statement by you that the information in your Notice is accurate and, under penalty of perjury, that you are the copyright owner or authorized to act on the copyright owner\'s behalf.\r\n\r\n<strong>Indemnity</strong>\r\n\r\nYou agree to indemnify and hold ArrayFire, and its subsidiaries, affiliates, officers, agents, co-branders or other partners, and employees, harmless from any claim or demand, including reasonable attorneys\' fees, made by any third party due to or arising out of content you submit, post to or transmit through the Site (including, without limitation, any User Content), your use of the Site, your connection to the Site, your violation of the Terms of Use, or your violation of any rights of another person or entity.\r\n\r\n<strong>Compliance with Local Laws</strong>\r\n\r\nThis site (excluding linked sites) is controlled by ArrayFire from its offices in Austell, GA, USA. ArrayFire makes no representation that materials or services available on this site are appropriate or available for use in specific locations. Accessing them from territories where their contents are illegal is prohibited. Those who choose to access this site from any location do so on their own initiative and are responsible for compliance with local laws.\r\n\r\n<strong>Trademark Information</strong>\r\n\r\nThe trademarks, logos and service marks (\"Marks\") displayed on this Site are the property of ArrayFire or other third parties. You are not permitted to use the Marks without the prior written consent of ArrayFire or such third party which may own the Marks. ArrayFire and the ArrayFire logo are trademarks of ArrayFire LLC. [/content_band][content_band inner_container=\"true\" no_margin=\"true\" border=\"bottom\" padding_top=\"40px\" padding_bottom=\"40px\"  ]\r\n<h3>Online Privacy Policy</h3>\r\nBy accessing or using the ArrayFire.com Web site, you agree to the terms of the ArrayFire Online Privacy Policy, as outlined below. If you do not agree to these terms, please do not access or use this site. ArrayFire reserves the right to change the Online Privacy Policy from time to time at its sole discretion. Your use of this site will be subject to the most current version of the Online Privacy Policy at the time of such use.\r\n\r\nCollection of personal information\r\n\r\nWhen you engage in certain activities on this site, such as ordering or registering products, Download software, or entering contests, ArrayFire may ask you to provide certain information about yourself by filling out and submitting an online form. It is completely optional for you to engage in these activities. If you elect to engage in these activities, however, ArrayFire may ask that you provide us personal information, such as your first and last name, mailing address (including zip code), e-mail address, employer, job title and department, telephone and facsimile numbers, and other personal identifying information. When ordering products or services on the site, you may be asked to provide a credit card number. Depending upon the activity, some of the information that we ask you to provide is identified as mandatory and some as voluntary. If you do not provide the mandatory data with respect to a particular activity, you will not be able to engage in that activity.\r\n\r\nWhen you submit personal information to ArrayFire on this site, you understand and agree that this information may be transferred across national boundaries and may be stored and processed in any of the countries in which ArrayFire and its affiliates and subsidiaries maintain offices, including without limitation, the United States. You also acknowledge that in certain countries or with respect to certain activities, the collection, transferring, storage and processing of your information may be undertaken by trusted vendors of ArrayFire.\r\n\r\nHow your personal information is used ArrayFire collects your information in order to record and support your participation in the activities you select. If you order a product that is to be electronically Download, for example, the information is used to register your license and rights, if any, to technical support, upgrade discounts, or other benefits that may be made available to registered users. If you enter a contest, information is collected to qualify the entry and contact you regarding the contest or prize awards. The information that you provide is also used as part of our effort to keep you informed about product upgrades, special offers, and other products and services of ArrayFire and selected third parties.\r\n\r\nYour choices with respect to personal information ArrayFire recognizes and appreciates the importance of responsible use of information collected on this site. If you do not want the information you provide to ArrayFire to be used to inform you of other products, services and special offers available from ArrayFire, and you indicate this preference when you provide your personal information to ArrayFire, ArrayFire will honor your preference. ArrayFire reserves the right to provide aggregate data to third parties for statistical analysis. Such data will not be linked to any particular individuals.\r\n\r\nProtection of your personal information\r\n\r\nThe personal information that you provide in connection with registering yourself as an ArrayFire user or registering an ArrayFire product is classified as Registration Information. Registration Information is protected. Your Registration Information resides on a secure server that only selected ArrayFire personnel and contractors have access to via password. ArrayFire encrypts your personal information and thereby prevents unauthorized parties from viewing such information when it is transmitted to ArrayFire.\r\n\r\nPersonal information that you provide that is not Registration Information also resides on a secure server and is only accessible via password. Since this information is not accessible from outside ArrayFire, you will not be asked to select a password in order to view or modify such information.\r\n\r\nPlease note that any information you post to a public bulletin board or chat room, such as the ArrayFire User to User Forums, is available to all persons accessing that site.\r\n\r\nUse of cookies\r\n\r\nThe rights specified above to view, Download and print the documents and information available on this Site are not applicable to the design or layout of this Site. Elements of this Site are protected by trade dress and other laws and may not be copied or imitated in whole or in part. When you visit ArrayFire.com, you can surf the site anonymously and access important information without revealing your identity. In order to improve our site, we use \"cookies\" to track your visit. A cookie is small amount of data that is transferred to your browser by a Web server and can only be read by the server that gave it to you. It functions as your identification card, recording your passwords, purchases, and preferences. It cannot be executed as code or deliver viruses.\r\n\r\nMost browsers are initially set to accept cookies. You can set your browser to notify you when you receive a cookie, giving you the chance to decide whether or not to accept it. (For some Web pages that require an authorization, cookies are not optional. Users choosing not to accept cookies will probably not be able to access those pages.)\r\n\r\nWhile ArrayFire uses cookies to track your visit to ArrayFire.com, and our Web servers automatically log the IP/Internet address of your computer, this information does not identify you personally and you remain anonymous unless you have otherwise provided ArrayFire with personal information.\r\n\r\nPrivacy related complaints\r\n\r\nIf you believe that ArrayFire has not complied with this Online Privacy Policy with respect to your personal information, you may write the ArrayFire Privacy Officer at the address indicated above.\r\n\r\nIn your letter, please describe in as much detail as possible the ways in which you believe that the ArrayFire Online Privacy Policy has not been complied with. We will investigate your complaint promptly.\r\n\r\nPlease note that if you provide ArrayFire with inconsistent privacy preferences (for example, by indicating on one occasion that third parties may contact you with marketing offers and indicating on another occasion that they may not), ArrayFire cannot guarantee that your most recent privacy preference will be honored.\r\n\r\nAlso, please note that ArrayFire is not responsible for the content or privacy practices of non-ArrayFire Web sites to which ArrayFire.com or any other ArrayFire Web site may link.<span style=\"color: #ffffff;\"><span style=\"color: #000000;\">[/content_band]</span></span>[content_band inner_container=\"true\" no_margin=\"true\" border=\"bottom\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n<h3>Imprint</h3>\r\n<strong>AccelerEyes LLC</strong>\r\n3423 Piedmont Rd NE STE 330\r\nAtlanta, GA  30305\r\nUSA\r\nPhone: (800) 570-1941\r\nEmail: <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a>\r\nEditor: AccelerEyes LLC, Atlanta, GA.\r\nState of Incorporation: Georgia, USA.\r\n\r\n<strong>Disclaimer</strong>\r\n\r\n<strong>Contents of the Website</strong>\r\n\r\nArrayFire makes every effort to ensure that the material contained in its web site is current, complete and correct. Despite this errors and mistakes cannot be completely ruled out. ArrayFire does not accept liability for the relevance, accuracy or completeness of the information and material offered in its website unless the mistake occurred intentionally or through gross negligence. This refers to any loss, additional costs or damage of any kind suffered as a result of any use of any material in this website.\r\n\r\n<strong>Copyright</strong>\r\n\r\nThe Layout of the Homepage, graphics and pictures used and the collection of individual contributions are protected by copyright. ArrayFire reserves all rights including the rights of reproduction, the duplication and distribution via special processes.\r\n\r\n<strong>Trademarks</strong>\r\n\r\nThe following are either registered trademarks or trademarks of the named company in the United States, United Kingdom and/or other countries.\r\n\r\n\"Personal Supercomputing\" - AccelerEyes LLC.\r\n\"Simple Software for Powerful Visual Computing\" - AccelerEyes LLC.\r\n\"AccelerEyes\", the AccelerEyes logo - AccelerEyes LLC.\r\n\"Jacket\", \"LibJacket\", \"ArrayFire\", and their respective logos - AccelerEyes LLC.\r\nthe NVIDIA logo - NVIDIA.\r\n\"Windows\" - Microsoft Corporation.\r\n\"OpenCL\" - Apple.\r\n\"Adobe\" and \"Acrobat\" - Adobe Systems Inc.\r\nAerospace Blockset™, Bioinformatics Toolbox™, Communications Blockset™, Communications Toolbox™, Control System Toolbox™, Curve Fitting Toolbox™, Data Acquisition Toolbox™, Database Toolbox™, Datafeed Toolbox™, Econometrics Toolbox™, EDA Simulator Link™, Embedded IDE Link™, Embedded MATLAB®, Extended Symbolic Math Toolbox™, Filter Design HDL Coder™, Filter Design Toolbox™, Financial Derivatives Toolbox™, Financial Toolbox™, Fixed-Income Toolbox™, Fixed-Point Toolbox™, Fuzzy Logic Toolbox™, GARCH Toolbox™, Gauges Blockset™, Genetic Algorithm and Direct Search Toolbox™, Handle Graphics®, Image Acquisition Toolbox™, Image Processing Toolbox™, Instrument Control Toolbox™, L-shaped membrane logo (graphic only)®, Mapping Toolbox™, MathWorks®, MATLAB®, MATLAB® Builder™ EX, MATLAB® Builder™ JA, MATLAB® Builder™ NE, MATLAB® Compiler™, MATLAB® Connector™, MATLAB® Distributed Computing Server™, MATLAB® Mobile™, MATLAB® Report Generator™, Model Predictive Control Toolbox™, Model-Based Calibration Toolbox™, Neural Network Toolbox™, OPC Toolbox™, Optimization Toolbox™, Parallel Computing Toolbox™, Partial Differential Equation Toolbox™, Polyspace®, Polyspace® Client™ for Ada, Polyspace® Client™ for C/C++, Polyspace® Model Link™ SL, Polyspace® Model Link™ TL, Polyspace® Server™ for Ada, Polyspace® Server™ for C/C++, Polyspace® UML Link™ RH, Real-Time Windows Target™, Real-Time Workshop®, Real-Time Workshop® Embedded Coder™, RF Blockset™, RF Toolbox™, Robust Control Toolbox™, Signal Processing Blockset™, Signal Processing Toolbox™, SimBiology®, SimDriveline™, SimElectronics®, SimEvents®, SimHydraulics®, SimMechanics™, SimPowerSystems™, SimRF™, Simscape™, Simulink®, Simulink® 3D Animation™, Simulink® Accelerator™, Simulink® Control Design™, Simulink® Design Optimization™, Simulink® Design Verifier™, Simulink® Fixed Point™, Simulink® HDL Coder™, Simulink® Parameter Estimation™, Simulink® PLC Coder™, Simulink® Report Generator™, Simulink® Response Optimization™, Simulink® Verification and Validation™, Spline Toolbox™, Spreadsheet Link™ EX, Stateflow®, Stateflow® Coder™, Statistics Toolbox™, Symbolic Math Toolbox™, System Identification Toolbox™, SystemTest™, Target Support Package™, Vehicle Network Toolbox™, Video and Image Processing Blockset™, Virtual Reality Toolbox™, Wavelet Toolbox™, xPC Target™, xPC TargetBox™, xPC Target™ Embedded Option™ - The MathWorks, Inc.\r\n\r\nIf you notice the use of a trademark on this site which is not accredited herein, please contact our Marketing Department at <a href=\"mailto:sales@arrayfire.com\">sales@arrayfire.com</a>.\r\n\r\n<strong>Links to Third Party Information</strong>\r\n\r\nThe ArrayFire website links to third party information providers. ArrayFire has no influence on the contents or reliability of the websites of these third party information providers. The following therefore applies to all links:\r\n\r\nArrayFire has no influence on the design and contents of third party internet websites. ArrayFire therefore expressly distances itself from the material of all third party internet websites, even if the ArrayFire website links to these external sites. The declaration is valid for all links given on our website and the material of all sites reached via links on the ArrayFire website. Privacy Where you are invited to submit personal information (eMail address, names, postal addresses) the submission of this information is purely voluntary.\r\n\r\n<strong>Legal validity</strong>\r\n\r\nThis general disclaimer is part of the material offered on the ArrayFire website. If any of the terms and conditions should be determined invalid by reason of the relevant laws then the remaining terms and conditions shall remain in full effect.[/content_band]\r\n<div id=\"eula\"></div>\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n<h3>End User License Agreement</h3>\r\nPLEASE READ THIS LICENSE CAREFULLY BEFORE USING THE SOFTWARE. BY USING THE SOFTWARE, YOU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS LICENSE. THE TERMS OF THIS LICENSE MAY CHANGE AT ANY TIME UPON ACTUAL OR CONSTRUCTIVE NOTICE TO YOU, AND YOU AGREE TO SUCH CHANGES UPON USING THE SOFTWARE. YOU AGREE TO MONITOR THE ArrayFire WEBSITE FOR SUCH CHANGES. IF YOU DO NOT AGREE TO THESE TERMS AND CONDITIONS, DO NOT USE THE SOFTWARE.\r\n\r\n1. License. AccelerEyes LLC (“ArrayFire”) hereby grants to you a non-exclusive, non-transferable, non-sublicensable, personal license to use the enclosed software program(s) and the accompanying documentation and any related documentation (the software program(s) and any documentation, including and any updates thereto, if any, are collectively referred to as the \"Software\") solely for your internal business purposes (the \"License\"). You own the medium on which the Software is recorded, but ArrayFire and ArrayFire\'s licensors (referred to collectively as \"ArrayFire\") retain title to the Software and related documentation. Under the License, you may only:\r\n\r\na) use the Software; and\r\n\r\nb) make a reasonable number of copies necessary for the purposes of this License. You must reproduce on such copy ArrayFire\'s copyright notice and any other proprietary legends that were on the original copy of the Software.\r\n\r\n2. Restrictions on License. The Software contains copyrighted and patented material, trade secrets and other proprietary material. In order to protect them, and except as permitted by applicable legislation, you may not:\r\n\r\na) decompile, reverse engineer, disassemble or otherwise reduce the Software to a human-perceivable form;\r\n\r\nb) modify, network, rent, lend, loan, distribute or create derivative works based upon the Software in whole or in part; or\r\n\r\nc) electronically transmit the Software from one computer to another or over a network or otherwise transfer the Software except as permitted by this License.\r\n\r\n3. Error Reporting and Usage Statistics. ArrayFire may monitor and collect information on your use of the Software.\r\n\r\n4. Terms for ArrayFire Free Software Subscription.\r\n\r\na) ArrayFire “ArrayFire Free” Subscription. Subject to the terms of this agreement, the ArrayFire ArrayFire Free Software is freely available for single GPU usage with a shared license and requires an internet connection. ArrayFire Free automatically connects to ArrayFire\'s online license server.\r\n\r\nb) Availability of the ArrayFire Free Software Subscription. While the ArrayFire Free Subscription is generally available, ArrayFire reserves the right to determine in its sole discretion who may or may not receive the ArrayFire Free Subscription. The ArrayFire Free subscription is only available for use through the shared license and requires an internet connection.\r\n\r\n5. Terms for ArrayFire 12 Month Annual (Purchased) Software Subscriptions.\r\n\r\na) ArrayFire 12 Month Annual “ArrayFire Pro” Subscription. Subject to the terms of this agreement, the ArrayFire ArrayFire Pro Software is a perpetual, subscription-based License. License updates, maintenance, and support are sold as 12 month annual subscriptions (1-year from the purchase date of the subscription).\r\n\r\nb) ArrayFire 12 Month Annual “ArrayFire Developer” Subscription. Subject to the terms of this agreement, the ArrayFire ArrayFire Developer Software is a perpetual, subscription-based License. License updates, maintenance, and support are sold as 12 month annual subscriptions (1-year from the purchase date of the subscription).\r\n\r\nc) ArrayFire 12 Month Annual “ArrayFire Enterprise” Subscription. Subject to the terms of this agreement, the ArrayFire ArrayFire Enterprise Software is a perpetual, subscription-based License. License updates, maintenance, and support are sold as 12 month annual subscriptions (1-year from the purchase date of the subscription).\r\n\r\nd) Availability of 12 Month Annual Software Subscription. While the “ArrayFire Pro,” “ArrayFire Developer,” and “ArrayFire Enterprise” 12 month annual Subscriptions are generally available, ArrayFire reserves the right to determine in its sole discretion who may or may not receive the ArrayFire Subscription.\r\n\r\n6. END OF SOFTWARE SUBSCRIPTION. Non-renewal and Cancellation. ArrayFire reserves the right to cancel or terminate the “ArrayFire Free” Software Subscription at any time without prior notice to you. For the “ArrayFire Pro,” “ArrayFire Developer,” and “ArrayFire Enterprise” Software Subscriptions, at the end of the 12 month annual subscription period (1-year from the purchase date of the subscription), you may either renew the annual subscription or continue using the ArrayFire Software without future license updates, maintenance, or support. Failure to renew the 12 month annual subscription will automatically terminate the subscription and all future software license updates, maintenance and support.\r\n\r\n7. Renewal of Software Subscription. On or about the expiration of the 12 month annual subscription period, you must provide notice to ArrayFire of your desire to renew the subscription. ArrayFire will not automatically renew or bill you for a subsequent subscription after termination without your prior consent. You may renew the “ArrayFire Pro,” “ArrayFire Developer,” or “ArrayFire Enterprise” 12 month annual subscription at any time after the end of the subscription period. The 12 month annual subscription shall be renewed upon your full payment, pro-rated from the date of the end of your last 12 month annual subscription period.\r\n\r\n8. Termination. ArrayFire may terminate this agreement if, in ArrayFire\'s sole determination, you fail to comply with these terms. Upon termination you must destroy the Software, related documentation and all copies thereof. ArrayFire reserves the right to revoke this License at any time, and may, at its discretion, cease to provide free license checkouts over the internet.\r\n\r\n9. Government End Users. If you are acquiring the Software on behalf of any unit or agency of the United States Government, the following provisions apply. The Government agrees the Software and documentation were developed at private expense and are provided with \"RESTRICTED RIGHTS\". Use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 227.7202-1(a) and 227.7202-3(a) (1995), DFARS 252.227-7013(c)(1) (ii) (Oct 1988), FAR 12.212(a)(1995), FAR 52.227-19, (June 1987) or FAR 52.227-14(ALT III) (June 1987), as amended from time to time. In the event that this License, or any part thereof, is deemed inconsistent with the minimum rights identified in the Restricted Rights provisions, the minimum rights shall prevail.\r\n\r\n10. No Other License. No rights or licenses are granted by ArrayFire under this License, expressly or by implication, with respect to any proprietary information or patent, copyright, trade secret or other intellectual property right owned or controlled by ArrayFire, except as expressly provided in this License.\r\n\r\n11. Additional Licenses. DISTRIBUTION OR USE OF THE SOFTWARE WITH AN OPERATING SYSTEM MAY REQUIRE ADDITIONAL LICENSES FROM THE OPERATING SYSTEM VENDOR. Additional third party licenses may also be required and you agree that you shall be solely responsible for obtaining such license rights.\r\n\r\n12. Disclaimer of Warranty on Software. You expressly acknowledge and agree that use of the Software is at your sole risk. The Software and related documentation are provided \"AS IS\" and without warranty of any kind and ArrayFire EXPRESSLY DISCLAIMS ALL WARRANTIES, EXPRESS AND IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, ACCURACY, CONDITION, OWNERSHIP, FITNESS FOR A PARTICULAR PURPOSE, AND/OR OF NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, AND THOSE ARISING FROM CUSTOM OR TRADE OR COURSE OF USAGE. ArrayFire DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS IN THE SOFTWARE WILL BE CORRECTED. THE ENTIRE RISK AS TO THE RESULTS AND PERFORMANCE OF THE SOFTWARE IS ASSUMED BY YOU. FURTHERMORE, ArrayFire DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OR THE RESULTS OF THE USE OF THE SOFTWARE OR RELATED DOCUMENTATION IN TERMS OF THEIR CORRECTNESS, ACCURACY, RELIABILITY, CURRENTNESS, OR OTHERWISE. NO ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY ArrayFire OR ArrayFire\'s AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY OR IN ANY WAY INCREASE THE SCOPE OF THIS WARRANTY. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND NOT ArrayFire OR ArrayFire\'s AUTHORIZED REPRESENTATIVE(S)) ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. THE SOFTWARE IS NOT INTENDED FOR USE IN MEDICAL, LIFE SAVING OR LIFE SUSTAINING APPLICATIONS. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT APPLY TO YOU.\r\n\r\n13. Limitation of Liability. UNDER NO CIRCUMSTANCES, INCLUDING NEGLIGENCE, GROSS NEGLIGENCE, RECKLESS DISREGARD, OR ANY OTHER CONDITION, SHALL ArrayFire, OR ITS DIRECTORS, OFFICERS, EMPLOYEES OR AGENTS (\"AUTHORIZED REPRESENTATIVES\"), BE LIABLE TO YOU FOR ANY PUNITIVE, EXEMPLARY, DIRECT, INCIDENTAL, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES (INCLUDING DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, AND THE LIKE) ARISING OUT OF THE USE, MISUSE OR INABILITY TO USE THE SOFTWARE OR RELATED DOCUMENTATION, BREACH OR DEFAULT, INCLUDING THOSE ARISING FROM INFRINGEMENT OR ALLEGED INFRINGEMENT OF ANY PATENT, TRADEMARK, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT, BY ArrayFire, EVEN IF ArrayFire OR ArrayFire\'s AUTHORIZED REPRESENTATIVE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE ABOVE LIMITATION OR EXCLUSION MAY NOT APPLY TO YOU. ArrayFire will not be liable for: 1) loss of, or damage to, your records or data; or 2) any damages claimed by you based on any third party claim. In no event shall ArrayFire\'s total liability to you for all damages, losses, and causes of action (whether in contract, tort (including negligence) or otherwise) exceed the dollar (or other applicable financial currency) amount paid by you for the Software.\r\n\r\n14. Export Restrictions. You shall adhere to all U.S. and other applicable export laws, including but not limited to the U.S. Export Administration Regulations (EAR), currently found at 15 C.F.R. Sections 730 through 744. Further, pursuant to 15 C.F.R Section 740.6, You hereby certifies that, except pursuant to a license granted by the United States Department of Commerce Bureau of Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export Administration Regulations (\"EAR\"), You will not (1) export, re-export or release to a national of a country in Country Groups D:1 or E:2 any restricted technology, software, or source code it receives from ArrayFire, or (2) export to Country Groups D:1 or E:2 the direct product of such technology or software, if such foreign produced direct product is subject to national security controls as identified on the Commerce Control List (currently found in Supplement 1 to Part 774 of EAR). For the most current Country Group listings, or for additional information about the EAR or Recipient\'s obligations under those regulations, please refer to the U.S. Bureau of Industry and Security\'s website at http://www.bis.doc.gov/. These export requirements shall survive any expiration or termination of this Agreement.\r\n\r\n15. Controlling Law and Severability. This Agreement will be governed by and construed under the laws of the State of Georgia without reference to its conflicts of law principles. The rights and obligations under this Agreement shall not be governed by the United Nations Convention on Contracts or the International Sale of Goods, the application of which is expressly excluded. Each party hereto submits to the jurisdiction of the state and federal courts of Fulton County and the Northern District of Georgia for the purpose of all legal proceedings arising out of or relating to this Agreement or the subject matter hereof. Each party waives any objection which it may have to contest such forum.\r\n\r\n16. Complete Agreement. This License constitutes the entire agreement between the parties with respect to the use of the Software and the related documentation, and supersedes all prior or contemporaneous understandings or agreements, written or oral, regarding such subject matter. No amendment to or modification of this License will be binding unless in writing and signed by a duly authorized representative of ArrayFire.\r\n\r\n---------------------------------------------\r\n\r\nCULA Basic and CULA Premium Software License Agreement\r\n\r\n---------------------------------------------\r\n\r\nThe contents of this file are subject to the Software License Agreement (the \"Agreement\"). You may not use this file except in compliance with the Agreement. You may obtain a copy of the Agreement at http://www.culatools.com/legal. Software distributed under the Agreement is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the Agreement for the specific language governing rights and limitations under the Agreement. The developer of the CULA Basic and CULA Premium is EM Photonics, Inc., a Delaware corporation. 2008-2009 (c) EM Photonics, Inc. All Rights Reserved. CULATOOLS(tm), CULA(tm), the EM Photonics logo, and certain other trademarks and logos are trademarks or registered trademarks of EM Photonics, Inc. in the United States and other countries.\r\n\r\n---------------------------------------------\r\n\r\nThis software uses the FreeImage open source image library. See http://freeimage.sourceforge.net for details. FreeImage is used under the (GNU GPL or FIPL), version (license version).\r\n\r\nFreeImage Public License - Version 1.0\r\n\r\n---------------------------------------------\r\n\r\n1. Definitions.\r\n\r\n1.1. \"Contributor\" means each entity that creates or contributes to the creation of Modifications.\r\n\r\n1.2. \"Contributor Version\" means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor.\r\n\r\n1.3. \"Covered Code\" means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof.\r\n\r\n1.4. \"Electronic Distribution Mechanism\" means a mechanism generally accepted in the software development community for the electronic transfer of data.\r\n\r\n1.5. \"Executable\" means Covered Code in any form other than Source Code.\r\n\r\n1.6. \"Initial Developer\" means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A.\r\n\r\n1.7. \"Larger Work\" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License.\r\n\r\n1.8. \"License\" means this document.\r\n\r\n1.9. \"Modifications\" means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is:\r\n\r\nA. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications.\r\n\r\nB. Any new file that contains any part of the Original Code or previous Modifications.\r\n\r\n1.10. \"Original Code\" means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License.\r\n\r\n1.11. \"Source Code\" means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or a list of source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor\'s choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge.\r\n\r\n1.12. \"You\" means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, \"You\" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, \"control\" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of fifty percent (50%) or more of the outstanding shares or beneficial ownership of such entity.\r\n\r\n2. Source Code License.\r\n\r\n2.1. The Initial Developer Grant. The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims:\r\n\r\n(a) to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, or as part of a Larger Work; and\r\n\r\n(b) under patents now or hereafter owned or controlled by Initial Developer, to make, have made, use and sell (\"Utilize\") the Original Code (or portions thereof), but solely to the extent that any such patent is reasonably necessary to enable You to Utilize the Original Code (or portions thereof) and not to any greater extent that may be necessary to Utilize further Modifications or combinations.\r\n\r\n2.2. Contributor Grant. Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims:\r\n\r\n(a) to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code or as part of a Larger Work; and\r\n\r\n(b) under patents now or hereafter owned or controlled by Contributor, to Utilize the Contributor Version (or portions thereof), but solely to the extent that any such patent is reasonably necessary to enable You to Utilize the Contributor Version (or portions thereof), and not to any greater extent that may be necessary to Utilize further Modifications or combinations.\r\n\r\n3. Distribution Obligations.\r\n\r\n3.1. Application of License.\r\n\r\nThe Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients\' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5.\r\n\r\n3.2. Availability of Source Code.\r\n\r\nAny Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party.\r\n\r\n3.3. Description of Modifications.\r\n\r\nYou must cause all Covered Code to which you contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code.\r\n\r\n3.4. Intellectual Property Matters\r\n\r\n(a) Third Party Claims.\r\n\r\nIf You have knowledge that a party claims an intellectual property right in particular functionality or code (or its utilization under this License), you must include a text file with the source code distribution titled \"LEGAL\" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If you obtain such knowledge after You make Your Modification available as described in Section 3.2, You shall promptly modify the LEGAL file in all copies You make available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained.\r\n\r\n(b) Contributor APIs.\r\n\r\nIf Your Modification is an application programming interface and You own or control patents which are reasonably necessary to implement that API, you must also include this information in the LEGAL file.\r\n\r\n3.5. Required Notices.\r\n\r\nYou must duplicate the notice in Exhibit A in each file of the Source Code, and this License in any documentation for the Source Code, where You describe recipients\' rights relating to Covered Code. If You created one or more Modification(s), You may add your name as a Contributor to the notice described in Exhibit A. If it is not possible to put such notice in a particular Source Code file due to its structure, then you must include such notice in a location (such as a relevant directory file) where a user would be likely to look for such a notice. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer.\r\n\r\n3.6. Distribution of Executable Versions.\r\n\r\nYou may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients\' rights relating to the Covered Code. You may distribute the Executable version of Covered Code under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient\'s rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer.\r\n\r\n3.7. Larger Works.\r\n\r\nYou may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code.\r\n\r\n4. Inability to Comply Due to Statute or Regulation.\r\n\r\nIf it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.\r\n\r\n5. Application of this License.\r\n\r\nThis License applies to code to which the Initial Developer has attached the notice in Exhibit A, and to related Covered Code.\r\n\r\n6. Versions of the License.\r\n\r\n6.1. New Versions.\r\n\r\nFloris van den Berg may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number.\r\n\r\n6.2. Effect of New Versions.\r\n\r\nOnce Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Floris van den Berg No one other than Floris van den Berg has the right to modify the terms applicable to Covered Code created under this License.\r\n\r\n6.3. Derivative Works.\r\n\r\nIf you create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), you must (a) rename Your license so that the phrases \"FreeImage\", `FreeImage Public License\", \"FIPL\", or any confusingly similar phrase do not appear anywhere in your license and (b) otherwise make it clear that your version of the license contains terms which differ from the FreeImage Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.)\r\n\r\n7. DISCLAIMER OF WARRANTY.\r\n\r\nCOVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN \"AS IS\" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.\r\n\r\n8. TERMINATION.\r\n\r\nThis License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive.\r\n\r\n9. LIMITATION OF LIABILITY.\r\n\r\nUNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY\'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.\r\n\r\n10. U.S. GOVERNMENT END USERS.\r\n\r\nThe Covered Code is a \"commercial item,\" as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of \"commercial computer software\" and \"commercial computer software documentation,\" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein.\r\n\r\n11. MISCELLANEOUS.\r\n\r\nThis License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by Dutch law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in, the The Netherlands: (a) unless otherwise agreed in writing, all disputes relating to this License (excepting any dispute relating to intellectual property rights) shall be subject to final and binding arbitration, with the losing party paying all costs of arbitration; (b) any arbitration relating to this Agreement shall be held in Almelo, The Netherlands; and (c) any litigation relating to this Agreement shall be subject to the jurisdiction of the court of Almelo, The Netherlands with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys fees and expenses. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License.\r\n\r\n12. RESPONSIBILITY FOR CLAIMS.\r\n\r\nExcept in cases where another Contributor has failed to comply with Section 3.4, You are responsible for damages arising, directly or indirectly, out of Your utilization of rights under this License, based on the number of copies of Covered Code you made available, the revenues you received from utilizing such rights, and other relevant factors. You agree to work with affected parties to distribute responsibility on an equitable basis.\r\n\r\nEXHIBIT A.\r\n\r\n\"The contents of this file are subject to the FreeImage Public License Version 1.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://home.wxs.nl/~flvdberg/freeimage-license.txt\r\n\r\nSoftware distributed under the License is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License.\r\n\r\n---------------------------------------------\r\n\r\nclBLAS, clFFT LICENSES\r\n\r\n---------------------------------------------\r\n\r\nApache License - Version 2.0, January 2004 - http://www.apache.org/licenses/\r\n\r\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n\r\n1. Definitions.\r\n\r\n\"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\r\n\r\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\r\n\r\n\"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\r\n\r\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\r\n\r\n\"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\r\n\r\n\"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\r\n\r\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\r\n\r\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\r\n\r\n\"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\r\n\r\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\r\n\r\n2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\r\n\r\n3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\r\n\r\n4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\r\n\r\n(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\r\n\r\n(b) You must cause any modified files to carry prominent notices stating that You changed the files; and\r\n\r\n(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\r\n\r\n(d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\r\n\r\nYou may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\r\n\r\n5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\r\n\r\n6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\r\n\r\n7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\r\n\r\n8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\r\n\r\n9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.\r\n\r\nEND OF TERMS AND CONDITIONS\r\n\r\nAPPENDIX: How to apply the Apache License to your work.\r\n\r\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don\'t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\r\n\r\nCopyright [yyyy] [name of copyright owner]\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\r\n\r\nhttp://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\r\n\r\n---------------------------------------------\r\n\r\nRANDOM123 LICENSE AGREEMENT\r\n\r\n---------------------------------------------\r\n\r\nCopyright 2010-2011, D. E. Shaw Research. All rights reserved.\r\n\r\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\r\n\r\n* Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.\r\n\r\n* Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution.\r\n\r\nNeither the name of D. E. Shaw Research nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\r\n\r\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<span style=\"color: #ffffff;\"><span style=\"color: #000000;\">[/content_band]</span></span>','Legal','','inherit','open','closed','','319-revision-v1','','','2014-05-19 20:44:31','2014-05-19 20:44:31','',319,'http://sandbox.arrayfire.com/319-revision-v1/',0,'revision','',0),(5612,7,'2014-05-19 20:54:18','2014-05-19 20:54:18','[content_band inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"two-fifths\"]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]If you want faster code, you\'ve come to the right place.[/custom_headline][gap size=\"15%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.sandbox.arrayfire.com/docs/installation.htm\" size=\"x-large\" block=\"true\"]Download ArrayFire[/button]\r\n\r\n[gap size=\"10%\"]\r\n\r\n[button  type=\"flat\" block=\"true\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"x-large\" ]Schedule a consultation[/button]\r\n\r\n[/column][column type=\"three-fifths\" last=\"true\"][gap size=\"7%\"]\r\n<div id=\"wistia_rj2bar3xxp\"></div>\r\n<script charset=\"ISO-8859-1\" type=\"text/javascript\" src=\"//fast.wistia.com/assets/external/E-v1.js\"></script><script type=\"text/javascript\">// <![CDATA[\r\nwistiaEmbed = Wistia.embed(\"rj2bar3xxp\");\r\n// ]]></script>[/column]\r\n<div id=\"arrayfire\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"]Faster code[/custom_headline]\r\n\r\nArrayFire is a fast, hardware-neutral software library for GPU computing with an easy-to-use API. Its array-based function set makes GPU programming simple. A few lines of code in ArrayFire can replace dozens of lines of raw GPU code, saving you valuable time and lowering development costs.\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.sandbox.arrayfire.com/docs/installation.htm\" size=\"x-large\" ]Download ArrayFire[/button][/column][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/Triumvirate_Exported.png\"][/column] [gap size=\"5%\"]\r\n\r\n[column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/Googlelogo-e1396387097279.png\"][line]Video content analysis is the basis for categorizing videos and enabling search by content. Google used ArrayFire to extract motion features in video, improving performance by substantially accelerating the solution of the L1-regularized least-squares optimization problem.[/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/Koch-Industries-e1396387359637.jpg\"][line]Andrew Shin, Market Risk Manager of Koch Supply &amp; Trading, achieves significant performance increases on option pricing algorithms using ArrayFire software, \"My buddy and I are, at best, novice programmers and we couldn\'t imagine having to figure out how to code all this in CUDA.\"[/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/nasa-e1396387230473.png\"][line]The main thrust of this research was improving Mars rover image compression via GPUs and genetic algorithms. With ArrayFire software and GPUs, the researchers were able to achieve 5X speedups on the larger data sizes.[/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n\r\n[column type=\"one-half\"][gap size=\"15%\"]\r\n\r\n<img alt=\"CUDA logo\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/CUDA-logo.jpg\" width=\"231\" height=\"140\" />\r\n\r\n<img alt=\"OpenCL\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/OpenCLLogo_678x452.png\" width=\"326\" height=\"217\" />\r\n\r\n[/column][column type=\"one-half\" last=\"true\"][gap size=\"10%\"]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"] ArrayFire for CUDA and OpenCL[/custom_headline]\r\n\r\nArrayFire supports CUDA-capable NVIDIA GPUs and most OpenCL devices, including AMD GPUs/APUs and Intel Xeon Phi co-processors. It also supports mobile OpenCL devices from ARM, Qualcomm, and others.\r\n\r\nArrayFire is a high-performance software library designed for maximum productivity and speed without the hassle of writing difficult low-level device code. Each of ArrayFire\'s functions has been hand-tuned by our CUDA and OpenCL experts.\r\n\r\n[/column]\r\n<div id=\"mobile\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"  ]Mobile GPU Computing[/custom_headline]\r\n\r\nMobile GPUs offer accelerated performance. If you would like to use ArrayFire in a mobile application or if you would like to hire our mobile acceleration services, email us at <a href=\"mailto:sales@arrayfire.com\" target=\"_blank\">sales@arrayfire.com</a> and include a description of your application.\r\n\r\nOur clients have achieved between 5X to 30X speed boosts for convolutions and other compute functions on mobile devices. It enables:[icon_list][icon_list_item type=\"angle-double-right\"]Real-time video processing[/icon_list_item][icon_list_item type=\"angle-double-right\"]Better augmented reality [/icon_list_item][icon_list_item type=\"angle-double-right\"]Better computational photograph[/icon_list_item][icon_list_item type=\"angle-double-right\"]Faster data processing[/icon_list_item][/icon_list]\r\n\r\nAll mobile devices have a GPU which can deliver greater compute throughput than the CPU. Why not use the GPU to make your app faster?[/column][column type=\"one-half\" fade=\"true\" last=\"true\" fade_animation=\"in-from-right\" class=\"center-text\"][gap size=\"10%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/mobile_Exported1-e1395437261846.png\"][/column]\r\n<div id=\"documentation\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"]Documentation[/custom_headline]\r\n\r\nArrayFire for C, C++, and Fortran\r\nOpen the hood—take a look at the beautiful nitty-gritty.\r\n\r\n[icon type=\"angle-double-right\"] <a href=\"http://www.sandbox.arrayfire.com/docs/\" target=\"_blank\">CUDA &amp; OpenCL C/C++</a>\r\n\r\nFunctions\r\nHundreds of functions, hand-tuned and optimized by our engineers.\r\n\r\n[icon type=\"angle-double-right\"] <a title=\"ArrayFire Functions\" href=\"http://www.sandbox.arrayfire.com/docs/modules.htm\">ArrayFire Functions</a>\r\n\r\nUser Forums\r\nEvery post gets a response from ArrayFire engineers.\r\n\r\n[icon type=\"angle-double-right\"] <a href=\"http://forums.accelereyes.com/\" target=\"_blank\">User Forums</a>\r\n\r\n[/column][column class=\"center-text\" type=\"one-half\" last=\"true\" fade=\"true\" fade_animation=\"in-from-right\" ][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/gears1.png\"][/column]\r\n<div id=\"benchmarks\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n[column type=\"one-half\" fade=\"true\" fade_animation=\"in-from-left\" ][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Benchmark-guy-torso-opposite-e1392155948298.png\"][/column]\r\n\r\n[column type=\"one-half\" last=\"true\"][custom_headline type=\"left\" level=\"h3\" ]Benchmarks[/custom_headline]\r\n\r\nAll benchmarks were performed on a NVIDIA Tesla C2050 with an Intel i7-950 processor. The benchmarks compare ArrayFire with several popular CPU-based acceleration libraries, including <a href=\"http://software.intel.com/en-us/articles/intel-mkl/\" target=\"_new\">Intel Math Kernel Library</a>, <a href=\"http://software.intel.com/en-us/articles/intel-ipp/\" target=\"_new\">Intel Integrated Performance Primitives</a>, <a href=\"http://eigen.tuxfamily.org/index.php?title=Main_Page\" target=\"_new\">Eigen</a>, and <a href=\"http://arma.sourceforge.net/\" target=\"_new\">Armadillo</a>.[/column]\r\n\r\n[column type=\"one-fifth\"].[/column][column type=\"three-fifths\"][tab_nav type=\"four-up\"][tab_nav_item title=\"Base\" active=\"true\"][tab_nav_item title=\"Linear Algebra\" active=\"\"][tab_nav_item title=\"Convolution\" active=\"\"][tab_nav_item title=\"Utility\" active=\"\"][/tab_nav][tabs][tab active=\"true\"]<img alt=\"Matrix Multiply\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/matrix_multiply-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"Matrix Transpose\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/matrix_transpose-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"FFT\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/fft-1024x730.png\" width=\"491\" height=\"350\" />[/tab][tab]<img alt=\"LU\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/lu-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"SVD\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/svd-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"Solve\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/solve-1024x730.png\" width=\"491\" height=\"350\" />[/tab][tab]<img alt=\"Convs\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/convs-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"Conv\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/conv-1024x730.png\" width=\"491\" height=\"350\" />[/tab][tab]<img alt=\"sum\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/sum-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"sort\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/sort-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"scan\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/scan-1024x730.png\" width=\"491\" height=\"350\" />[/tab][/tabs][/column][column type=\"one-fifth\" last=\"true\"].[/column]\r\n<div id=\"free\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"].[/column][column type=\"one-fourth\"].[custom_headline type=\"center\"  level=\"h3\" class=\"mtn\"]ArrayFire Free[/custom_headline][/column][column type=\"one-fourth\" last=\"true\"].[/column][column type=\"one-fourth\"  fade=\"true\" fade_animation=\"in-from-left\" ][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/right-leaning-e1391788779101.png\"][/column][column type=\"one-fourth\"]\r\n<table>\r\n<tbody>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Functions[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Basic Operations</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Arithmetic</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Signal Processing</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Image Processing</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Statistics</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Visualization</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n[gap size=\"17%\"][button type=\"flat\" block=\"true\" shape=\"rounded\" size=\"large\"  href=\"http://www.sandbox.arrayfire.com/docs/installation.htm\"]Download ArrayFire[/button] [/column][column type=\"one-fourth\"]\r\n<table>\r\n<tbody>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Hardware[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] CUDA</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] OpenCL</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Languages[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] C/C++</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Fortran</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Advanced[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td> [icon type=\"check-circle\" style=\"color: #8cc540;\"] GFOR Loop</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n[/column][column type=\"one-fourth\" last=\"true\"]\r\n<table>\r\n<tbody>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Platforms[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Windows</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Linux</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Mac</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Data Types[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] All types</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Support[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td> [icon type=\"check-circle\" style=\"color: #8cc540;\"] Forums</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n<div id=\"licensing\"></div>\r\n[/column][gap size=\"8%\"]\r\n\r\n[pricing_table id=\"pricing\" columns=\"3\"][pricing_table_column  featured=\"false\" title=\"ArrayFire Developer\" currency=\"$\" price=\"499 / year\" interval=\"$149 / year (Academic)\"] [icon_list] [icon_list_item type=\"star\" ]Dedicated license [/icon_list_item] [icon_list_item  type=\"times-circle\"] Starts at 2 GPUs or devices [/icon_list_item] [icon_list_item type=\"times-circle\"] Linear algebra [/icon_list_item] [icon_list_item type=\"times-circle\"] Sparse matrices [/icon_list_item][icon_list_item type=\"times-circle\"] Phone support [/icon_list_item][icon_list_item type=\"times-circle\"] Premium support &amp; consulting [/icon_list_item][/icon_list] [button href=\"http://sandbox.arrayfire.com/shop\"] Purchase [/button] [/pricing_table_column] [pricing_table_column featured=\"true\" featured_sub=\"Most Popular\" title=\"ArrayFire Pro\" currency=\"$\" price=\"1,499 / year\" interval=\"$525 / year (Academic)\"] [icon_list] [icon_list_item type=\"star\"] Dedicated license [/icon_list_item] [icon_list_item type=\"star\"] Starts at 2 GPUs or devices [/icon_list_item] [icon_list_item type=\"star\"] Linear algebra [/icon_list_item][icon_list_item type=\"star\"] Sparse matrices [/icon_list_item][icon_list_item type=\"times-circle\"] Phone support [/icon_list_item][icon_list_item type=\"times-circle\"] Premium support &amp; consulting [/icon_list_item] [/icon_list] [button href=\"http://sandbox.arrayfire.com/shop\"]Purchase [/button] [/pricing_table_column] [pricing_table_column featured=\"false\" title=\"ArrayFire Enterprise\" currency=\"$\" price=\"2,999 / year\" interval=\"$1,049 / year (Academic)\"] [icon_list] [icon_list_item type=\"star\"] Dedicated license [/icon_list_item] [icon_list_item type=\"star\"] Starts at 2 GPUs or devices [/icon_list_item] [icon_list_item type=\"star\"] Linear algebra [/icon_list_item][icon_list_item type=\"star\"]Sparse matrices [/icon_list_item][icon_list_item type=\"star\"] Phone support[/icon_list_item][icon_list_item type=\"star\"]Premium support &amp; consulting [/icon_list_item][/icon_list] [button href=\"http://sandbox.arrayfire.com/shop\"] Purchase [/button] [/pricing_table_column] [/pricing_table]\r\n<div id=\"whitepapers\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][gap size=\"20%\"][image type=\"thumbnail\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/wp2.jpg\"][button href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/03/arrayfire_matrix_computations_chrzeszczyk.pdf\" shape=\"rounded\" size=\"regular\" block=\"true\"]Download Matrix Computations on the GPU with ArrayFire for C/C++[/button][/column][column type=\"one-half\" last=\"true\"]\r\n\r\n[custom_headline type=\"left\" level=\"h3\" ]Whitepapers[/custom_headline]\r\n\r\n<img alt=\"Whitepaper 1\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Whitepaper-1.png\" width=\"466\" height=\"374\" />\r\n\r\n&nbsp;\r\n\r\n[/column][gap size=\"10%\"]\r\n\r\n[column type=\"one-half\"]<img alt=\"Whitepaper 2\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Whitepaper-2.png\" width=\"442\" height=\"304\" />[/column][column type=\"one-half\" last=\"true\"][image type=\"thumbnail\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/wp1.jpg\"][button href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/03/arrayfire_whitepaper.pdf\" shape=\"rounded\" size=\"regular\"  block=\"true\" float=\"right\"]Download High-level GPU Computing in C, C++, and Fortran[/button][/column]\r\n<div id=\"casestudies\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][gap size=\"12%\"][custom_headline type=\"left\" level=\"h3\" ]Case Studies[/custom_headline]\r\n\r\nLearn how ArrayFire has worked in real code, including applications in academia, finance, government, life sciences, manufacturing, media, and oil &amp; gas.[/column][column type=\"one-half\" last=\"true\" fade=\"true\" fade_animation=\"in-from right\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/model-A.png\"][/column][custom_headline type=\"left\" level=\"h5\"]Academia [/custom_headline][accordion][accordion_item title=\"Accelerating LTE Simulation | Tsinghua University\"]\r\n\r\nAuthors: Yuan Gao, Yin Sun, Chun Hui Zhou, Xin Su, Xi Bin Xu, Shi Dong Zhou, Tsinghua University\r\nSpeedup: 3X\r\n\r\nFast simulations are a driving force in several research projects. However, the accompanying long simulation times can tend to be a drag in many of these projects. In this article, we shall bring up the example of the work on 3GPP LTE System Simulation by Yuan Gao et al (from Tsinghua University, Beijing) and demonstrate how the use of ArrayFire software can significantly improve the simulator performance and lead to faster validation times in simulation projects.[/accordion_item]\r\n\r\n[accordion_item title=\"High Performance Compressive Sensing | Rice University\"]\r\n\r\nAuthors: Nabor Reyna and Wotao Yin from Rice University\r\nSpeedup: 5X\r\n\r\nThis work deals with reconstruction of signals using partial Fourier matrices (RecPF). The major computational components of the algorithm involve shrinkage and FFTs. ArrayFire software is employed to accelerate this compute-heavy code.[/accordion_item]\r\n\r\n[accordion_item title=\"Power System Simulations | Indian Institute of Technology, Roorkee, India\"]\r\nAuthors: Indian Institute of Technology, Roorkee\r\nSpeedup: 35X\r\n\r\nPower flow studies are one of the most important aspects of power system planning and operation. The power flow reveals the sinusoidal steady state characteristics of the entire system - voltages, real and reactive power generated, and absorbed and line losses- elucidating the voltage magnitudes and angles at each bus, the generation of each generating unit, and real and reactive power losses in the system. All this is necessary to ensure the security, economy, and control of electrical energy distribution. Learn how ArrayFire software can deliver magnitudes of performance improvement over CPU-based solutions.[/accordion_item]\r\n\r\n[accordion_item title=\"Antenna Array Simulations | University of Naples Federico II\"]\r\n\r\nAuthors: A. Capozzoli, C. Cucio, A. Liseno at University of Naples Federico II\r\nSpeedup: 24X\r\n\r\nAntenna array design involves repeated simulation to tune the many parameters involved, and waiting around for simulations to finish is no fun. Offloading the optimization problem onto the GPU cuts that time down significantly. In their recent paper, Capozzoli, Curcio, and Liseno of University of Naples Federico II demonstrated how a simple modification to their echo generator array simulation took advantage of the GPU to bring immediate speedups.[/accordion_item]\r\n\r\n[accordion_item title=\"Laplace Transform Inversion | Acunum Algorithms and Simulations\"]\r\n\r\nAuthors: Patrick Kano and Moysey Brio at Acunum Algorithms and Simulations\r\nSpeedup: 3.8X\r\n\r\nThe numerical inversion of the Laplace transform is a long standing problem due its implicit ill-posedness. Patrick Kano and Moysey Brio of Acunum Algorithms and Simulations, with their experience in computational methods and algorithm development, found a solution that not only works, but is very fast.[/accordion_item]\r\n\r\n[accordion_item title=\"Compressed Sensing for Image Reconstruction | College of Engineering, Roorkee, India\"]\r\n\r\nAuthors: Kuldeep Yadav, Ankush Mittal, M. A. Ansar, and Avi Srivastava, College of Engineering, Roorkee, India\r\nSpeedup: 8X\r\n\r\nCompressed sensing is very critical in the areas of medical image reconstruction, image acquisition or sensor networks. An algorithm for compressed sensing developed using a Basis Pursuit Algorithm shows over 8X speedup when run on an NVIDIA GPU.[/accordion_item]\r\n\r\n[accordion_item title=\"Fat/Water Reconstruction for Medical Images | Case Western Reserve University\"]\r\n\r\nAuthors: D. H. Johnson, S. Narayan, C. A. Flask, and D. L. Wilson, Case Western Reserve University\r\nSpeedup: 11.6X\r\n\r\nCase Western Reserve University researchers turned to GPUs running ArrayFire software to develop a fast and robust version of the \"Iterative Decomposition of water and fat with an Echo Asymmetry and Least-squares\" (IDEAL) reconstruction algorithm. This algorithm uses a lot of Image Processing algorithms for reconstruction, and was shown to achieve very high speedups.\r\n[/accordion_item]\r\n\r\n[/accordion]\r\n<h5>Finance</h5>\r\n[accordion][accordion_item title=\"Option Pricing | Koch Supply and Trading\"]\r\n\r\nAuthors: Koch Supply &amp; Trading\r\nSpeedup: 51.8X\r\n\r\nAndrew Shin, Market Risk Manager of Koch Supply &amp; Trading, achieves significant performance increases on option pricing algorithms using ArrayFire software to accelerate his code with GPUs. Andrew says, \"My buddy and I are, at best, novice programmers and we couldn\'t imagine having to figure out how to code all this in CUDA.\" But he found ArrayFire software to be straight-forward. With these results, he says he can see ArrayFire software and GPUs populating Koch\'s mark-to-futures cube, which contains its assets, simulations, and simulated asset prices.[/accordion_item]\r\n\r\n[accordion_item title=\"GPU Computing in Automated Trader | Automated Trader\"]\r\n\r\nAuthors: Automated Trader\r\nSpeedup: 37.5X\r\n\r\nThe Q1 2012 issue of Automated Trader contains an excellent Mashup piece reviewing software for algorithmic trading. The article provides a wonderful glimpse into the 1-2 month adventure of Andy Webb, Automated Trader.s Founder, and Wrecking Crew building a fast trading platform from several technologies. The full trading platform they built was quite extensive. The part that caught our eye was the core computational component of the pipeline. That component involved permuting 1,000 potential pairs with cointegration tests for 350 time windows on each potential pair.\r\n[/accordion_item]\r\n[accordion_item title=\"GPUs in Quantitative Analytics and Finance | Private Bank\"]\r\n\r\nThe world of Quantitative finance is all about getting accurate results really, really fast. ArrayFire is working with one of the largest banks in Spain to maximize their output using GPUs. Click the link below for an overview of the uses of GPU computing in finance.[/accordion_item][/accordion]\r\n<h5>Government</h5>\r\n[accordion][accordion_item title=\"Powering Mars Research | NASA and UAA in Anchorage\" ]\r\n\r\nAuthors: NASA and UAA in Anchorage\r\nSpeedup: 5X\r\n\r\nThe main thrust of this research is improving mars rover image compression via GPUs and genetic algorithms. With ArrayFire software and GPUs, the researchers were able to achieve 5X speedups on the larger data sizes. The algorithm works by pairing neighboring pixels with a random one and then adjusting the random pixel based on whether it incrementally improves the original image. Babb described the algorithm as an embarrassingly parallel process, ideally suited to GPU acceleration. He estimates he has been able to achieve a 20 to 30 percent error reduction in subjects like fingerprints and satellite imagery.[/accordion_item]\r\n\r\n[accordion_item title=\"Radar Image Formation | System Planning Corporation\"]\r\n\r\nAuthors: Gary Rubin and Earl Sager - System Planning Corporation\r\nSpeedup: ~45X\r\n\r\nRadar imaging is computationally intensive. As a result, many imaging algorithms apply FFT-based approximations. While efficient, these algorithms sacrifice data fidelity for speed. Other algorithms better preserve information, but are often too slow for many applications. At System Planning Corporation (SPC) , we have implemented a SAR/ISAR imaging routine based on the Backprojection algorithm. Using ArrayFire software, we have demonstrated speedups of roughly 45x for large datasets.[/accordion_item]\r\n\r\n[accordion_item title=\"Radar Clutter Reduction | System Planning Corporation\"]\r\n\r\nAuthors: David Berger and Gary Rubin - System Planning Corporation\r\nSpeedup: 5-10X\r\n\r\nSystem Planning Corporation (SPC) uses ArrayFire software to accelerate radar processing algorithms. The system processes raw data from marine navigation radars using a variety of thresholding techniques to extract real targets from clutter. This involves highly data-parallel processing in which each radar pulse is subjected to the same computations; very few operations occur across multiple pulses. Using ArrayFire software, SPC has achieved 10x speed improvements relative to a Core i7-920 CPU and 5x improvements relative to a realtime DSP implementation.[/accordion_item]\r\n\r\n[accordion_item title=\"Novel Algorithms for Linear Algebra | SAIC\" ]\r\n\r\nAuthors: Nolan Davis and Daniel Redig, SAIC\r\nSpeedup: 3.5X\r\n\r\nNolan Davis and Daniel Redig at SAIC recently presented work on Hybrid GPU/Multicore Solutions for Large Linear Algebra Problems where they developed a novel algorithm for LU decomposition, one of the most important routines in linear algebra. They presented a Hybrid CPU/GPU computing approach, where problems too large to fit in GPU memory can also be solved faster than using only the CPU.\r\n[/accordion_item]\r\n[accordion_item title=\"Geolocation | BAE Systems\"]\r\n\r\nAuthors: BAE Systems\r\nSpeedup: 17X\r\n\r\nGeolocation is the identification of the real-world geographic location of a target of interest. In this application, the system receives the signal with an array of several antennas and computes the direction of arrival of the radio energy by measuring the time difference of arrival (or the phase difference) at the different antennas.\r\n[/accordion_item]\r\n[accordion_item title=\"Tsunami Modeling | University of Minnesota, Boise State, Saint Scholastica, and NCAR\"]\r\n\r\nAuthors: University of Minnesota, Boise State, Saint Scholastica, and NCAR\r\nSpeedup: 3-5X\r\n\r\nNatural catastrophic disasters like tsunamis commonly strike with little warning. For most people, tsunamis are underrated as major hazards. People sometimes wrongly believe that they occur infrequently and only along distant coasts. Tsunamis are usually caused by earthquakes. Seismic signals can give some margin of warning since the speed of tsunami waves travels at 1/30 the speed of seismic waves. Still there is little time between the creation of the tsunami and its impact making fast processing critical to producing effective warning systems. ArrayFire software was used to run an RBF simulation on the GPU with a time to solution not available by other alternatives.\r\n[/accordion_item][/accordion]\r\n<h5>Life Sciences</h5>\r\n[accordion][accordion_item title=\"Parallelized Gene Predictors | University of Quebec\" ]\r\n\r\nAuthors: University of Quebec\r\nSpeedup: 43X\r\n\r\nComputerized approaches to studying the human genome are challenged by the exploding amount of data, which doubles roughly every 6 months. In order to deal with this burgeoning datasets, demands for faster processing power continue to arise. This work focuses on predicting genes using frequency analysis with FFTs and with an equivalent technique known as Goertzel\'s algorithm. In these applications, the emphasis of this paper is to propose tools to geneticists and molecular biologists for the prediction or identification of new genes using existing complementary strategies. The criteria for these tools are speed, reliability, accuracy and ease of use, thus requiring little training.\r\n[/accordion_item]\r\n[accordion_item title=\"Pathology Advances with GPUs | Northeastern University\" ]\r\n\r\nAuthors: Laboratory for Spectral Diagnosis at Northeastern University\r\nSpeedup: 100X+\r\n\r\nOne element of the hyperspectral image analysis workflow that requires more than a traditional desktop workstation or personal computer is Hierarchical Cluster analysis (HCA). HCA requires a large amount of data space and substantial computation time (~11 hours) for typical datasets using a single processor personal computer. Rather than following the traditional approach of moving to a lower level programming language like C or C++ and complex parallel programming paradigms such as OpenMP or the Massage Passing Interface (MPI), the lab utilized graphics processing units, or GPUs, and the ArrayFire software platform. The solution allowed the lab to dramatically increase the performance of the analysis while substantially decreasing the amount of calendar time to reach the desired results.\r\n[/accordion_item]\r\n[accordion_item title=\"Hepatitis C Virus - Mutation Modeling | Centers for Disease Control and Prevention\" ]\r\n\r\nAuthors: CDC Research and Development Team\r\nSpeedup: ~20X\r\n\r\nThis case study provides a look at biological research regarding coordinated mutations of the Hepatitis C Virus (HCV). ArrayFire provided collaborative R&amp;D resources and greatly improved the speed of this HCV research with the use of parallelization, reducing the computing time from 40 days to less than 1 day. Most importantly, the conclusion of the case study illustrates the the relative price-performance of personal supercomputers that leverage GPUs and ArrayFire software provides a compelling solution versus other architectures and approaches.\r\n[/accordion_item]\r\n[accordion_item title=\"Accelerating the SPM Package for Neuroimaging | Georgia Institute of Technology\" ]\r\n\r\nAuthors: Georgia Institute of Technology\r\nSpeedup: 3.5X\r\n\r\nThe Georgia Tech team explores the value of ArrayFire software and GPUs for fMRI workflows within the popular SPM - Statistical Parametric Mapping software widely used in neuroscience research.\r\n[/accordion_item]\r\n[accordion_item title=\"Medical Image Compression | Indian Institute of Technology, Roorkee, India\" ]\r\n\r\nAuthors: Jaideep Singh, Ipseeta Aruni, R. Balasubramanian - IIT - Roorkee, India\r\nSpeedup: 38X\r\n\r\nThis study presents the acceleration of Haar wavelet-based image compression algorithm for medical imaging on the Graphics Processing Unit (GPU) using ArrayFire software. Due to bandwidth and image size constraints of medical imaging systems, image compression plays a vital role in reducing the bit rate of transmission or storage. Wavelet-based image compression provides the most promising approach for high quality image compression.\r\n[/accordion_item]\r\n[accordion_item title=\"Brain Displacement | Spencer Technologies\"]\r\n\r\nAuthors: Spencer Technologies\r\nSpeedup: 12X\r\n\r\nSpencer describes how ArrayFire software facilitates the development of fast algorithms enabling observation of brain displacement across depth with sampling density that far surpasses previous benchmarks.\r\n[/accordion_item]\r\n[accordion_item title=\"Multidimensional Scaling for Genomics | Leibniz Institute of Plant Genetics and Crop Plant Research\" ]\r\n\r\nAuthors: Leibniz Institute of Plant Genetics and Crop Plant Research\r\nSpeedup: 20-35X\r\n\r\nMultidimensional scaling (MDS) is a general computing technique to turn a distance matrix into a set of reconstructed points with pair-wise relationships approximating the original distances by points located in a usually low-dimensional space. ArrayFire software is used to enhance execution of the HiT-MDS procedure and delivers considerable performance improvement.\r\n[/accordion_item]\r\n[accordion_item title=\"Drug Delivery Model | Georgia Institute of Technology\"]\r\n\r\nAuthors: Georgia Institute of Technology\r\nSpeedup: 70X\r\n\r\nIn this work, the researchers simulate the delivery of a novel nanoparticle chemotherapy drug to cancerous tissue. Simulation allows scientists to predict experimental outcomes and thus reduce the cost of development and time to clinical relevance. The simulation model includes blood vessels, tumor cells, and healthy cells and an engine to calculate the spatial distributions of both drug and oxygen. ArrayFire software is used to speed up the diffusion calculations for the drug and oxygen within the tissue.\r\n[/accordion_item]\r\n[accordion_item title=\"Biomedical Infrared Spectroscopy | University of Manchester and Nofima Mat, Norway\" ]\r\n\r\nAuthors: University of Manchester and Nofima Mat, Norway\r\nSpeedup: Hours of runtime reduction\r\n\r\nThe authors present an iterative algorithm that applies full Mie scattering theory and avoids noise accumulation in their iterative algorithm by integrating a curve-fitting step. ArrayFire software along with NVIDIA GPUs are leveraged to reduce the time added by the curve-fitting step.\r\n[/accordion_item][/accordion]\r\n<h5>Manufacturing</h5>\r\n[accordion][accordion_item title=\"Feature Learning on Images | Stanford\" ]\r\n\r\nAuthors: Andrew Ng, Stanford University\r\nSpeedup: Ability to process many images in parallel\r\n\r\nStanford researchers in Andrew Ng\'s group used GPUs and ArrayFire software to speed up their work on Feature Learning Architectures. They decided to use ArrayFire software for this study because of the need to quickly evaluate many architectures on thousands of images. ArrayFire software taps into the immense computing power of GPUs and speeds up research utilizing many images.\r\n[/accordion_item]\r\n[accordion_item title=\"Tomography of Vegetation - Filtered Back-Projection and Non-Uniform FFTs | Universita di Napoli Federico II\" ]\r\n\r\nAuthors: Drs. Capozzoli, Curcio, di Vico, and Liseno, Universita di Napoli Federico II\r\nSpeedup: 10X\r\n\r\nIn order to investigate changes of forest biomass, scientists use microwave tomography to image the vegetation. At the smallest scale, individual plants can be imaged to investigate branching and growth, but even synthetic aperture radar can reveal large-scale changes in regional ecology. To the right, you can see the experimental setup to image an individual plant.\r\n[/accordion_item]\r\n[accordion_item title=\"Action Recognition with Independent Subspace Analysis | Stanford University\" ]\r\n\r\nAuthors: Quoc Le, Will Zou, Serena Yeung, Andrew Ng, Stanford University\r\nSpeedup: 4.4X\r\n\r\nIn a paper at this year\'s CVPR 2011, entitled \"Learning hierarchical invariant spatio-temporal features for action recognition with independent subspace analysis\", the authors explain how their unsupervised feature learning algorithm competes with other algorithms that are hand crafted or use learned features. For their training purposes, they used a multi-layered stacked convolutional ISA (Independent subspace analysis) network. An ISA is used for learning features from image patches without supervision.\r\n[/accordion_item][/accordion]\r\n<h5>Media and Computer Vision</h5>\r\n[accordion][accordion_item title=\"Fast Computer Vision with OpenCV and ArrayFire | OpenCV Blogger\" ]\r\n\r\nAuthors: OpenCV Blogger\r\nSpeedup: ~10X\r\n\r\nThe OpenCV library is the defacto standard for doing computer vision and image processing research projects. OpenCV includes several hundreds of computer vision algorithms, aimed for use in realtime vision applications. This case study shows how to use both libraries together. There is a simple example application that demonstrates using OpenCV for webcam access and ArrayFire for some basic processing routines and displaying results.\r\n[/accordion_item]\r\n[accordion_item title=\"Video Processing | Google\" ]\r\n\r\nAuthors: Google and Stanford\r\nSpeedup: 10-20X\r\n\r\nVideo content analysis is the basis for categorizing videos and enabling search by content. Growing interest in using sparse-coding methods to extract motion features in video in support of video content analysis led to the application of ArrayFire software to improve performance by substantially accelerating the solution of the L1-regularized least-squares optimization problem.\r\n[/accordion_item]\r\n[accordion_item title=\"Action Recognition with Independent Subspace Analysis | Stanford University\"]\r\n\r\nAuthors: Quoc Le, Will Zou, Serena Yeung, Andrew Ng, Stanford University\r\nSpeedup: 4.4X\r\n\r\nIn a paper at this year\'s CVPR 2011, entitled \"Learning hierarchical invariant spatio-temporal features for action recognition with independent subspace analysis\", the authors explain how their unsupervised feature learning algorithm competes with other algorithms that are hand crafted or use learned features. For their training purposes, they used a multi-layered stacked convolutional ISA (Independent subspace analysis) network. An ISA is used for learning features from image patches without supervision.\r\n[/accordion_item]\r\n[accordion_item title=\"Music Beat Analysis | Georgia Tech\"]\r\n\r\nAuthors: Vidhur Vohra - Georgia Tech\r\nSpeedup: 15X\r\n\r\nDid you ever wonder how the music visualizer in your media player works? Watching it pulsate in synchrony with the beats of the song is almost as entertaining as listening to the song itself! Researchers have been attempting to detect beats in audio signals for many years, and there are many techniques available, from the simplest (and least accurate) to more complicated algorithms that are highly accurate. All algorithms, though, perform some form of signal processing and frequency analysis, applications highly suited to GPU Computing.\r\n[/accordion_item]\r\n[accordion_item title=\"Optimization Methods for Deep Learning | Stanford Artificial Intelligence Laboratory\" ]\r\n\r\nAuthors: Stanford Artificial Intelligence Laboratory\r\nSpeedup: Improved accuracy\r\n\r\nResearchers at SAIL (Stanford Artificial Intelligence Laboratory), have done it again. They have successfully used ArrayFire software to speed up the training part of Deep Learning algorithms. In their paper titled .On Optimization Methods for Deep Learning., they experiment with some of the well known training algorithms and demostrate their scalability across parallel architectures (GPUs as well as multi-machine networks). The algorithms include SGDs (Stochastic Gradient Descent) L-BFGS (Limited BFGS used for solving non-linear problems), CG (Conjugate Gradient).\r\n[/accordion_item]\r\n[accordion_item title=\"Feature Learning on Images | Stanford University\" ]\r\n\r\nAuthors: Andrew Ng, Stanford University\r\nSpeedup: Ability to process many images in parallel\r\n\r\nStanford researchers in Andrew Ng’s group used ArrayFire software to speed up their work on Feature Learning Architectures. They decided to use ArrayFire software for this study because of the need to quickly evaluate many architectures on thousands of images. ArrayFire software taps into the immense computing power of GPUs and speeds up research utilizing many images.\r\n[/accordion_item]\r\n[accordion_item title=\"Digital Holography for Imaging | National University of Ireland, Maynooth\" ]\r\n\r\nAuthors: Nitesh Pandey, Damien Kelly, Bryan Hennelly and Thomas Naughton from the National University of Ireland, Maynooth\r\nSpeedup: 17X\r\n\r\nDigital holography is a powerful imaging technique with many new applications like true 3D display. It allows the capture of both amplitude and phase information of the light reflected off the surface of 3D objects. Researchers at the National University of Ireland, Maynooth are developing techniques based on digital holography for 3D display applications.\r\nReconstruction of large digital holograms can be computationally intensive to generate on CPUs, but GPUs running ArrayFire software offer amazing possibilities.\r\n[/accordion_item][/accordion]\r\n<h5>Oil and Gas</h5>\r\n[accordion][accordion_item title=\"3D Mantle Convection - Geodynamics | Boise State, University of Colorado, University of Minnesota\" ]\r\n\r\nAuthors: Boise State, University of Colorado, University of Minnesota\r\nSpeedup: 2.5-4.5X\r\n\r\nThe authors introduce a GPU implementation of a three-dimensional mantle convection modeling at a high Rayleigh number to the solid earth geophysics community. They outline code development time, compare performance of CPUs versus GPUs, and deliver powerful visualizations.\r\n[/accordion_item]\r\n[accordion_item title=\"Ground Water Simulations | Louisiana State University\" ]\r\n\r\nAuthors: Kevin R. Tubbs and Frank T-C. Tsai at Louisiana State University\r\nSpeedup: &gt;20X\r\n\r\nA lattice Boltzmann method for solving the shallow water equations and the advection-dispersion equation is developed and implemented on graphics processing unit (GPU)-based architectures. The proposed LBM is implemented to an NVIDIA Computing Processor in a single GPU workstation. GPU computing is performed using ArrayFire software. Mass transport with velocity-dependent dispersion in shallow water flow is simulated by combining the MRT-LBM model and the TRT-LBM model. The GPU parallel performance increases as the grid size increases. The results indicate the promise of the GPU-accelerated LBM for modeling mass transport phenomena in shallow water flows.\r\n[/accordion_item]\r\n[accordion_item title=\"Shallow Water Fluid Flow | Louisiana State University\" ]\r\n\r\nAuthors: Louisiana State University\r\nSpeedup: &gt;10X\r\n\r\nA lattice Boltzmann method (LBM) on high performance computing (HPC) environments for three-dimensional shallow water flow fields coupled to mass transport is developed. LBM is an attractive method for solving the multilayered shallow water equations because the extension to multilayer is straight forward with all of the simplicities and advantages of the LBM in mass transport in shallow water flows and the LBM performance on central processing unit (CPU)-based and graphics processing unit (GPU)-based HPC environments.\r\n[/accordion_item][/accordion]\r\n<div id=\"consulting\"></div>\r\n[/content_band]\r\n<div id=\"services\"></div>\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"]Hire our acceleration gang[/custom_headline]\r\n\r\nHire us to accelerate your code. Or to train your pros. Or even to write new code for your organization!\r\n\r\nWe’ve already helped thousands of organizations speedup their code. We’ve accelerated algorithms, data sets, and challenging problems of all types in the past, and we’re confident that we can accelerate your code too.\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://meetme.so/arrayfire\" size=\"x-large\" ]Schedule a consultation[/button][/column][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/Bat-signal-e1391790016951.png\"][/column] [gap size=\"7%\"]\r\n\r\n[column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/LFG-B-HORZ_202_K-e1396448935778.jpg\"][line]Lincoln Financial Group ported their CPU code (C/C++) to CUDA, and this enabled them to speed up the necessary financial calculations. Their primary objective was to reduce the time taken to run this code. Before porting to CUDA, they required 10-12 hours to run the entire code. After porting to CUDA, they were able to do the same work in about 30 minutes.[/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][line]Reveal Imaging, an SAIC company, uses ArrayFire in developing threat-detection products for transportation systems—such as cargo and baggage screening in airports—and in securing facilities and public events.[/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][line]The Glasses.com app relies on computer vision to recognize the features of a user’s face. The application then generates an accurate, high-fidelity, three-dimensional model of that face, and virtually places selected frames on the image.[/column]\r\n<div id=\"starterpackage\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n\r\n[column type=\"one-half\" last=\"false\" fade=\"true\" fade_animation=\"in-from-left\" ][gap size=\"10%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/comingatyou.png\"][/column][column type=\"one-half\" last=\"true\"] [custom_headline type=\"left\" level=\"h3\"]Starter Package ($500)* [/custom_headline] Hire us for 1-day. We set you up with one engineer dedicated for a full day, as well as support from senior and test engineers throughout the day. Here\'s how it works:\r\n\r\n[icon_list] [icon_list_item type=\"angle-double-right\"]Initial phone call[/icon_list_item] [icon_list_item type=\"angle-double-right\"]You send us your code or algorithm [/icon_list_item] [icon_list_item type=\"angle-double-right\"]We analyze your code for potential GPU benefit[/icon_list_item][icon_list_item type=\"angle-double-right\"]We accelerate as much of the code as is possible within the 1-day effort, applying our extensive GPU software libraries[/icon_list_item][icon_list_item type=\"angle-double-right\"]We produce a final report, along with code[/icon_list_item] [/icon_list] The final report outlines the best approach to follow for full GPU-acceleration of your code.\r\n\r\n&nbsp;\r\n\r\n[button type=\"flat\" shape=\"rounded\" size=\"regular\" href=\"http://sandbox.arrayfire.com/product/consulting-starter-package/\" title=\"Starter Package\"]Buy the Starter Package[/button]\r\n\r\n&nbsp;\r\n\r\n*Limit one (1) per customer.\r\n\r\n[/column]\r\n<div id=\"customcode\"></div>\r\n[/content_band] [content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\" ]Custom Coding Work[/custom_headline]\r\n\r\n[custom_headline type=\"left\" level=\"h6\" ]Why Choose Us?[/custom_headline] [icon_list] [icon_list_item type=\"angle-double-right\"]Deep experience, already servicing thousands of customers[/icon_list_item] [icon_list_item type=\"angle-double-right\"]Quality work, with leading GPU software [/icon_list_item] [icon_list_item type=\"angle-double-right\"]Efficient delivery, with ArrayFire\'s code base we can deliver results fast[/icon_list_item][icon_list_item type=\"angle-double-right\"]Proven, we make customers happy through faster code[/icon_list_item][/icon_list] [custom_headline type=\"left\" level=\"h6\" ]Our Strengths[/custom_headline] [icon_list] [icon_list_item type=\"angle-double-right\"]Excellence in GPU code[/icon_list_item] [icon_list_item type=\"angle-double-right\"]Well-written, efficient C, C++, Fortran, Java, or .NET [/icon_list_item] [icon_list_item type=\"angle-double-right\"]Application porting and integration[/icon_list_item][icon_list_item type=\"angle-double-right\"]Tuning software to peak hardware performance[/icon_list_item][icon_list_item type=\"angle-double-right\"]Scalability of algorithms to handle enterprise-level programs[/icon_list_item] [/icon_list][button type=\"flat\" shape=\"rounded\" size=\"regular\" href=\"http://meetme.so/arrayfire\" title=\"Tech Consultation\"]Schedule a consultation[/button] [/column][column type=\"one-half\"  fade=\"true\" fade_animation=\"in-from-right\" last=\"true\" ][gap size=\"25%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Holoham.png\"][/column]\r\n<div id=\"training\"></div>\r\n[/content_band] [content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\" ]Training[/custom_headline] Attendees will receive the latest industry knowledge and techniques for GPU computing in CUDA and OpenCL.\r\n\r\nArrayFire offers up to four days of specialized GPU training in CUDA and OpenCL programming. We provide customized on-site training courses for customers that have 3 or more attendees from their organization. We can travel to your location and provide a CUDA or OpenCL training course tailored to meet your application-specific needs. We also offer individual trainings at our Atlanta office. Please <a href=\"mailto:sales@arrayfire.com\">contact us</a> to learn more about our training offerings.\r\n\r\nWe recommend that attendees have a working knowledge of C/C++ in order to gain the most from the training courses. For more information about the content of our training lectures and hands-on practicums, please see the following training course syllabus.\r\n\r\n[/column]\r\n\r\n[column type=\"one-half\" last=\"true\" fade=\"true\" fade_animation=\"in-from-right\" class=\"center-text\"][gap size=\"15%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Professor-AF_Exported-e1395436350363.png\" ][/column]\r\n\r\n[column type=\"one-half\" class=\"center-text\"] [gap size=\"17%\"]\r\n<div>[button type=\"flat\" shape=\"rounded\" size=\"jumbo\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]</div>\r\n[/column][column type=\"one-half\" last=\"true\"][custom_headline type=\"left\" level=\"h3\"]Included in Course[/custom_headline]\r\n\r\n[icon_list] [icon_list_item type=\"angle-double-right\"]Instruction by an excellent and interesting expert, with hands-on exercises[/icon_list_item] [icon_list_item type=\"angle-double-right\"]Use of a laptop with CUDA and OpenCL capable GPUs and CPUs [/icon_list_item] [icon_list_item type=\"angle-double-right\"]Choice of Linux or Windows operating system[/icon_list_item][icon_list_item type=\"angle-double-right\"]Printed manual of lecture material[/icon_list_item][icon_list_item type=\"angle-double-right\"]Electronic copy of programming exercises[/icon_list_item][/icon_list]\r\n\r\n[/column]\r\n\r\n<span style=\"line-height: 1.5em;\">[gap size=\"5%\"]</span>\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]Training Course Syllabus[/custom_headline] [column type=\"one-half\"] [custom_headline type=\"left\" level=\"h5\"  accent=\"false\"]Day 1, Introduction[/custom_headline] Lectures:\r\nGPU Computing Overview\r\nThe Programming Model\r\nBasic Dataset Mapping Techniques\r\nLibraries, ArrayFire\r\nProfiling Tools\r\n\r\nPractice:\r\nA Simple Kernel\r\nEquivalent ArrayFire Example\r\nUsing Libraries\r\nMonte Carlo Pi Estimation\r\nTiming and ArrayFire\r\nDebugging Code\r\n\r\n[custom_headline type=\"left\" level=\"h5\" accent=\"false\"]Day 3, Multi-GPU[/custom_headline] Lectures:\r\nMulti-GPU Use Cases\r\nMulti-GPUs: Contexts\r\nExisting Libraries\r\nScaling Across Multiple GPUs\r\n\r\nPractice:\r\nOut of Core Problems: Matrix Multiply\r\nTask Level Parallelism: Optimization\r\nArrayFire Multi-GPU[/column]\r\n\r\n[column type=\"one-half\" last=\"true\"] [custom_headline type=\"left\" level=\"h5\" accent=\"false\"]Day 2, Optimization[/custom_headline] Lectures:\r\nArchitecture: Grids, Blocks, and Threads\r\nMemory Model: Global, Shared, and Constant Memory\r\nAdvanced Mapping Techniques\r\nStreams: Asynchronos Launches and Concurrent Execution\r\nArrayFire: Lazy Evaluation and Code Vectorization\r\n\r\nPractice:\r\nMatrix Transpose\r\nOptimization Using Shared Memory\r\nMedian Filter\r\nOptimization Using Constant Memory\r\nStream Example\r\nArrayFire Example: Nearest Neighbor Algorithm\r\n\r\n[custom_headline type=\"left\" level=\"h5\" accent=\"false\"]Day 4, Algorithm Problems[/custom_headline]\r\n\r\nLectures and Practice:\r\nReductions\r\nScan Algorithms\r\nSort\r\nConvolution\r\nCustomer-Specific Problem [/column][/content_band]','Home','','inherit','open','closed','','245-revision-v1','','','2014-05-19 20:54:18','2014-05-19 20:54:18','',245,'http://sandbox.arrayfire.com/245-revision-v1/',0,'revision','',0),(5614,17729,'2014-05-19 23:22:05','2014-05-19 23:22:05','<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<h1 id=\"opencl\">OpenCL</h1>\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 along with library to do my work, however that turned out to be a disaster. I faced compilation errors for OpenGL-header inclusion. There are three 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 &quot;<Adreno_SDK>/Development/Inc/CL&quot;. For Mali SDK, you can find the headers at &quot;<MALI_SDK>/include/CL&quot;.</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<h2 id=\"adreno-gpu\">Adreno GPU</h2>\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<h2 id=\"mali-gpu\">Mali GPU</h2>\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<h2 id=\"kernels\">Kernels</h2>\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<h2 id=\"auxilary-code\">Auxilary Code</h2>\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<h1 id=\"build-on-linux\">Build (on Linux)</h1>\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<h2 id=\"android.mk\">Android.mk</h2>\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<h2 id=\"application.mk\">Application.mk</h2>\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<h1 id=\"app-installation\">App Installation</h1>\r\n<h2 id=\"ant-users\">ant-users</h2>\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<h2 id=\"eclipse-users\">eclipse-users</h2>\r\n<p>Right click the project in workspace and click the menu item &quot;Run As -&gt; Android Application&quot;.</p>\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]','OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-19 23:22:05','2014-05-19 23:22:05','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5615,17729,'2014-05-19 23:45:00','2014-05-19 23:45:00','<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<h1 id=\"opencl\">OpenCL</h1>\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<h2 id=\"adreno-gpu\">Adreno GPU</h2>\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<h2 id=\"mali-gpu\">Mali GPU</h2>\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<h2 id=\"kernels\">Kernels</h2>\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<h2 id=\"auxilary-code\">Auxilary Code</h2>\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<h1 id=\"build-on-linux\">Build (on Linux)</h1>\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<h2 id=\"android.mk\">Android.mk</h2>\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<h2 id=\"application.mk\">Application.mk</h2>\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<h1 id=\"app-installation\">App Installation</h1>\r\n<h2 id=\"ant-users\">ant-users</h2>\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<h2 id=\"eclipse-users\">eclipse-users</h2>\r\n<p>Right click the project in workspace and click the menu item &quot;Run As -&gt; Android Application&quot;.</p>\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]','Getting started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-19 23:45:00','2014-05-19 23:45:00','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5616,7,'2015-06-01 19:18:31','2015-06-01 19:18:31','[content_band inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"two-fifths\"]\n\n[custom_headline type=\"left\" level=\"h3\"]If you want faster code, you\'ve come to the right place.[/custom_headline][gap size=\"3%\"]<img class=\"aligncenter wp-image-8232 size-medium\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/05/Button-scribbles-02-01-300x43.png\" alt=\"Button scribbles-02-01\" width=\"300\" height=\"43\" />[button  type=\"flat\" shape=\"rounded\" href=\"http://sandbox.arrayfire.com/download\" size=\"x-large\" block=\"true\"]Download ArrayFire[/button]\n\n[gap size=\"5%\"]\n\n[button  type=\"flat\" block=\"true\" shape=\"rounded\" href=\"http://sandbox.arrayfire.com/consulting/\" size=\"x-large\" ]Schedule a consultation[/button][gap size=\"2%\"]<img class=\"aligncenter size-full wp-image-8229\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/05/Button-scribbles-01.png\" alt=\"Button scribbles-01\" width=\"976\" height=\"117\" />\n\n[/column][column type=\"three-fifths\" last=\"true\"][gap size=\"7%\"]\n<div id=\"wistia_rj2bar3xxp\" class=\"wistia_embed\" style=\"width: 640px; height: 388px;\"></div>\n<script src=\"//fast.wistia.com/assets/external/E-v1.js\" charset=\"ISO-8859-1\"></script><script>// <![CDATA[\nwistiaEmbed = Wistia.embed(\"rj2bar3xxp\");\n// ]]></script>\n[/column]\n<div id=\"arrayfire\"></div>\n[/content_band]\n\n[content_band bg_color=\"#f2f2f2\" inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"40px\" padding_bottom=\"40px\"]\n\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/car-e1412967813807.png\" class=\"mbn\"] Faster Code[/custom_headline][line style=\"border-top: solid #999999;\"]ArrayFire is a blazing fast software library for GPU computing. Its easy-to-use API and array-based function set make GPU programming simple. A few lines of code in ArrayFire can replace dozens of lines of raw GPU code, saving you valuable time and lowering development costs.[/column]\n\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/09/mini-motorcycle-01-e1412969290876.png\" class=\"mbn\"] Hardware Neutral[/custom_headline][line style=\"border-top: solid #999999;\"]ArrayFire supports both CUDA-capable NVIDIA GPUs and most OpenCL devices, including AMD GPUs/APUs and Intel Xeon Phi co-processors. It also supports mobile OpenCL devices from ARM, Qualcomm, and others. We want your code to run as fast as possible, regardless of the hardware.[/column]\n\n[column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/09/mini-plane-01-e1412969527633.png\" class=\"mbn\"] Open Source[/custom_headline][line style=\"border-top: solid #999999;\"]ArrayFire is open source—it\'s all there and it\'s all free. Be sure to check out all of the ArrayFire functions (and a lot more!) in our excellent <a href=\"http://www.sandbox.arrayfire.com/docs/index.htm\">documentation</a>. And don\'t forget to visit our <a href=\"http://sandbox.arrayfire.com/forums/\">forums</a> to connect with the ArrayFire community and pick up acceleration tips and innovative best practices.[/column]\n<p style=\"text-align: center;\">[column type=\"one-third\" class=\"center-text\"][button  type=\"flat\" shape=\"rounded\" size=\"regular\" href=\"http://www.sandbox.arrayfire.com/docs/examples.htm\"]See some examples[/button][/column]</p>\n<p style=\"text-align: center;\">[column type=\"one-third\" class=\"center-text\"][button type=\"flat\" shape=\"rounded\" size=\"regular\" href=\"http://www.sandbox.arrayfire.com/download\"]Download ArrayFire[/button][/column]</p>\n<p style=\"text-align: center;\">[column type=\"one-third\" class=\"center-text\" last=\"true\"][button type=\"flat\" shape=\"rounded\" size=\"regular\" href=\"http://www.sandbox.arrayfire.com/docs/index.htm\"]View the documentation[/button][/column][gap size=\"3%\"][/content_band]</p>','Home','','inherit','open','closed','','245-autosave-v1','','','2015-06-01 19:18:31','2015-06-01 19:18:31','',245,'http://sandbox.arrayfire.com/245-autosave-v1/',0,'revision','',0),(5617,7,'2014-05-20 13:37:04','2014-05-20 13:37:04','[content_band inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"two-fifths\"]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]If you want faster code, you\'ve come to the right place.[/custom_headline][gap size=\"15%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.sandbox.arrayfire.com/docs/installation.htm\" size=\"x-large\" block=\"true\"]Download ArrayFire[/button]\r\n\r\n[gap size=\"10%\"]\r\n\r\n[button  type=\"flat\" block=\"true\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"x-large\" ]Schedule a consultation[/button]\r\n\r\n[/column][column type=\"three-fifths\" last=\"true\"][gap size=\"7%\"]\r\n<div id=\"wistia_rj2bar3xxp\" class=\"wistia_embed\" style=\"width:640px;height:388px;\"> </div>\r\n<script charset=\"ISO-8859-1\" src=\"//fast.wistia.com/assets/external/E-v1.js\"></script>\r\n<script>\r\nwistiaEmbed = Wistia.embed(\"rj2bar3xxp\");\r\n</script>[/column]\r\n<div id=\"arrayfire\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"]Faster code[/custom_headline]\r\n\r\nArrayFire is a fast, hardware-neutral software library for GPU computing with an easy-to-use API. Its array-based function set makes GPU programming simple. A few lines of code in ArrayFire can replace dozens of lines of raw GPU code, saving you valuable time and lowering development costs.\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.sandbox.arrayfire.com/docs/installation.htm\" size=\"x-large\" ]Download ArrayFire[/button][/column][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/Triumvirate_Exported.png\"][/column] [gap size=\"5%\"]\r\n\r\n[column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/Googlelogo-e1396387097279.png\"][line]Video content analysis is the basis for categorizing videos and enabling search by content. Google used ArrayFire to extract motion features in video, improving performance by substantially accelerating the solution of the L1-regularized least-squares optimization problem.[/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/Koch-Industries-e1396387359637.jpg\"][line]Andrew Shin, Market Risk Manager of Koch Supply &amp; Trading, achieves significant performance increases on option pricing algorithms using ArrayFire software, \"My buddy and I are, at best, novice programmers and we couldn\'t imagine having to figure out how to code all this in CUDA.\"[/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/nasa-e1396387230473.png\"][line]The main thrust of this research was improving Mars rover image compression via GPUs and genetic algorithms. With ArrayFire software and GPUs, the researchers were able to achieve 5X speedups on the larger data sizes.[/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n\r\n[column type=\"one-half\"][gap size=\"15%\"]\r\n\r\n<img alt=\"CUDA logo\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/CUDA-logo.jpg\" width=\"231\" height=\"140\" />\r\n\r\n<img alt=\"OpenCL\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/OpenCLLogo_678x452.png\" width=\"326\" height=\"217\" />\r\n\r\n[/column][column type=\"one-half\" last=\"true\"][gap size=\"10%\"]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"] ArrayFire for CUDA and OpenCL[/custom_headline]\r\n\r\nArrayFire supports CUDA-capable NVIDIA GPUs and most OpenCL devices, including AMD GPUs/APUs and Intel Xeon Phi co-processors. It also supports mobile OpenCL devices from ARM, Qualcomm, and others.\r\n\r\nArrayFire is a high-performance software library designed for maximum productivity and speed without the hassle of writing difficult low-level device code. Each of ArrayFire\'s functions has been hand-tuned by our CUDA and OpenCL experts.\r\n\r\n[/column]\r\n<div id=\"mobile\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"  ]Mobile GPU Computing[/custom_headline]\r\n\r\nMobile GPUs offer accelerated performance. If you would like to use ArrayFire in a mobile application or if you would like to hire our mobile acceleration services, email us at <a href=\"mailto:sales@arrayfire.com\" target=\"_blank\">sales@arrayfire.com</a> and include a description of your application.\r\n\r\nOur clients have achieved between 5X to 30X speed boosts for convolutions and other compute functions on mobile devices. It enables:[icon_list][icon_list_item type=\"angle-double-right\"]Real-time video processing[/icon_list_item][icon_list_item type=\"angle-double-right\"]Better augmented reality [/icon_list_item][icon_list_item type=\"angle-double-right\"]Better computational photograph[/icon_list_item][icon_list_item type=\"angle-double-right\"]Faster data processing[/icon_list_item][/icon_list]\r\n\r\nAll mobile devices have a GPU which can deliver greater compute throughput than the CPU. Why not use the GPU to make your app faster?[/column][column type=\"one-half\" fade=\"true\" last=\"true\" fade_animation=\"in-from-right\" class=\"center-text\"][gap size=\"10%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/mobile_Exported1-e1395437261846.png\"][/column]\r\n<div id=\"documentation\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"]Documentation[/custom_headline]\r\n\r\nArrayFire for C, C++, and Fortran\r\nOpen the hood—take a look at the beautiful nitty-gritty.\r\n\r\n[icon type=\"angle-double-right\"] <a href=\"http://www.sandbox.arrayfire.com/docs/\" target=\"_blank\">CUDA &amp; OpenCL C/C++</a>\r\n\r\nFunctions\r\nHundreds of functions, hand-tuned and optimized by our engineers.\r\n\r\n[icon type=\"angle-double-right\"] <a title=\"ArrayFire Functions\" href=\"http://www.sandbox.arrayfire.com/docs/modules.htm\">ArrayFire Functions</a>\r\n\r\nUser Forums\r\nEvery post gets a response from ArrayFire engineers.\r\n\r\n[icon type=\"angle-double-right\"] <a href=\"http://forums.accelereyes.com/\" target=\"_blank\">User Forums</a>\r\n\r\n[/column][column class=\"center-text\" type=\"one-half\" last=\"true\" fade=\"true\" fade_animation=\"in-from-right\" ][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/gears1.png\"][/column]\r\n<div id=\"benchmarks\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n[column type=\"one-half\" fade=\"true\" fade_animation=\"in-from-left\" ][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Benchmark-guy-torso-opposite-e1392155948298.png\"][/column]\r\n\r\n[column type=\"one-half\" last=\"true\"][custom_headline type=\"left\" level=\"h3\" ]Benchmarks[/custom_headline]\r\n\r\nAll benchmarks were performed on a NVIDIA Tesla C2050 with an Intel i7-950 processor. The benchmarks compare ArrayFire with several popular CPU-based acceleration libraries, including <a href=\"http://software.intel.com/en-us/articles/intel-mkl/\" target=\"_new\">Intel Math Kernel Library</a>, <a href=\"http://software.intel.com/en-us/articles/intel-ipp/\" target=\"_new\">Intel Integrated Performance Primitives</a>, <a href=\"http://eigen.tuxfamily.org/index.php?title=Main_Page\" target=\"_new\">Eigen</a>, and <a href=\"http://arma.sourceforge.net/\" target=\"_new\">Armadillo</a>.[/column]\r\n\r\n[column type=\"one-fifth\"].[/column][column type=\"three-fifths\"][tab_nav type=\"four-up\"][tab_nav_item title=\"Base\" active=\"true\"][tab_nav_item title=\"Linear Algebra\" active=\"\"][tab_nav_item title=\"Convolution\" active=\"\"][tab_nav_item title=\"Utility\" active=\"\"][/tab_nav][tabs][tab active=\"true\"]<img alt=\"Matrix Multiply\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/matrix_multiply-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"Matrix Transpose\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/matrix_transpose-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"FFT\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/fft-1024x730.png\" width=\"491\" height=\"350\" />[/tab][tab]<img alt=\"LU\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/lu-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"SVD\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/svd-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"Solve\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/solve-1024x730.png\" width=\"491\" height=\"350\" />[/tab][tab]<img alt=\"Convs\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/convs-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"Conv\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/conv-1024x730.png\" width=\"491\" height=\"350\" />[/tab][tab]<img alt=\"sum\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/sum-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"sort\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/sort-1024x730.png\" width=\"491\" height=\"350\" />[line]<img alt=\"scan\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/scan-1024x730.png\" width=\"491\" height=\"350\" />[/tab][/tabs][/column][column type=\"one-fifth\" last=\"true\"].[/column]\r\n<div id=\"free\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"].[/column][column type=\"one-fourth\"].[custom_headline type=\"center\"  level=\"h3\" class=\"mtn\"]ArrayFire Free[/custom_headline][/column][column type=\"one-fourth\" last=\"true\"].[/column][column type=\"one-fourth\"  fade=\"true\" fade_animation=\"in-from-left\" ][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/right-leaning-e1391788779101.png\"][/column][column type=\"one-fourth\"]\r\n<table>\r\n<tbody>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Functions[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Basic Operations</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Arithmetic</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Signal Processing</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Image Processing</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Statistics</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Visualization</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n[gap size=\"17%\"][button type=\"flat\" block=\"true\" shape=\"rounded\" size=\"large\"  href=\"http://www.sandbox.arrayfire.com/docs/installation.htm\"]Download ArrayFire[/button] [/column][column type=\"one-fourth\"]\r\n<table>\r\n<tbody>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Hardware[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] CUDA</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] OpenCL</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Languages[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] C/C++</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Fortran</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Advanced[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td> [icon type=\"check-circle\" style=\"color: #8cc540;\"] GFOR Loop</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n[/column][column type=\"one-fourth\" last=\"true\"]\r\n<table>\r\n<tbody>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Platforms[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Windows</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Linux</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] Mac</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Data Types[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td>[icon type=\"check-circle\" style=\"color: #8cc540;\"] All types</td>\r\n</tr>\r\n<tr>\r\n<td>[custom_headline type=\"center\" level=\"h5\"]Support[/custom_headline]</td>\r\n</tr>\r\n<tr>\r\n<td> [icon type=\"check-circle\" style=\"color: #8cc540;\"] Forums</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n<div id=\"licensing\"></div>\r\n[/column][gap size=\"8%\"]\r\n\r\n[pricing_table id=\"pricing\" columns=\"3\"][pricing_table_column  featured=\"false\" title=\"ArrayFire Developer\" currency=\"$\" price=\"499 / year\" interval=\"$149 / year (Academic)\"] [icon_list] [icon_list_item type=\"star\" ]Dedicated license [/icon_list_item] [icon_list_item  type=\"times-circle\"] Starts at 2 GPUs or devices [/icon_list_item] [icon_list_item type=\"times-circle\"] Linear algebra [/icon_list_item] [icon_list_item type=\"times-circle\"] Sparse matrices [/icon_list_item][icon_list_item type=\"times-circle\"] Phone support [/icon_list_item][icon_list_item type=\"times-circle\"] Premium support &amp; consulting [/icon_list_item][/icon_list] [button href=\"http://sandbox.arrayfire.com/shop\"] Purchase [/button] [/pricing_table_column] [pricing_table_column featured=\"true\" featured_sub=\"Most Popular\" title=\"ArrayFire Pro\" currency=\"$\" price=\"1,499 / year\" interval=\"$525 / year (Academic)\"] [icon_list] [icon_list_item type=\"star\"] Dedicated license [/icon_list_item] [icon_list_item type=\"star\"] Starts at 2 GPUs or devices [/icon_list_item] [icon_list_item type=\"star\"] Linear algebra [/icon_list_item][icon_list_item type=\"star\"] Sparse matrices [/icon_list_item][icon_list_item type=\"times-circle\"] Phone support [/icon_list_item][icon_list_item type=\"times-circle\"] Premium support &amp; consulting [/icon_list_item] [/icon_list] [button href=\"http://sandbox.arrayfire.com/shop\"]Purchase [/button] [/pricing_table_column] [pricing_table_column featured=\"false\" title=\"ArrayFire Enterprise\" currency=\"$\" price=\"2,999 / year\" interval=\"$1,049 / year (Academic)\"] [icon_list] [icon_list_item type=\"star\"] Dedicated license [/icon_list_item] [icon_list_item type=\"star\"] Starts at 2 GPUs or devices [/icon_list_item] [icon_list_item type=\"star\"] Linear algebra [/icon_list_item][icon_list_item type=\"star\"]Sparse matrices [/icon_list_item][icon_list_item type=\"star\"] Phone support[/icon_list_item][icon_list_item type=\"star\"]Premium support &amp; consulting [/icon_list_item][/icon_list] [button href=\"http://sandbox.arrayfire.com/shop\"] Purchase [/button] [/pricing_table_column] [/pricing_table]\r\n<div id=\"whitepapers\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][gap size=\"20%\"][image type=\"thumbnail\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/wp2.jpg\"][button href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/03/arrayfire_matrix_computations_chrzeszczyk.pdf\" shape=\"rounded\" size=\"regular\" block=\"true\"]Download Matrix Computations on the GPU with ArrayFire for C/C++[/button][/column][column type=\"one-half\" last=\"true\"]\r\n\r\n[custom_headline type=\"left\" level=\"h3\" ]Whitepapers[/custom_headline]\r\n\r\n<img alt=\"Whitepaper 1\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Whitepaper-1.png\" width=\"466\" height=\"374\" />\r\n\r\n&nbsp;\r\n\r\n[/column][gap size=\"10%\"]\r\n\r\n[column type=\"one-half\"]<img alt=\"Whitepaper 2\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Whitepaper-2.png\" width=\"442\" height=\"304\" />[/column][column type=\"one-half\" last=\"true\"][image type=\"thumbnail\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/wp1.jpg\"][button href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/03/arrayfire_whitepaper.pdf\" shape=\"rounded\" size=\"regular\"  block=\"true\" float=\"right\"]Download High-level GPU Computing in C, C++, and Fortran[/button][/column]\r\n<div id=\"casestudies\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][gap size=\"12%\"][custom_headline type=\"left\" level=\"h3\" ]Case Studies[/custom_headline]\r\n\r\nLearn how ArrayFire has worked in real code, including applications in academia, finance, government, life sciences, manufacturing, media, and oil &amp; gas.[/column][column type=\"one-half\" last=\"true\" fade=\"true\" fade_animation=\"in-from right\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/model-A.png\"][/column][custom_headline type=\"left\" level=\"h5\"]Academia [/custom_headline][accordion][accordion_item title=\"Accelerating LTE Simulation | Tsinghua University\"]\r\n\r\nAuthors: Yuan Gao, Yin Sun, Chun Hui Zhou, Xin Su, Xi Bin Xu, Shi Dong Zhou, Tsinghua University\r\nSpeedup: 3X\r\n\r\nFast simulations are a driving force in several research projects. However, the accompanying long simulation times can tend to be a drag in many of these projects. In this article, we shall bring up the example of the work on 3GPP LTE System Simulation by Yuan Gao et al (from Tsinghua University, Beijing) and demonstrate how the use of ArrayFire software can significantly improve the simulator performance and lead to faster validation times in simulation projects.[/accordion_item]\r\n\r\n[accordion_item title=\"High Performance Compressive Sensing | Rice University\"]\r\n\r\nAuthors: Nabor Reyna and Wotao Yin from Rice University\r\nSpeedup: 5X\r\n\r\nThis work deals with reconstruction of signals using partial Fourier matrices (RecPF). The major computational components of the algorithm involve shrinkage and FFTs. ArrayFire software is employed to accelerate this compute-heavy code.[/accordion_item]\r\n\r\n[accordion_item title=\"Power System Simulations | Indian Institute of Technology, Roorkee, India\"]\r\nAuthors: Indian Institute of Technology, Roorkee\r\nSpeedup: 35X\r\n\r\nPower flow studies are one of the most important aspects of power system planning and operation. The power flow reveals the sinusoidal steady state characteristics of the entire system - voltages, real and reactive power generated, and absorbed and line losses- elucidating the voltage magnitudes and angles at each bus, the generation of each generating unit, and real and reactive power losses in the system. All this is necessary to ensure the security, economy, and control of electrical energy distribution. Learn how ArrayFire software can deliver magnitudes of performance improvement over CPU-based solutions.[/accordion_item]\r\n\r\n[accordion_item title=\"Antenna Array Simulations | University of Naples Federico II\"]\r\n\r\nAuthors: A. Capozzoli, C. Cucio, A. Liseno at University of Naples Federico II\r\nSpeedup: 24X\r\n\r\nAntenna array design involves repeated simulation to tune the many parameters involved, and waiting around for simulations to finish is no fun. Offloading the optimization problem onto the GPU cuts that time down significantly. In their recent paper, Capozzoli, Curcio, and Liseno of University of Naples Federico II demonstrated how a simple modification to their echo generator array simulation took advantage of the GPU to bring immediate speedups.[/accordion_item]\r\n\r\n[accordion_item title=\"Laplace Transform Inversion | Acunum Algorithms and Simulations\"]\r\n\r\nAuthors: Patrick Kano and Moysey Brio at Acunum Algorithms and Simulations\r\nSpeedup: 3.8X\r\n\r\nThe numerical inversion of the Laplace transform is a long standing problem due its implicit ill-posedness. Patrick Kano and Moysey Brio of Acunum Algorithms and Simulations, with their experience in computational methods and algorithm development, found a solution that not only works, but is very fast.[/accordion_item]\r\n\r\n[accordion_item title=\"Compressed Sensing for Image Reconstruction | College of Engineering, Roorkee, India\"]\r\n\r\nAuthors: Kuldeep Yadav, Ankush Mittal, M. A. Ansar, and Avi Srivastava, College of Engineering, Roorkee, India\r\nSpeedup: 8X\r\n\r\nCompressed sensing is very critical in the areas of medical image reconstruction, image acquisition or sensor networks. An algorithm for compressed sensing developed using a Basis Pursuit Algorithm shows over 8X speedup when run on an NVIDIA GPU.[/accordion_item]\r\n\r\n[accordion_item title=\"Fat/Water Reconstruction for Medical Images | Case Western Reserve University\"]\r\n\r\nAuthors: D. H. Johnson, S. Narayan, C. A. Flask, and D. L. Wilson, Case Western Reserve University\r\nSpeedup: 11.6X\r\n\r\nCase Western Reserve University researchers turned to GPUs running ArrayFire software to develop a fast and robust version of the \"Iterative Decomposition of water and fat with an Echo Asymmetry and Least-squares\" (IDEAL) reconstruction algorithm. This algorithm uses a lot of Image Processing algorithms for reconstruction, and was shown to achieve very high speedups.\r\n[/accordion_item]\r\n\r\n[/accordion]\r\n<h5>Finance</h5>\r\n[accordion][accordion_item title=\"Option Pricing | Koch Supply and Trading\"]\r\n\r\nAuthors: Koch Supply &amp; Trading\r\nSpeedup: 51.8X\r\n\r\nAndrew Shin, Market Risk Manager of Koch Supply &amp; Trading, achieves significant performance increases on option pricing algorithms using ArrayFire software to accelerate his code with GPUs. Andrew says, \"My buddy and I are, at best, novice programmers and we couldn\'t imagine having to figure out how to code all this in CUDA.\" But he found ArrayFire software to be straight-forward. With these results, he says he can see ArrayFire software and GPUs populating Koch\'s mark-to-futures cube, which contains its assets, simulations, and simulated asset prices.[/accordion_item]\r\n\r\n[accordion_item title=\"GPU Computing in Automated Trader | Automated Trader\"]\r\n\r\nAuthors: Automated Trader\r\nSpeedup: 37.5X\r\n\r\nThe Q1 2012 issue of Automated Trader contains an excellent Mashup piece reviewing software for algorithmic trading. The article provides a wonderful glimpse into the 1-2 month adventure of Andy Webb, Automated Trader.s Founder, and Wrecking Crew building a fast trading platform from several technologies. The full trading platform they built was quite extensive. The part that caught our eye was the core computational component of the pipeline. That component involved permuting 1,000 potential pairs with cointegration tests for 350 time windows on each potential pair.\r\n[/accordion_item]\r\n[accordion_item title=\"GPUs in Quantitative Analytics and Finance | Private Bank\"]\r\n\r\nThe world of Quantitative finance is all about getting accurate results really, really fast. ArrayFire is working with one of the largest banks in Spain to maximize their output using GPUs. Click the link below for an overview of the uses of GPU computing in finance.[/accordion_item][/accordion]\r\n<h5>Government</h5>\r\n[accordion][accordion_item title=\"Powering Mars Research | NASA and UAA in Anchorage\" ]\r\n\r\nAuthors: NASA and UAA in Anchorage\r\nSpeedup: 5X\r\n\r\nThe main thrust of this research is improving mars rover image compression via GPUs and genetic algorithms. With ArrayFire software and GPUs, the researchers were able to achieve 5X speedups on the larger data sizes. The algorithm works by pairing neighboring pixels with a random one and then adjusting the random pixel based on whether it incrementally improves the original image. Babb described the algorithm as an embarrassingly parallel process, ideally suited to GPU acceleration. He estimates he has been able to achieve a 20 to 30 percent error reduction in subjects like fingerprints and satellite imagery.[/accordion_item]\r\n\r\n[accordion_item title=\"Radar Image Formation | System Planning Corporation\"]\r\n\r\nAuthors: Gary Rubin and Earl Sager - System Planning Corporation\r\nSpeedup: ~45X\r\n\r\nRadar imaging is computationally intensive. As a result, many imaging algorithms apply FFT-based approximations. While efficient, these algorithms sacrifice data fidelity for speed. Other algorithms better preserve information, but are often too slow for many applications. At System Planning Corporation (SPC) , we have implemented a SAR/ISAR imaging routine based on the Backprojection algorithm. Using ArrayFire software, we have demonstrated speedups of roughly 45x for large datasets.[/accordion_item]\r\n\r\n[accordion_item title=\"Radar Clutter Reduction | System Planning Corporation\"]\r\n\r\nAuthors: David Berger and Gary Rubin - System Planning Corporation\r\nSpeedup: 5-10X\r\n\r\nSystem Planning Corporation (SPC) uses ArrayFire software to accelerate radar processing algorithms. The system processes raw data from marine navigation radars using a variety of thresholding techniques to extract real targets from clutter. This involves highly data-parallel processing in which each radar pulse is subjected to the same computations; very few operations occur across multiple pulses. Using ArrayFire software, SPC has achieved 10x speed improvements relative to a Core i7-920 CPU and 5x improvements relative to a realtime DSP implementation.[/accordion_item]\r\n\r\n[accordion_item title=\"Novel Algorithms for Linear Algebra | SAIC\" ]\r\n\r\nAuthors: Nolan Davis and Daniel Redig, SAIC\r\nSpeedup: 3.5X\r\n\r\nNolan Davis and Daniel Redig at SAIC recently presented work on Hybrid GPU/Multicore Solutions for Large Linear Algebra Problems where they developed a novel algorithm for LU decomposition, one of the most important routines in linear algebra. They presented a Hybrid CPU/GPU computing approach, where problems too large to fit in GPU memory can also be solved faster than using only the CPU.\r\n[/accordion_item]\r\n[accordion_item title=\"Geolocation | BAE Systems\"]\r\n\r\nAuthors: BAE Systems\r\nSpeedup: 17X\r\n\r\nGeolocation is the identification of the real-world geographic location of a target of interest. In this application, the system receives the signal with an array of several antennas and computes the direction of arrival of the radio energy by measuring the time difference of arrival (or the phase difference) at the different antennas.\r\n[/accordion_item]\r\n[accordion_item title=\"Tsunami Modeling | University of Minnesota, Boise State, Saint Scholastica, and NCAR\"]\r\n\r\nAuthors: University of Minnesota, Boise State, Saint Scholastica, and NCAR\r\nSpeedup: 3-5X\r\n\r\nNatural catastrophic disasters like tsunamis commonly strike with little warning. For most people, tsunamis are underrated as major hazards. People sometimes wrongly believe that they occur infrequently and only along distant coasts. Tsunamis are usually caused by earthquakes. Seismic signals can give some margin of warning since the speed of tsunami waves travels at 1/30 the speed of seismic waves. Still there is little time between the creation of the tsunami and its impact making fast processing critical to producing effective warning systems. ArrayFire software was used to run an RBF simulation on the GPU with a time to solution not available by other alternatives.\r\n[/accordion_item][/accordion]\r\n<h5>Life Sciences</h5>\r\n[accordion][accordion_item title=\"Parallelized Gene Predictors | University of Quebec\" ]\r\n\r\nAuthors: University of Quebec\r\nSpeedup: 43X\r\n\r\nComputerized approaches to studying the human genome are challenged by the exploding amount of data, which doubles roughly every 6 months. In order to deal with this burgeoning datasets, demands for faster processing power continue to arise. This work focuses on predicting genes using frequency analysis with FFTs and with an equivalent technique known as Goertzel\'s algorithm. In these applications, the emphasis of this paper is to propose tools to geneticists and molecular biologists for the prediction or identification of new genes using existing complementary strategies. The criteria for these tools are speed, reliability, accuracy and ease of use, thus requiring little training.\r\n[/accordion_item]\r\n[accordion_item title=\"Pathology Advances with GPUs | Northeastern University\" ]\r\n\r\nAuthors: Laboratory for Spectral Diagnosis at Northeastern University\r\nSpeedup: 100X+\r\n\r\nOne element of the hyperspectral image analysis workflow that requires more than a traditional desktop workstation or personal computer is Hierarchical Cluster analysis (HCA). HCA requires a large amount of data space and substantial computation time (~11 hours) for typical datasets using a single processor personal computer. Rather than following the traditional approach of moving to a lower level programming language like C or C++ and complex parallel programming paradigms such as OpenMP or the Massage Passing Interface (MPI), the lab utilized graphics processing units, or GPUs, and the ArrayFire software platform. The solution allowed the lab to dramatically increase the performance of the analysis while substantially decreasing the amount of calendar time to reach the desired results.\r\n[/accordion_item]\r\n[accordion_item title=\"Hepatitis C Virus - Mutation Modeling | Centers for Disease Control and Prevention\" ]\r\n\r\nAuthors: CDC Research and Development Team\r\nSpeedup: ~20X\r\n\r\nThis case study provides a look at biological research regarding coordinated mutations of the Hepatitis C Virus (HCV). ArrayFire provided collaborative R&amp;D resources and greatly improved the speed of this HCV research with the use of parallelization, reducing the computing time from 40 days to less than 1 day. Most importantly, the conclusion of the case study illustrates the the relative price-performance of personal supercomputers that leverage GPUs and ArrayFire software provides a compelling solution versus other architectures and approaches.\r\n[/accordion_item]\r\n[accordion_item title=\"Accelerating the SPM Package for Neuroimaging | Georgia Institute of Technology\" ]\r\n\r\nAuthors: Georgia Institute of Technology\r\nSpeedup: 3.5X\r\n\r\nThe Georgia Tech team explores the value of ArrayFire software and GPUs for fMRI workflows within the popular SPM - Statistical Parametric Mapping software widely used in neuroscience research.\r\n[/accordion_item]\r\n[accordion_item title=\"Medical Image Compression | Indian Institute of Technology, Roorkee, India\" ]\r\n\r\nAuthors: Jaideep Singh, Ipseeta Aruni, R. Balasubramanian - IIT - Roorkee, India\r\nSpeedup: 38X\r\n\r\nThis study presents the acceleration of Haar wavelet-based image compression algorithm for medical imaging on the Graphics Processing Unit (GPU) using ArrayFire software. Due to bandwidth and image size constraints of medical imaging systems, image compression plays a vital role in reducing the bit rate of transmission or storage. Wavelet-based image compression provides the most promising approach for high quality image compression.\r\n[/accordion_item]\r\n[accordion_item title=\"Brain Displacement | Spencer Technologies\"]\r\n\r\nAuthors: Spencer Technologies\r\nSpeedup: 12X\r\n\r\nSpencer describes how ArrayFire software facilitates the development of fast algorithms enabling observation of brain displacement across depth with sampling density that far surpasses previous benchmarks.\r\n[/accordion_item]\r\n[accordion_item title=\"Multidimensional Scaling for Genomics | Leibniz Institute of Plant Genetics and Crop Plant Research\" ]\r\n\r\nAuthors: Leibniz Institute of Plant Genetics and Crop Plant Research\r\nSpeedup: 20-35X\r\n\r\nMultidimensional scaling (MDS) is a general computing technique to turn a distance matrix into a set of reconstructed points with pair-wise relationships approximating the original distances by points located in a usually low-dimensional space. ArrayFire software is used to enhance execution of the HiT-MDS procedure and delivers considerable performance improvement.\r\n[/accordion_item]\r\n[accordion_item title=\"Drug Delivery Model | Georgia Institute of Technology\"]\r\n\r\nAuthors: Georgia Institute of Technology\r\nSpeedup: 70X\r\n\r\nIn this work, the researchers simulate the delivery of a novel nanoparticle chemotherapy drug to cancerous tissue. Simulation allows scientists to predict experimental outcomes and thus reduce the cost of development and time to clinical relevance. The simulation model includes blood vessels, tumor cells, and healthy cells and an engine to calculate the spatial distributions of both drug and oxygen. ArrayFire software is used to speed up the diffusion calculations for the drug and oxygen within the tissue.\r\n[/accordion_item]\r\n[accordion_item title=\"Biomedical Infrared Spectroscopy | University of Manchester and Nofima Mat, Norway\" ]\r\n\r\nAuthors: University of Manchester and Nofima Mat, Norway\r\nSpeedup: Hours of runtime reduction\r\n\r\nThe authors present an iterative algorithm that applies full Mie scattering theory and avoids noise accumulation in their iterative algorithm by integrating a curve-fitting step. ArrayFire software along with NVIDIA GPUs are leveraged to reduce the time added by the curve-fitting step.\r\n[/accordion_item][/accordion]\r\n<h5>Manufacturing</h5>\r\n[accordion][accordion_item title=\"Feature Learning on Images | Stanford\" ]\r\n\r\nAuthors: Andrew Ng, Stanford University\r\nSpeedup: Ability to process many images in parallel\r\n\r\nStanford researchers in Andrew Ng\'s group used GPUs and ArrayFire software to speed up their work on Feature Learning Architectures. They decided to use ArrayFire software for this study because of the need to quickly evaluate many architectures on thousands of images. ArrayFire software taps into the immense computing power of GPUs and speeds up research utilizing many images.\r\n[/accordion_item]\r\n[accordion_item title=\"Tomography of Vegetation - Filtered Back-Projection and Non-Uniform FFTs | Universita di Napoli Federico II\" ]\r\n\r\nAuthors: Drs. Capozzoli, Curcio, di Vico, and Liseno, Universita di Napoli Federico II\r\nSpeedup: 10X\r\n\r\nIn order to investigate changes of forest biomass, scientists use microwave tomography to image the vegetation. At the smallest scale, individual plants can be imaged to investigate branching and growth, but even synthetic aperture radar can reveal large-scale changes in regional ecology. To the right, you can see the experimental setup to image an individual plant.\r\n[/accordion_item]\r\n[accordion_item title=\"Action Recognition with Independent Subspace Analysis | Stanford University\" ]\r\n\r\nAuthors: Quoc Le, Will Zou, Serena Yeung, Andrew Ng, Stanford University\r\nSpeedup: 4.4X\r\n\r\nIn a paper at this year\'s CVPR 2011, entitled \"Learning hierarchical invariant spatio-temporal features for action recognition with independent subspace analysis\", the authors explain how their unsupervised feature learning algorithm competes with other algorithms that are hand crafted or use learned features. For their training purposes, they used a multi-layered stacked convolutional ISA (Independent subspace analysis) network. An ISA is used for learning features from image patches without supervision.\r\n[/accordion_item][/accordion]\r\n<h5>Media and Computer Vision</h5>\r\n[accordion][accordion_item title=\"Fast Computer Vision with OpenCV and ArrayFire | OpenCV Blogger\" ]\r\n\r\nAuthors: OpenCV Blogger\r\nSpeedup: ~10X\r\n\r\nThe OpenCV library is the defacto standard for doing computer vision and image processing research projects. OpenCV includes several hundreds of computer vision algorithms, aimed for use in realtime vision applications. This case study shows how to use both libraries together. There is a simple example application that demonstrates using OpenCV for webcam access and ArrayFire for some basic processing routines and displaying results.\r\n[/accordion_item]\r\n[accordion_item title=\"Video Processing | Google\" ]\r\n\r\nAuthors: Google and Stanford\r\nSpeedup: 10-20X\r\n\r\nVideo content analysis is the basis for categorizing videos and enabling search by content. Growing interest in using sparse-coding methods to extract motion features in video in support of video content analysis led to the application of ArrayFire software to improve performance by substantially accelerating the solution of the L1-regularized least-squares optimization problem.\r\n[/accordion_item]\r\n[accordion_item title=\"Action Recognition with Independent Subspace Analysis | Stanford University\"]\r\n\r\nAuthors: Quoc Le, Will Zou, Serena Yeung, Andrew Ng, Stanford University\r\nSpeedup: 4.4X\r\n\r\nIn a paper at this year\'s CVPR 2011, entitled \"Learning hierarchical invariant spatio-temporal features for action recognition with independent subspace analysis\", the authors explain how their unsupervised feature learning algorithm competes with other algorithms that are hand crafted or use learned features. For their training purposes, they used a multi-layered stacked convolutional ISA (Independent subspace analysis) network. An ISA is used for learning features from image patches without supervision.\r\n[/accordion_item]\r\n[accordion_item title=\"Music Beat Analysis | Georgia Tech\"]\r\n\r\nAuthors: Vidhur Vohra - Georgia Tech\r\nSpeedup: 15X\r\n\r\nDid you ever wonder how the music visualizer in your media player works? Watching it pulsate in synchrony with the beats of the song is almost as entertaining as listening to the song itself! Researchers have been attempting to detect beats in audio signals for many years, and there are many techniques available, from the simplest (and least accurate) to more complicated algorithms that are highly accurate. All algorithms, though, perform some form of signal processing and frequency analysis, applications highly suited to GPU Computing.\r\n[/accordion_item]\r\n[accordion_item title=\"Optimization Methods for Deep Learning | Stanford Artificial Intelligence Laboratory\" ]\r\n\r\nAuthors: Stanford Artificial Intelligence Laboratory\r\nSpeedup: Improved accuracy\r\n\r\nResearchers at SAIL (Stanford Artificial Intelligence Laboratory), have done it again. They have successfully used ArrayFire software to speed up the training part of Deep Learning algorithms. In their paper titled .On Optimization Methods for Deep Learning., they experiment with some of the well known training algorithms and demostrate their scalability across parallel architectures (GPUs as well as multi-machine networks). The algorithms include SGDs (Stochastic Gradient Descent) L-BFGS (Limited BFGS used for solving non-linear problems), CG (Conjugate Gradient).\r\n[/accordion_item]\r\n[accordion_item title=\"Feature Learning on Images | Stanford University\" ]\r\n\r\nAuthors: Andrew Ng, Stanford University\r\nSpeedup: Ability to process many images in parallel\r\n\r\nStanford researchers in Andrew Ng’s group used ArrayFire software to speed up their work on Feature Learning Architectures. They decided to use ArrayFire software for this study because of the need to quickly evaluate many architectures on thousands of images. ArrayFire software taps into the immense computing power of GPUs and speeds up research utilizing many images.\r\n[/accordion_item]\r\n[accordion_item title=\"Digital Holography for Imaging | National University of Ireland, Maynooth\" ]\r\n\r\nAuthors: Nitesh Pandey, Damien Kelly, Bryan Hennelly and Thomas Naughton from the National University of Ireland, Maynooth\r\nSpeedup: 17X\r\n\r\nDigital holography is a powerful imaging technique with many new applications like true 3D display. It allows the capture of both amplitude and phase information of the light reflected off the surface of 3D objects. Researchers at the National University of Ireland, Maynooth are developing techniques based on digital holography for 3D display applications.\r\nReconstruction of large digital holograms can be computationally intensive to generate on CPUs, but GPUs running ArrayFire software offer amazing possibilities.\r\n[/accordion_item][/accordion]\r\n<h5>Oil and Gas</h5>\r\n[accordion][accordion_item title=\"3D Mantle Convection - Geodynamics | Boise State, University of Colorado, University of Minnesota\" ]\r\n\r\nAuthors: Boise State, University of Colorado, University of Minnesota\r\nSpeedup: 2.5-4.5X\r\n\r\nThe authors introduce a GPU implementation of a three-dimensional mantle convection modeling at a high Rayleigh number to the solid earth geophysics community. They outline code development time, compare performance of CPUs versus GPUs, and deliver powerful visualizations.\r\n[/accordion_item]\r\n[accordion_item title=\"Ground Water Simulations | Louisiana State University\" ]\r\n\r\nAuthors: Kevin R. Tubbs and Frank T-C. Tsai at Louisiana State University\r\nSpeedup: &gt;20X\r\n\r\nA lattice Boltzmann method for solving the shallow water equations and the advection-dispersion equation is developed and implemented on graphics processing unit (GPU)-based architectures. The proposed LBM is implemented to an NVIDIA Computing Processor in a single GPU workstation. GPU computing is performed using ArrayFire software. Mass transport with velocity-dependent dispersion in shallow water flow is simulated by combining the MRT-LBM model and the TRT-LBM model. The GPU parallel performance increases as the grid size increases. The results indicate the promise of the GPU-accelerated LBM for modeling mass transport phenomena in shallow water flows.\r\n[/accordion_item]\r\n[accordion_item title=\"Shallow Water Fluid Flow | Louisiana State University\" ]\r\n\r\nAuthors: Louisiana State University\r\nSpeedup: &gt;10X\r\n\r\nA lattice Boltzmann method (LBM) on high performance computing (HPC) environments for three-dimensional shallow water flow fields coupled to mass transport is developed. LBM is an attractive method for solving the multilayered shallow water equations because the extension to multilayer is straight forward with all of the simplicities and advantages of the LBM in mass transport in shallow water flows and the LBM performance on central processing unit (CPU)-based and graphics processing unit (GPU)-based HPC environments.\r\n[/accordion_item][/accordion]\r\n<div id=\"consulting\"></div>\r\n[/content_band]\r\n<div id=\"services\"></div>\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\"]Hire our acceleration gang[/custom_headline]\r\n\r\nHire us to accelerate your code. Or to train your pros. Or even to write new code for your organization!\r\n\r\nWe’ve already helped thousands of organizations speedup their code. We’ve accelerated algorithms, data sets, and challenging problems of all types in the past, and we’re confident that we can accelerate your code too.\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://meetme.so/arrayfire\" size=\"x-large\" ]Schedule a consultation[/button][/column][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"5%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/Bat-signal-e1391790016951.png\"][/column] [gap size=\"7%\"]\r\n\r\n[column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/LFG-B-HORZ_202_K-e1396448935778.jpg\"][line]Lincoln Financial Group ported their CPU code (C/C++) to CUDA, and this enabled them to speed up the necessary financial calculations. Their primary objective was to reduce the time taken to run this code. Before porting to CUDA, they required 10-12 hours to run the entire code. After porting to CUDA, they were able to do the same work in about 30 minutes.[/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][line]Reveal Imaging, an SAIC company, uses ArrayFire in developing threat-detection products for transportation systems—such as cargo and baggage screening in airports—and in securing facilities and public events.[/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][line]The Glasses.com app relies on computer vision to recognize the features of a user’s face. The application then generates an accurate, high-fidelity, three-dimensional model of that face, and virtually places selected frames on the image.[/column]\r\n<div id=\"starterpackage\"></div>\r\n[/content_band]\r\n\r\n[content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\"]\r\n\r\n[column type=\"one-half\" last=\"false\" fade=\"true\" fade_animation=\"in-from-left\" ][gap size=\"10%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/comingatyou.png\"][/column][column type=\"one-half\" last=\"true\"] [custom_headline type=\"left\" level=\"h3\"]Starter Package ($500)* [/custom_headline] Hire us for 1-day. We set you up with one engineer dedicated for a full day, as well as support from senior and test engineers throughout the day. Here\'s how it works:\r\n\r\n[icon_list] [icon_list_item type=\"angle-double-right\"]Initial phone call[/icon_list_item] [icon_list_item type=\"angle-double-right\"]You send us your code or algorithm [/icon_list_item] [icon_list_item type=\"angle-double-right\"]We analyze your code for potential GPU benefit[/icon_list_item][icon_list_item type=\"angle-double-right\"]We accelerate as much of the code as is possible within the 1-day effort, applying our extensive GPU software libraries[/icon_list_item][icon_list_item type=\"angle-double-right\"]We produce a final report, along with code[/icon_list_item] [/icon_list] The final report outlines the best approach to follow for full GPU-acceleration of your code.\r\n\r\n&nbsp;\r\n\r\n[button type=\"flat\" shape=\"rounded\" size=\"regular\" href=\"http://sandbox.arrayfire.com/product/consulting-starter-package/\" title=\"Starter Package\"]Buy the Starter Package[/button]\r\n\r\n&nbsp;\r\n\r\n*Limit one (1) per customer.\r\n\r\n[/column]\r\n<div id=\"customcode\"></div>\r\n[/content_band] [content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\" ]Custom Coding Work[/custom_headline]\r\n\r\n[custom_headline type=\"left\" level=\"h6\" ]Why Choose Us?[/custom_headline] [icon_list] [icon_list_item type=\"angle-double-right\"]Deep experience, already servicing thousands of customers[/icon_list_item] [icon_list_item type=\"angle-double-right\"]Quality work, with leading GPU software [/icon_list_item] [icon_list_item type=\"angle-double-right\"]Efficient delivery, with ArrayFire\'s code base we can deliver results fast[/icon_list_item][icon_list_item type=\"angle-double-right\"]Proven, we make customers happy through faster code[/icon_list_item][/icon_list] [custom_headline type=\"left\" level=\"h6\" ]Our Strengths[/custom_headline] [icon_list] [icon_list_item type=\"angle-double-right\"]Excellence in GPU code[/icon_list_item] [icon_list_item type=\"angle-double-right\"]Well-written, efficient C, C++, Fortran, Java, or .NET [/icon_list_item] [icon_list_item type=\"angle-double-right\"]Application porting and integration[/icon_list_item][icon_list_item type=\"angle-double-right\"]Tuning software to peak hardware performance[/icon_list_item][icon_list_item type=\"angle-double-right\"]Scalability of algorithms to handle enterprise-level programs[/icon_list_item] [/icon_list][button type=\"flat\" shape=\"rounded\" size=\"regular\" href=\"http://meetme.so/arrayfire\" title=\"Tech Consultation\"]Schedule a consultation[/button] [/column][column type=\"one-half\"  fade=\"true\" fade_animation=\"in-from-right\" last=\"true\" ][gap size=\"25%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Holoham.png\"][/column]\r\n<div id=\"training\"></div>\r\n[/content_band] [content_band inner_container=\"true\" no_margin=\"true\" border=\"top\" padding_top=\"40px\" padding_bottom=\"40px\" ]\r\n\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\" ]Training[/custom_headline] Attendees will receive the latest industry knowledge and techniques for GPU computing in CUDA and OpenCL.\r\n\r\nArrayFire offers up to four days of specialized GPU training in CUDA and OpenCL programming. We provide customized on-site training courses for customers that have 3 or more attendees from their organization. We can travel to your location and provide a CUDA or OpenCL training course tailored to meet your application-specific needs. We also offer individual trainings at our Atlanta office. Please <a href=\"mailto:sales@arrayfire.com\">contact us</a> to learn more about our training offerings.\r\n\r\nWe recommend that attendees have a working knowledge of C/C++ in order to gain the most from the training courses. For more information about the content of our training lectures and hands-on practicums, please see the following training course syllabus.\r\n\r\n[/column]\r\n\r\n[column type=\"one-half\" last=\"true\" fade=\"true\" fade_animation=\"in-from-right\" class=\"center-text\"][gap size=\"15%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Professor-AF_Exported-e1395436350363.png\" ][/column]\r\n\r\n[column type=\"one-half\" class=\"center-text\"] [gap size=\"17%\"]\r\n<div>[button type=\"flat\" shape=\"rounded\" size=\"jumbo\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]</div>\r\n[/column][column type=\"one-half\" last=\"true\"][custom_headline type=\"left\" level=\"h3\"]Included in Course[/custom_headline]\r\n\r\n[icon_list] [icon_list_item type=\"angle-double-right\"]Instruction by an excellent and interesting expert, with hands-on exercises[/icon_list_item] [icon_list_item type=\"angle-double-right\"]Use of a laptop with CUDA and OpenCL capable GPUs and CPUs [/icon_list_item] [icon_list_item type=\"angle-double-right\"]Choice of Linux or Windows operating system[/icon_list_item][icon_list_item type=\"angle-double-right\"]Printed manual of lecture material[/icon_list_item][icon_list_item type=\"angle-double-right\"]Electronic copy of programming exercises[/icon_list_item][/icon_list]\r\n\r\n[/column]\r\n\r\n<span style=\"line-height: 1.5em;\">[gap size=\"5%\"]</span>\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]Training Course Syllabus[/custom_headline] [column type=\"one-half\"] [custom_headline type=\"left\" level=\"h5\"  accent=\"false\"]Day 1, Introduction[/custom_headline] Lectures:\r\nGPU Computing Overview\r\nThe Programming Model\r\nBasic Dataset Mapping Techniques\r\nLibraries, ArrayFire\r\nProfiling Tools\r\n\r\nPractice:\r\nA Simple Kernel\r\nEquivalent ArrayFire Example\r\nUsing Libraries\r\nMonte Carlo Pi Estimation\r\nTiming and ArrayFire\r\nDebugging Code\r\n\r\n[custom_headline type=\"left\" level=\"h5\" accent=\"false\"]Day 3, Multi-GPU[/custom_headline] Lectures:\r\nMulti-GPU Use Cases\r\nMulti-GPUs: Contexts\r\nExisting Libraries\r\nScaling Across Multiple GPUs\r\n\r\nPractice:\r\nOut of Core Problems: Matrix Multiply\r\nTask Level Parallelism: Optimization\r\nArrayFire Multi-GPU[/column]\r\n\r\n[column type=\"one-half\" last=\"true\"] [custom_headline type=\"left\" level=\"h5\" accent=\"false\"]Day 2, Optimization[/custom_headline] Lectures:\r\nArchitecture: Grids, Blocks, and Threads\r\nMemory Model: Global, Shared, and Constant Memory\r\nAdvanced Mapping Techniques\r\nStreams: Asynchronos Launches and Concurrent Execution\r\nArrayFire: Lazy Evaluation and Code Vectorization\r\n\r\nPractice:\r\nMatrix Transpose\r\nOptimization Using Shared Memory\r\nMedian Filter\r\nOptimization Using Constant Memory\r\nStream Example\r\nArrayFire Example: Nearest Neighbor Algorithm\r\n\r\n[custom_headline type=\"left\" level=\"h5\" accent=\"false\"]Day 4, Algorithm Problems[/custom_headline]\r\n\r\nLectures and Practice:\r\nReductions\r\nScan Algorithms\r\nSort\r\nConvolution\r\nCustomer-Specific Problem [/column][/content_band]','Home','','inherit','open','closed','','245-revision-v1','','','2014-05-20 13:37:04','2014-05-20 13:37:04','',245,'http://sandbox.arrayfire.com/245-revision-v1/',0,'revision','',0),(5618,17729,'2014-05-20 14:53:30','2014-05-20 14:53:30','<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<h2 id=\"opencl\">OpenCL</h2>\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<h3 id=\"adreno-gpu\">Adreno GPU</h3>\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<h3 id=\"mali-gpu\">Mali GPU</h3>\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<h3 id=\"kernels\">Kernels</h3>\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<h3 id=\"auxilary-code\">Auxilary Code</h3>\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<h2 id=\"build-on-linux\">Build (on Linux)</h2>\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<h3 id=\"android.mk\">Android.mk</h3>\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<h2 id=\"application.mk\">Application.mk</h2>\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<h3 id=\"ant-users\">ant-users</h3>\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<h3 id=\"eclipse-users\">eclipse-users</h3>\r\n<p>Right click the project in workspace and click the menu item &quot;Run As -&gt; Android Application&quot;.</p>\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]','Getting started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-20 14:53:30','2014-05-20 14:53:30','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5619,17729,'2014-05-20 14:56:38','2014-05-20 14:56:38','<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\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]','Getting started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-20 14:56:38','2014-05-20 14:56:38','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5620,17729,'2014-05-20 15:04:18','2014-05-20 15:04:18','<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\n<h3>Video of the app running live</h3>\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]','Getting started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-20 15:04:18','2014-05-20 15:04:18','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),(5621,17729,'2014-05-20 15:07:53','2014-05-20 15:07:53','<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\n<h3>Video of the app running live</h3>\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 support for OpenCL on Andriod!','Getting started with OpenCL on Android','','inherit','open','closed','','5574-revision-v1','','','2014-05-20 15:07:53','2014-05-20 15:07:53','',5574,'http://sandbox.arrayfire.com/5574-revision-v1/',0,'revision','',0),