(6386,17796,'2014-08-12 15:38:43','2014-08-12 15:38:43','In this blog we will review the benefit of using element-wise operations for your computations. Element-wise operations are operations that are applied to every element in an array. If the operation is on two elements, these elements are located in the same place in their respective arrays. The simplest example of an element-wise operation is the addition (+) operation.\r\n<pre>array A=array(1024,1024), B=array(1024,1024), C=array(1024,1024);\r\nC=A+B;\r\n</pre>\r\nAn element-wise operator that is applied to a single element is unary operator. An operator that works on two elements is a binary operator. ArrayFire has implemented a large number element-wise operations that are applied to the elements of an array. These operators can help reduce the programming overhead for an application designer as:\r\n<ul>\r\n	<li>Productivity - the application need not worry about implementing the operator.</li>\r\n	<li>Portability - as these are implemented in OpenCL, the programmer does not have deal with the partitioning of the work and load-balancing. These are key components for performance.</li>\r\n	<li>Readability and maintenance - simplifies going over code.</li>\r\n	<li>Completeness - the <pre>array</pre> data type is no different than any other C scalar data type.</li>\r\n</ul>\r\n&nbsp;\r\n\r\n&nbsp;','The Benefits of Array Element-Wise Operations ','','inherit','open','open','','6383-revision-v1','','','2014-08-12 15:38:43','2014-08-12 15:38:43','',6383,'http://sandbox.arrayfire.com/6383-revision-v1/',0,'revision','',0),(6388,17796,'2014-08-12 16:11:25','2014-08-12 16:11:25','In this blog we will review the benefit of using element-wise operations for your computations. Element-wise operations are operations that are applied to every element in an array. The simplest example of an element-wise operation is the addition (+) operation.\r\n<pre>array A=array(1024,1024), B=array(1024,1024), C=array(1024,1024);\r\nC=A+B;\r\n</pre>\r\nAn element-wise operator that is applied to a single element is unary operator. An operator that works on two elements is a binary operator. ArrayFire has implemented a large number element-wise operations that are applied to the elements of an array. These operators can help reduce the programming overhead for an application designer as:\r\n<ul>\r\n	<li>Productivity - the application designed need not worry about implementing the operator.</li>\r\n	<li>Portability - as these are implemented in OpenCL, the programmer does not have deal with the partitioning of the work and load-balancing. These are key components for performance.</li>\r\n	<li>Completeness - the array data type is no different than any other C scalar data type.</li>\r\n	<li>Readability and maintenance - high performance computing becomes as simple as writing a script.</li>\r\n</ul>\r\nOur element-wise operations also include operations between an array and a scalar value. For example:\r\n<pre>array A,B\r\nB=A+1;\r\n</pre>\r\nA small subset of these operators include:\r\n<ul>\r\n	<li>sin - computes the sine for each element in the array.</li>\r\n	<li>cosine - computes the sine for each element in the array.</li>\r\n	<li>abs - computes the absolute value for each element in the array.</li>\r\n	<li>trunc - truncates every element in the array.</li>\r\n</ul>\r\nA full list of element-wise operators can also be found in our document under: <a title=\"element-wise operators\" href=\"http://sandbox.arrayfire.com/docs/group__arith.htm\" target=\"_blank\">ele</a><span style=\"text-decoration: underline;\">ment-wise operators</span> and <a title=\"operator overloading\" href=\"http://sandbox.arrayfire.com/docs/group__array__operator.htm\" target=\"_blank\">operator-overloading functions</a>   . These will include trigonometric, arithmetic, and utility functions.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','The Benefits of Array Element-Wise Operations ','','inherit','open','open','','6383-revision-v1','','','2014-08-12 16:11:25','2014-08-12 16:11:25','',6383,'http://sandbox.arrayfire.com/6383-revision-v1/',0,'revision','',0),(6389,18132,'2014-08-13 12:14:14','2014-08-13 12:14:14','<img style=\"float: right; margin-top: 10px; margin-right: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n<h1>TL;DR</h1>\r\nWhy did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants,\r\n<pre>sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\nFrom, <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">cross compiling tinc for windows 64</a>.\r\n\r\nThere are some caveats, however,\r\n\r\n<h2>Caveats</h2>\r\n\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\n\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n\r\n<pre>\r\ntemplate <class T> void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\n\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n\r\n<pre>\r\nvoid __force_compile() {\r\n  scale<float>(0, 0, NULL);\r\n  scale<int>(0, 0, NULL);\r\n}\r\n</pre>\r\n\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\n\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n\r\n<h3>External Dependencies</h3>\r\n\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n\r\nLets say you\'ve downloaded \r\n\r\n<h4>MinGW and Boost</h4>\r\n\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n\r\n<pre>\r\nwget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:14:14','2014-08-13 12:14:14','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6390,18132,'2014-08-13 12:14:49','2014-08-13 12:14:49','<img style=\"float: right; margin-top: 10px; margin-right: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants,\r\n<pre>sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\nFrom, <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">cross compiling tinc for windows 64</a>.\r\n\r\nThere are some caveats, however,\r\n\r\n<h2>Caveats</h2>\r\n\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\n\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n\r\n<pre>\r\ntemplate <class T> void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\n\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n\r\n<pre>\r\nvoid __force_compile() {\r\n  scale<float>(0, 0, NULL);\r\n  scale<int>(0, 0, NULL);\r\n}\r\n</pre>\r\n\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\n\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n\r\n<h3>External Dependencies</h3>\r\n\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n\r\nLets say you\'ve downloaded \r\n\r\n<h4>MinGW and Boost</h4>\r\n\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n\r\n<pre>\r\nwget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:14:49','2014-08-13 12:14:49','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6391,18132,'2014-08-13 12:15:15','2014-08-13 12:15:15','<img style=\"float: left; margin-top: 10px; margin-right: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants,\r\n<pre>sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\nFrom, <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">cross compiling tinc for windows 64</a>.\r\n\r\nThere are some caveats, however,\r\n\r\n<h2>Caveats</h2>\r\n\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\n\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n\r\n<pre>\r\ntemplate <class T> void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\n\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n\r\n<pre>\r\nvoid __force_compile() {\r\n  scale<float>(0, 0, NULL);\r\n  scale<int>(0, 0, NULL);\r\n}\r\n</pre>\r\n\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\n\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n\r\n<h3>External Dependencies</h3>\r\n\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n\r\nLets say you\'ve downloaded \r\n\r\n<h4>MinGW and Boost</h4>\r\n\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n\r\n<pre>\r\nwget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:15:15','2014-08-13 12:15:15','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6392,18132,'2014-08-13 12:17:06','2014-08-13 12:17:06','\r\n\r\nWhy did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n\r\n<pre>\r\nsudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\n<img style=\"float: right; margin-top: 10px; margin-right: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\nFrom, \r\n\r\nThere are some caveats, however,\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\nLets say you\'ve downloaded\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:17:06','2014-08-13 12:17:06','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6393,18132,'2014-08-13 12:18:30','2014-08-13 12:18:30','\r\nWhy did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n\r\n<pre>\r\nsudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nThere are some caveats, however,\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\nLets say you\'ve downloaded\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:18:30','2014-08-13 12:18:30','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6394,18132,'2014-08-13 12:19:33','2014-08-13 12:19:33','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"float: left;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nThere are some caveats, however,\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\nLets say you\'ve downloaded\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:19:33','2014-08-13 12:19:33','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6395,18132,'2014-08-13 12:21:30','2014-08-13 12:21:30','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"float: left;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n<img style=\"float: right;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nThere are some caveats, however,\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\nLets say you\'ve downloaded\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:21:30','2014-08-13 12:21:30','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6396,18132,'2014-08-13 12:23:18','2014-08-13 12:23:18','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre>sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nThere are some caveats, however,\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\nLets say you\'ve downloaded\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:23:18','2014-08-13 12:23:18','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6397,18132,'2014-08-13 12:27:01','2014-08-13 12:27:01','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre>sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe    # 64-bit\r\n</pre>\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\nLets say you\'ve downloaded\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:27:01','2014-08-13 12:27:01','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6398,18132,'2014-08-13 12:30:11','2014-08-13 12:30:11','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n\r\n<pre style=\"margin-bottom: 20px\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n\r\n<img class=\"aligncenter\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\nLets say you\'ve downloaded\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:30:11','2014-08-13 12:30:11','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6399,18132,'2014-08-13 12:30:49','2014-08-13 12:30:49','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n\r\n<pre style=\"margin-bottom: 20px\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n\r\n<img class=\"aligncenter\" style=\"margin-top: 20px; src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\nLets say you\'ve downloaded\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:30:49','2014-08-13 12:30:49','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6400,18132,'2014-08-13 12:31:09','2014-08-13 12:31:09','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n\r\n<pre style=\"margin-bottom: 20px\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols on link. For instance something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\nLets say you\'ve downloaded\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 12:31:09','2014-08-13 12:31:09','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6401,18132,'2014-08-13 13:21:24','2014-08-13 13:21:24','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n\r\n<pre style=\"margin-bottom: 20px\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n\r\n\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\n\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n\r\n<pre>\r\ni686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 13:21:24','2014-08-13 13:21:24','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6402,18132,'2014-08-13 13:22:22','2014-08-13 13:22:22','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n\r\n<pre style=\"margin-bottom: 20px\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n\r\n\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n\r\n<pre>template  void scale(class T a, class T *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\n\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n\r\n<pre>\r\ni686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 13:22:22','2014-08-13 13:22:22','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6403,18132,'2014-08-13 13:33:46','2014-08-13 13:33:46','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template &lt;class ty&gt; void scale(ty a, ty *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 13:33:46','2014-08-13 13:33:46','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6404,18132,'2014-08-13 13:34:46','2014-08-13 13:34:46','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\r\n  for (int i = 0; i &lt; n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 13:34:46','2014-08-13 13:34:46','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6405,18132,'2014-08-13 13:35:35','2014-08-13 13:35:35','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 13:35:35','2014-08-13 13:35:35','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6406,18132,'2014-08-13 13:36:06','2014-08-13 13:36:06','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale<float>(2.0, A, n);\r\n  scale<int>(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale(0, 0, NULL);\r\n  scale(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 13:36:06','2014-08-13 13:36:06','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6407,18132,'2014-08-13 13:36:36','2014-08-13 13:36:36','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale<float>(0, 0, NULL);\r\n  scale<int>(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built windows library and specific notes for Boost.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 13:36:36','2014-08-13 13:36:36','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6408,18132,'2014-08-13 13:41:57','2014-08-13 13:41:57','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale<float>(0, 0, NULL);\r\n  scale<int>(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. They also need to be I give some quick notes for the case where you\'d like to use a pre-built (mingw) windows library and specific notes for Boost.\r\n\r\nNote that except for purely C external libraries, the libraries themselves must have been built with MinGW. The naming conventions of C++ symbols differ between MingGW and Visual Studio.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 13:41:57','2014-08-13 13:41:57','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6409,18132,'2014-08-13 14:18:20','2014-08-13 14:18:20','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale<float>(0, 0, NULL);\r\n  scale<int>(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built (mingw) windows library and specific notes for Boost.\r\n\r\nNote that except for purely C external libraries, the libraries themselves must have been built with MinGW. The naming conventions of C++ symbols differ between MingGW and Visual Studio.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 14:18:20','2014-08-13 14:18:20','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6411,18132,'2014-08-13 18:02:38','2014-08-13 18:02:38','Why did I not know about this? It\'s like I just discovered the screw driver!\n\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\n\n# C\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\n\n# C++\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\n</pre>\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\n\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\n\nI cover some quick solutions to the most common caveats I\'ve run into, below.\n<h2>Caveats</h2>\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\n}\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\n  scale(2.0, A, n);\n  scale(  3, B, n);\n}\n</pre>\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\n<pre>void __force_compile() {\n  scale<float>(0, 0, NULL);\n  scale<int>(0, 0, NULL);\n}\n</pre>\n<h3>C/C++ Standard Library Dependencies</h3>\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\n\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\n\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.\n\nNote that you can hav\n\n<h3>External Dependencies</h3>\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built (mingw) windows library and specific notes for Boost.\n\nNote that except for purely C external libraries, the libraries themselves must have been built with MinGW. The naming conventions of C++ symbols differ between MingGW and Visual Studio.\n\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\n\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\n</pre>\n<h4>MinGW and Boost</h4>\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\n\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\ntar xzfp boost.tar.gz\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-autosave-v1','','','2014-08-13 18:02:38','2014-08-13 18:02:38','',6297,'http://sandbox.arrayfire.com/6297-autosave-v1/',0,'revision','',0),(6412,18132,'2014-08-13 18:03:46','2014-08-13 18:03:46','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale<float>(0, 0, NULL);\r\n  scale<int>(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>. Note that you can have gcc include these libraries statically by including the flags, `-static-libgcc -static-libstdc++`.\r\n\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built (mingw) windows library and specific notes for Boost.\r\n\r\nNote that except for purely C external libraries, the libraries themselves must have been built with MinGW. The naming conventions of C++ symbols differ between MingGW and Visual Studio.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 18:03:46','2014-08-13 18:03:46','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6413,18132,'2014-08-13 18:05:57','2014-08-13 18:05:57','Why did I not know about this? It\'s like I just discovered the screw driver!\r\n\r\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\r\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\r\n\r\n# C\r\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\r\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\r\n\r\n# C++\r\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\r\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\r\n</pre>\r\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\r\n\r\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\r\n\r\nI cover some quick solutions to the most common caveats I\'ve run into, below.\r\n<h2>Caveats</h2>\r\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\r\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\r\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\r\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\r\n}\r\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\r\n  scale(2.0, A, n);\r\n  scale(  3, B, n);\r\n}\r\n</pre>\r\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\r\n<pre>void __force_compile() {\r\n  scale<float>(0, 0, NULL);\r\n  scale<int>(0, 0, NULL);\r\n}\r\n</pre>\r\n<h3>C/C++ Standard Library Dependencies</h3>\r\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\r\n\r\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\r\n\r\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>. Note that you can have gcc include these libraries statically by including the flags, <code>-static-libgcc</code> and <code>-static-libstdc++</code>.\r\n\r\n<h3>External Dependencies</h3>\r\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built (mingw) windows library and specific notes for Boost.\r\n\r\nNote that except for purely C external libraries, the libraries themselves must have been built with MinGW. The naming conventions of C++ symbols differ between MingGW and Visual Studio.\r\n\r\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\r\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\r\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\r\n\r\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\r\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\r\n</pre>\r\n<h4>MinGW and Boost</h4>\r\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\r\n\r\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\r\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\r\ntar xzfp boost.tar.gz\r\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\r\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-revision-v1','','','2014-08-13 18:05:57','2014-08-13 18:05:57','',6297,'http://sandbox.arrayfire.com/6297-revision-v1/',0,'revision','',0),(6415,17729,'2014-08-13 18:54:16','2014-08-13 18:54:16','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n	<li>Image Histogram</li>\r\n	<li>Simple Binary Theshold</li>\r\n	<li>Otsu Threshold</li>\r\n	<li>Iterative Threshold</li>\r\n	<li>Adaptive Binary Threshold</li>\r\n	<li>Emboss Filter</li>\r\n</ul>\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n<h4>Image Histogram</h4>\r\nWe have a built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>. The input image was converted to gray scale before histogram calculation as our histogram implementation works for vector and 2D matrices only.\r\n<div style=\"text-align: center;\">\r\n<div style=\"vertical-align: top;\">\r\n\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img class=\"size-medium wp-image-6311\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"vertical-align: bottom;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n</div>\r\nIn case, you need histogram for all three channels of a color image, you can do it using the following four line code stub.\r\n<pre>array color = loadimage(\"\",true); // last parameter is to indicate that you would like \r\n                                             // array to have all channels of the image\r\narray hist(256,color.dims(2)); // 2nd dimension is our channel dimension\r\n                               // ArrayFire stores channels as independent slices currently.\r\nhist(span,0) = histogram(color(span,span,0),256,0,255);\r\nhist(span,1) = histogram(color(span,span,1),256,0,255);\r\nhist(span,2) = histogram(color(span,span,2),256,0,255);\r\n</pre>\r\n<div style=\"text-align: center;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=1893315835\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>array threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLet\'s go through what\'s going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that, we set the pixels that are less than threshold to 0 and the rest of them to 255 <code>255.0f*(ret_val&gt;thresholdValue)</code>. If you are interested in knowing about what other element wise operations you can do on the objects of type array, you can find the details <a href=\"http://www.sandbox.arrayfire.com/docs/group__array__operator.htm\">here</a>.\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img class=\"size-medium wp-image-6322\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img class=\"size-medium wp-image-6313\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>/**\r\n * Note:\r\n * suffix B indicates subset of all graylevels before current gray level\r\n * suffix F indicates subset of all gray levels after current gray level\r\n */\r\narray otsu(const array&amp; in)\r\n{\r\n    array gray;\r\n    int channels = in.dims(2);\r\n    if (channels&gt;1)\r\n        gray  = colorspace(in,af_gray,af_rgb);\r\n    else\r\n        gray  = in;\r\n    unsigned total = gray.elements();\r\n    array hist  = histogram(gray,256,0.0f,255.0f);\r\n    array wts   = array(seq(256));\r\n\r\n    array wtB   = accum(hist);\r\n    array wtF   = total - wtB;\r\n    array sumB  = accum(wts*hist);\r\n    array meanB = sumB/wtB;\r\n    array meanF = (sumB(255)-sumB) / wtF;\r\n    array mDiff = meanB-meanF;\r\n\r\n    array interClsVar= wtB * wtF * mDiff * mDiff;\r\n    float max        = af::max(interClsVar);\r\n    float threshold2 = where(interClsVar==max).scalar();\r\n    array threshIdx  = where(interClsVar&gt;=max);\r\n    float threshold1 = threshIdx.elements()&gt;0 ? threshIdx.scalar() : 0.0f;\r\n\r\n    return threshold(gray,(threshold1+threshold2)/2.0f);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img class=\"size-thumbnail wp-image-6312\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" /></a> Input image with Bimodal histogram[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img class=\"size-thumbnail wp-image-6333\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img class=\"size-thumbnail wp-image-6332\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" /></a> Otsu threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively thresholded. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>array iterativeThreshold(const array &amp;in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean(ret_val), prevT=0.0f;\r\n    do {\r\n        array region1 = (ret_val &gt; T)*ret_val;\r\n        array region2 = (ret_val &lt;= T)*ret_val;\r\n        float r1_avg  = mean(region1);\r\n        float r2_avg  = mean(region2);\r\n        prevT = T;\r\n        T = (r1_avg+r2_avg)/2.0f;        \r\n    } while (abs(T-prevT)&gt;0.01f);\r\n    return threshold(ret_val,T);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img class=\"size-thumbnail wp-image-6326\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img class=\"size-thumbnail wp-image-6328\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" /></a> Otsu threhsold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img class=\"size-thumbnail wp-image-6327\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" /></a> Iterative threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is thresholded using a value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference. The algorithm essentially follows theses main steps\r\n<ol>\r\n	<li>Convert image to gray scale if required</li>\r\n	<li>Convolve the gray scale image using the local operator</li>\r\n	<li>Take a difference between the convolved image and gray scale image</li>\r\n	<li>Threshold the difference image using constant</li>\r\n	<li>Invert the thresholded image and return the result</li>\r\n</ol>\r\n<pre>typedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &amp;in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff&gt;constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = 255.f*(diff&gt;constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff&gt;constnt);\r\n    }\r\n    ret_val = 255.f - ret_val;\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img class=\"size-medium wp-image-6329\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img class=\"size-medium wp-image-6309\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img class=\"size-medium wp-image-6310\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Minimum &amp; Maximum as local operator[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img class=\"size-medium wp-image-6308\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on its three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &amp;input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth100) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)&gt;1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot &lt; 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img class=\"size-medium wp-image-6319\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" /></a> Emboss with low elevation angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img class=\"size-medium wp-image-6316\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" /></a> Emboss with high elevation value[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img class=\"size-medium wp-image-6317\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with low azimuth angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img class=\"size-medium wp-image-6314\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with high azimuth angle[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img class=\"size-medium wp-image-6318\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" /></a> Emboss with low depth value[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img class=\"size-medium wp-image-6315\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" /></a> Emboss with high depth value[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-13 18:54:16','2014-08-13 18:54:16','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6416,17729,'2014-08-13 18:57:44','2014-08-13 18:57:44','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n	<li>Image Histogram</li>\r\n	<li>Simple Binary Theshold</li>\r\n	<li>Otsu Threshold</li>\r\n	<li>Iterative Threshold</li>\r\n	<li>Adaptive Binary Threshold</li>\r\n	<li>Emboss Filter</li>\r\n</ul>\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n<h4>Image Histogram</h4>\r\nWe have a built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>. The input image was converted to gray scale before histogram calculation as our histogram implementation works for vector and 2D matrices only.\r\n<div style=\"text-align: center;\">\r\n<div style=\"vertical-align: top;\">\r\n\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img class=\"size-medium wp-image-6311\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"vertical-align: bottom;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n</div>\r\nIn case, you need histogram for all three channels of a color image, you can do it using the following four line code stub.\r\n<pre>array color = loadimage(\"\",true); // last parameter is to indicate that you would like \r\n                                             // array to have all channels of the image\r\narray hist(256,color.dims(2)); // 2nd dimension is our channel dimension\r\n                               // ArrayFire stores channels as independent slices currently.\r\nhist(span,0) = histogram(color(span,span,0),256,0,255);\r\nhist(span,1) = histogram(color(span,span,1),256,0,255);\r\nhist(span,2) = histogram(color(span,span,2),256,0,255);\r\n</pre>\r\n<div style=\"text-align: center;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=1893315835\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>array threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLet\'s go through what\'s going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that, we set the pixels that are less than threshold to 0 and the rest of them to 255 <code>255.0f*(ret_val&gt;thresholdValue)</code>. If you are interested in knowing about what other element wise operations you can do on the objects of type array, you can find the details <a href=\"http://www.sandbox.arrayfire.com/docs/group__array__operator.htm\">here</a>.\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img class=\"size-medium wp-image-6322\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img class=\"size-medium wp-image-6313\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>/**\r\n * Note:\r\n * suffix B indicates subset of all graylevels before current gray level\r\n * suffix F indicates subset of all gray levels after current gray level\r\n */\r\narray otsu(const array& in)\r\n{\r\n    array gray;\r\n    int channels = in.dims(2);\r\n    if (channels>1)\r\n        gray  = colorspace(in,af_gray,af_rgb);\r\n    else\r\n        gray  = in;\r\n    unsigned total = gray.elements();\r\n    array hist  = histogram(gray,256,0.0f,255.0f);\r\n    array wts   = array(seq(256));\r\n\r\n    array wtB   = accum(hist);\r\n    array wtF   = total - wtB;\r\n    array sumB  = accum(wts*hist);\r\n    array meanB = sumB/wtB;\r\n    array meanF = (sumB(255)-sumB) / wtF;\r\n    array mDiff = meanB-meanF;\r\n\r\n    array interClsVar= wtB * wtF * mDiff * mDiff;\r\n    float max        = af::max(interClsVar);\r\n    float threshold2 = where(interClsVar==max).scalar();\r\n    array threshIdx  = where(interClsVar>=max);\r\n    float threshold1 = threshIdx.elements()>0 ? threshIdx.scalar() : 0.0f;\r\n\r\n    return threshold(gray,(threshold1+threshold2)/2.0f);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img class=\"size-thumbnail wp-image-6312\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" /></a> Input image with Bimodal histogram[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img class=\"size-thumbnail wp-image-6333\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img class=\"size-thumbnail wp-image-6332\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" /></a> Otsu threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively thresholded. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>array iterativeThreshold(const array &amp;in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean(ret_val), prevT=0.0f;\r\n    do {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean(region1);\r\n        float r2_avg  = mean(region2);\r\n        prevT = T;\r\n        T = (r1_avg+r2_avg)/2.0f;        \r\n    } while (abs(T-prevT)>0.01f);\r\n    return threshold(ret_val,T);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img class=\"size-thumbnail wp-image-6326\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img class=\"size-thumbnail wp-image-6328\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" /></a> Otsu threhsold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img class=\"size-thumbnail wp-image-6327\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" /></a> Iterative threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is thresholded using a value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference. The algorithm essentially follows theses main steps\r\n<ol>\r\n	<li>Convert image to gray scale if required</li>\r\n	<li>Convolve the gray scale image using the local operator</li>\r\n	<li>Take a difference between the convolved image and gray scale image</li>\r\n	<li>Threshold the difference image using constant</li>\r\n	<li>Invert the thresholded image and return the result</li>\r\n</ol>\r\n<pre>typedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &amp;in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - ret_val;\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img class=\"size-medium wp-image-6329\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img class=\"size-medium wp-image-6309\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img class=\"size-medium wp-image-6310\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Minimum &amp; Maximum as local operator[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img class=\"size-medium wp-image-6308\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on its three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &amp;input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth>100 || depth<1) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img class=\"size-medium wp-image-6319\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" /></a> Emboss with low elevation angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img class=\"size-medium wp-image-6316\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" /></a> Emboss with high elevation value[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img class=\"size-medium wp-image-6317\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with low azimuth angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img class=\"size-medium wp-image-6314\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with high azimuth angle[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img class=\"size-medium wp-image-6318\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" /></a> Emboss with low depth value[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img class=\"size-medium wp-image-6315\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" /></a> Emboss with high depth value[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-13 18:57:44','2014-08-13 18:57:44','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6417,17729,'2014-08-13 19:00:27','2014-08-13 19:00:27','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n	<li>Image Histogram</li>\r\n	<li>Simple Binary Theshold</li>\r\n	<li>Otsu Threshold</li>\r\n	<li>Iterative Threshold</li>\r\n	<li>Adaptive Binary Threshold</li>\r\n	<li>Emboss Filter</li>\r\n</ul>\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n<h4>Image Histogram</h4>\r\nWe have a built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>. The input image was converted to gray scale before histogram calculation as our histogram implementation works for vector and 2D matrices only.\r\n<div style=\"text-align: center;\">\r\n<div style=\"vertical-align: top;\">\r\n\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img class=\"size-medium wp-image-6311\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"vertical-align: bottom;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n</div>\r\nIn case, you need histogram for all three channels of a color image, you can do it using the following four line code stub.\r\n<pre>array color = loadimage(\"\",true); // last parameter is to indicate that you would like \r\n                                             // array to have all channels of the image\r\narray hist(256,color.dims(2)); // 2nd dimension is our channel dimension\r\n                               // ArrayFire stores channels as independent slices currently.\r\nhist(span,0) = histogram(color(span,span,0),256,0,255);\r\nhist(span,1) = histogram(color(span,span,1),256,0,255);\r\nhist(span,2) = histogram(color(span,span,2),256,0,255);\r\n</pre>\r\n<div style=\"text-align: center;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=1893315835\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>array threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLet\'s go through what\'s going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that, we set the pixels that are less than threshold to 0 and the rest of them to 255 <code>255.0f*(ret_val&gt;thresholdValue)</code>. If you are interested in knowing about what other element wise operations you can do on the objects of type array, you can find the details <a href=\"http://www.sandbox.arrayfire.com/docs/group__array__operator.htm\">here</a>.\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img class=\"size-medium wp-image-6322\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img class=\"size-medium wp-image-6313\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>/**\r\n * Note:\r\n * suffix B indicates subset of all graylevels before current gray level\r\n * suffix F indicates subset of all gray levels after current gray level\r\n */\r\narray otsu(const array& in)\r\n{\r\n    array gray;\r\n    int channels = in.dims(2);\r\n    if (channels>1)\r\n        gray  = colorspace(in,af_gray,af_rgb);\r\n    else\r\n        gray  = in;\r\n    unsigned total = gray.elements();\r\n    array hist  = histogram(gray,256,0.0f,255.0f);\r\n    array wts   = array(seq(256));\r\n\r\n    array wtB   = accum(hist);\r\n    array wtF   = total - wtB;\r\n    array sumB  = accum(wts*hist);\r\n    array meanB = sumB/wtB;\r\n    array meanF = (sumB(255)-sumB) / wtF;\r\n    array mDiff = meanB-meanF;\r\n\r\n    array interClsVar= wtB * wtF * mDiff * mDiff;\r\n    float max        = af::max(interClsVar);\r\n    float threshold2 = where(interClsVar==max).scalar();\r\n    array threshIdx  = where(interClsVar>=max);\r\n    float threshold1 = threshIdx.elements()>0 ? threshIdx.scalar<float>() : 0.0f;\r\n\r\n    return threshold(gray,(threshold1+threshold2)/2.0f);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img class=\"size-thumbnail wp-image-6312\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" /></a> Input image with Bimodal histogram[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img class=\"size-thumbnail wp-image-6333\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img class=\"size-thumbnail wp-image-6332\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" /></a> Otsu threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively thresholded. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>array iterativeThreshold(const array &amp;in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean(ret_val), prevT=0.0f;\r\n    do {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean(region1);\r\n        float r2_avg  = mean(region2);\r\n        prevT = T;\r\n        T = (r1_avg+r2_avg)/2.0f;        \r\n    } while (abs(T-prevT)>0.01f);\r\n    return threshold(ret_val,T);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img class=\"size-thumbnail wp-image-6326\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img class=\"size-thumbnail wp-image-6328\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" /></a> Otsu threhsold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img class=\"size-thumbnail wp-image-6327\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" /></a> Iterative threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is thresholded using a value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference. The algorithm essentially follows theses main steps\r\n<ol>\r\n	<li>Convert image to gray scale if required</li>\r\n	<li>Convolve the gray scale image using the local operator</li>\r\n	<li>Take a difference between the convolved image and gray scale image</li>\r\n	<li>Threshold the difference image using constant</li>\r\n	<li>Invert the thresholded image and return the result</li>\r\n</ol>\r\n<pre>typedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &amp;in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - ret_val;\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img class=\"size-medium wp-image-6329\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img class=\"size-medium wp-image-6309\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img class=\"size-medium wp-image-6310\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Minimum &amp; Maximum as local operator[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img class=\"size-medium wp-image-6308\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on its three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth>100 || depth<1) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img class=\"size-medium wp-image-6319\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" /></a> Emboss with low elevation angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img class=\"size-medium wp-image-6316\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" /></a> Emboss with high elevation value[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img class=\"size-medium wp-image-6317\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with low azimuth angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img class=\"size-medium wp-image-6314\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with high azimuth angle[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img class=\"size-medium wp-image-6318\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" /></a> Emboss with low depth value[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img class=\"size-medium wp-image-6315\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" /></a> Emboss with high depth value[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-13 19:00:27','2014-08-13 19:00:27','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6418,17729,'2014-08-13 19:01:44','2014-08-13 19:01:44','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n	<li>Image Histogram</li>\r\n	<li>Simple Binary Theshold</li>\r\n	<li>Otsu Threshold</li>\r\n	<li>Iterative Threshold</li>\r\n	<li>Adaptive Binary Threshold</li>\r\n	<li>Emboss Filter</li>\r\n</ul>\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n<h4>Image Histogram</h4>\r\nWe have a built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>. The input image was converted to gray scale before histogram calculation as our histogram implementation works for vector and 2D matrices only.\r\n<div style=\"text-align: center;\">\r\n<div style=\"vertical-align: top;\">\r\n\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img class=\"size-medium wp-image-6311\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"vertical-align: bottom;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n</div>\r\nIn case, you need histogram for all three channels of a color image, you can do it using the following four line code stub.\r\n<pre>array color = loadimage(\"\",true); // last parameter is to indicate that you would like \r\n                                             // array to have all channels of the image\r\narray hist(256,color.dims(2)); // 2nd dimension is our channel dimension\r\n                               // ArrayFire stores channels as independent slices currently.\r\nhist(span,0) = histogram(color(span,span,0),256,0,255);\r\nhist(span,1) = histogram(color(span,span,1),256,0,255);\r\nhist(span,2) = histogram(color(span,span,2),256,0,255);\r\n</pre>\r\n<div style=\"text-align: center;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=1893315835\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>array threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLet\'s go through what\'s going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that, we set the pixels that are less than threshold to 0 and the rest of them to 255 <code>255.0f*(ret_val&gt;thresholdValue)</code>. If you are interested in knowing about what other element wise operations you can do on the objects of type array, you can find the details <a href=\"http://www.sandbox.arrayfire.com/docs/group__array__operator.htm\">here</a>.\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img class=\"size-medium wp-image-6322\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img class=\"size-medium wp-image-6313\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>/**\r\n * Note:\r\n * suffix B indicates subset of all graylevels before current gray level\r\n * suffix F indicates subset of all gray levels after current gray level\r\n */\r\narray otsu(const array& in)\r\n{\r\n    array gray;\r\n    int channels = in.dims(2);\r\n    if (channels>1)\r\n        gray  = colorspace(in,af_gray,af_rgb);\r\n    else\r\n        gray  = in;\r\n    unsigned total = gray.elements();\r\n    array hist  = histogram(gray,256,0.0f,255.0f);\r\n    array wts   = array(seq(256));\r\n\r\n    array wtB   = accum(hist);\r\n    array wtF   = total - wtB;\r\n    array sumB  = accum(wts*hist);\r\n    array meanB = sumB/wtB;\r\n    array meanF = (sumB(255)-sumB) / wtF;\r\n    array mDiff = meanB-meanF;\r\n\r\n    array interClsVar= wtB * wtF * mDiff * mDiff;\r\n    float max        = af::max(interClsVar);\r\n    float threshold2 = where(interClsVar==max).scalar();\r\n    array threshIdx  = where(interClsVar>=max);\r\n    float threshold1 = threshIdx.elements()>0 ? threshIdx.scalar<float>() : 0.0f;\r\n\r\n    return threshold(gray,(threshold1+threshold2)/2.0f);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img class=\"size-thumbnail wp-image-6312\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" /></a> Input image with Bimodal histogram[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img class=\"size-thumbnail wp-image-6333\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img class=\"size-thumbnail wp-image-6332\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" /></a> Otsu threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively thresholded. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>array iterativeThreshold(const array &amp;in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean(ret_val), prevT=0.0f;\r\n    do {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean(region1);\r\n        float r2_avg  = mean(region2);\r\n        prevT = T;\r\n        T = (r1_avg+r2_avg)/2.0f;        \r\n    } while (abs(T-prevT)>0.01f);\r\n    return threshold(ret_val,T);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img class=\"size-thumbnail wp-image-6326\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img class=\"size-thumbnail wp-image-6328\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" /></a> Otsu threhsold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img class=\"size-thumbnail wp-image-6327\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" /></a> Iterative threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is thresholded using a value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference. The algorithm essentially follows theses main steps\r\n<ol>\r\n	<li>Convert image to gray scale if required</li>\r\n	<li>Convolve the gray scale image using the local operator</li>\r\n	<li>Take a difference between the convolved image and gray scale image</li>\r\n	<li>Threshold the difference image using constant</li>\r\n	<li>Invert the thresholded image and return the result</li>\r\n</ol>\r\n<pre>typedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - ret_val;\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img class=\"size-medium wp-image-6329\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img class=\"size-medium wp-image-6309\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img class=\"size-medium wp-image-6310\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Minimum &amp; Maximum as local operator[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img class=\"size-medium wp-image-6308\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on its three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth>100 || depth<1) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img class=\"size-medium wp-image-6319\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" /></a> Emboss with low elevation angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img class=\"size-medium wp-image-6316\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" /></a> Emboss with high elevation value[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img class=\"size-medium wp-image-6317\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with low azimuth angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img class=\"size-medium wp-image-6314\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with high azimuth angle[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img class=\"size-medium wp-image-6318\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" /></a> Emboss with low depth value[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img class=\"size-medium wp-image-6315\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" /></a> Emboss with high depth value[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-13 19:01:44','2014-08-13 19:01:44','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6419,17729,'2014-08-13 19:02:17','2014-08-13 19:02:17','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n	<li>Image Histogram</li>\r\n	<li>Simple Binary Theshold</li>\r\n	<li>Otsu Threshold</li>\r\n	<li>Iterative Threshold</li>\r\n	<li>Adaptive Binary Threshold</li>\r\n	<li>Emboss Filter</li>\r\n</ul>\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n<h4>Image Histogram</h4>\r\nWe have a built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>. The input image was converted to gray scale before histogram calculation as our histogram implementation works for vector and 2D matrices only.\r\n<div style=\"text-align: center;\">\r\n<div style=\"vertical-align: top;\">\r\n\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img class=\"size-medium wp-image-6311\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"vertical-align: bottom;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n</div>\r\nIn case, you need histogram for all three channels of a color image, you can do it using the following four line code stub.\r\n<pre>array color = loadimage(\"\",true); // last parameter is to indicate that you would like \r\n                                             // array to have all channels of the image\r\narray hist(256,color.dims(2)); // 2nd dimension is our channel dimension\r\n                               // ArrayFire stores channels as independent slices currently.\r\nhist(span,0) = histogram(color(span,span,0),256,0,255);\r\nhist(span,1) = histogram(color(span,span,1),256,0,255);\r\nhist(span,2) = histogram(color(span,span,2),256,0,255);\r\n</pre>\r\n<div style=\"text-align: center;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=1893315835\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>array threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLet\'s go through what\'s going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that, we set the pixels that are less than threshold to 0 and the rest of them to 255 <code>255.0f*(ret_val&gt;thresholdValue)</code>. If you are interested in knowing about what other element wise operations you can do on the objects of type array, you can find the details <a href=\"http://www.sandbox.arrayfire.com/docs/group__array__operator.htm\">here</a>.\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img class=\"size-medium wp-image-6322\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img class=\"size-medium wp-image-6313\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>/**\r\n * Note:\r\n * suffix B indicates subset of all graylevels before current gray level\r\n * suffix F indicates subset of all gray levels after current gray level\r\n */\r\narray otsu(const array& in)\r\n{\r\n    array gray;\r\n    int channels = in.dims(2);\r\n    if (channels>1)\r\n        gray  = colorspace(in,af_gray,af_rgb);\r\n    else\r\n        gray  = in;\r\n    unsigned total = gray.elements();\r\n    array hist  = histogram(gray,256,0.0f,255.0f);\r\n    array wts   = array(seq(256));\r\n\r\n    array wtB   = accum(hist);\r\n    array wtF   = total - wtB;\r\n    array sumB  = accum(wts*hist);\r\n    array meanB = sumB/wtB;\r\n    array meanF = (sumB(255)-sumB) / wtF;\r\n    array mDiff = meanB-meanF;\r\n\r\n    array interClsVar= wtB * wtF * mDiff * mDiff;\r\n    float max        = af::max(interClsVar);\r\n    float threshold2 = where(interClsVar==max).scalar();\r\n    array threshIdx  = where(interClsVar>=max);\r\n    float threshold1 = threshIdx.elements()>0 ? threshIdx.scalar<float>() : 0.0f;\r\n\r\n    return threshold(gray,(threshold1+threshold2)/2.0f);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img class=\"size-thumbnail wp-image-6312\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" /></a> Input image with Bimodal histogram[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img class=\"size-thumbnail wp-image-6333\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img class=\"size-thumbnail wp-image-6332\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" /></a> Otsu threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively thresholded. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>array iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean(ret_val), prevT=0.0f;\r\n    do {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean(region1);\r\n        float r2_avg  = mean(region2);\r\n        prevT = T;\r\n        T = (r1_avg+r2_avg)/2.0f;        \r\n    } while (abs(T-prevT)>0.01f);\r\n    return threshold(ret_val,T);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img class=\"size-thumbnail wp-image-6326\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img class=\"size-thumbnail wp-image-6328\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" /></a> Otsu threhsold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img class=\"size-thumbnail wp-image-6327\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" /></a> Iterative threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is thresholded using a value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference. The algorithm essentially follows theses main steps\r\n<ol>\r\n	<li>Convert image to gray scale if required</li>\r\n	<li>Convolve the gray scale image using the local operator</li>\r\n	<li>Take a difference between the convolved image and gray scale image</li>\r\n	<li>Threshold the difference image using constant</li>\r\n	<li>Invert the thresholded image and return the result</li>\r\n</ol>\r\n<pre>typedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - ret_val;\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img class=\"size-medium wp-image-6329\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img class=\"size-medium wp-image-6309\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img class=\"size-medium wp-image-6310\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Minimum &amp; Maximum as local operator[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img class=\"size-medium wp-image-6308\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on its three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth>100 || depth<1) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img class=\"size-medium wp-image-6319\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" /></a> Emboss with low elevation angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img class=\"size-medium wp-image-6316\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" /></a> Emboss with high elevation value[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img class=\"size-medium wp-image-6317\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with low azimuth angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img class=\"size-medium wp-image-6314\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with high azimuth angle[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img class=\"size-medium wp-image-6318\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" /></a> Emboss with low depth value[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img class=\"size-medium wp-image-6315\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" /></a> Emboss with high depth value[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-13 19:02:17','2014-08-13 19:02:17','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6420,17729,'2014-08-13 19:02:58','2014-08-13 19:02:58','Today, we will be doing the third post in our series <em>Image editing using ArrayFire</em>. References to old posts are available below.\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire/\">Part 1</a>\r\n* <a href=\"http://sandbox.arrayfire.com/image-editing-using-arrayfire-part-2/\">Part 2</a>\r\n\r\nIn this post, we will be looking at the following operations.\r\n<ul>\r\n	<li>Image Histogram</li>\r\n	<li>Simple Binary Theshold</li>\r\n	<li>Otsu Threshold</li>\r\n	<li>Iterative Threshold</li>\r\n	<li>Adaptive Binary Threshold</li>\r\n	<li>Emboss Filter</li>\r\n</ul>\r\nToday\'s post will be mostly dominated by different types of threshold operations we can achieve using ArrayFire.\r\n<h4>Image Histogram</h4>\r\nWe have a built-in function in ArrayFire that creates a <a href=\"http://www.sandbox.arrayfire.com/docs/group__image__func__cpp__histogram.htm\">histogram</a>. The input image was converted to gray scale before histogram calculation as our histogram implementation works for vector and 2D matrices only.\r\n<div style=\"text-align: center;\">\r\n<div style=\"vertical-align: top;\">\r\n\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow.jpg\"><img class=\"size-medium wp-image-6311\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/arrow-300x168.jpg\" alt=\"Input\" width=\"300\" height=\"168\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"vertical-align: bottom;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=928171252\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n</div>\r\nIn case, you need histogram for all three channels of a color image, you can do it using the following four line code stub.\r\n<pre>array color = loadimage(\"\",true); // last parameter is to indicate that you would like \r\n                                             // array to have all channels of the image\r\narray hist(256,color.dims(2)); // 2nd dimension is our channel dimension\r\n                               // ArrayFire stores channels as independent slices currently.\r\nhist(span,0) = histogram(color(span,span,0),256,0,255);\r\nhist(span,1) = histogram(color(span,span,1),256,0,255);\r\nhist(span,2) = histogram(color(span,span,2),256,0,255);\r\n</pre>\r\n<div style=\"text-align: center;\"><iframe src=\"//docs.google.com/a/sandbox.arrayfire.com/spreadsheets/d/1mWvh5XftcIF4hkcf2gwe_7K0kKWngiayhqA7NOIKAPA/gviz/chartiframe?oid=1893315835\" width=\"600\" height=\"371\" frameborder=\"0\" scrolling=\"no\" seamless=\"\"></iframe></div>\r\n<h4>Simple Binary Threshold</h4>\r\nA simple threshold operation can be achieved very easily in ArrayFire using the awesome element wise operations. For this particular use case, we will use the greater than and less than operators.\r\n<pre>array threshold(const array &in, float thresholdValue)\r\n{\r\n    int channels = in.dims(2);\r\n    array ret_val= in.copy();\r\n    if (channels>1)\r\n        ret_val = colorspace(in,af_gray,af_rgb);\r\n    ret_val = 255.0f*(ret_val>thresholdValue);\r\n    return ret_val;\r\n}\r\n</pre>\r\nLet\'s go through what\'s going on in this function line by line. We initially check if the image has more than one channel and convert it to gray scale image if required. Following that, we set the pixels that are less than threshold to 0 and the rest of them to 255 <code>255.0f*(ret_val&gt;thresholdValue)</code>. If you are interested in knowing about what other element wise operations you can do on the objects of type array, you can find the details <a href=\"http://www.sandbox.arrayfire.com/docs/group__array__operator.htm\">here</a>.\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6322\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house.jpg\"><img class=\"size-medium wp-image-6322\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/house-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6313\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary.jpg\"><img class=\"size-medium wp-image-6313\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/binary-300x225.jpg\" alt=\"Simple binary threshold\" width=\"300\" height=\"225\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Otsu Threshold</h4>\r\nThe famous Otsu threshold method is very reliable in the case of images with bi-modal histograms. Otsu method calculates a global threshold value using the histogram of the image rather than working on the image itself. Since the histogram is only a array of 256 elements, we chose to do the threshold computation on CPU. ArrayFire is used to calculate the histogram and finally threshold the image using the threshold value computed by Otsu method. The image threshold operation reuses the simple threshold function discussed in the previous section. Below given is a comparison of simple binary threshold and Otsu threshold for your reference.\r\n<pre>/**\r\n * Note:\r\n * suffix B indicates subset of all graylevels before current gray level\r\n * suffix F indicates subset of all gray levels after current gray level\r\n */\r\narray otsu(const array &in)\r\n{\r\n    array gray;\r\n    int channels = in.dims(2);\r\n    if (channels>1)\r\n        gray  = colorspace(in,af_gray,af_rgb);\r\n    else\r\n        gray  = in;\r\n    unsigned total = gray.elements();\r\n    array hist  = histogram(gray,256,0.0f,255.0f);\r\n    array wts   = array(seq(256));\r\n\r\n    array wtB   = accum(hist);\r\n    array wtF   = total - wtB;\r\n    array sumB  = accum(wts*hist);\r\n    array meanB = sumB/wtB;\r\n    array meanF = (sumB(255)-sumB) / wtF;\r\n    array mDiff = meanB-meanF;\r\n\r\n    array interClsVar= wtB * wtF * mDiff * mDiff;\r\n    float max        = af::max(interClsVar);\r\n    float threshold2 = where(interClsVar==max).scalar();\r\n    array threshIdx  = where(interClsVar>=max);\r\n    float threshold1 = threshIdx.elements()>0 ? threshIdx.scalar<float>() : 0.0f;\r\n\r\n    return threshold(gray,(threshold1+threshold2)/2.0f);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6312\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal.jpg\"><img class=\"size-thumbnail wp-image-6312\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodal-150x150.jpg\" alt=\"Input image with Bimodal histogram\" width=\"150\" height=\"150\" /></a> Input image with Bimodal histogram[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6333\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary.jpg\"><img class=\"size-thumbnail wp-image-6333\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/simpleBinary-150x150.jpg\" alt=\"Simple binary threshold\" width=\"150\" height=\"150\" /></a> Simple binary threshold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6332\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary.jpg\"><img class=\"size-thumbnail wp-image-6332\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/bimodalBinary-150x150.jpg\" alt=\"Otsu threshold\" width=\"150\" height=\"150\" /></a> Otsu threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Iterative Threshold</h4>\r\nThis is a global threshold method where the input image is repetitively thresholded. In each iteration, threshold value is calculated from the previous step\'s result. In the first iteration, the threshold value is selected randomly. When the difference between two successive steps threshold is less than certain value, the algorithm exits the iterative loop and the last iteration\'s threshold value is used to threshold the original input image.\r\n<pre>array iterativeThreshold(const array &in)\r\n{\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    float T = mean(ret_val), prevT=0.0f;\r\n    do {\r\n        array region1 = (ret_val > T)*ret_val;\r\n        array region2 = (ret_val <= T)*ret_val;\r\n        float r1_avg  = mean(region1);\r\n        float r2_avg  = mean(region2);\r\n        prevT = T;\r\n        T = (r1_avg+r2_avg)/2.0f;        \r\n    } while (abs(T-prevT)>0.01f);\r\n    return threshold(ret_val,T);\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6326\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider.jpg\"><img class=\"size-thumbnail wp-image-6326\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spider-150x150.jpg\" alt=\"Input\" width=\"150\" height=\"150\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6328\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu.jpg\"><img class=\"size-thumbnail wp-image-6328\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_otsu-150x150.jpg\" alt=\"Otsu threhsold\" width=\"150\" height=\"150\" /></a> Otsu threhsold[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6327\" align=\"alignnone\" width=\"150\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter.jpg\"><img class=\"size-thumbnail wp-image-6327\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/spi_iter-150x150.jpg\" alt=\"Iterative threshold\" width=\"150\" height=\"150\" /></a> Iterative threshold[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Adaptive Binary Threshold</h4>\r\nThreshold methods are usually categorized into two types: global and variable. Global threshold methods have a single threshold value that helps classify the image pixels into two classes. Variable threshold is where local neighborhood properties of the current pixel are used to threshold that very pixel. Adaptive binary threshold is where every pixel is thresholded using a value that is computed using the pixel intensities from the spatial neighborhood of the current pixel. In the below implementation, we used the local operators such as Mean, Median and Minimum &amp; Maximum to calculate the pixel threshold from local neighborhood. Threshold output for each local operator mentioned above are provided below for your reference. The algorithm essentially follows theses main steps\r\n<ol>\r\n	<li>Convert image to gray scale if required</li>\r\n	<li>Convolve the gray scale image using the local operator</li>\r\n	<li>Take a difference between the convolved image and gray scale image</li>\r\n	<li>Threshold the difference image using constant</li>\r\n	<li>Invert the thresholded image and return the result</li>\r\n</ol>\r\n<pre>typedef enum {\r\n    MEAN=0,\r\n    MEDIAN,\r\n    MINMAX_AVG\r\n} LocalThresholdType;\r\n\r\narray adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt)\r\n{\r\n    int wr = window_size;\r\n    array ret_val = colorspace(in,af_gray,af_rgb);\r\n    if (kind==MEAN) {\r\n        array wind = constant(1,wr,wr)/(wr*wr);\r\n        array mean = convolve(ret_val,wind);\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MEDIAN) {\r\n        array medf = medfilt(ret_val,wr,wr);\r\n        array diff = medf - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    } else if (kind==MINMAX_AVG) {\r\n        array minf = minfilt(ret_val,wr,wr);\r\n        array maxf = maxfilt(ret_val,wr,wr);\r\n        array mean = (minf+maxf)/2.0f;\r\n        array diff = mean - ret_val;\r\n        ret_val    = 255.f*(diff>constnt);\r\n    }\r\n    ret_val = 255.f - ret_val;\r\n    return ret_val;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6329\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku.jpg\"><img class=\"size-medium wp-image-6329\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/sudoku-300x225.jpg\" alt=\"Input\" width=\"300\" height=\"225\" /></a> Input[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6309\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed.jpg\"><img class=\"size-medium wp-image-6309\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmed-300x225.jpg\" alt=\"Adaptive Threshold with Median as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Median as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6310\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma.jpg\"><img class=\"size-medium wp-image-6310\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmma-300x225.jpg\" alt=\"Adaptive Threshold with Minimum &amp; Maximum as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Minimum &amp; Maximum as local operator[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6308\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean.jpg\"><img class=\"size-medium wp-image-6308\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/adapmean-300x225.jpg\" alt=\"Adaptive Threshold with Mean as local operator\" width=\"300\" height=\"225\" /></a> Adaptive Threshold with Mean as local operator[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Emboss Filter</h4>\r\nThe emboss function is tailored after the emboss filter provided in GIMP, an open source image editing software. The final outcome of emboss function is based on its three input parameters: azimuth, elevation &amp; depth. The code and the sample outputs of emboss function are provided below.\r\n<pre>/**\r\n * azimuth range is [0-360]\r\n * elevation range is [0-180]\r\n * depth range is [1-100]\r\n * Note: this function has been tailored after\r\n * the emboss implementation in GIMP editor\r\n **/\r\narray emboss(const array &input, float azimuth, float elevation, float depth)\r\n{\r\n    if (depth>100 || depth<1) {\r\n        printf(\"Depth should be in the range of 1-100\");\r\n        return input;\r\n    }\r\n    static float x[3] = {-1,0,1};\r\n    static array hg(3,x);\r\n    static array vg = hg.T();\r\n\r\n    array in = input;\r\n    if (in.dims(2)>1)\r\n        in = colorspace(input,af_gray,af_rgb);\r\n    else\r\n        in = input;\r\n\r\n    // convert angles to radians\r\n    float phi   = elevation*af::Pi/180.0f;\r\n    float theta = azimuth*af::Pi/180.0f;\r\n\r\n    // compute light pos in cartesian coordinates\r\n    // and scale with maximum intensity\r\n    // phi will effect the amount of we intend to put\r\n    // on a pixel\r\n    float pos[3];\r\n    pos[0] = 255.99f * cos(phi)*cos(theta);\r\n    pos[1] = 255.99f * cos(phi)*sin(theta);\r\n    pos[2] = 255.99f * sin(phi);\r\n\r\n    // compute gradient vector\r\n    array gx = filter(in,vg);\r\n    array gy = filter(in,hg);\r\n\r\n    // create a array from depth value which \r\n    // is of same dimensions as gradient vector array\r\n    float pxlz  = (6*255.0f)/depth;\r\n    array zdepth= constant(pxlz,gx.dims());\r\n    // dot product of light position vector and gradient vector\r\n    array vdot  = gx*pos[0] + gy*pos[1] + pxlz*pos[2];\r\n    // divide dot product by gradient vector magnitude to\r\n    // calculate scalar projection value\r\n    array norm  = vdot/sqrt(gx*gx+gy*gy+zdepth*zdepth);\r\n    // compute shading condition\r\n    array outwd = vdot < 0.0f;\r\n    // choose shading color based on the above condition\r\n    array color = (1-outwd) * norm;\r\n    return color;\r\n}\r\n</pre>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel.jpg\"><img class=\"size-medium wp-image-6319\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_lel-300x168.jpg\" alt=\"Emboss with low elevation angle\" width=\"300\" height=\"168\" /></a> Emboss with low elevation angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6316\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel.jpg\"><img class=\"size-medium wp-image-6316\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hel-300x168.jpg\" alt=\"Emboss with high elevation value\" width=\"300\" height=\"168\" /></a> Emboss with high elevation value[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6317\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz.jpg\"><img class=\"size-medium wp-image-6317\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_laz-300x168.jpg\" alt=\"Emboss with low azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with low azimuth angle[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6314\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz.jpg\"><img class=\"size-medium wp-image-6314\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_haz-300x168.jpg\" alt=\"Emboss with high azimuth angle\" width=\"300\" height=\"168\" /></a> Emboss with high azimuth angle[/caption]\r\n\r\n</div>\r\n</div>\r\n<div style=\"text-align: center;\">\r\n<div style=\"display: inline-block; margin-right: 5px;\">\r\n\r\n[caption id=\"attachment_6318\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth.jpg\"><img class=\"size-medium wp-image-6318\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_ldepth-300x168.jpg\" alt=\"Emboss with low depth value\" width=\"300\" height=\"168\" /></a> Emboss with low depth value[/caption]\r\n\r\n</div>\r\n<div style=\"display: inline-block;\">\r\n\r\n[caption id=\"attachment_6315\" align=\"alignnone\" width=\"300\"]<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth.jpg\"><img class=\"size-medium wp-image-6315\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/07/emboss_hdepth-300x168.jpg\" alt=\"Emboss with high depth value\" width=\"300\" height=\"168\" /></a> Emboss with high depth value[/caption]\r\n\r\n</div>\r\n</div>\r\n<h4>Conclusion</h4>\r\nAll the functions from this post are updated and available through github repository located <a href=\"https://github.com/9prady9/wildfire\">here</a>.','Image editing using ArrayFire: Part 3','','inherit','open','open','','6334-revision-v1','','','2014-08-13 19:02:58','2014-08-13 19:02:58','',6334,'http://sandbox.arrayfire.com/6334-revision-v1/',0,'revision','',0),(6469,17728,'2014-08-18 10:29:29','2014-08-18 10:29:29','Why did I not know about this? It\'s like I just discovered the screw driver!\n\nOn Debian and variants (from <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s windows cross-compilation page</a>),\n<pre style=\"margin-bottom: 20px;\">sudo apt-get install mingw-w64\n\n# C\ni686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit\nx86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit\n\n# C++\ni686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit\nx86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit\n</pre>\n<img class=\"aligncenter\" style=\"margin-top: 20px;\" src=\"http://i.imgur.com/C4buo.gif\" alt=\"blown\" />\n\nGranted, this isn\'t a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I\'ve found that this approach makes it easy to get binaries out the door in a hurry when it\'s hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).\n\nI cover some quick solutions to the most common caveats I\'ve run into, below.\n<h2>Caveats</h2>\n<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>\nWhatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of <code>scale</code> can\'t be found on link,\n<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {\n  for (int i = 0; i < n; i++) X[i] = a * X[i];\n}\nvoid scale_ALL_the_things(float *A, int *B, unsigned n) {\n  scale(2.0, A, n);\n  scale(  3, B, n);\n}\n</pre>\nA horrible (but effective) solution I\'ve found is to push the compile along with a dead function containing references to the template instantiations that you need,\n<pre>void __force_compile() {\n  scale<float>(0, 0, NULL);\n  scale<int>(0, 0, NULL);\n}\n</pre>\n<h3>C/C++ Standard Library Dependencies</h3>\nWhen compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> is on clients\' systems. Therefore, you\'ll need to make sure clients have the Microsoft C Runtime installed to use your software.\n\nWhen compiling a C++ project, you <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you\'ll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.\n\nWhen shipping a C++ project, you\'ll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you\'re performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>. Note that you can have gcc include these libraries statically by including the flags, <code>-static-libgcc</code> and <code>-static-libstdc++</code>.\n<h3>External Dependencies</h3>\nIf your project depends on external libraries, you\'ll need them available on your Linux machine during your build. I give some quick notes for the case where you\'d like to use a pre-built (mingw) windows library and specific notes for Boost.\n\nNote that except for purely C external libraries, the libraries themselves must have been built with MinGW. The naming conventions of C++ symbols differ between MingGW and Visual Studio.\n\nGetting a MinGW build going for each project you might want to use is different. <a href=\"http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/\">tinc\'s cross compilation page</a> gives instructions for a few libraries that it requires. You\'ll need to consult the documentation on a project-by-project basis for each of your dependencies.\n<h4>Using a Prebuilt DLL From Windows (libpng)</h4>\n<a href=\"http://gnuwin32.sourceforge.net/packages/libpng.htm\">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href=\"http://gnuwin32.sourceforge.net/packages/zlib.htm\">zlib</a> since LibPNG depends on it, as well.\n\nTo build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL\'s on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,\n<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz\n</pre>\n<h4>MinGW and Boost</h4>\nI give notes on Boost, here, as it\'s a popular library and - since much of it is header-based - does not require a build before use in many instances.\n\nIf on Debian, you\'ll need a fresh copy of Boost. When building with Debian\'s stock version of Boost, MinGW complains of missing headers. Once you\'ve obtained Boost, you\'re ready to go,\n<pre>wget \'http://sourceforge.net/projects/boost/files/latest/download?source=files\' -O boost.tar.gz\ntar xzfp boost.tar.gz\nx86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe\n</pre>','Cross Compile to Windows From Linux','','inherit','open','open','','6297-autosave-v1','','','2014-08-18 10:29:29','2014-08-18 10:29:29','',6297,'http://sandbox.arrayfire.com/6297-autosave-v1/',0,'revision','',0),(6470,17728,'2014-08-18 13:43:52','2014-08-18 13:43:52','<p>At SIGGRAPH 2014 The Khronos Group announced, among other things, <a href=\"https://www.khronos.org/news/press/khronos-releases-spir-2.0-provisional-specification\">SPIR 2.0</a> provisional specification.\r\nThe release of SPIR 2.0 spec follows the release of <a href=\"https://www.khronos.org/news/press/khronos-releases-opencl-2.0\">OpenCL 2.0</a> spec last year.</p>\r\n\r\n<p>In this post, we would like to offer our take on SPIR 2.0 and what it means to OpenCL developers.</p>\r\n\r\n<h3>Feature Parity With OpenCL 2.0</h3>\r\n\r\n<p>SPIR 1.2 had feature parity with OpenCL 1.2. With 2.0, SPIR has feature parity with OpenCL 2.0. Here are a few new features that we find interesting.</p>\r\n\r\n<h5>Generic Address Space</h5>\r\n\r\n<blockquote>\r\n  <p>where functions can be written without specifying a named address space for arguments, especially useful for those arguments that are declared to be a pointer to a type, eliminating the need for multiple functions to be written for each named address space used in an application</p>\r\n</blockquote>\r\n\r\n<p>This greatly reduces code redundancy and increases code reusability. Many algorithms perform the same operations on  <code>__global</code> memory and <code>__local</code> memory at various points in the algorithm. A good example an algorithm that would benefit from this would be the parallel reduction algorithm.</p>\r\n\r\n<h5>Device Side Kernel Enqueue</h5>\r\n\r\n<blockquote>\r\n  <p>where device kernels can enqueue kernels to the same device with no host interaction, enabling flexible work scheduling paradigms and avoiding the need to transfer execution control and data between the device and host, often significantly offloading host processor bottlenecks</p>\r\n</blockquote>\r\n\r\n<p>While this sounds like a nice feature to have, we are skeptical about the performance benefits. The improvements in performance will be highly dependent on the platform specific implementation of the scheduler and may not provide reliable improvements across the board. This feature can increase the readability of  complex algorithms.</p>\r\n\r\n<h5>Pipes</h5>\r\n\r\n<blockquote>\r\n  <p>memory objects that store data organized as a FIFO. OpenCL 2.0 provides built-in functions for kernels to read from or write to a pipe, providing straightforward programming of pipe data structures that can be highly optimized by OpenCL implementers.</p>\r\n</blockquote>\r\n\r\n<p>Pipes are FIFO data structures that enable communication between two kernels being executed concurrently. This feature seems to be designed for architectures that support streaming data and will likely be inefficient on OpenCL capable GPUs.</p>\r\n\r\n<h3>SPIR Compiler and Tools</h3>\r\n\r\n<p>The Khronos group has also added <a href=\"https://github.com/KhronosGroup/SPIR\">SPIR compiler</a> and <a href=\"https://github.com/KhronosGroup/SPIR-Tools\">SPIR Tools</a> to their github page.</p>\r\n\r\n<blockquote>\r\n  <ul>\r\n<li>modified Clang which generates SPIR from OpenCL C kernel language device programs;</li>\r\n<li>SPIR module verifier, written in the form of an LLVM pass;</li>\r\n<li>SPIR built-ins name mangler, written as a standalone library and executable;</li>\r\n<li>header file containing definitions for all enumerated values in the SPIR specification.</li>\r\n</ul>\r\n</blockquote>\r\n\r\n<p>The SPIR compiler is a patched version of <code>clang</code> that compiles <code>OpenCL C</code> code into <code>SPIR</code>. <code>SPIR tools</code> repository enables the usage of OpenCL builtin functions in SPIR. We\'ll be exploring the SPIR compiler a lot more in a follow up post.</p>\r\n\r\n<h3>Future of SPIR</h3>\r\n\r\n<p>While it is encouraging to see continued development of SPIR, it is still an optional extension in OpenCL. AMD and Intel have supported SPIR since their OpenCL 1.2 implementations. NVIDIA has NVVM IR that may or may not be compatible with SPIR.</p>\r\n\r\n<p>OpenCL brought the portability across different architectures. Similarily, SPIR will bring portability across multiple programming languages. All the vendors would be doing themselves and the ecosystem a favor if they support SPIR and implemented their compute language of choice on top of it.</p>','OpenCL SPIR 2.0','','inherit','open','open','','6379-autosave-v1','','','2014-08-18 13:43:52','2014-08-18 13:43:52','',6379,'http://sandbox.arrayfire.com/6379-autosave-v1/',0,'revision','',0),(6471,17728,'2014-08-18 13:43:47','2014-08-18 13:43:47','<p>At SIGGRAPH 2014 The Khronos Group announced, among other things, <a href=\"https://www.khronos.org/news/press/khronos-releases-spir-2.0-provisional-specification\">SPIR 2.0</a> provisional specification.\r\nThe release of SPIR 2.0 spec follows the release of <a href=\"https://www.khronos.org/news/press/khronos-releases-opencl-2.0\">OpenCL 2.0</a> spec last year.</p>\r\n\r\n<p>In this post, we would like to offer our take on SPIR 2.0 and what it means to OpenCL developers.</p>\r\n\r\n<h3>Feature Parity With OpenCL 2.0</h3>\r\n\r\n<p>SPIR 1.2 had feature parity with OpenCL 1.2. With 2.0, SPIR has feature parity with OpenCL 2.0. Here are a few new features that we find interesting.</p>\r\n\r\n<h5>Generic Address Space</h5>\r\n\r\n<blockquote>\r\n  <p>where functions can be written without specifying a named address space for arguments, especially useful for those arguments that are declared to be a pointer to a type, eliminating the need for multiple functions to be written for each named address space used in an application</p>\r\n</blockquote>\r\n\r\n<p>This greatly reduces code redundancy and increases code reusability. Many algorithms perform the same operations on  <code>__global</code> memory and <code>__local</code> memory at various points in the algorithm. A good example an algorithm that would benefit from this would be the parallel reduction algorithm.</p>\r\n\r\n<h5>Device Side Kernel Enqueue</h5>\r\n\r\n<blockquote>\r\n  <p>where device kernels can enqueue kernels to the same device with no host interaction, enabling flexible work scheduling paradigms and avoiding the need to transfer execution control and data between the device and host, often significantly offloading host processor bottlenecks</p>\r\n</blockquote>\r\n\r\n<p>While this sounds like a nice feature to have, we are skeptical about the performance benefits. The improvements in performance will be highly dependent on the platform specific implementation of the scheduler and may not provide reliable improvements across the board. This feature can increase the readability of  complex algorithms.</p>\r\n\r\n<h5>Pipes</h5>\r\n\r\n<blockquote>\r\n  <p>memory objects that store data organized as a FIFO. OpenCL 2.0 provides built-in functions for kernels to read from or write to a pipe, providing straightforward programming of pipe data structures that can be highly optimized by OpenCL implementers.</p>\r\n</blockquote>\r\n\r\n<p>Pipes are FIFO data structures that enable communication between two kernels being executed concurrently. This feature seems to be designed for architectures that support streaming data and will likely be inefficient on OpenCL capable GPUs.</p>\r\n\r\n<h3>SPIR Compiler and Tools</h3>\r\n\r\n<p>The Khronos group has also added <a href=\"https://github.com/KhronosGroup/SPIR\">SPIR compiler</a> and <a href=\"https://github.com/KhronosGroup/SPIR-Tools\">SPIR Tools</a> to their github page.</p>\r\n\r\n<blockquote>\r\n  <ul>\r\n<li>modified Clang which generates SPIR from OpenCL C kernel language device programs;</li>\r\n<li>SPIR module verifier, written in the form of an LLVM pass;</li>\r\n<li>SPIR built-ins name mangler, written as a standalone library and executable;</li>\r\n<li>header file containing definitions for all enumerated values in the SPIR specification.</li>\r\n</ul>\r\n</blockquote>\r\n\r\n<p>The SPIR compiler is a patched version of <code>clang</code> that compiles <code>OpenCL C</code> code into <code>SPIR</code>. <code>SPIR tools</code> repository enables the usage of OpenCL builtin functions in SPIR. We\'ll be exploring the SPIR compiler a lot more in a follow up post.</p>\r\n\r\n<h3>Future of SPIR</h3>\r\n\r\n<p>While it is encouraging to see continued development of SPIR, it is still an optional extension in OpenCL. AMD and Intel have supported SPIR since their OpenCL 1.2 implementations. NVIDIA has NVVM IR that may or may not be compatible with SPIR.</p>\r\n\r\n<p>OpenCL brought the portability across different architectures. Similarily, SPIR will bring portability across multiple programming languages. All the vendors would be doing themselves and the ecosystem a favor if they support SPIR and implemented their compute language of choice on top of it.</p>','OpenCL SPIR 2.0','','inherit','open','open','','6379-revision-v1','','','2014-08-18 13:43:47','2014-08-18 13:43:47','',6379,'http://sandbox.arrayfire.com/6379-revision-v1/',0,'revision','',0),(6473,17796,'2014-08-18 16:46:00','2014-08-18 16:46:00','At SIGGRAPH 2014 The Khronos Group announced, among other things, the <a href=\"https://www.khronos.org/news/press/khronos-releases-spir-2.0-provisional-specification\">SPIR 2.0</a> provisional specification.\nThe release of SPIR 2.0 spec follows the release of <a href=\"https://www.khronos.org/news/press/khronos-releases-opencl-2.0\">OpenCL 2.0</a> spec last year.\n\nIn this post, we would like to offer our take on SPIR 2.0 and what it means to OpenCL developers.\n<h3>Feature Parity With OpenCL 2.0</h3>\nSPIR 1.2 had feature parity with OpenCL 1.2. With 2.0, SPIR has feature parity with OpenCL 2.0. Here are a few new features that we find interesting.\n<h5>Generic Address Space</h5>\n<blockquote>Where functions can be written without specifying a named address space for arguments, especially useful for those arguments that are declared to be a pointer to a type, eliminating the need for multiple functions to be written for each named address space used in an application.</blockquote>\nThis greatly reduces code redundancy and increases code reusability. Many algorithms perform the same operations on <code>__global</code> memory and <code>__local</code> memory at various points in the algorithm. A great example of an algorithm that benefits from this is parallel reduction algorithm.\n<h5>Device Side Kernel Enqueue</h5>\n<blockquote>Where device kernels can enqueue kernels to the same device with no host interaction, enabling flexible work scheduling paradigms and avoiding the need to transfer execution control and data between the device and host, often significantly offloading host processor bottlenecks.</blockquote>\nWhile this sounds like a nice feature to have, we are skeptical about the performance benefits. The improvements in performance will be highly dependent on the platform specific implementation of the scheduler and may not provide reliable improvements across the board. This feature can increase the readability of complex algorithms.\n<h5>Pipes</h5>\n<blockquote>memory objects that store data organized as a FIFO. OpenCL 2.0 provides built-in functions for kernels to read from or write to a pipe, providing straightforward programming of pipe data structures that can be highly optimized by OpenCL implementers.</blockquote>\nPipes are FIFO data structures that enable communication between two kernels being executed concurrently. This feature seems to be designed for architectures that support streaming data and will likely be inefficient on OpenCL capable GPUs.\n<h3>SPIR Compiler and Tools</h3>\nThe Khronos group also added the <a href=\"https://github.com/KhronosGroup/SPIR\">SPIR compiler</a> and <a href=\"https://github.com/KhronosGroup/SPIR-Tools\">SPIR Tools</a> to their github page.\n<blockquote>\n<ul>\n	<li>Modified Clang which generates SPIR from OpenCL C kernel language device programs;</li>\n	<li>SPIR module verifier, written in the form of an LLVM pass;</li>\n	<li>SPIR built-ins name mangler, written as a standalone library and executable;</li>\n	<li>header file containing definitions for all enumerated values in the SPIR specification.</li>\n</ul>\n</blockquote>\nThe SPIR compiler is a patched version of <code>clang</code> that compiles <code>OpenCL C</code> code into <code>SPIR</code>. <code>SPIR tools</code> repository enables the usage of OpenCL builtin functions in SPIR. We\'ll be exploring the SPIR compiler a lot more in a follow up post.\n<h3>Future of SPIR</h3>\nWhile it is encouraging to see continued development of SPIR, it is still an optional extension in OpenCL. AMD and Intel have supported SPIR since their OpenCL 1.2 implementations. NVIDIA has NVVM IR that may or may not be compatible with SPIR.\n\nOpenCL brought the portability across different architectures. Similarily, SPIR will bring portability across multiple programming languages. All the vendors would be doing themselves and the ecosystem a favor if they support SPIR and implemented their compute language of choice on top of it.','OpenCL SPIR 2.0','','inherit','open','open','','6379-autosave-v1','','','2014-08-18 16:46:00','2014-08-18 16:46:00','',6379,'http://sandbox.arrayfire.com/6379-autosave-v1/',0,'revision','',0),(6474,17796,'2014-08-18 16:46:11','2014-08-18 16:46:11','At SIGGRAPH 2014 The Khronos Group announced, among other things, the <a href=\"https://www.khronos.org/news/press/khronos-releases-spir-2.0-provisional-specification\">SPIR 2.0</a> provisional specification.\r\nThe release of SPIR 2.0 spec follows the release of <a href=\"https://www.khronos.org/news/press/khronos-releases-opencl-2.0\">OpenCL 2.0</a> spec last year.\r\n\r\nIn this post, we would like to offer our take on SPIR 2.0 and what it means to OpenCL developers.\r\n<h3>Feature Parity With OpenCL 2.0</h3>\r\nSPIR 1.2 had feature parity with OpenCL 1.2. With 2.0, SPIR has feature parity with OpenCL 2.0. Here are a few new features that we find interesting.\r\n<h5>Generic Address Space</h5>\r\n<blockquote>Where functions can be written without specifying a named address space for arguments, especially useful for those arguments that are declared to be a pointer to a type, eliminating the need for multiple functions to be written for each named address space used in an application.</blockquote>\r\nThis greatly reduces code redundancy and increases code reusability. Many algorithms perform the same operations on <code>__global</code> memory and <code>__local</code> memory at various points in the algorithm. A great example of an algorithm that benefits from this is parallel reduction algorithm.\r\n<h5>Device Side Kernel Enqueue</h5>\r\n<blockquote>Where device kernels can enqueue kernels to the same device with no host interaction, enabling flexible work scheduling paradigms and avoiding the need to transfer execution control and data between the device and host, often significantly offloading host processor bottlenecks.</blockquote>\r\nWhile this sounds like a nice feature to have, we are skeptical about the performance benefits. The improvements in performance will be highly dependent on the platform specific implementation of the scheduler and may not provide reliable improvements across the board. This feature can increase the readability of complex algorithms.\r\n<h5>Pipes</h5>\r\n<blockquote>memory objects that store data organized as a FIFO. OpenCL 2.0 provides built-in functions for kernels to read from or write to a pipe, providing straightforward programming of pipe data structures that can be highly optimized by OpenCL implementers.</blockquote>\r\nPipes are FIFO data structures that enable communication between two kernels being executed concurrently. This feature seems to be designed for architectures that support streaming data and will likely be inefficient on OpenCL capable GPUs.\r\n<h3>SPIR Compiler and Tools</h3>\r\nThe Khronos group also added the <a href=\"https://github.com/KhronosGroup/SPIR\">SPIR compiler</a> and <a href=\"https://github.com/KhronosGroup/SPIR-Tools\">SPIR Tools</a> to their github page.\r\n<blockquote>\r\n<ul>\r\n	<li>Modified Clang which generates SPIR from OpenCL C kernel language device programs;</li>\r\n	<li>SPIR module verifier, written in the form of an LLVM pass;</li>\r\n	<li>SPIR built-ins name mangler, written as a standalone library and executable;</li>\r\n	<li>header file containing definitions for all enumerated values in the SPIR specification.</li>\r\n</ul>\r\n</blockquote>\r\nThe SPIR compiler is a patched version of <code>clang</code> that compiles <code>OpenCL C</code> code into <code>SPIR</code>. <code>SPIR tools</code> repository enables the usage of OpenCL builtin functions in SPIR. We\'ll be exploring the SPIR compiler a lot more in a follow up post.\r\n<h3>Future of SPIR</h3>\r\nWhile it is encouraging to see continued development of SPIR, it is still an optional extension in OpenCL. AMD and Intel have supported SPIR since their OpenCL 1.2 implementations. NVIDIA has NVVM IR that may or may not be compatible with SPIR.\r\n\r\nOpenCL brought the portability across different architectures. Similarily, SPIR will bring portability across multiple programming languages. All the vendors would be doing themselves and the ecosystem a favor if they support SPIR and implemented their compute language of choice on top of it.','OpenCL SPIR 2.0','','inherit','open','open','','6379-revision-v1','','','2014-08-18 16:46:11','2014-08-18 16:46:11','',6379,'http://sandbox.arrayfire.com/6379-revision-v1/',0,'revision','',0),(6475,17728,'2014-08-18 16:48:32','2014-08-18 16:48:32','At SIGGRAPH 2014 The Khronos Group announced, among other things, the <a href=\"https://www.khronos.org/news/press/khronos-releases-spir-2.0-provisional-specification\">SPIR 2.0</a> provisional specification. The release of SPIR 2.0 spec follows the release of <a href=\"https://www.khronos.org/news/press/khronos-releases-opencl-2.0\">OpenCL 2.0</a> spec last year.\r\n\r\nIn this post, we would like to offer our take on SPIR 2.0 and what it means to OpenCL developers.\r\n<h3>Feature Parity With OpenCL 2.0</h3>\r\nSPIR 1.2 had feature parity with OpenCL 1.2. With 2.0, SPIR has feature parity with OpenCL 2.0. Here are a few new features that we find interesting.\r\n<h5>Generic Address Space</h5>\r\n<blockquote>Where functions can be written without specifying a named address space for arguments, especially useful for those arguments that are declared to be a pointer to a type, eliminating the need for multiple functions to be written for each named address space used in an application.</blockquote>\r\nThis greatly reduces code redundancy and increases code reusability. Many algorithms perform the same operations on <code>__global</code> memory and <code>__local</code> memory at various points in the algorithm. A great example of an algorithm that benefits from this is parallel reduction algorithm.\r\n<h5>Device Side Kernel Enqueue</h5>\r\n<blockquote>Where device kernels can enqueue kernels to the same device with no host interaction, enabling flexible work scheduling paradigms and avoiding the need to transfer execution control and data between the device and host, often significantly offloading host processor bottlenecks.</blockquote>\r\nWhile this sounds like a nice feature to have, we are skeptical about the performance benefits. The improvements in performance will be highly dependent on the platform specific implementation of the scheduler and may not provide reliable improvements across the board. This feature can increase the readability of complex algorithms.\r\n<h5>Pipes</h5>\r\n<blockquote>memory objects that store data organized as a FIFO. OpenCL 2.0 provides built-in functions for kernels to read from or write to a pipe, providing straightforward programming of pipe data structures that can be highly optimized by OpenCL implementers.</blockquote>\r\nPipes are FIFO data structures that enable communication between two kernels being executed concurrently. This feature seems to be designed for architectures that support streaming data and will likely be inefficient on OpenCL capable GPUs.\r\n<h3>SPIR Compiler and Tools</h3>\r\nThe Khronos group also added the <a href=\"https://github.com/KhronosGroup/SPIR\">SPIR compiler</a> and <a href=\"https://github.com/KhronosGroup/SPIR-Tools\">SPIR Tools</a> to their github page.\r\n<blockquote>\r\n<ul>\r\n	<li>Modified Clang which generates SPIR from OpenCL C kernel language device programs;</li>\r\n	<li>SPIR module verifier, written in the form of an LLVM pass;</li>\r\n	<li>SPIR built-ins name mangler, written as a standalone library and executable;</li>\r\n	<li>header file containing definitions for all enumerated values in the SPIR specification.</li>\r\n</ul>\r\n</blockquote>\r\nThe SPIR compiler is a patched version of <code>clang</code> that compiles <code>OpenCL C</code> code into <code>SPIR</code>. <code>SPIR tools</code> repository enables the usage of OpenCL builtin functions in SPIR. We\'ll be exploring the SPIR compiler a lot more in a follow up post.\r\n<h3>Future of SPIR</h3>\r\nWhile it is encouraging to see continued development of SPIR, it is still an optional extension in OpenCL. AMD and Intel have supported SPIR since their OpenCL 1.2 implementations. NVIDIA has NVVM IR that may or may not be compatible with SPIR.\r\n\r\nOpenCL brought the portability across different architectures. Similarily, SPIR will bring portability across multiple programming languages. All the vendors would be doing themselves and the ecosystem a favor if they support SPIR and implemented their compute language of choice on top of it.','OpenCL SPIR 2.0','','inherit','open','open','','6379-revision-v1','','','2014-08-18 16:48:32','2014-08-18 16:48:32','',6379,'http://sandbox.arrayfire.com/6379-revision-v1/',0,'revision','',0),(6476,17728,'2014-08-18 16:50:08','2014-08-18 16:50:08','At SIGGRAPH 2014 The Khronos Group announced, among other things, the <a href=\"https://www.khronos.org/news/press/khronos-releases-spir-2.0-provisional-specification\">SPIR 2.0</a> provisional specification. This release of SPIR (Standard Portable Intermediate Representation) follows the release of <a href=\"https://www.khronos.org/news/press/khronos-releases-opencl-2.0\">OpenCL 2.0</a> spec last year.\r\n\r\nIn this post, we would like to offer our take on SPIR 2.0 and what it means to OpenCL developers.\r\n<h3>Feature Parity With OpenCL 2.0</h3>\r\nSPIR 1.2 had feature parity with OpenCL 1.2. With 2.0, SPIR has feature parity with OpenCL 2.0. Here are a few new features that we find interesting.\r\n<h5>Generic Address Space</h5>\r\n<blockquote>Where functions can be written without specifying a named address space for arguments, especially useful for those arguments that are declared to be a pointer to a type, eliminating the need for multiple functions to be written for each named address space used in an application.</blockquote>\r\nThis greatly reduces code redundancy and increases code reusability. Many algorithms perform the same operations on <code>__global</code> memory and <code>__local</code> memory at various points in the algorithm. A great example of an algorithm that benefits from this is parallel reduction algorithm.\r\n<h5>Device Side Kernel Enqueue</h5>\r\n<blockquote>Where device kernels can enqueue kernels to the same device with no host interaction, enabling flexible work scheduling paradigms and avoiding the need to transfer execution control and data between the device and host, often significantly offloading host processor bottlenecks.</blockquote>\r\nWhile this sounds like a nice feature to have, we are skeptical about the performance benefits. The improvements in performance will be highly dependent on the platform specific implementation of the scheduler and may not provide reliable improvements across the board. This feature can increase the readability of complex algorithms.\r\n<h5>Pipes</h5>\r\n<blockquote>memory objects that store data organized as a FIFO. OpenCL 2.0 provides built-in functions for kernels to read from or write to a pipe, providing straightforward programming of pipe data structures that can be highly optimized by OpenCL implementers.</blockquote>\r\nPipes are FIFO data structures that enable communication between two kernels being executed concurrently. This feature seems to be designed for architectures that support streaming data and will likely be inefficient on OpenCL capable GPUs.\r\n<h3>SPIR Compiler and Tools</h3>\r\nThe Khronos group also added the <a href=\"https://github.com/KhronosGroup/SPIR\">SPIR compiler</a> and <a href=\"https://github.com/KhronosGroup/SPIR-Tools\">SPIR Tools</a> to their github page.\r\n<blockquote>\r\n<ul>\r\n	<li>Modified Clang which generates SPIR from OpenCL C kernel language device programs;</li>\r\n	<li>SPIR module verifier, written in the form of an LLVM pass;</li>\r\n	<li>SPIR built-ins name mangler, written as a standalone library and executable;</li>\r\n	<li>header file containing definitions for all enumerated values in the SPIR specification.</li>\r\n</ul>\r\n</blockquote>\r\nThe SPIR compiler is a patched version of <code>clang</code> that compiles <code>OpenCL C</code> code into <code>SPIR</code>. <code>SPIR tools</code> repository enables the usage of OpenCL builtin functions in SPIR. We\'ll be exploring the SPIR compiler a lot more in a follow up post.\r\n<h3>Future of SPIR</h3>\r\nWhile it is encouraging to see continued development of SPIR, it is still an optional extension in OpenCL. AMD and Intel have supported SPIR since their OpenCL 1.2 implementations. NVIDIA has NVVM IR that may or may not be compatible with SPIR.\r\n\r\nOpenCL brought the portability across different architectures. Similarily, SPIR will bring portability across multiple programming languages. All the vendors would be doing themselves and the ecosystem a favor if they support SPIR and implemented their compute language of choice on top of it.','OpenCL SPIR 2.0','','inherit','open','open','','6379-revision-v1','','','2014-08-18 16:50:08','2014-08-18 16:50:08','',6379,'http://sandbox.arrayfire.com/6379-revision-v1/',0,'revision','',0),(6477,17728,'2014-08-18 16:50:53','2014-08-18 16:50:53','At SIGGRAPH 2014 The Khronos Group announced, among other things, the <a href=\"https://www.khronos.org/news/press/khronos-releases-spir-2.0-provisional-specification\">SPIR 2.0</a> provisional specification. This release of SPIR (Standard Portable Intermediate Representation) follows the release of <a href=\"https://www.khronos.org/news/press/khronos-releases-opencl-2.0\">OpenCL 2.0</a> spec last year.\r\n\r\nIn this post, we would like to offer our take on SPIR 2.0 and what it means to OpenCL developers.\r\n<h3>Feature Parity With OpenCL 2.0</h3>\r\nSPIR 1.2 had feature parity with OpenCL 1.2. With 2.0, SPIR has feature parity with OpenCL 2.0. Here are a few new features that we find interesting.\r\n<h5>Generic Address Space</h5>\r\n<blockquote>\"Where functions can be written without specifying a named address space for arguments, especially useful for those arguments that are declared to be a pointer to a type, eliminating the need for multiple functions to be written for each named address space used in an application.</blockquote>\r\nThis greatly reduces code redundancy and increases code reusability. Many algorithms perform the same operations on <code>__global</code> memory and <code>__local</code> memory at various points in the algorithm. A great example of an algorithm that benefits from this is parallel reduction algorithm.\r\n<h5>Device Side Kernel Enqueue</h5>\r\n<blockquote>Where device kernels can enqueue kernels to the same device with no host interaction, enabling flexible work scheduling paradigms and avoiding the need to transfer execution control and data between the device and host, often significantly offloading host processor bottlenecks.</blockquote>\r\nWhile this sounds like a nice feature to have, we are skeptical about the performance benefits. The improvements in performance will be highly dependent on the platform specific implementation of the scheduler and may not provide reliable improvements across the board. This feature can increase the readability of complex algorithms.\r\n<h5>Pipes</h5>\r\n<blockquote>memory objects that store data organized as a FIFO. OpenCL 2.0 provides built-in functions for kernels to read from or write to a pipe, providing straightforward programming of pipe data structures that can be highly optimized by OpenCL implementers.</blockquote>\r\nPipes are FIFO data structures that enable communication between two kernels being executed concurrently. This feature seems to be designed for architectures that support streaming data and will likely be inefficient on OpenCL capable GPUs.\r\n<h3>SPIR Compiler and Tools</h3>\r\nThe Khronos group also added the <a href=\"https://github.com/KhronosGroup/SPIR\">SPIR compiler</a> and <a href=\"https://github.com/KhronosGroup/SPIR-Tools\">SPIR Tools</a> to their github page.\r\n<blockquote>\r\n<ul>\r\n	<li>Modified Clang which generates SPIR from OpenCL C kernel language device programs;</li>\r\n	<li>SPIR module verifier, written in the form of an LLVM pass;</li>\r\n	<li>SPIR built-ins name mangler, written as a standalone library and executable;</li>\r\n	<li>header file containing definitions for all enumerated values in the SPIR specification.</li>\r\n</ul>\r\n</blockquote>\r\nThe SPIR compiler is a patched version of <code>clang</code> that compiles <code>OpenCL C</code> code into <code>SPIR</code>. <code>SPIR tools</code> repository enables the usage of OpenCL builtin functions in SPIR. We\'ll be exploring the SPIR compiler a lot more in a follow up post.\r\n<h3>Future of SPIR</h3>\r\nWhile it is encouraging to see continued development of SPIR, it is still an optional extension in OpenCL. AMD and Intel have supported SPIR since their OpenCL 1.2 implementations. NVIDIA has NVVM IR that may or may not be compatible with SPIR.\r\n\r\nOpenCL brought the portability across different architectures. Similarily, SPIR will bring portability across multiple programming languages. All the vendors would be doing themselves and the ecosystem a favor if they support SPIR and implemented their compute language of choice on top of it.','OpenCL SPIR 2.0','','inherit','open','open','','6379-revision-v1','','','2014-08-18 16:50:53','2014-08-18 16:50:53','',6379,'http://sandbox.arrayfire.com/6379-revision-v1/',0,'revision','',0),(6478,17728,'2014-08-18 16:51:33','2014-08-18 16:51:33','At SIGGRAPH 2014 The Khronos Group announced, among other things, the <a href=\"https://www.khronos.org/news/press/khronos-releases-spir-2.0-provisional-specification\">SPIR 2.0</a> provisional specification. This release of SPIR (Standard Portable Intermediate Representation) follows the release of <a href=\"https://www.khronos.org/news/press/khronos-releases-opencl-2.0\">OpenCL 2.0</a> spec last year.\r\n\r\nIn this post, we would like to offer our take on SPIR 2.0 and what it means to OpenCL developers.\r\n<h3>Feature Parity With OpenCL 2.0</h3>\r\nSPIR 1.2 had feature parity with OpenCL 1.2. With 2.0, SPIR has feature parity with OpenCL 2.0. Here are a few new features that we find interesting.\r\n<h5>Generic Address Space</h5>\r\n<blockquote>\"Where functions can be written without specifying a named address space for arguments, especially useful for those arguments that are declared to be a pointer to a type, eliminating the need for multiple functions to be written for each named address space used in an application.\"</blockquote>\r\nThis greatly reduces code redundancy and increases code reusability. Many algorithms perform the same operations on <code>__global</code> memory and <code>__local</code> memory at various points in the algorithm. A great example of an algorithm that benefits from this is parallel reduction algorithm.\r\n<h5>Device Side Kernel Enqueue</h5>\r\n<blockquote>\"Where device kernels can enqueue kernels to the same device with no host interaction, enabling flexible work scheduling paradigms and avoiding the need to transfer execution control and data between the device and host, often significantly offloading host processor bottlenecks.\"</blockquote>\r\nWhile this sounds like a nice feature to have, we are skeptical about the performance benefits. The improvements in performance will be highly dependent on the platform specific implementation of the scheduler and may not provide reliable improvements across the board. This feature can increase the readability of complex algorithms.\r\n<h5>Pipes</h5>\r\n<blockquote>\"memory objects that store data organized as a FIFO. OpenCL 2.0 provides built-in functions for kernels to read from or write to a pipe, providing straightforward programming of pipe data structures that can be highly optimized by OpenCL implementers.\"</blockquote>\r\nPipes are FIFO data structures that enable communication between two kernels being executed concurrently. This feature seems to be designed for architectures that support streaming data and will likely be inefficient on OpenCL capable GPUs.\r\n<h3>SPIR Compiler and Tools</h3>\r\nThe Khronos group also added the <a href=\"https://github.com/KhronosGroup/SPIR\">SPIR compiler</a> and <a href=\"https://github.com/KhronosGroup/SPIR-Tools\">SPIR Tools</a> to their github page.\r\n<blockquote>\r\n<ul>\r\n	<li>Modified Clang which generates SPIR from OpenCL C kernel language device programs;</li>\r\n	<li>SPIR module verifier, written in the form of an LLVM pass;</li>\r\n	<li>SPIR built-ins name mangler, written as a standalone library and executable;</li>\r\n	<li>header file containing definitions for all enumerated values in the SPIR specification.</li>\r\n</ul>\r\n</blockquote>\r\nThe SPIR compiler is a patched version of <code>clang</code> that compiles <code>OpenCL C</code> code into <code>SPIR</code>. <code>SPIR tools</code> repository enables the usage of OpenCL builtin functions in SPIR. We\'ll be exploring the SPIR compiler a lot more in a follow up post.\r\n<h3>Future of SPIR</h3>\r\nWhile it is encouraging to see continued development of SPIR, it is still an optional extension in OpenCL. AMD and Intel have supported SPIR since their OpenCL 1.2 implementations. NVIDIA has NVVM IR that may or may not be compatible with SPIR.\r\n\r\nOpenCL brought the portability across different architectures. Similarily, SPIR will bring portability across multiple programming languages. All the vendors would be doing themselves and the ecosystem a favor if they support SPIR and implemented their compute language of choice on top of it.','OpenCL SPIR 2.0','','inherit','open','open','','6379-revision-v1','','','2014-08-18 16:51:33','2014-08-18 16:51:33','',6379,'http://sandbox.arrayfire.com/6379-revision-v1/',0,'revision','',0),(6481,17796,'2014-08-19 18:02:39','2014-08-19 18:02:39','In this blog we will review the benefit of using element-wise operations for your computations. Element-wise operations are operations that are applied to every element in an array. The simplest example of an element-wise operation is the addition (+) operation.\r\n<pre>array A=array(1024,1024), B=array(1024,1024), C=array(1024,1024);\r\nC=A+B;\r\n</pre>\r\nAn element-wise operator that is applied to a single element is unary operator. An operator that works on two elements is a binary operator. ArrayFire has implemented a large number element-wise operations that are applied to the elements of an array. These operators can help reduce the programming overhead for an application designer as:\r\n<ul>\r\n	<li>Productivity - the application designed need not worry about implementing the operator.</li>\r\n	<li>Portability - as these are implemented in OpenCL, the programmer does not have deal with the partitioning of the work and load-balancing. These are key components for performance.</li>\r\n	<li>Completeness - the array data type is no different than any other C scalar data type.</li>\r\n	<li>Readability and maintenance - high performance computing becomes as simple as writing a script.</li>\r\n</ul>\r\nOur element-wise operations also include operations between an array and a scalar value. For example:\r\n<pre>array A,B\r\nB=A+1;\r\n</pre>\r\nA small subset of these operators include:\r\n<ul>\r\n	<li>sin - computes the sine for each element in the array.</li>\r\n	<li>cosine - computes the sine for each element in the array.</li>\r\n	<li>abs - computes the absolute value for each element in the array.</li>\r\n	<li>trunc - truncates every element in the array.</li>\r\n</ul>\r\nA full list of element-wise operators can also be found in our document under: <a href=\"http://sandbox.arrayfire.com/docs/group__arith.htm\"><span style=\"text-decoration: underline;\">element-wise operators</span></a> and <a title=\"operator overloading\" href=\"http://sandbox.arrayfire.com/docs/group__array__operator.htm\" target=\"_blank\">operator-overloading functions</a>   . These will include trigonometric, arithmetic, and utility functions.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','The Benefits of Array Element-Wise Operations ','','inherit','open','open','','6383-revision-v1','','','2014-08-19 18:02:39','2014-08-19 18:02:39','',6383,'http://sandbox.arrayfire.com/6383-revision-v1/',0,'revision','',0),(6482,17796,'2014-08-19 18:03:56','2014-08-19 18:03:56','In this blog we will review the benefit of using element-wise operations for your computations. Element-wise operations are operations that are applied to every element in an array. The simplest example of an element-wise operation is the addition (+) operation.\r\n<pre>array A=array(1024,1024), B=array(1024,1024), C=array(1024,1024);\r\nC=A+B;\r\n</pre>\r\nAn element-wise operator that is applied to a single element is unary operator. An operator that works on two elements is a binary operator. ArrayFire has implemented a large number element-wise operations that are applied to the elements of an array. These operators can help reduce the programming overhead for an application designer as:\r\n<ul>\r\n	<li>Productivity - the application designed need not worry about implementing the operator.</li>\r\n	<li>Portability - as these are implemented in OpenCL, the programmer does not have deal with the partitioning of the work and load-balancing. These are key components for performance.</li>\r\n	<li>Completeness - the array data type is no different than any other C scalar data type.</li>\r\n	<li>Readability and maintenance - high performance computing becomes as simple as writing a script.</li>\r\n</ul>\r\nOur element-wise operations also include operations between an array and a scalar value. For example:\r\n<pre>array A,B\r\nB=A+1;\r\n</pre>\r\nA small subset of these operators include:\r\n<ul>\r\n	<li>sin - computes the sine for each element in the array.</li>\r\n	<li>cosine - computes the sine for each element in the array.</li>\r\n	<li>abs - computes the absolute value for each element in the array.</li>\r\n	<li>trunc - truncates every element in the array.</li>\r\n</ul>\r\nA full list of element-wise operators can also be found in our document under: <a href=\"http://sandbox.arrayfire.com/docs/group__arith.htm\"><span style=\"text-decoration: underline;\">element-wise operators</span></a> and <span style=\"text-decoration: underline;\"><a title=\"operator overloading\" href=\"http://sandbox.arrayfire.com/docs/group__array__operator.htm\" target=\"_blank\">operator-overloading functions</a></span>. These will include trigonometric, arithmetic, and utility functions.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','The Benefits of Array Element-Wise Operations ','','inherit','open','open','','6383-revision-v1','','','2014-08-19 18:03:56','2014-08-19 18:03:56','',6383,'http://sandbox.arrayfire.com/6383-revision-v1/',0,'revision','',0),(6483,17796,'2014-08-19 18:05:20','2014-08-19 18:05:20','In this blog we will review the benefit of using element-wise operations for your computations. Element-wise operations are operations that are applied to every element in an array. The simplest example of an element-wise operation is the addition (+) operation.\r\n<pre>array A=array(1024,1024), B=array(1024,1024), C=array(1024,1024);\r\nC=A+B;\r\n</pre>\r\nAn element-wise operator that is applied to a single element is unary operator. An operator that works on two elements is a binary operator. ArrayFire has implemented a large number element-wise operations that are applied to the elements of an array. These operators can help reduce the programming overhead for an application designer as:\r\n<ul>\r\n	<li>Productivity - the application designed need not worry about implementing the operator.</li>\r\n	<li>Portability - as these are implemented in OpenCL, the programmer does not have deal with the partitioning of the work and load-balancing. These are key components for performance.</li>\r\n	<li>Completeness - the array data type is no different than any other C scalar data type.</li>\r\n	<li>Readability and maintenance - high performance computing becomes as simple as writing a script.</li>\r\n</ul>\r\nOur element-wise operations also include operations between an array and a scalar value. For example:\r\n<pre>array A,B\r\nB=A+1;\r\n</pre>\r\nA small subset of these operators include:\r\n<ul>\r\n	<li>sin - computes the sine for each element in the array.</li>\r\n	<li>cosine - computes the sine for each element in the array.</li>\r\n	<li>abs - computes the absolute value for each element in the array.</li>\r\n	<li>trunc - truncates every element in the array.</li>\r\n</ul>\r\nA full list of element-wise operators can also be found in our document under: <a href=\"http://sandbox.arrayfire.com/docs/group__arith.htm\"><span style=\"text-decoration: underline;\">element-wise operators</span></a> and <span style=\"text-decoration: underline;\"><a title=\"operator overloading\" href=\"http://sandbox.arrayfire.com/docs/group__array__operator.htm\" target=\"_blank\">operator-overloading functions</a></span>. These include trigonometric, arithmetic, and utility functions. We will extend the discussion on these in future posts.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','The Benefits of Array Element-Wise Operations ','','inherit','open','open','','6383-revision-v1','','','2014-08-19 18:05:20','2014-08-19 18:05:20','',6383,'http://sandbox.arrayfire.com/6383-revision-v1/',0,'revision','',0),(6485,17796,'2014-08-20 15:14:54','2014-08-20 15:14:54','In this blog we will review the benefit of using element-wise operations for your computations. Element-wise operations are operations that are applied to every element in an array. In a simple example of an element-wise operation, we use both the addition (+) and multiply (*)operations:\r\n<pre>array A = randu(1024, 1024), B = randu(1024, 1024);</pre>\r\n<pre>array C=A*A+B+B;</pre>\r\nAn element-wise operator that is applied to a single element is unary operator. An operator that works on two elements is a binary operator. ArrayFire has implemented a large number element-wise operations that are applied to the elements of an array. These operators can help reduce the programming overhead for an application designer as:\r\n<ul>\r\n	<li>Productivity - the application designed need not worry about implementing the operator.</li>\r\n	<li>Portability - as these are implemented in OpenCL, the programmer does not have deal with the partitioning of the work and load-balancing. These are key components for performance.</li>\r\n	<li>Completeness - the array data type is no different than any other C scalar data type.</li>\r\n	<li>Readability and maintenance - high performance computing becomes as simple as writing a script.</li>\r\n</ul>\r\nOur element-wise operations also include operations between an array and a scalar value. For example:\r\n<pre>array A,B\r\nB=A+1;\r\n</pre>\r\nA small subset of these operators include:\r\n<ul>\r\n	<li>sin - computes the sine for each element in the array.</li>\r\n	<li>cosine - computes the sine for each element in the array.</li>\r\n	<li>abs - computes the absolute value for each element in the array.</li>\r\n	<li>trunc - truncates every element in the array.</li>\r\n</ul>\r\nA full list of element-wise operators can also be found in our document under: <a href=\"http://sandbox.arrayfire.com/docs/group__arith.htm\"><span style=\"text-decoration: underline;\">element-wise operators</span></a> and <span style=\"text-decoration: underline;\"><a title=\"operator overloading\" href=\"http://sandbox.arrayfire.com/docs/group__array__operator.htm\" target=\"_blank\">operator-overloading functions</a></span>. These include trigonometric, arithmetic, and utility functions. We will extend the discussion on these in future posts.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','The Benefits of Array Element-Wise Operations ','','inherit','open','open','','6383-revision-v1','','','2014-08-20 15:14:54','2014-08-20 15:14:54','',6383,'http://sandbox.arrayfire.com/6383-revision-v1/',0,'revision','',0),(6486,17796,'2014-08-20 15:18:36','2014-08-20 15:18:36','In this blog we will review the benefit of using element-wise operations for your computations. Element-wise operations are operations that are applied to every element in an array. In a simple example of an element-wise operation, we use both the addition (+) and multiply (*)operations:\r\n<pre>array A = randu(1024, 1024), B = randu(1024, 1024);</pre>\r\n<pre>array C=A*A+B+B;</pre>\r\nAn element-wise operator that is applied to a single element is unary operator. An operator that works on two elements is a binary operator. ArrayFire has implemented a large number element-wise operations that are applied to the elements of an array. These operators can help reduce the programming overhead for an application designer as:\r\n<ul>\r\n	<li>Performance - the application designed need not worry about implementing the operator. As these are implemented in OpenCL (with a focus on achieving high utilization), the programmer does not have deal with the partitioning of the work and load-balancing.</li>\r\n	<li>Completeness - the array data type is no different than any other C scalar data type.</li>\r\n	<li>Readability and maintenance - high performance computing becomes as simple as writing a script.</li>\r\n</ul>\r\nOur element-wise operations also include operations between an array and a scalar value. For example:\r\n<pre>array A=randu(1024, 1024),B; \r\nB=A+1;</pre>\r\nA small subset of these operators include:\r\n<ul>\r\n	<li>sin - computes the sine for each element in the array.</li>\r\n	<li>cosine - computes the sine for each element in the array.</li>\r\n	<li>abs - computes the absolute value for each element in the array.</li>\r\n	<li>trunc - truncates every element in the array.</li>\r\n</ul>\r\nA full list of element-wise operators can also be found in our document under: <a href=\"http://sandbox.arrayfire.com/docs/group__arith.htm\"><span style=\"text-decoration: underline;\">element-wise operators</span></a> and <span style=\"text-decoration: underline;\"><a title=\"operator overloading\" href=\"http://sandbox.arrayfire.com/docs/group__array__operator.htm\" target=\"_blank\">operator-overloading functions</a></span>. These include trigonometric, arithmetic, and utility functions. We will extend the discussion on these in future posts.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','The Benefits of Array Element-Wise Operations ','','inherit','open','open','','6383-revision-v1','','','2014-08-20 15:18:36','2014-08-20 15:18:36','',6383,'http://sandbox.arrayfire.com/6383-revision-v1/',0,'revision','',0),(6487,17796,'2014-08-20 15:55:25','2014-08-20 15:55:25','In this blog we will review the benefit of using element-wise operations for your computations. Element-wise operations are operations that are applied to every element in an array and allow the user to avoid coding loops and nested loops for rudimentary operations. In a simple example of an element-wise operation, we use both the addition (+) and multiply (*)operations:\r\n<pre>array A = randu(1024, 1024), B = randu(1024, 1024);\r\narray C=A*A+B+B;</pre>\r\nAn element-wise operator that is applied to a single element is unary operator. An operator that works on two elements is a binary operator. ArrayFire has implemented a large number element-wise operations that are applied to the elements of an array. These operators can help reduce the programming overhead for an application designer as:\r\n<ul>\r\n	<li>Performance - the application designed need not worry about implementing the operator. As these are implemented in OpenCL (with a focus on achieving high utilization), the programmer does not have deal with the partitioning of the work and load-balancing.</li>\r\n	<li>Completeness - the array data type is no different than any other C scalar data type.</li>\r\n	<li>Readability and maintenance - high performance computing becomes as simple as writing a script.</li>\r\n</ul>\r\nOur element-wise operations also include operations between an array and a scalar value. For example:\r\n<pre>array A=randu(1024, 1024),B; \r\nB=A+1;</pre>\r\nA small subset of these operators include:\r\n<ul>\r\n	<li>sin - computes the sine for each element in the array.</li>\r\n	<li>cosine - computes the sine for each element in the array.</li>\r\n	<li>abs - computes the absolute value for each element in the array.</li>\r\n	<li>trunc - truncates every element in the array.</li>\r\n</ul>\r\nA full list of element-wise operators can also be found in our document under: <a href=\"http://sandbox.arrayfire.com/docs/group__arith.htm\"><span style=\"text-decoration: underline;\">element-wise operators</span></a> and <span style=\"text-decoration: underline;\"><a title=\"operator overloading\" href=\"http://sandbox.arrayfire.com/docs/group__array__operator.htm\" target=\"_blank\">operator-overloading functions</a></span>. These include trigonometric, arithmetic, and utility functions. We will extend the discussion on these in future posts.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','The Benefits of Array Element-Wise Operations ','','inherit','open','open','','6383-revision-v1','','','2014-08-20 15:55:25','2014-08-20 15:55:25','',6383,'http://sandbox.arrayfire.com/6383-revision-v1/',0,'revision','',0),(6488,17796,'2014-08-20 17:23:52','2014-08-20 17:23:52','In this blog we will review the benefit of using element-wise operations for your computations. Element-wise operations are operations that are applied to every element in an array and allow the user to avoid coding loops and nested loops for rudimentary operations. In a simple example of an element-wise operation, we use both the addition (+) and multiply (*)operations:\r\n<pre>array A = randu(1024, 1024), B = randu(1024, 1024);\r\narray C=A*A+B+B;</pre>\r\nAn element-wise operator that is applied to a single element is unary operator. An operator that works on two elements is a binary operator. ArrayFire has implemented a large number element-wise operations that are applied to the elements of an array. These operators can help reduce the programming overhead for an application designer as:\r\n<ul>\r\n	<li>Performance - the application designed need not worry about implementing the operator. As these are implemented in OpenCL (with a focus on achieving high utilization), the programmer does not have deal with the partitioning of the work and load-balancing.</li>\r\n	<li>Completeness - the array data type is no different than any other C scalar data type. This means that you can user operators such as &lt; or &lt;=.</li>\r\n	<li>Readability and maintenance - high performance computing becomes as simple as writing a script.</li>\r\n</ul>\r\nOur element-wise operations also include operations between an array and a scalar value. For example:\r\n<pre>array A=randu(1024, 1024),B; \r\nB=A+1;</pre>\r\nA small subset of our operators include:\r\n<ul>\r\n	<li>sin - computes the sine for each element in the array.</li>\r\n	<li>cosine - computes the sine for each element in the array.</li>\r\n	<li>abs - computes the absolute value for each element in the array.</li>\r\n	<li>trunc - truncates every element in the array.</li>\r\n</ul>\r\nA full list of element-wise operators can also be found in our document under: <a href=\"http://sandbox.arrayfire.com/docs/group__arith.htm\"><span style=\"text-decoration: underline;\">element-wise operators</span></a> and <span style=\"text-decoration: underline;\"><a title=\"operator overloading\" href=\"http://sandbox.arrayfire.com/docs/group__array__operator.htm\" target=\"_blank\">operator-overloading functions</a></span>. These include trigonometric, arithmetic, logical,and utility functions. We will extend the discussion on these in future posts.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','The Benefits of Array Element-Wise Operations ','','inherit','open','open','','6383-revision-v1','','','2014-08-20 17:23:52','2014-08-20 17:23:52','',6383,'http://sandbox.arrayfire.com/6383-revision-v1/',0,'revision','',0),(6489,17796,'2014-08-20 17:25:15','2014-08-20 17:25:15','In this blog we will review the benefit of using element-wise operations for your computations. Element-wise operations are operations that are applied to every element in an array and allow the user to avoid coding loops and nested loops for rudimentary operations. In a simple example of an element-wise operation, we use both the addition (+) and multiply (*)operations:\r\n<pre>array A = randu(1024, 1024), B = randu(1024, 1024);\r\narray C=A*A+B*B;</pre>\r\nAn element-wise operator that is applied to a single element is unary operator. An operator that works on two elements is a binary operator. ArrayFire has implemented a large number element-wise operations that are applied to the elements of an array. These operators can help reduce the programming overhead for an application designer as:\r\n<ul>\r\n	<li>Performance - the application designed need not worry about implementing the operator. As these are implemented in OpenCL (with a focus on achieving high utilization), the programmer does not have deal with the partitioning of the work and load-balancing.</li>\r\n	<li>Completeness - the array data type is no different than any other C scalar data type. This means that you can user operators such as &lt; or &lt;=.</li>\r\n	<li>Readability and maintenance - high performance computing becomes as simple as writing a script.</li>\r\n</ul>\r\nOur element-wise operations also include operations between an array and a scalar value. For example:\r\n<pre>array A=randu(1024, 1024),B; \r\nB=A+1;</pre>\r\nA small subset of our operators include:\r\n<ul>\r\n	<li>sin - computes the sine for each element in the array.</li>\r\n	<li>cosine - computes the sine for each element in the array.</li>\r\n	<li>abs - computes the absolute value for each element in the array.</li>\r\n	<li>trunc - truncates every element in the array.</li>\r\n</ul>\r\nA full list of element-wise operators can also be found in our document under: <a href=\"http://sandbox.arrayfire.com/docs/group__arith.htm\"><span style=\"text-decoration: underline;\">element-wise operators</span></a> and <span style=\"text-decoration: underline;\"><a title=\"operator overloading\" href=\"http://sandbox.arrayfire.com/docs/group__array__operator.htm\" target=\"_blank\">operator-overloading functions</a></span>. These include trigonometric, arithmetic, logical,and utility functions. We will extend the discussion on these in future posts.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n&nbsp;','The Benefits of Array Element-Wise Operations ','','inherit','open','open','','6383-revision-v1','','','2014-08-20 17:25:15','2014-08-20 17:25:15','',6383,'http://sandbox.arrayfire.com/6383-revision-v1/',0,'revision','',0),(6495,17795,'2014-08-25 17:10:15','2014-08-25 17:10:15','Here at ArrayFire, we develop code that will work efficiently on both CUDA and OpenCL platforms. Therefore, it is not uncommon that CUDA code on NVIDIA GPUs will run faster than OpenCL. A very good way to understand what is behind the curtains is to generate the PTX file for both cases and compare them. In this post, we show how to generate PTX for both CUDA and OpenCL kernels.\r\n\r\nPTX stands for <a title=\"Parallel Thread eXecution\" href=\"http://docs.nvidia.com/cuda/parallel-thread-execution\">Parallel Thread eXecution</a>, which is a low-level virtual machine and instruction set architecture (ISA). For those familiar with assembly language, the PTX instruction set is not really more complicated than a single thread assembly code, except that now we are thinking in massive parallel execution.\r\n\r\nRetrieving the PTX file from a CUDA kernel is a pretty straightforward process. First, we need a CUDA kernel, we will use the following code for this article, a simple vector addition kernel.\r\n<pre>__global__ void add_vectors(\r\n    const float* a,\r\n    const float* b,\r\n    float *c,\r\n    const int n)\r\n{\r\n    const int idx = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\n    if (idx <= n) return;\r\n\r\n    c[idx] = a[idx] + b[idx];\r\n}\r\n</pre>\r\nFor simplicity assume that this function is saved to  <code>add_vectors.cu.</code> Now we simply call the NVCC compiler with the <code>--ptx</code> argument.\r\n<pre>nvcc --ptx add_vectors.cu\r\n</pre>\r\nThe compiler output is a text file named <code>add_vectors.ptx</code>.\r\n\r\nRetrieving the PTX file for an OpenCL file is somewhat more challenging. Those of you familiar with OpenCL are probably not surprised. Retrieving the PTX code requires host-side code and the OpenCL file which is only extracted at runtime. This means that the host-side code is necessary for compilation of the OpenCL function whereas this was not necessary for the CUDA code.\r\n\r\nThe OpenCL kernel will be very similar to the CUDA kernel and can be saved with any name, here we will use <code>add_vectors.cl</code>, just be aware of the file name to pass the correct one to the host-side code. Below the vector addition kernel adapted to OpenCL is provided.\r\n<pre>__kernel void add_vectors(\r\n    __global const int* a,\r\n    __global const int* b,\r\n    __global       int* c,\r\n    int n)\r\n{\r\n    int idx = get_global_id(0);\r\n\r\n    if (idx <= n) return;\r\n\r\n    c[idx] = a[idx] + b[idx];\r\n}\r\n</pre>\r\nFinally, we need the host-side code. A minimalist version (without actually executing the OpenCL kernel) follows.\r\n<pre>#include \r\n#include \r\n\r\n#ifdef __APPLE__\r\n#include <OpenCL/opencl.h>\r\n#else\r\n#include <CL/cl.h>\r\n#endif\r\n\r\nint main(int argc, char* argv[])\r\n{\r\n    // Loads add_vectors.cl\r\n    FILE* fp;\r\n    fp = fopen(\"add_vectors.cl\", \"r\");\r\n    if (!fp) {\r\n        fprintf(stderr, \"Error loading kernel.\\n\");\r\n        exit(1);\r\n    }\r\n\r\n    fseek(fp, 0, SEEK_END);\r\n    size_t kernel_sz = ftell(fp);\r\n    rewind(fp);\r\n\r\n    char* kernel_str = (char*)malloc(kernel_sz);\r\n    fread(kernel_str, 1, kernel_sz, fp);\r\n    fclose(fp);\r\n\r\n    // Query platforms and devices\r\n    cl_platform_id platform;\r\n    cl_device_id device;\r\n    cl_uint num_devices, num_platforms;\r\n    cl_int err = clGetPlatformIDs(1, &platform, &num_platforms);\r\n    err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1,\r\n                         &device, &num_devices);\r\n\r\n    // Create OpenCL context\r\n    cl_context context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);\r\n\r\n    // Create OpenCL command queue\r\n    cl_command_queue command_queue = clCreateCommandQueue(context, device, 0, &err);\r\n\r\n    // Create OpenCL program for add_vectors.cl\r\n    cl_program program = clCreateProgramWithSource(context, 1,\r\n            (const char **)&kernel_str, (const size_t *)&kernel_sz, &err);\r\n\r\n    // Build OpenCL program\r\n    err = clBuildProgram(program, 1, &device, NULL, NULL, NULL);\r\n\r\n    // Create OpenCL kernel\r\n    cl_kernel kernel = clCreateKernel(program, \"add_vectors\", &err);\r\n\r\n    // Query binary (PTX file) size\r\n    size_t bin_sz;\r\n    err = clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &bin_sz, NULL);\r\n\r\n    // Read binary (PTX file) to memory buffer\r\n    unsigned char *bin = (unsigned char *)malloc(bin_sz);\r\n    err = clGetProgramInfo(program, CL_PROGRAM_BINARIES, sizeof(unsigned char *), &bin, NULL);\r\n\r\n    // Save PTX to add_vectors_ocl.ptx\r\n    fp = fopen(\"add_vectors_ocl.ptx\", \"wb\");\r\n    fwrite(bin, sizeof(char), bin_sz, fp);\r\n    fclose(fp);\r\n    free(bin);\r\n\r\n    // Release OpenCL resources\r\n    clFlush(command_queue);\r\n    clFinish(command_queue);\r\n    clReleaseKernel(kernel);\r\n    clReleaseProgram(program);\r\n    clReleaseCommandQueue(command_queue);\r\n    clReleaseContext(context);\r\n    return 0;\r\n}\r\n</pre>\r\nTo compile the code above with GCC, it is necessary only to pass the OpenCL include files to the compiler and the OpenCL library to the linker. The code should also compile under Visual Studio with little or no changes.\r\n<pre>gcc -Wall -g add_vectors.c -o add_vectors -I/usr/local/cuda/include -lOpenCL\r\n</pre>\r\nFinally, the code can be executed and the PTX will be saved to the file <code>add_vectors_ocl.ptx</code>. Note that for this simple example the PTX will only be extracted if the device 0 is an NVIDIA device, otherwise, it will not be a PTX file.\r\n\r\nIf you think the host-side code is too long and complicated, don\'t worry, check the <a href=\"http://sandbox.arrayfire.com/quest-for-the-smallest-opencl-program/\">Quest for the Smallest OpenCL Program</a>. One of our engineers wrote a blog that uses the C++ API of OpenCL and he explains how to write simple and short OpenCL code. With few changes, it is possible to use the short C++ code to extract the PTX file from OpenCL kernels.\r\n\r\nThe complete code along with Makefile and instructions to build it can be found <a href=\"https://github.com/pentschev/ptxtract\">here</a>.\r\n\r\nWe plan on following up this blog and discuss in more depth analyzing PTX for both CUDA and OpenCL kernels, altogether with a more general host-side code. We will introduce some simple but interesting methods that we use that help us understand and improve code performance. So stay in touch!','Generating PTX files from OpenCL code','','publish','open','open','','generating-ptx-files-from-opencl-code','','\nhttp://sandbox.arrayfire.com/quest-for-the-smallest-opencl-program/','2016-12-29 14:06:48','2016-12-29 19:06:48','',0,'http://sandbox.arrayfire.com/?p=6495',0,'post','',2),(6496,17795,'2014-08-24 22:40:11','2014-08-24 22:40:11','Here at ArrayFire, we develop code to work efficiently on both CUDA and OpenCL devices. Therefore, it is not uncommon that CUDA code on NVIDIA GPUs run faster than OpenCL. A very good way to understand what is behind the curtains is to generate the PTX file for both cases and compare them.\r\n\r\nPTX stands for Parallel Thread eXecution [1], which is a low-level virtual machine and instruction set architecture (ISA). For those familiar with assembly language, the PTX instruction set is nothing much more complicated as a single processor assembly code, except that now we are thinking in massively parellel execution.\r\n\r\nRetrieving the PTX file from a CUDA kernel is a pretty straightforward process. First, we need a CUDA kernel, we will use a simple vector addition kernel for this article, as shown below:\r\n\r\n&lt;pre&gt;__global__ void addVectors(\r\nconst float* a,\r\nconst float* b,\r\nfloat *c,\r\nconst int n)\r\n{\r\nconst int idx = blockIdx.x * blockDim.x + threadIdx.x;\r\n\r\nc[idx] = a[idx] + b[idx];\r\n}\r\n\r\nAfter the code is properly saved to a file with the `.cu` extension, here the file name is `add_vectors.cu`, we simply call the NVCC compiler with the `--ptx` argument.\r\n\r\nnvcc --ptx add_vectors.cu\r\n\r\nThe output is a simple text file named `add_vectors.ptx`.\r\n\r\nFor the OpenCL case, as most people familiar with both technologies would expect, the process to retrieve the PTX file is a bit more complicated, it requires the host-side code and the file will only be extracted at runtime, which means that the host-side code must be compiled.\r\n\r\n\r\n\r\n[1] http://docs.nvidia.com/cuda/parallel-thread-execution','Generating PTX files from OpenCL code','','inherit','open','open','','6495-revision-v1','','','2014-08-24 22:40:11','2014-08-24 22:40:11','',6495,'http://sandbox.arrayfire.com/6495-revision-v1/',0,'revision','',0);

INSERT INTO `wp_posts` VALUES (6647,1,'2014-09-16 00:12:20','2014-09-16 00:12:20','[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://sandbox.arrayfire.com/download\" 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 src=\"//fast.wistia.com/assets/external/E-v1.js\" charset=\"ISO-8859-1\"></script><script>// <![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://sandbox.arrayfire.com/download\" 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-e1409844599610.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 class=\"aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/CUDA-logo.jpg\" alt=\"CUDA logo\" width=\"231\" height=\"140\" />\r\n\r\n<img class=\"aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/OpenCLLogo_678x452.png\" alt=\"OpenCL\" 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<h5>ArrayFire for C, C++, and Fortran</h5>\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/installation.htm\" target=\"_blank\">CUDA &amp; OpenCL C/C++</a>\r\n<h5>Functions</h5>\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<h5>User Forums</h5>\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-e1395437543311.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 src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/matrix_multiply-1024x730.png\" alt=\"Matrix Multiply\" width=\"491\" height=\"350\" />[line]<img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/matrix_transpose-1024x730.png\" alt=\"Matrix Transpose\" width=\"491\" height=\"350\" />[line]<img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/fft-1024x730.png\" alt=\"FFT\" width=\"491\" height=\"350\" />[/tab][tab]<img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/lu-1024x730.png\" alt=\"LU\" width=\"491\" height=\"350\" />[line]<img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/svd-1024x730.png\" alt=\"SVD\" width=\"491\" height=\"350\" />[line]<img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/solve-1024x730.png\" alt=\"Solve\" width=\"491\" height=\"350\" />[/tab][tab]<img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/convs-1024x730.png\" alt=\"Convs\" width=\"491\" height=\"350\" />[line]<img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/conv-1024x730.png\" alt=\"Conv\" width=\"491\" height=\"350\" />[/tab][tab]<img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/sum-1024x730.png\" alt=\"sum\" width=\"491\" height=\"350\" />[line]<img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/sort-1024x730.png\" alt=\"sort\" width=\"491\" height=\"350\" />[line]<img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/scan-1024x730.png\" alt=\"scan\" 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://sandbox.arrayfire.com/download\"]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/product-category/arrayfire/\"] 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/product-category/arrayfire/\"]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/product-category/arrayfire/\"] 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://go.sandbox.arrayfire.com/l/37882/2014-05-29/dw83/37882/18534/arrayfire_matrix_computations_chrzeszczyk.pdf\" shape=\"rounded\" size=\"regular\" block=\"true\"]Download <em>Matrix Computations on the GPU with ArrayFire for C/C++</em>[/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 src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Whitepaper-1.png\" alt=\"Whitepaper 1\" 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 src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/Whitepaper-2.png\" alt=\"Whitepaper 2\" 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://go.sandbox.arrayfire.com/l/37882/2014-05-29/dw81/37882/18532/arrayfire_whitepaper.pdf\" shape=\"rounded\" size=\"regular\"  block=\"true\" float=\"right\"]Download <em>High-level GPU Computing in C, C++, and Fortran</em>[/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-e1409844543721.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-e1409844224608.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-e1409844116266.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','open','','245-revision-v1','','','2014-09-16 00:12:20','2014-09-16 00:12:20','',245,'http://sandbox.arrayfire.com/245-revision-v1/',0,'revision','',0),(6648,7,'2014-11-12 15:09:08','2014-11-12 15:09:08','[content_band inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"10px\" padding_bottom=\"40px\"]\r\n\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h2\" ]Choose your own support[/custom_headline]\r\n\r\nEveryone could use a hand now and then. Choose from among three ArrayFire support packages, or simply go hour-by-hour. Whatever your level of need, the ArrayFire team is here for you.\r\n\r\nOur ArrayFire developers are the best in the business. With a support package, you can tap into their extensive knowledge base directly—no more waiting for forums, and no sketchy responses from Joe Schmo. Don\'t lose precious time and money fumbling for answers. Get some support.\r\n\r\nSupport issues generally include installation, compilation, builds for unique systems, debugging, ArrayFire feature development, and profiling. Custom code development would be better serviced via our <a href=\"http://sandbox.arrayfire.com/?page_id=6634\">consulting services</a>.\r\n\r\n[button type=\"flat\" shape=\"rounded\" size=\"regular\" href=\"http://meetme.so/arrayfire\"]Schedule a support consultation[/button][/column][column type=\"one-half\" last=\"true\"][gap size=\"10%\"]\r\n\r\n<img class=\"aligncenter wp-image-4822\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/dj-Flame-1024x769.png\" alt=\"dj Flame\" width=\"506\" height=\"380\" />[/column][/content_band]\r\n\r\n[content_band bg_color=\"#F2f2f2\" inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"10px\" padding_bottom=\"40px\"][gap size=\"4%\"]\r\n\r\n[column type=\"three-fourths\"][pricing_table columns=\"3\"] [pricing_table_column title=\"Smolder\" currency=\"$\" price=\"500/mo.\" interval=\"$4,800 Annual Prepay (20% discount)\" ][icon_list][icon_list_item type=\"star\"]2 hours of support[/icon_list_item][icon_list_item type=\"star\"]48-hour response time[/icon_list_item][icon_list_item type=\"times-circle\" ]Phone support[/icon_list_item][icon_list_item type=\"times-circle\" ]Dedicated engineer[/icon_list_item][/icon_list][button shape=\"rounded\" href=\"http://sandbox.arrayfire.com/product/smolder-support-package-monthly/\"  title=\"Example\"]Go Smolder[/button] [/pricing_table_column] [pricing_table_column  featured=\"true\" featured_sub=\"Most Popular\" title=\"Flame\" currency=\"$\" price=\"750/mo.\" interval=\"$7,200 Annual Prepay (20% discount)\" ][icon_list][icon_list_item type=\"star\"]5 hours of support[/icon_list_item][icon_list_item type=\"star\"]24-hour response time[/icon_list_item][icon_list_item type=\"star\"]Phone support[/icon_list_item][icon_list_item type=\"star\" ]Dedicated engineer[/icon_list_item][/icon_list][button shape=\"rounded\"  size=\"x-large\" href=\"http://sandbox.arrayfire.com/product/blaze-support-package-monthly/\" title=\"Example\"]Go Flame[/button][/pricing_table_column] [pricing_table_column title=\"Inferno\" currency=\"$\" price=\"999/mo.\" interval=\"$9,590 Annual Prepay (20% discount)\"][icon_list][icon_list_item type=\"star\"]10 hours of support[/icon_list_item][icon_list_item type=\"star\"]2-hour response time[/icon_list_item][icon_list_item type=\"star\" ]Phone support[/icon_list_item][icon_list_item type=\"star\"]Dedicated engineer[/icon_list_item][/icon_list][button shape=\"rounded\" href=\"http://sandbox.arrayfire.com/product/inferno-support-package-monthly/\" title=\"Example\"]Go Inferno[/button][/pricing_table_column][/pricing_table][/column][column type=\"one-fourth\" last=\"true\"][pricing_table columns=\"1\"][pricing_table_column  title=\"Hourly\" currency=\"$\" price=\"200/hr.\" interval=\".\"][icon_list][icon_list_item]As needed[/icon_list_item][icon_list_item]As available[/icon_list_item][icon_list_item type=\"star\"]Phone support[/icon_list_item][icon_list_item type=\"star\"]Dedicated engineer[/icon_list_item][/icon_list][button shape=\"rounded\" href=\"http://sandbox.arrayfire.com/product/custom-application-consulting-hourly-rate/\" title=\"Example\"]Go Hourly[/button][/pricing_table_column] [/pricing_table][/column]\r\n\r\n[column type=\"one-half\"][custom_headline type=\"left\" level=\"h2\" ]FAQs[/custom_headline]\r\n\r\n<strong>What\'s the advantage to having a support package rather than the hourly support?</strong>\r\n\r\nHour-to-hour, most of our support packages are more economical. Additionally, all support packages have priority status over hourly support. Issues submitted by those having support packages will be placed at the top of the support queue. We will respond to hourly purchases as our engineers become available.\r\n\r\n<strong>What do you mean by \"dedicated engineer\"?</strong>\r\n\r\nBy \"dedicated engineer\" we  mean that you will be matched with a specific engineer when you sign up. That engineer will be your point-man for the length of your purchase period. No carousel of strangers, unfamiliar with your work—just answers from your trusty ArrayFire engineer.\r\n\r\n<strong>If I don\'t use my monthly allotment of support, will the unused hours rollover?</strong>\r\n\r\nNo, there\'s no hoarding of hours here. We like to make sure our engineers are available to all who need assistance.\r\n\r\n[/column]\r\n\r\n[column type=\"one-half\" last=\"true\"][gap size=\"20%\"]\r\n\r\n<strong>I\'m new to GPU computing, and I\'m not sure what I need. What do you suggest?</strong>\r\n\r\nAwesome. Welcome to the world of parallel processing! We recommend that you look into our <a href=\"http://sandbox.arrayfire.com/?page_id=6634/#starter\">Starter Package</a>. This is a great option for first-timers as well as pros looking for a general assessment of their code.\r\n\r\n<strong>If I buy a support package, am I limited to those hours?</strong>\r\n\r\nNo. The indicated hours of support are included in your support package, but should you require more, you may purchase additional support at our hourly rate.\r\n\r\n<strong>So you guys are accessible all day and all night, weekends included?</strong>\r\n\r\nNegative. These response times are limited to standard operating hours, Monday through Friday, 8:00 am-5:00 pm EST. [/column]\r\n<p class=\"x-code\">[/content_band]</p>','Support','','publish','closed','closed','','support','','','2015-05-04 19:37:09','2015-05-04 19:37:09','',0,'http://sandbox.arrayfire.com/?page_id=6648',0,'page','',0),(6649,7,'2014-09-16 14:26:19','2014-09-16 14:26:19','','Support, OPSC','','inherit','open','open','','6648-revision-v1','','','2014-09-16 14:26:19','2014-09-16 14:26:19','',6648,'http://sandbox.arrayfire.com/6648-revision-v1/',0,'revision','',0),(6650,7,'2014-09-16 20:20:45','2014-09-16 20:20: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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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://sandbox.arrayfire.com/download\" 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%\"][/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-16 20:20:45','2014-09-16 20:20:45','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6651,7,'2014-09-17 15:51:46','2014-09-17 15:51:46','[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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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://sandbox.arrayfire.com/download\" 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\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 15:51:46','2014-09-17 15:51:46','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6652,7,'2014-09-17 15:55:55','2014-09-17 15:55:55','[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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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://sandbox.arrayfire.com/download\" 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\"][custom_headline type=\"left\" level=\"h3\"]Faster code[/custom_headline][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\"][custom_headline type=\"left\" level=\"h3\"]Open Source[/custom_headline][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\"][custom_headline type=\"left\" level=\"h3\"]Hardware Neutral[/custom_headline][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\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 15:55:55','2014-09-17 15:55:55','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6653,7,'2014-09-17 16:05:03','2014-09-17 16:05:03','[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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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\n&nbsp;\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://sandbox.arrayfire.com/download\" 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\"][custom_headline type=\"left\" level=\"h3\"]Faster code[/custom_headline][line]ArrayFire is a blazing fast 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.[/column][column type=\"one-third\" class=\"center-text\"][custom_headline type=\"left\" level=\"h3\"]Hardware neutral[/custom_headline][line]ArrayFire 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.[/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][custom_headline type=\"left\" level=\"h3\"]Open Source[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. While you\'re at it, check out our excellent documentation and pick up some tips on our forums![/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 16:05:03','2014-09-17 16:05:03','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6654,7,'2014-09-17 16:06:11','2014-09-17 16:06:11','[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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\"]Faster code[/custom_headline][line]ArrayFire is a blazing fast 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.[/column][column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\"]Hardware neutral[/custom_headline][line]ArrayFire 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.[/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\"]Open Source[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. While you\'re at it, check out our excellent documentation and pick up some tips on our forums![/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 16:06:11','2014-09-17 16:06:11','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6655,7,'2014-09-17 16:06:53','2014-09-17 16:06:53','[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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]Faster code[/custom_headline][line]ArrayFire is a blazing fast 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.[/column][column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\"]Hardware neutral[/custom_headline][line]ArrayFire 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.[/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\"]Open Source[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. While you\'re at it, check out our excellent documentation and pick up some tips on our forums![/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 16:06:53','2014-09-17 16:06:53','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6656,7,'2014-09-17 16:07:15','2014-09-17 16:07:15','[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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]Faster code[/custom_headline][line]ArrayFire is a blazing fast 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.[/column][column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]Hardware neutral[/custom_headline][line]ArrayFire 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.[/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]Open Source[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. While you\'re at it, check out our excellent documentation and pick up some tips on our forums![/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 16:07:15','2014-09-17 16:07:15','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6657,7,'2014-09-17 16:07:50','2014-09-17 16:07:50','[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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]FASTER CODE[/custom_headline][line]ArrayFire is a blazing fast 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.[/column][column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]HARDWARE NEUTRAL[/custom_headline][line]ArrayFire 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.[/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]OPEN SOURCE[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. While you\'re at it, check out our excellent documentation and pick up some tips on our forums![/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 16:07:50','2014-09-17 16:07:50','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6658,7,'2014-09-17 16:09:01','2014-09-17 16:09:01','[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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]FASTER CODE[/custom_headline][line]ArrayFire is a blazing fast 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.[/column][column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]HARDWARE NEUTRAL[/custom_headline][line]ArrayFire 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.[/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]OPEN SOURCE[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. And don\'t forget to check out our excellent documentation and pick up some tips and best practices on our forums![/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 16:09:01','2014-09-17 16:09:01','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6659,7,'2014-09-17 16:13:31','2014-09-17 16:13:31','[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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]FASTER CODE[/custom_headline][line]ArrayFire is a blazing fast 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.[/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]OPEN SOURCE[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. And don\'t forget to check out our excellent documentation and pick up some tips and best practices on our forums![/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]HARDWARE NEUTRAL[/custom_headline][line]ArrayFire 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.[/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 16:13:31','2014-09-17 16:13:31','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6660,7,'2014-09-17 16:15:40','2014-09-17 16:15:40','[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://sandbox.arrayfire.com/download\" 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\"></div>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]FASTER CODE[/custom_headline][line]ArrayFire is a blazing fast 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.[/column][column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]HARDWARE NEUTRAL[/custom_headline][line]ArrayFire 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.[/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]OPEN SOURCE[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. And don\'t forget to check out our excellent documentation and pick up some tips and best practices from the ArrayFire community on our forums![/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 16:15:40','2014-09-17 16:15:40','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6661,7,'2014-09-17 18:29:24','2014-09-17 18:29:24','[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://sandbox.arrayfire.com/download\" 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 src=\"//fast.wistia.com/assets/external/E-v1.js\" charset=\"ISO-8859-1\"></script><script>// <![CDATA[\r\nwistiaEmbed = Wistia.embed(\"rj2bar3xxp\");\r\n// ]]></script>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]FASTER CODE[/custom_headline][line]ArrayFire is a blazing fast 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.[/column][column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]HARDWARE NEUTRAL[/custom_headline][line]ArrayFire 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.[/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]OPEN SOURCE[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. And don\'t forget to check out our excellent documentation and pick up some tips and best practices from the ArrayFire community on our forums![/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 18:29:24','2014-09-17 18:29:24','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6663,7,'2014-09-17 18:33:53','2014-09-17 18:33:53','[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://sandbox.arrayfire.com/download\" 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 src=\"//fast.wistia.com/assets/external/E-v1.js\" charset=\"ISO-8859-1\"></script><script>// <![CDATA[\r\nwistiaEmbed = Wistia.embed(\"rj2bar3xxp\");\r\n// ]]></script>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]FASTER CODE[/custom_headline][line]ArrayFire is a blazing fast 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[button  type=\"flat\" block=\"true\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"regular\" ]Learn more[/button][/column][column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]HARDWARE NEUTRAL[/custom_headline][line]ArrayFire 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.[/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]OPEN SOURCE[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. And don\'t forget to check out our excellent documentation and pick up some tips and best practices from the ArrayFire community on our forums![/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 18:33:53','2014-09-17 18:33:53','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6664,7,'2014-09-17 18:34:35','2014-09-17 18:34:35','[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://sandbox.arrayfire.com/download\" 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 src=\"//fast.wistia.com/assets/external/E-v1.js\" charset=\"ISO-8859-1\"></script><script>// <![CDATA[\r\nwistiaEmbed = Wistia.embed(\"rj2bar3xxp\");\r\n// ]]></script>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]FASTER CODE[/custom_headline][line]ArrayFire is a blazing fast 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[button  type=\"flat\" block=\"true\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"regular\" ]LEARN MORE[/button][/column][column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]HARDWARE NEUTRAL[/custom_headline][line]ArrayFire 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.[/column][column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]OPEN SOURCE[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. And don\'t forget to check out our excellent documentation and pick up some tips and best practices from the ArrayFire community on our forums![/column]\r\n<div id=\"hardware\"></div>\r\n[/content_band]\r\n\r\n&nbsp;','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 18:34:35','2014-09-17 18:34:35','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6665,7,'2014-09-17 18:49:42','2014-09-17 18:49:42','[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://sandbox.arrayfire.com/download\" 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 src=\"//fast.wistia.com/assets/external/E-v1.js\" charset=\"ISO-8859-1\"></script><script>// <![CDATA[\r\nwistiaEmbed = Wistia.embed(\"rj2bar3xxp\");\r\n// ]]></script>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]FASTER CODE[/custom_headline][line]ArrayFire is a blazing fast 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.[/column]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]HARDWARE NEUTRAL[/custom_headline][line]ArrayFire 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.[/column]\r\n\r\n[column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]OPEN SOURCE[/custom_headline][line]ArrayFire is open source—it\'s all there and it\'s all free. And don\'t forget to check out our excellent documentation and pick up some tips and best practices from the ArrayFire community on our forums![/column]\r\n\r\n[column type=\"one-third\" class=\"center-text\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"regular\" ]Learn more[/button][/column]\r\n\r\n[column type=\"one-third\" class=\"center-text\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"regular\" ]Learn more[/button][/column]\r\n\r\n[column type=\"one-third\" class=\"center-text\" last=\"true\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"regular\" ]Learn more[/button][/column]\r\n<div id=\"hardware\">[/content_band]</div>','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 18:49:42','2014-09-17 18:49:42','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6666,7,'2014-09-17 20:37:40','2014-09-17 20:37:40','[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://sandbox.arrayfire.com/download\" 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 src=\"//fast.wistia.com/assets/external/E-v1.js\" charset=\"ISO-8859-1\"></script><script>// <![CDATA[\r\nwistiaEmbed = Wistia.embed(\"rj2bar3xxp\");\r\n// ]]></script>\r\n[/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\"]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]FASTER CODE[/custom_headline][line]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]\r\n\r\n[column type=\"one-third\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]HARDWARE NEUTRAL[/custom_headline][line]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]\r\n\r\n[column type=\"one-third\" last=\"true\" ][custom_headline type=\"left\" level=\"h3\" class=\"center-text\"]OPEN SOURCE[/custom_headline][line]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 well-composed documentation. And don\'t forget to visit our forums to connect with the ArrayFire community and pick up acceleration tips and innovative best practices.[/column][gap size=\"1%\"]\r\n\r\n[column type=\"one-third\" class=\"center-text\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"regular\" ]Learn more[/button][/column]\r\n\r\n[column type=\"one-third\" class=\"center-text\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"regular\" ]Learn more[/button][/column]\r\n\r\n[column type=\"one-third\" class=\"center-text\" last=\"true\"][button  type=\"flat\" shape=\"rounded\" href=\"http://www.meetme.so/arrayfire\" size=\"regular\" ]Learn more[/button][/column]\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n<div id=\"hardware\">[/content_band]</div>','Home OPSC','','inherit','open','open','','6613-revision-v1','','','2014-09-17 20:37:40','2014-09-17 20:37:40','',6613,'http://sandbox.arrayfire.com/6613-revision-v1/',0,'revision','',0),(6696,7,'2014-09-18 15:06:12','2014-09-18 15:06:12','<div>\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\"]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\"][gap size=\"5%\"] [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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:06:12','2014-09-18 15:06:12','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6697,7,'2014-09-18 15:06:47','2014-09-18 15:06:47','<div>\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\"]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\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][gap size=\"2%\"][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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:06:47','2014-09-18 15:06:47','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6698,7,'2014-09-18 15:07:02','2014-09-18 15:07:02','<div>\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\"]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\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][gap size=\"3%\"][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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:07:02','2014-09-18 15:07:02','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6699,7,'2014-09-18 15:21:23','2014-09-18 15:21:23','<div>\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\"]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=\"large\" block=\"true\"]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\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][gap size=\"3%\"][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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:21:23','2014-09-18 15:21:23','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6700,7,'2014-09-18 15:21:52','2014-09-18 15:21:52','<div>\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\"]HIRE THE ARRAYFIRE TEAM[/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=\"large\" block=\"true\"]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\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][gap size=\"3%\"][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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:21:52','2014-09-18 15:21:52','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6701,7,'2014-09-18 15:23:06','2014-09-18 15:23:06','<div>\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\"]HIRE THE ARRAYFIRE TEAM[/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=\"large\" block=\"true\"]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\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][gap size=\"3%\"][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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:23:06','2014-09-18 15:23:06','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6702,7,'2014-09-18 15:26:00','2014-09-18 15:26:00','<div>\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\"]HIRE THE ARRAYFIRE TEAM[/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=\"large\" block=\"true\"]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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:26:00','2014-09-18 15:26:00','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6703,7,'2014-09-18 15:27:15','2014-09-18 15:27:15','<div>\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\"]HIRE THE ARRAYFIRE TEAM[/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=\"large\" block=\"true\"]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=\"12%\"]\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:27:15','2014-09-18 15:27:15','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6704,7,'2014-09-18 15:27:28','2014-09-18 15:27:28','<div>\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\"]HIRE THE ARRAYFIRE TEAM[/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=\"large\" block=\"true\"]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=\"10%\"]\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:27:28','2014-09-18 15:27:28','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6705,7,'2014-09-18 15:27:55','2014-09-18 15:27:55','<div>\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\"]HIRE THE ARRAYFIRE TEAM[/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=\"large\" block=\"true\"]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] [line]\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:27:55','2014-09-18 15:27:55','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6706,7,'2014-09-18 15:28:20','2014-09-18 15:28:20','<div>\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\"]HIRE THE ARRAYFIRE TEAM[/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=\"large\" block=\"true\"]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%\"] [line]\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]\r\n\r\n</div>','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:28:20','2014-09-18 15:28:20','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6707,7,'2014-09-18 15:33:01','2014-09-18 15:33:01','[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 THE ARRAYFIRE TEAM[/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=\"large\" block=\"true\"]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%\"] [line]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]WHERE WE\'VE BEEN...[/custom_headline]\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:33:01','2014-09-18 15:33:01','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6708,7,'2014-09-18 15:33:25','2014-09-18 15:33:25','[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 THE ARRAYFIRE TEAM[/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=\"large\" block=\"true\"]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%\"] [line]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]WHERE WE\'VE BEEN LATELY[/custom_headline]\r\n\r\n&nbsp;\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:33:25','2014-09-18 15:33:25','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6709,7,'2014-09-18 15:33:39','2014-09-18 15:33:39','[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 THE ARRAYFIRE TEAM[/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=\"large\" block=\"true\"]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%\"] [line]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]WHERE WE\'VE BEEN LATELY...[/custom_headline]\r\n\r\n&nbsp;\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:33:39','2014-09-18 15:33:39','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6710,7,'2014-09-18 15:34:45','2014-09-18 15:34:45','[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 THE ARRAYFIRE TEAM[/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[Something about pricing]\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://meetme.so/arrayfire\" size=\"large\" block=\"true\"]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%\"] [line]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]WHERE WE\'VE BEEN LATELY...[/custom_headline]\r\n\r\n&nbsp;\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:34:45','2014-09-18 15:34:45','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6711,7,'2014-09-18 15:45:20','2014-09-18 15:45:20','[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 THE ARRAYFIRE TEAM[/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,  sped up data sets, and solved challenging problems of all types in the past, and we’re confident that we can accelerate your code, too.\r\n\r\nStart by setting up a free consultation to discuss your project with an ArrayFire expert.\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://meetme.so/arrayfire\" size=\"large\" block=\"true\"]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%\"] [line]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]WHERE WE\'VE BEEN LATELY...[/custom_headline]\r\n\r\n&nbsp;\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:45:20','2014-09-18 15:45:20','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6712,7,'2014-09-18 15:45:54','2014-09-18 15:45:54','[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 THE ARRAYFIRE TEAM[/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,  sped up data sets, and solved challenging problems of all types in the past, and we’re confident that we can accelerate your code, too.\r\n\r\nStart by setting up a free consultation to discuss your project with an ArrayFire expert today!\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://meetme.so/arrayfire\" size=\"large\" block=\"true\"]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%\"] [line]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]WHERE WE\'VE BEEN LATELY...[/custom_headline]\r\n\r\n&nbsp;\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:45:54','2014-09-18 15:45:54','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6713,7,'2014-09-18 15:47:03','2014-09-18 15:47:03','[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 THE ARRAYFIRE TEAM[/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,  sped up data sets, and solved challenging problems of all types in the past, and we’re confident that we can accelerate your code, too.\r\n\r\nStart by setting up a free consultation to discuss your project with an ArrayFire expert today!\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://meetme.so/arrayfire\" size=\"large\" block=\"true\"]Schedule a consultation[/button][/column][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"10%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/Bat-signal-e1391790016951.png\"][/column] [gap size=\"7%\"] [line]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]WHERE WE\'VE BEEN LATELY...[/custom_headline]\r\n\r\n&nbsp;\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:47:03','2014-09-18 15:47:03','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6714,7,'2014-09-18 15:47:32','2014-09-18 15:47:32','[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 THE ARRAYFIRE TEAM[/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,  sped up data sets, and solved challenging problems of all types in the past, and we’re confident that we can accelerate your code, too.\r\n\r\nStart by setting up a free consultation to discuss your project with an ArrayFire expert today!\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://meetme.so/arrayfire\" size=\"large\" block=\"true\"]Schedule a consultation[/button][/column][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"15%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/Bat-signal-e1391790016951.png\"][/column] [gap size=\"7%\"] [line]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]WHERE WE\'VE BEEN LATELY...[/custom_headline]\r\n\r\n&nbsp;\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:47:32','2014-09-18 15:47:32','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6715,7,'2014-09-18 15:48:04','2014-09-18 15:48:04','[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 THE ARRAYFIRE TEAM[/custom_headline]\r\n\r\nHire us to accelerate your code, 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,  sped up data sets, and solved challenging problems of all types in the past, and we’re confident that we can accelerate your code, too.\r\n\r\nStart by setting up a free consultation to discuss your project with an ArrayFire expert today!\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://meetme.so/arrayfire\" size=\"large\" block=\"true\"]Schedule a consultation[/button][/column][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"15%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/Bat-signal-e1391790016951.png\"][/column] [gap size=\"7%\"] [line]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]WHERE WE\'VE BEEN LATELY...[/custom_headline]\r\n\r\n&nbsp;\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:48:04','2014-09-18 15:48:04','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6716,7,'2014-09-18 15:48:37','2014-09-18 15:48:37','[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 THE ARRAYFIRE TEAM[/custom_headline]\r\n\r\nHire us to accelerate your code, train your pros, or even write new code for your organization!\r\n\r\nWe’ve already helped thousands of organizations speedup their code. We’ve accelerated algorithms,  sped up data sets, and solved challenging problems of all types in the past, and we’re confident that we can accelerate your code, too.\r\n\r\nStart by setting up a free consultation to discuss your project with an ArrayFire expert today!\r\n\r\n[gap size=\"10%\"][button  type=\"flat\" shape=\"rounded\" href=\"http://meetme.so/arrayfire\" size=\"large\" block=\"true\"]Schedule a consultation[/button][/column][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"15%\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/Bat-signal-e1391790016951.png\"][/column] [gap size=\"7%\"] [line]\r\n\r\n[custom_headline type=\"left\" level=\"h3\"]WHERE WE\'VE BEEN LATELY...[/custom_headline]\r\n\r\n&nbsp;\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\"][/column][column type=\"one-third\" class=\"center-text\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/reveal_logo-e1396449044651.jpg\"][/column][column type=\"one-third\" last=\"true\" class=\"center-text\"][gap size=\"5%\"] [image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/04/1800contactlogo.png\"][/column]\r\n\r\n[column type=\"one-third\" ][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\" ][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\" ][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></div>\r\n[/content_band]','Consulting, OPSC','','inherit','open','open','','6634-revision-v1','','','2014-09-18 15:48:37','2014-09-18 15:48:37','',6634,'http://sandbox.arrayfire.com/6634-revision-v1/',0,'revision','',0),(6730,7,'2014-09-18 21:30:17','2014-09-18 21:30:17','<div>\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\"][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[gap size=\"5%\"]\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]\r\n\r\n</div>','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:30:17','2014-09-18 21:30:17','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6731,7,'2014-09-18 21:31:36','2014-09-18 21:31:36','<div>\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\"][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[gap size=\"5%\"]\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]\r\n\r\n</div>','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:31:36','2014-09-18 21:31:36','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6732,7,'2014-09-18 21:32:54','2014-09-18 21:32:54','[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\"]\r\n\r\n[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[gap size=\"17%\"]\r\n\r\n[/column][column type=\"one-half\" last=\"true\"][button type=\"flat\" shape=\"rounded\" size=\"jumbo\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]\r\n\r\n[/column]\r\n\r\n[gap size=\"5%\"]\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]','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:32:54','2014-09-18 21:32:54','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6733,7,'2014-09-18 21:33:22','2014-09-18 21:33:22','[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\"]\r\n\r\n[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][column type=\"one-half\" last=\"true\"][button type=\"flat\" shape=\"rounded\" size=\"jumbo\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]\r\n\r\n[/column]\r\n\r\n[gap size=\"5%\"]\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]','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:33:22','2014-09-18 21:33:22','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6734,7,'2014-09-18 21:34:05','2014-09-18 21:34:05','[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\"]\r\n\r\n[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][column type=\"one-half\" last=\"true\"][gap size=\"15%\"][button type=\"flat\" shape=\"rounded\" size=\"jumbo\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]\r\n\r\n[/column]\r\n\r\n[gap size=\"5%\"]\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]','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:34:05','2014-09-18 21:34:05','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6735,7,'2014-09-18 21:34:21','2014-09-18 21:34:21','[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\"]\r\n\r\n[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][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"15%\"][button type=\"flat\" shape=\"rounded\" size=\"jumbo\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]\r\n\r\n[/column]\r\n\r\n[gap size=\"5%\"]\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]','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:34:21','2014-09-18 21:34:21','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6736,7,'2014-09-18 21:34:53','2014-09-18 21:34:53','[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\"]\r\n\r\n[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][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"15%\"][button type=\"flat\" shape=\"rounded\" block=\"true\" size=\"large\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]\r\n\r\n[/column]\r\n\r\n[gap size=\"5%\"]\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]','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:34:53','2014-09-18 21:34:53','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6737,7,'2014-09-18 21:35:29','2014-09-18 21:35:29','[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\"]\r\n\r\n[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][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"15%\"][button type=\"flat\" shape=\"rounded\" block=\"true\" size=\"jumbo\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]\r\n\r\n[/column]\r\n\r\n[gap size=\"5%\"]\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]','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:35:29','2014-09-18 21:35:29','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6738,7,'2014-09-18 21:35:44','2014-09-18 21:35:44','[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\"]\r\n\r\n[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][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"15%\"][button type=\"flat\" shape=\"rounded\" block=\"true\" size=\"large\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]\r\n\r\n[/column]\r\n\r\n[gap size=\"5%\"]\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]','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:35:44','2014-09-18 21:35:44','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6739,7,'2014-09-18 21:35:59','2014-09-18 21:35:59','[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\"]\r\n\r\n[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][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"15%\"][button type=\"flat\" shape=\"rounded\" block=\"true\" size=\"large\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]\r\n\r\n[/column]\r\n\r\n[gap size=\"5%\"]\r\n\r\n[line]\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]','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:35:59','2014-09-18 21:35:59','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6740,7,'2014-09-18 21:36:16','2014-09-18 21:36:16','[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\"]\r\n\r\n[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][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"15%\"][button type=\"flat\" shape=\"rounded\" block=\"true\" size=\"large\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]\r\n\r\n[/column]\r\n\r\n[line]\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]','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:36:16','2014-09-18 21:36:16','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),(6741,7,'2014-09-18 21:36:26','2014-09-18 21:36:26','[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\"]\r\n\r\n[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][column type=\"one-half\" last=\"true\" class=\"center-text\"][gap size=\"15%\"][button type=\"flat\" shape=\"rounded\" block=\"true\" size=\"large\" href=\"mailto:sales@arrayfire.com?Subject=Training%20Inquiry\"] Register for Training[/button]\r\n\r\n[/column]\r\n\r\n&nbsp;\r\n\r\n[line]\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]','Training, OPSC','','inherit','open','open','','6640-revision-v1','','','2014-09-18 21:36:26','2014-09-18 21:36:26','',6640,'http://sandbox.arrayfire.com/6640-revision-v1/',0,'revision','',0),